我有一个非常类似于cmake邮件列表中描述的问题,我们有一个依赖于许多静态库的项目(都是从各个子模块中的源代码构建的,每个子库都有自己的CMakeLists.txt描述每个库的构建过程)我想组合成一个静态库,以便向消费者发布。 我的库的依赖性可能会发生变化,我不想让开发人员在这些变化的后面进一步负担。 简洁的解决方案是将所有lib捆绑到一个单独的lib中。
有趣的是,在将目标设置为mylib
并使用它时, target_link_libraries
命令并未组合所有静态。 。
target_link_libraries(mylib abcd)
但是,奇怪的是,如果我将mylib
项目作为可执行项目的子模块,并且仅在顶级可执行文件CMAkeLists.txt中链接mylib
,那么该库似乎确实是组合在一起的。 即,当我将目标设置为仅构建mylib
时,mylib为27 MB,而不是3 MB。
有一些解决方案描述了将lib解压缩到目标文件并重新组合( 这里和这里 ),但是当CMake看起来完全能够自动合并lib时,这似乎非常笨拙,如上例所述。 它有一个我失踪的神奇命令,或推荐的优雅方式制作发布库?
给出最简单的工作示例,我可以想到:2个类, a
和b
,其中a
取决于b
。 。
啊
#ifndef A_H #define A_H class aclass { public: int method(int x, int y); }; #endif
a.cpp
#include "ah" #include "bh" int aclass::method(int x, int y) { bclass b; return x * b.method(x,y); }
BH
#ifndef B_H #define B_H class bclass { public: int method(int x, int y); }; #endif
b.cpp
#include "bh" int bclass::method(int x, int y) { return x+y; }
main.cpp中
#include "ah" #include int main() { aclass a; std::cout << a.method(3,4) << std::endl; return 0; }
可以将它们编译为单独的静态库,然后使用自定义目标组合静态库。
cmake_minimum_required(VERSION 2.8.7) add_library(b b.cpp bh) add_library(a a.cpp ah) add_executable(main main.cpp) set(C_LIB ${CMAKE_BINARY_DIR}/libcombi.a) add_custom_target(combined COMMAND ar -x $ COMMAND ar -x $ COMMAND ar -qcs ${C_LIB} *.o WORKING_DIRECTORY ${CMAKE_BINARY_DIR} DEPENDS ab ) add_library(c STATIC IMPORTED GLOBAL) add_dependencies(c combined) set_target_properties(c PROPERTIES IMPORTED_LOCATION ${C_LIB} ) target_link_libraries(main c)
使用Apple的libtool
版本的自定义目标也可以正常工作。 。 。
add_custom_target(combined COMMAND libtool -static -o ${C_LIB} $ $ WORKING_DIRECTORY ${CMAKE_BINARY_DIR} DEPENDS ab )
仍然接缝似乎应该有一个更简洁的方式。 。
如果您尝试合并的库来自第三方,那么(遵循learnvst示例)此代码会处理可能的.o文件替换(例如,如果liba和libb都有文件名zzz.o)
## Create static library (by joining the new objects and the dependencies) ADD_LIBRARY("${PROJECT_NAME}-static" STATIC ${SOURCES}) add_custom_command(OUTPUT lib${PROJECT_NAME}.a COMMAND rm ARGS -f *.o COMMAND ar ARGS -x ${CMAKE_BINARY_DIR}/lib${PROJECT_NAME}-static.a COMMAND rename ARGS 's/^/lib${PROJECT_NAME}-static./g' *.o COMMAND rename ARGS 's/\.o/.otmp/g' *.o COMMAND ar ARGS -x ${CMAKE_SOURCE_DIR}/lib/a/liba.a COMMAND rename ARGS 's/^/liba./g' *.o COMMAND rename ARGS 's/\.o/.otmp/g' *.o COMMAND ar ARGS -x ${CMAKE_SOURCE_DIR}/lib/b/libb.a COMMAND rename ARGS 's/^/libb./g' *.o COMMAND rename ARGS 's/\.o/.otmp/g' *.o COMMAND rename ARGS 's/\.otmp/.o/g' *.otmp COMMAND ar ARGS -r lib${PROJECT_NAME}.a *.o COMMAND rm ARGS -f *.o DEPENDS "${PROJECT_NAME}-static") add_custom_target(${PROJECT_NAME} ALL DEPENDS lib${PROJECT_NAME}.a)
否则,如果库是你的,你应该使用CMake OBJECT库,这是一个很好的机制来合并它们。
需要了解更多c/c++开发分享使用CMake将几个静态库合并为一个,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!
以上就是c/c++开发分享使用CMake将几个静态库合并为一个相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/980255.html