add_library可直接创建静态库,但需显式指定STATIC参数,配合target_include_directories、target_link_libraries及install(TARGETS ... ARCHIVE)才能完整使用。

直接用 add_library 指定 STATIC 就能构建静态库,但必须配 target_include_directories 和 target_link_libraries 才能真正被其他目标使用。
add_library 里写错类型就白忙活
常见错误是漏写或写错第二个参数:add_library(mylib mylib.cpp) 默认生成的是 OBJECT 库(不是静态库),链接时会报 undefined reference;必须显式写成 add_library(mylib STATIC mylib.cpp)。Windows 下生成 mylib.lib,Linux/macOS 下生成 libmylib.a。如果源文件列表为空,CMake 不报错但链接失败——建议用 file(GLOB SRC_LIST "src/*.cpp") 自动收集,再检查 SRC_LIST 是否非空。
头文件路径不设好,别人根本没法 include
静态库自己编译没问题,但调用方 #include "mylib.h" 会失败,除非你告诉 CMake 头文件在哪。用 target_include_directories(mylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include),其中 PUBLIC 表示:这个路径既用于编译 mylib 自身,也自动透传给所有链接它的目标(比如可执行文件)。别用 PRIVATE,否则链接方看不到头文件。
install 静态库时 ARCHIVE 是关键字段
静态库安装到系统或前缀路径,必须用 ARCHIVE 字段,不是 LIBRARY(那是给动态库的):install(TARGETS mylib ARCHIVE DESTINATION lib)。同时要装头文件:install(DIRECTORY include/ DESTINATION include)。漏掉 ARCHIVE,make install 后 libmylib.a 根本不会被复制过去。另外,CMAKE_INSTALL_PREFIX 默认是 /usr/local,想改就加 -DCMAKE_INSTALL_PREFIX=/opt/myproject。
链接静态库时 target_link_libraries 的作用域不能乱
假设可执行文件叫 app,写 target_link_libraries(app PRIVATE mylib) 是最常见的正确写法。这里 PRIVATE 表示:只把 mylib 链给 app,不向更上层目标透传依赖。但如果 app 又被别的目标链接(比如测试目标),而测试目标也需要 mylib 的头文件,就得改成 PUBLIC 或拆成两行:target_link_libraries(app PRIVATE mylib) + target_include_directories(app PRIVATE $<mylib>)</mylib>。多数情况下,PRIVATE 就够用。
最容易被忽略的是:静态库目标本身不参与最终链接,它只是个中间产物;真正决定能否链接成功的,是 target_link_libraries 调用时机和作用域、头文件路径是否透传、以及 install 时有没有用对 ARCHIVE 字段。


















