如何用CMake将libA.a、libB.a及自研源码打包为单个共享库?
把静态库+源码打包成单个共享库的实现方案
嘿,我来帮你搞定这个需求——把libA.a、libB.a还有mod1、mod2的源码打包成一个单独的共享库对吧?下面是最直接的CMake实现方案,还有几个备选思路:
核心实现方案:用CMake构建(推荐)
这是最规范、可维护的方式,适合长期迭代的项目。你只需要在项目根目录创建/修改CMakeLists.txt,步骤如下:
基础配置与头文件引入
先设置CMake版本、项目名,把所有需要的头文件目录包含进来:cmake_minimum_required(VERSION 3.10) project(my_shared_library) # 全局添加位置无关代码编译选项(如果静态库没加-fPIC的话必须加) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") # 引入所有头文件目录 include_directories( inc/mod1 inc/mod2 inc/libA inc/libB )收集源码文件
自动抓取mod1和mod2下的所有.cpp文件:# 收集mod1、mod2的源码 file(GLOB MOD1_SOURCE_FILES src/mod1/*.cpp) file(GLOB MOD2_SOURCE_FILES src/mod2/*.cpp)如果你不想用
GLOB(担心文件变动没被检测到),也可以手动列出每个.cpp文件,更稳妥。创建共享库并链接静态库
把mod1、mod2的源码编译成共享库,再把libA.a、libB.a的内容合并进去:# 创建共享库,加入mod1、mod2的源码 add_library(my_shared_library SHARED ${MOD1_SOURCE_FILES} ${MOD2_SOURCE_FILES} ) # 链接静态库,指定静态库的绝对路径 target_link_libraries(my_shared_library ${CMAKE_CURRENT_SOURCE_DIR}/lib/libA.a ${CMAKE_CURRENT_SOURCE_DIR}/lib/libB.a )执行
cmake .. && make之后,就会生成libmy_shared_library.so(Linux)或者my_shared_library.dll(Windows),这个共享库已经包含了所有静态库和源码的功能。
其他可行方案
如果不想用CMake,也可以用手动命令行或者工具来实现:
1. 手动用GCC/Clang命令行
适合临时测试或者小型项目,步骤如下:
# 1. 编译mod1、mod2的源码为位置无关目标文件 g++ -fPIC -I inc/mod1 -I inc/mod2 -I inc/libA -I inc/libB -c src/mod1/*.cpp -o mod1_objs.o g++ -fPIC -I inc/mod1 -I inc/mod2 -I inc/libA -I inc/libB -c src/mod2/*.cpp -o mod2_objs.o # 2. 从静态库中提取所有目标文件 ar x lib/libA.a ar x lib/libB.a # 3. 把所有目标文件链接成共享库 g++ -shared -o libmy_shared.so mod1_objs.o mod2_objs.o *.o # 4. 清理临时文件(可选) rm -f mod1_objs.o mod2_objs.o *.o
⚠️ 注意:如果静态库的目标文件名和mod1/mod2的目标文件重名,会被覆盖,需要提前处理重名问题。
2. 用objcopy合并(不推荐)
可以先把静态库转换成共享库,再和mod1/mod2的编译产物合并,但这种方式容易出现符号冲突、依赖缺失的问题,仅作为应急方案:
# 把静态库转成共享库 g++ -shared -o libtempA.so -Wl,--whole-archive lib/libA.a -Wl,--no-whole-archive g++ -shared -o libtempB.so -Wl,--whole-archive lib/libB.a -Wl,--no-whole-archive # 编译mod1/mod2并合并所有共享库 g++ -fPIC -shared -I inc/... src/mod1/*.cpp src/mod2/*.cpp libtempA.so libtempB.so -o libmy_shared.so
内容的提问来源于stack exchange,提问作者KaDw
相关产品推荐
相关产品推荐

