add_library创建静态库最安全的方式是显式指定static参数,避免受build_shared_libs变量影响;需确保目标名唯一、源文件路径正确,并用target_include_directories(... public)暴露头文件路径供链接方使用。

add_library 是创建静态库最直接的方式,不加类型参数默认就是静态库,但显式写 STATIC 更安全、可读性更强。
怎么用 add_library 创建静态库
核心就是一条命令,但要注意目标名唯一、源文件路径正确、头文件路径要暴露给使用者:
-
add_library(mylib STATIC src/a.cpp src/b.cpp)—— 显式声明STATIC,避免受全局BUILD_SHARED_LIBS影响 - 源文件路径必须存在且可被 CMake 解析;推荐用
file(GLOB ...)或target_sources()管理,不用硬编码列表 - 必须配
target_include_directories(mylib PUBLIC include/),否则链接方找不到头文件 - 如果库有内部依赖(比如用了第三方头),用
PRIVATE修饰;供外部使用的头路径必须用PUBLIC
STATIC 和不写类型有什么区别?
区别在于确定性。CMake 默认行为由 BUILD_SHARED_LIBS 控制,这个变量可能被父项目或命令行覆盖(例如 -DBUILD_SHARED_LIBS=ON),导致你以为建的是静态库,实际输出了 .so 或 .dll。
- 不写类型:
add_library(mylib src/x.cpp)→ 输出取决于BUILD_SHARED_LIBS - 显式写
STATIC:add_library(mylib STATIC src/x.cpp)→ 一定生成.a(Linux/macOS)或.lib(Windows) - 跨平台项目尤其建议显式指定,避免 CI 或他人构建时行为不一致
为什么链接静态库后编译失败?常见头文件问题
错误现象通常是 fatal error: xxx.h: No such file or directory,不是库没链接上,而是头文件没找到。
- 只在库的
CMakeLists.txt里写了target_include_directories(mylib PUBLIC include/)不够 - 必须确保链接方(比如
add_executable(app main.cpp))能“看到”这个路径,而PUBLIC属性正是干这个的 - 检查路径是否相对于
target_include_directories调用位置:如果include/在项目根目录,而CMakeLists.txt在src/下,就得写${CMAKE_SOURCE_DIR}/include - Windows 下注意路径分隔符和大小写敏感性(MSVC 通常不敏感,但 MinGW 可能敏感)
静态库安装后怎么被其他项目引用?
靠 install() + export 配合 find_package(),不是简单复制文件就能用。
-
install(TARGETS mylib ARCHIVE DESTINATION lib)→ 安装.a或.lib -
install(DIRECTORY include/ DESTINATION include)→ 安装头文件 -
install(EXPORT mylib-config NAMESPACE mylib:: DESTINATION lib/cmake/mylib)→ 生成配置文件,让find_package(mylib)能定位到 - 下游项目必须调用
find_package(mylib REQUIRED),再target_link_libraries(app PRIVATE mylib::mylib),不能直接写mylib
漏掉 export 或没设 NAMESPACE,下游 find_package 就会报 Could not find a package configuration file —— 这是静态库发布后最常卡住的地方。











