CMake Day 8 —— 编译成一个库(利用OBJECT)
# CMake Day 8 —— 编译成一个库(利用OBJECT)
对外发布库时,通常考虑发布少量的库,此时可以收集所有源码编译成一个库,但是不够简洁,可以先编译成OBJECT库,然后再编译成目标文件。
须知:
静态库可以视作编译过程的中间文件,因为单独的静态库没有任何作用。动态库则不然,动态库可以视作最终的二进制文件,所以不存在合并动态库。通俗的讲,合并路径有如下几种:
- 静态库+静态库=静态库
- 静态库+静态库=可执行文件
- 静态库+动态库=动态库
例如有这样一个项目(https://github.com/AZMDDY/cmake-demo/tree/main/cmake-day-8/demo1):
.
├── CMakeLists.txt
├── dir1
│ ├── CMakeLists.txt
│ ├── dir3
│ │ ├── CMakeLists.txt
│ │ └── test3.cpp
│ └── test1.cpp
└── dir2
├── CMakeLists.txt
└── test2.cpp
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
如果想将这些源码编译成一个库,有三个办法:
直接获取这些源码路径,一次性编译成库。
add_library(demo1 STATIC ../dir2/test2.cpp ../dir1/test1.cpp ../dir1/dir3/test3.cpp)
1如上,这仅仅是个demo,在实际项目中不可能采用这样的方法,实际项目也会划分了很多模块,都这样编译放在一起,维护成本太高。
在编译好每个模块后,利用
ar
命令将多个静态库合并。ar crsT libdemo1.a libdemo1_test1.a libdemo1_test2.a libdemo1_test3.a
1
顺带提一下,静态库合并成动态库的方式如下:
g++ -shared -o libdemo1.so -Wl,--whole-archive dir1/libdemo1_test1.a dir1/dir3/libdemo1_test3.a dir2/libdemo1_test2.a -Wl,--no-whole-archive
1
利用OBJECT将每个模块都编译成OBJECT库,然后再将OBJECT编译成静态库或动态库。
add_library(demo1_test1_obj OBJECT test1.cpp) add_library(demo1_test2_obj OBJECT test2.cpp) add_library(demo1_test3_obj OBJECT test3.cpp) add_library(obj_demo1 SHARED $<TARGET_OBJECTS:demo1_test1_obj> $<TARGET_OBJECTS:demo1_test2_obj> $<TARGET_OBJECTS:demo1_test3_obj>)
1
2
3
4
5
上次更新: 2022/11/19, 16:52:47