如何用CMake将系统库静态链接到静态库?
CMake静态库链接系统库及CRT版本冲突解决方案
一、链接crypt32、libucrt.lib等系统库
静态库本质是目标文件的归档集合,无法直接将外部系统库的代码合并到自身归档中,但可以通过CMake的依赖配置让下游项目自动链接这些库,具体操作如下:
1. 声明系统库依赖
使用target_link_libraries为MyLibrary添加系统库依赖,CMake会自动将这些依赖传递给所有使用该库的项目:
add_library( MyLibrary STATIC ${MyLibrarySourceFiles} $<TARGET_OBJECTS:SubLib1> $<TARGET_OBJECTS:SubLib2> ) # 链接crypt32和静态UCRT库 target_link_libraries(MyLibrary PRIVATE crypt32 libucrt.lib)
- Windows系统库如
crypt32无需指定完整路径,CMake会自动在系统库目录中查找; libucrt.lib是UCRT的静态版本,若需链接动态版本可替换为ucrt.lib。
2. 配置静态链接CRT解决版本冲突
你遇到的Release版库无法在Debug测试应用中使用的问题,核心是CRT版本不匹配。通过让MyLibrary静态链接CRT,可避免这类冲突:
# 针对MSVC,设置Release模式下静态链接CRT set_target_properties(MyLibrary PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Release>:>" )
- 该配置会让
MyLibrary在Release模式下链接静态UCRT(libucrt.lib),此时下游测试应用无论使用Release还是Debug模式,只要自身也配置为静态链接CRT,就能正常编译运行; - 若下游项目必须使用动态Debug CRT,此方法无法解决,建议为
MyLibrary同步提供Debug版本。
二、静态库合并的注意事项
你用$<TARGET_OBJECTS>合并子库目标文件的方式是有效的,但需注意:
- 此方式仅合并子库的目标文件,子库的依赖不会自动传递,需手动将子库的依赖添加到
MyLibrary的target_link_libraries中; - 系统库无法通过
$<TARGET_OBJECTS>合并,只能通过依赖声明让下游项目链接。
内容的提问来源于stack exchange,提问作者gvanvoor
相关产品推荐
相关产品推荐

