CMake 012:Linux 下动态库与可执行程序的单文件构建
- Bilibili 同步视频
- 一、先搞懂:静态库 vs 动态库,CMake 编译差在哪?
- 二、工程结构设计:一个 CMakeLists 管到底
- 三、核心 CMakeLists.txt 编写(逐行解析)
- 关键配置说明
- 四、编译 + 运行:一键执行,运行不报错
- 1. 标准编译命令
- 2. 运行验证:为什么不用改 LD_LIBRARY_PATH?
- 五、跨平台小提示
- 六、总结
Bilibili 同步视频
CMake 012:Linux 下动态库与可执行程序的单文件构建
在 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管理,这次直接合并到一个文件,同时编译动态库 + 可执行程序,工程结构如下:
102-Cmake-Lib/ ├── CMakeLists.txt # 总构建文件(核心) ├── xlog/ # 动态库源码 │ ├── xlog.cpp │ └── xlog.h └── test-xlog/ # 测试可执行程序 └── test-xlog.cpp所有构建逻辑都写在根目录的CMakeLists.txt里,后续加模块、加库都能直接扩展,不用拆分成多个文件。
三、核心 CMakeLists.txt 编写(逐行解析)
直接上可运行的完整配置,每一步都标注清楚,复制就能用:
# 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. 标准编译命令
# 生成构建文件(输出到build目录)cmake-S.-Bbuild# 编译工程cmake--buildbuild编译完成后,进入build目录,能看到生成的文件:
动态库:
libxlog.so(Linux 核心动态库文件)可执行程序:
test-xlog
2. 运行验证:为什么不用改 LD_LIBRARY_PATH?
直接运行测试程序:
cdbuild ./test-xlog神奇的是:不用 export LD_LIBRARY_PATH,也能正常运行!
用ldd查看依赖库路径,真相一目了然:
ldd test-xlog输出结果里,libxlog.so指向的是绝对路径,这是 CMake 自动帮我们添加的编译参数:
-Wl,-rpath=/xxx/102-Cmake-Lib/build手动 GCC 编译:必须自己加
-Wl,-rpath或改环境变量,否则运行报错;CMake 编译:自动注入 rpath 绝对路径,运行时直接定位库文件,零配置运行。
即使把test-xlog复制到其他目录,依然能正常执行,只有删除原动态库后,才会去系统默认库路径查找,完美规避运行时找不到库的问题。
五、跨平台小提示
这套配置不只是 Linux 能用,跨平台直接兼容:
Linux:动态库 →
.soMac:动态库 →
.dylibWindows:动态库 →
.dll+.lib
CMake 会自动根据系统适配输出格式,不用修改任何配置,真正做到 “一次编写,多平台运行”。
六、总结
CMake 编译静态 / 动态库,仅差
STATIC/SHARED一个关键字;动态库需编译期 + 运行期查找库,静态库仅编译期需要;
单文件
CMakeLists.txt可同时管理库 + 可执行程序,结构更简洁;CMake 自动添加
rpath绝对路径,Linux 运行动态库不用改环境变量;配置跨平台兼容,复制即用,适配 Linux/Mac/Windows。
掌握这套流程,C/C++ 工程的库编译、链接、运行问题,基本都能轻松解决~