add_library(mylib shared src/a.cpp src/b.cpp)是最直接生成动态库的方式,cmake自动按平台生成.so/.dylib/.dll;漏写shared会默认建静态库,需显式设soversion和导出符号(windows)以确保正确链接与运行。

add_library() 里加 SHARED 关键字
生成动态库最直接的方式,就是在 add_library() 命令中把 STATIC 换成 SHARED。CMake 会自动按平台生成对应后缀:.so(Linux)、.dylib(macOS)、.dll(Windows)。
常见错误是漏写关键字,或者误用 OBJECT 或默认(无关键字)——那会生成静态库或对象库,不是你要的动态链接行为。
-
add_library(mylib SHARED src/a.cpp src/b.cpp)—— 正确 -
add_library(mylib src/a.cpp src/b.cpp)—— 默认是 STATIC,不是动态库 -
add_library(mylib OBJECT src/a.cpp)—— 只生成 .o/.obj,不链接
必须显式设置 SOVERSION 或 VERSION 吗?
不强制,但不设会导致版本混乱:Linux 下 libmylib.so 没有版本号,链接时无法区分兼容性;安装后更新库可能破坏已有程序。
推荐至少设 SOVERSION(主版本号),它控制 libmylib.so.1 这种符号链接指向:
set_target_properties(mylib PROPERTIES SOVERSION 1)- 可选加
VERSION补全完整版号:VERSION 1.2.0→ 生成libmylib.so.1.2.0,并自动创建libmylib.so.1和libmylib.so软链 - Windows 不用 SOVERSION,但
VERSION会影响 DLL 的文件版本资源(需额外配置WINDOWS_EXPORT_ALL_SYMBOLS或导出声明)
Windows 下 DLL 导出符号经常找不到?
Linux/macOS 动态库默认导出所有符号;Windows DLL 默认不导出,调用方会报 LNK2019: unresolved external symbol。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
两种主流解法:
- 用
WINDOWS_EXPORT_ALL_SYMBOLS属性(CMake 3.4+):set_property(TARGET mylib PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS ON)—— 简单但不推荐用于大型项目(导出太多、影响加载速度) - 手动控制:在头文件中用宏定义
__declspec(dllexport)(构建时)和__declspec(dllimport)(使用时),并在 CMake 中通过target_compile_definitions(mylib PRIVATE MYLIB_EXPORTS)触发导出分支
注意:WINDOWS_EXPORT_ALL_SYMBOLS 对模板、内联函数无效,仍需显式声明。
install() 时动态库路径和依赖怎么处理?
install(TARGETS mylib DESTINATION lib) 只复制库文件,不处理 RPATH 或运行时路径。结果就是:安装后程序运行时报 error while loading shared libraries: libmylib.so.1: cannot open shared object file。
关键动作有两步:
- 构建时嵌入运行时路径:
set_target_properties(mylib PROPERTIES INSTALL_RPATH "$ORIGIN/../lib")(Linux/macOS),让程序从自身所在目录向上找lib/ - 安装时确保依赖也被装走:
若mylib依赖otherlib,得一起install(TARGETS mylib otherlib ...),否则ldd查出来缺依赖
macOS 还要额外设 INSTALL_NAME_DIR,否则 otool -L 显示的路径可能是构建路径,而非安装路径。










