Bilibili 同步视频
在 C/C++ 工程化开发里,库的编译与链接 是绕不开的核心环节,而静态库与动态库的差异,更是很多开发者从 "能跑通" 到 "做得稳" 的必经之路。今天就用最清晰的思路,带你用 CMake 把动态库编译、链接、运行时查找 一次性讲透,全程一个 CMakeLists.txt 搞定,Linux 环境直接复用~
一、先搞懂:静态库 vs 动态库,CMake 编译差在哪?
很多刚接触 CMake 的同学会疑惑:静态库和动态库,编译配置是不是天差地别? 答案是:几乎一样!
CMake 本身就是为了简化构建流程设计的,两者的核心差异,只在 add_library 的一个关键字:
-
静态库:
add_library(xxx STATIC xxx.cpp) -
动态库:
add_library(xxx SHARED xxx.cpp)
不加关键字时,会走 CMake 默认规则(不同环境默认值不同,有的默认动态、有的默认静态)。只需要把 STATIC 换成 SHARED,就能无缝切换库类型,这也是 CMake 高效的核心体现。
除了编译标识,两者最关键的区别在查找时机:
-
✅ 静态库:仅编译期需要找到库文件,链接后会打包进可执行程序,运行时无依赖;
-
✅ 动态库:编译期 + 运行期都需要找到库文件,运行时系统会动态加载,体积更小、便于更新。
这也是动态库最容易踩坑的点:编译过了,运行却提示 "找不到库",后文会给出 CMake 原生解决方案,不用手动改环境变量~
二、工程结构设计:一个 CMakeLists 管到底
以往我们习惯把库、测试程序分两个 CMakeLists.txt 管理,这次直接合并到一个文件,同时编译动态库 + 可执行程序,工程结构如下:
Plain
102-Cmake-Lib/
├── CMakeLists.txt # 总构建文件(核心)
├── xlog/ # 动态库源码
│ ├── xlog.cpp
│ └── xlog.h
└── test-xlog/ # 测试可执行程序
└── test-xlog.cpp
所有构建逻辑都写在根目录的 CMakeLists.txt 里,后续加模块、加库都能直接扩展,不用拆分成多个文件。
三、核心 CMakeLists.txt 编写(逐行解析)
直接上可运行的完整配置,每一步都标注清楚,复制就能用:
cmake
# 1. 指定CMake最低版本(兼容现代特性)
cmake_minimum_required(VERSION 3.20)
# 2. 定义项目名称(主库为xlog,测试程序为附属)
project(XLOG)
# 3. 编译动态库:xlog(SHARED = 动态库标识)
# 源文件路径:子目录xlog下的xlog.cpp
add_library(xlog SHARED
xlog/xlog.cpp
)
# 4. 设置公共头文件路径(所有目标共享)
# 让test-xlog能找到xlog.h
include_directories(xlog)
# 5. 编译可执行程序:test-xlog
# 源文件路径:子目录test-xlog下的test-xlog.cpp
add_executable(test-xlog
test-xlog/test-xlog.cpp
)
# 6. 链接动态库:给test-xlog关联xlog库
target_link_libraries(test-xlog
xlog
)
关键配置说明
-
SHARED** 关键字**:强制编译为动态库,Linux 下输出.so、Mac 下.dylib、Windows 下.dll; -
include_directories:公共头文件路径,避免手动在每个目标里重复配置; -
target_link_libraries:目标级链接,只给test-xlog绑定xlog库,耦合度更低。
四、编译 + 运行:一键执行,运行不报错
1. 标准编译命令
bash
# 生成构建文件(输出到build目录)
cmake -S . -B build
# 编译工程
cmake --build build
编译完成后,进入 build 目录,能看到生成的文件:
-
动态库:
libxlog.so(Linux 核心动态库文件) -
可执行程序:
test-xlog
2. 运行验证:为什么不用改 LD_LIBRARY_PATH?
直接运行测试程序:
bash
cd build
./test-xlog
神奇的是:不用 export LD_LIBRARY_PATH,也能正常运行!
用 ldd 查看依赖库路径,真相一目了然:
bash
ldd test-xlog
输出结果里,libxlog.so 指向的是绝对路径,这是 CMake 自动帮我们添加的编译参数:
Plain
-Wl,-rpath=/xxx/102-Cmake-Lib/build
-
手动 GCC 编译:必须自己加
-Wl,-rpath或改环境变量,否则运行报错; -
CMake 编译:自动注入 rpath 绝对路径,运行时直接定位库文件,零配置运行。
即使把 test-xlog 复制到其他目录,依然能正常执行,只有删除原动态库后,才会去系统默认库路径查找,完美规避运行时找不到库的问题。
五、跨平台小提示
这套配置不只是 Linux 能用,跨平台直接兼容:
-
Linux:动态库 →
.so -
Mac:动态库 →
.dylib -
Windows:动态库 →
.dll+.lib
CMake 会自动根据系统适配输出格式,不用修改任何配置,真正做到 "一次编写,多平台运行"。
六、总结
-
CMake 编译静态 / 动态库,仅差
STATIC/SHARED一个关键字; -
动态库需编译期 + 运行期查找库,静态库仅编译期需要;
-
单文件
CMakeLists.txt可同时管理库 + 可执行程序,结构更简洁; -
CMake 自动添加
rpath绝对路径,Linux 运行动态库不用改环境变量; -
配置跨平台兼容,复制即用,适配 Linux/Mac/Windows。

掌握这套流程,C/C++ 工程的库编译、链接、运行问题,基本都能轻松解决~