windows下cmake生成静态库必须显式指定static,否则默认生成动态库;头文件需通过target_include_directories(public)声明路径;.lib输出由archive_output_directory控制;链接时须用public/private明确依赖传播。

add_library 必须显式写 STATIC,否则默认生成动态库(.dll),Windows 下不会产出 .lib 文件。
add_library STATIC 参数不能省略
Windows 上 CMake 默认行为是生成动态库,哪怕你只打算链接进本地项目,不写 STATIC 就会出 .dll + .lib 导出库(不是静态库),而真正需要的纯静态 .lib 会被跳过。
-
add_library(mylib STATIC mylib.cpp)→ 输出mylib.lib(正确) -
add_library(mylib mylib.cpp)→ 输出mylib.dll和mylib.lib(导出符号用的 stub lib,不是静态库) -
add_library(mylib SHARED mylib.cpp)→ 同上,明确声明动态库
别信“CMake 会根据平台自动判断”——它不会。Windows 下必须硬写 STATIC。
头文件要进 target_include_directories(PUBLIC)
只把 .h 文件列在 add_library 参数里(比如 add_library(mylib STATIC mylib.cpp mylib.h))能让构建依赖生效,但不解决包含路径问题。调用方 #include "mylib.h" 仍会报错找不到头文件。
- 必须加
target_include_directories(mylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -
PUBLIC表示:这个目录既供库自己编译用,也透传给所有链接该库的目标 - 如果头文件在
include/子目录下,路径就得写成${CMAKE_CURRENT_SOURCE_DIR}/include
ARCHIVE_OUTPUT_DIRECTORY 控制 .lib 输出位置
静态库在 Windows 是 .lib 文件,对应 CMake 的 ARCHIVE 类型输出(不是 LIBRARY 或 RUNTIME)。不设路径的话,默认落在 build/lib/ 下,且名字可能带配置后缀(如 mylibd.lib)。
- 用
set_target_properties(mylib PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) - 避免用
LIBRARY_OUTPUT_DIRECTORY——它管的是.dll或.so,对.lib无效 - 若需区分 Debug/Release,可追加
ARCHIVE_OUTPUT_DIRECTORY_DEBUG等属性
链接时 target_link_libraries 不能漏 PUBLIC 或 PRIVATE
如果你的主程序 add_executable(app app.cpp) 链了静态库,但没声明依赖传递性,调用方仍可能找不到库里的符号或头文件。
-
target_link_libraries(app PRIVATE mylib)→ 库代码链接进去,但头文件路径不透传 -
target_link_libraries(app PUBLIC mylib)→ 链接 + 头文件路径都继承(推荐用于工具库) - 常见错误:
target_link_libraries(app mylib)(无关键字)→ CMake 3.14+ 会警告,且行为等价于PRIVATE
静态库本身没有运行时依赖,但它的头文件路径和链接顺序必须由 target_link_libraries 显式传播,否则 app.cpp 里 #include "mylib.h" 直接失败。
STATIC 就万事大吉”——路径、作用域、输出类型三者缺一不可,少一个,.lib 就要么不存在,要么链接失败,要么头文件找不到。











