【CMake基础入门教程】第八课:构建并导出可复用的 CMake 库(支持 find_package() 查找)
很好!我们进入 第八课:构建并导出可复用的 CMake 库(支持 find_package()
查找)。
🎯 本课目标
你将掌握:
-
如何构建一个库并通过
install()
导出其配置; -
如何让别人在项目中使用
find_package(MyMathLib)
来找到你的库; -
install(EXPORT ...)
与CMake Package Config
的标准结构; -
自己项目变成像 Qt / Boost / OpenCV 那样被“可复用”的第三方库。
一、场景:我们要让 math_lib
成为“真正的可复用库”
即别人可以这样用你:
find_package(MyMathLib REQUIRED)
target_link_libraries(their_app PRIVATE MyMathLib::math_lib)
二、导出 CMake 包需要做的几步
步骤 | 操作 |
---|---|
1️⃣ 安装目标 | install(TARGETS ...) 安装库 |
2️⃣ 安装头文件 | install(FILES ...) 安装接口头 |
3️⃣ 导出目标信息 | install(EXPORT ...) |
4️⃣ 安装 CMake 配置文件 | 写 MyMathLibConfig.cmake |
5️⃣ 生成版本描述文件 | 使用 write_basic_package_version_file() |
三、完整示例:导出 math_lib 包
假设项目结构如下:
my_math_lib/
├── CMakeLists.txt
├── math/
│ ├── CMakeLists.txt
│ ├── add.h
│ └── add.cpp
└── cmake/└── MyMathLibConfig.cmake.in
📄 顶层 CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(MyMathLib VERSION 1.0 LANGUAGES CXX)# 创建导出组名(可选)
include(GNUInstallDirs)add_subdirectory(math)# 生成版本文件
include(CMakePackageConfigHelpers)
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/MyMathLibConfigVersion.cmake"VERSION ${PROJECT_VERSION}COMPATIBILITY SameMajorVersion
)# 安装配置文件
configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/MyMathLibConfig.cmake.in""${CMAKE_CURRENT_BINARY_DIR}/MyMathLibConfig.cmake"INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyMathLib
)# 安装配置 + 导出目标
install(FILES"${CMAKE_CURRENT_BINARY_DIR}/MyMathLibConfig.cmake""${CMAKE_CURRENT_BINARY_DIR}/MyMathLibConfigVersion.cmake"DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyMathLib
)
📄 math/CMakeLists.txt
add_library(math_lib add.cpp)
target_include_directories(math_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})# 设置导出别名(名字空间)
add_library(MyMathLib::math_lib ALIAS math_lib)# 安装目标
install(TARGETS math_libEXPORT MyMathLibTargetsARCHIVE DESTINATION libLIBRARY DESTINATION libRUNTIME DESTINATION binINCLUDES DESTINATION include
)# 安装头文件
install(FILES add.h DESTINATION include)# 导出目标信息(用于 find_package)
install(EXPORT MyMathLibTargetsNAMESPACE MyMathLib::DESTINATION lib/cmake/MyMathLib
)
📄 cmake/MyMathLibConfig.cmake.in
@PACKAGE_INIT@include("${CMAKE_CURRENT_LIST_DIR}/MyMathLibTargets.cmake")
四、构建 + 安装 + 使用流程
✅ 构建并安装:
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=D:/MyMathLib/install
cmake --build . --config Release
cmake --install . --config Release
📁 安装目录结构(标准化)
D:/MyMathLib/install/
├── include/
│ └── add.h
├── lib/
│ └── math_lib.lib
├── lib/cmake/MyMathLib/
│ ├── MyMathLibTargets.cmake
│ ├── MyMathLibConfig.cmake
│ └── MyMathLibConfigVersion.cmake
五、别人的项目如何使用你这个库?
示例 CMakeLists.txt:
cmake_minimum_required(VERSION 3.14)
project(UserProject LANGUAGES CXX)set(CMAKE_PREFIX_PATH "D:/MyMathLib/install") # 设置查找路径find_package(MyMathLib REQUIRED)add_executable(app main.cpp)
target_link_libraries(app PRIVATE MyMathLib::math_lib)
✅ 小结
组件 | 用途 |
---|---|
install(EXPORT ...) | 导出目标给别人用 |
MyMathLibConfig.cmake.in | 配置包的入口文件 |
write_basic_package_version_file() | 提供版本信息 |
一旦配置好,你的库就能被任何支持 find_package()
的项目复用了。
⏭️ 下一课预告:跨平台支持与条件判断(if、platform-specific)
你将学会:
-
如何为 Windows / Linux / macOS 写不同逻辑
-
如何处理编译器差异(如 MSVC / GCC)
-
用
option()
设置用户开关(如是否启用日志、测试)
是否希望我把这个完整导出库模板也整理进 Canvas?或者你希望我打包为 zip 并生成目录结构?