cmake中创建动态库唯一标准方式是add_library(... shared),平台自动处理lib前缀与.so/.dll后缀;需显式导出符号(尤其windows)、分别配置构建输出路径和install路径,并注意dll运行时依赖。

add_library(... SHARED) 是唯一正确写法
不是 add_shared_library,也不是 set_target_properties(... TYPE SHARED)——CMake 中创建动态库只有一种标准方式:add_library 加 SHARED 参数。漏掉这个关键字,或者拼错(比如写成 SHARE),就会默认生成静态库或报错。
Linux 和 Windows 的命名差异自动处理
CMake 会根据平台自动补全前缀和后缀,你只需指定库名(如 calc),它会生成:
- Linux:
libcalc.so - Windows:
calc.dll(以及配套的calc.lib导入库)
不需要手动拼接 lib 或 .so;硬编码这些会导致跨平台构建失败。
必须显式导出符号(尤其 Windows)
Linux 下通常默认导出所有符号,但 Windows 要求显式声明 __declspec(dllexport),否则链接时找不到符号。常见错误是:编译成功、链接时报 LNK2019 或运行时报 undefined symbol。
解决方法:
- 在头文件中用宏控制导出/导入,例如:
#ifdef BUILD_DLL→__declspec(dllexport),#else→__declspec(dllimport) - 在 CMake 中为动态库 target 添加编译定义:
target_compile_definitions(calc PRIVATE BUILD_DLL) - 避免依赖隐式导出(如 GCC 的
-fvisibility=hidden默认不导出,需额外配置)
输出路径和 install 需要分开设置
LIBRARY_OUTPUT_PATH 控制构建时输出位置(如 build/lib),而 install(TARGETS ... LIBRARY DESTINATION ...) 控制安装时目标路径(如 /usr/local/lib)。两者不互通,漏设任一者都会导致找不到库。
典型配置:
- 构建期:
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib) - 安装期:
install(TARGETS calc LIBRARY DESTINATION lib) - 别忘了同时
install(DIRECTORY include/ DESTINATION include)头文件
最容易被忽略的是 Windows 下 DLL 运行时依赖——即使生成了 .dll,若没把依赖的 DLL 放进 PATH 或可执行目录,程序仍会启动失败。这和 CMake 构建逻辑无关,但属于“生成了却用不了”的高频问题。











