cmake生成动态库的核心操作是add_library(name shared ...),它隐式启用-fpic并自动适配平台后缀(如.so/.dll),不加shared则默认生成静态库;需配合target_include_directories、统一c++标准、正确设置输出与安装路径。

直接用 add_library(... SHARED) 就能生成动态库,但必须加 -fPIC,否则链接会失败——CMake 默认已处理这点,你不用手动写编译选项。
为什么 add_library(name SHARED ...) 是核心操作
这是 CMake 中声明动态库的唯一标准方式。它隐式启用位置无关代码(-fPIC),并根据平台自动选择后缀(Linux 为 .so,Windows 为 .dll,macOS 为 .dylib)。不写 SHARED 就默认是静态库,写错成 STATIC 或漏掉会导致生成错误类型。
-
add_library(hello SHARED hello.cpp)→ 输出libhello.so(Linux) - 源文件路径建议用变量或
${CMAKE_CURRENT_SOURCE_DIR}显式指定,避免跨子目录时路径失效 - 如果源文件含头文件依赖,需用
target_include_directories(hello PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)暴露头文件路径,否则下游链接时找不到声明
set(CMAKE_CXX_STANDARD ...) 和编译器标准要配对
动态库的 ABI 兼容性高度依赖 C++ 标准版本。比如用 CMAKE_CXX_STANDARD 17 编译的库,若主程序用 14 链接,可能因 std::string 内存布局不同而崩溃。
- 统一设在顶层
CMakeLists.txt:set(CMAKE_CXX_STANDARD 17)、set(CMAKE_CXX_STANDARD_REQUIRED ON) - 不要在子目录里覆盖该设置,否则同一个项目混用不同标准,
undefined reference错误会很难定位 - 如需导出 C 接口,加
extern "C"声明,并禁用 name mangling,避免 C++ 符号名不一致
Windows 下用 MinGW 生成 DLL 时,MSVC 调用需要 .lib 文件
MinGW 默认只生成 .dll 和 .dll.a(GNU import library),而 MSVC 链接器只认 .lib(MS import library)。不处理会导致 LNK2019: unresolved external symbol。
- 启用转换:在调用
cmake时加-DCMAKE_GNUtoMS:BOOL=ON - 前提是系统已安装 Visual Studio 或 Windows SDK(提供
lib.exe工具) - 生成的
.lib会和.dll同名同目录,MSVC 项目里直接#pragma comment(lib, "hello.lib")即可
动态库输出路径和安装逻辑容易被忽略
默认输出到 build/ 下,但实际部署时往往需要集中管理路径,且 install() 步骤常被跳过,导致运行时报 error while loading shared libraries。
- 设输出目录:
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib) - 加安装规则:
install(TARGETS hello LIBRARY DESTINATION lib) - Linux 上运行前记得更新缓存:
ldconfig -n ${CMAKE_BINARY_DIR}/lib或临时加LD_LIBRARY_PATH











