CMake 合并静态库 | C & C++

本文最后更新于:2023年3月6日

本文转载自《Cmake 静态库链接静态库》,原文有删改。

问题

一个静态库 B 依赖了静态库 A,同时在 CMakeLists.txt 使用 target_link_libraries(B A) 设定了 B 链接 A,但是在使用 B 时,发现静态库 B 中并没有 A 的符号。也就是说,cmake 并没有帮我把静态库 A 的符号添加到静态库 B 中。

实际上,cmake 确实不会合并两个静态库,那么才能如何让 cmake 真正做到静态库呢。

答案

通过生成后事件,自己合并。

Windows

add_custom_command(TARGET example_lib POST_BUILD
                   COMMAND lib.exe /out:tmp.lib B.lib A.lib
                   COMMAND ${CMAKE_COMMAND} -E rename tmp.lib B.lib)

Linux

ar 程序并不能直接将两个 .a 文件合并,必须先把 .a 拆成 .o 文件,再把所有 .o 文件合并在一起

add_custom_command(TARGET examplelib POST_BUILD
                   COMMAND ar x libA.a
                   COMMAND ar rcs libB.a *.o)

macOS

macOS 则提供了 libtool 这个工具,可以直接合并静态库。

add_custom_command(TARGET examplelib POST_BUILD
                   COMMAND libtool -static -o libB.a libB.a libA.a)