【编译与代码分析记录】03 · CMake 链接静态库与动态库
CMake 链接静态库与动态库
整理自博客园旧笔记:《cmake链接静态库&动态库》(原发布于 2022-09-13)
一、项目结构
./sample7
+-- CMakeLists.txt # 顶层
+-- build/
+-- src/
+-- CMakeLists.txt
+-- main.cpp
+-- lib/
+-- libmath.a # 静态库(macOS/Windows 为 .a/.lib)
+-- libmath.dylib # 动态库(Linux 为 .so,Windows 为 .dll)
+-- Math.h
main.cpp 中引用外部 math 库:
#include <stdio.h>
#include <stdlib.h>
#include "Math.h"
int main(int argc, char *argv[])
{
double base = atof(argv[1]);
return 0;
}
二、引入外部静态库
src/CMakeLists.txt:
# 打印信息
message(STATUS "src This is BINARY dir " ${PROJECT_BINARY_DIR})
message(STATUS "src This is SOURCE dir " ${PROJECT_SOURCE_DIR})
# 定义工程根目录;CMAKE_SOURCE_DIR 为内建变量,表示工程根目录的 CMakeLists.txt 路径
SET(ROOT_DIR ${CMAKE_SOURCE_DIR})
# 指定头文件搜索路径
INCLUDE_DIRECTORIES(${ROOT_DIR}/lib)
# 指定引用的外部库的搜索路径
LINK_DIRECTORIES(${ROOT_DIR}/lib)
# 指定可执行文件存放目录
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
# 构建可执行程序
ADD_EXECUTABLE(sample7 main.cpp)
TARGET_LINK_LIBRARIES(sample7 libmath.a)
三、引入外部动态库
结构与上面完全一致,只把链接目标换成动态库:
INCLUDE_DIRECTORIES(${ROOT_DIR}/lib)
LINK_DIRECTORIES(${ROOT_DIR}/lib)
ADD_EXECUTABLE(sample7 main.cpp)
TARGET_LINK_LIBRARIES(sample7 libmath.dylib) # Linux 下为 libmath.so
四、静态库 vs 动态库
| 静态库(.a/.lib) | 动态库(.so/.dylib/.dll) | |
|---|---|---|
| 链接时机 | 链接阶段整体拷贝进最终目标(如可执行程序) | 链接阶段不拷贝,运行时按搜索规则找到后加载 |
| 内存 | 被多个程序引用时,各程序各存一份函数拷贝 | 多个程序共享同一份库代码 |
| 分发 | 可执行文件自包含、无依赖 | 目标机器上必须有该库(或随程序分发) |
| 升级 | 重新链接 | 替换库文件即可(注意 ABI 兼容与 soname) |
| 体积 | 可执行文件更大 | 可执行文件小 |
4.1、现代 CMake 推荐写法
INCLUDE_DIRECTORIES + LINK_DIRECTORIES 是"全局式"老写法,容易污染其他 target。现代写法把依赖挂在具体 target 上:
# 链接已有库
target_link_libraries(sample7 PRIVATE ${ROOT_DIR}/lib/libmath.a)
target_include_directories(sample7 PRIVATE ${ROOT_DIR}/lib)
# 项目内生成库再链接
add_library(math STATIC src/math.cpp) # 或 SHARED
target_link_libraries(sample7 PRIVATE math)
4.2、动态库运行时找不到怎么办
链接通过 ≠ 运行能跑。动态库运行时按以下顺序搜索:
- 可执行文件的
RPATH/RUNPATH(链接时-Wl,-rpath,/path写入) - 环境变量
LD_LIBRARY_PATH(Linux)/DYLD_LIBRARY_PATH(macOS) - 系统配置
/etc/ld.so.conf+ldconfig缓存
排查工具:ldd a.out(Linux)看依赖解析;otool -L a.out(macOS)。
五、常用内建变量速查
| 变量 | 含义 |
|---|---|
CMAKE_SOURCE_DIR |
顶层 CMakeLists.txt 所在目录 |
PROJECT_BINARY_DIR |
构建目录 |
CMAKE_BUILD_TYPE |
Debug/Release/RelWithDebInfo |
EXECUTABLE_OUTPUT_PATH |
可执行文件输出目录(现代用 RUNTIME_OUTPUT_DIRECTORY) |
构建命令:
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .

浙公网安备 33010602011771号