使用cmake从整个项目中创建一个静态库

时间:2012-12-01 18:38:51

标签: linux cmake

c ++ - 项目,比如说,foo由cmake维护。 一个人想要创建一个库libfoo.a(在整个源树中创建所有类/方法/函数),以便创建可以使用-lfoo链接到库的程序。

好吧,让我们现在考虑一个玩具示例,并且这个问题很明显。目录foo(项目的根目录)包含目录ab。创建了两个CmakeLists.txt

# a/CMakeLists.txt
add_library(A <a_sources>)
# b/CMakeLists.txt
add_library(B <b_sources>)

根目录有一个CMakeLists.txt

add_subdirectory(a)
add_subdirectory(b)
add_library(foo <foo_sources>
target_link_libraries(foo A B)

对我来说这是一个惊喜:构建libfoo.a后只包含来自foo_sources的方法,而a_sourcesb_sources被排除在外。 在使用相同项目构建可执行文件的情况下,这是可以的:在创建可执行文件时,如果链接到a,则“猜测”必须链接bfoo。 但是在可执行文件创建“外部”项目以使用库foo的情况下,必须与-lfoo -la -lb链接,现在想象一个包含许多子目录的项目 - 如何处理它?所以问题是“如何创建一个库,使用cmake从整个项目聚合方法?”

谷歌搜索引导我进入最近嵌入(出现在2.8.8)OBJECT library机会。使用它的好例子显示为here。现在上面的问题可以解决:

# a/CMakeLists.txt
add_library(A OBJECT <a_sources>)
# b/CMakeLists.txt
add_library(B OBJECT <b_sources>)
# foo/CMakeLists.txt
add_subdirectory(a)
add_subdirectory(b)
add_library(foo <foo_sources> $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)
不幸的是,

问题似乎已经解决了。不过。

如果依赖关系链长于2,例如,foo取决于A,这取决于B,问题仍然存在。 那是因为,

  

对象库可能只包含编译为目标文件的源(和标题)。

  

无法导入,导出,安装或链接对象库。

(引用取自同一link

我尝试了target_link_library()add_library(), add_library(... OBJECT ..)的几种组合尝试将ABfoo联系起来但没有成功(cmake-process期间出错)。 )

我一定要放松一些简单的东西,请帮助,谢谢! 我不确定它是否重要:项目是在linux上维护的。

2 个答案:

答案 0 :(得分:3)

我认为你在这个词中纠缠不清&#34;取决于&#34;。如果您正在构建名为foo的库,并且它包含AB两个部分,那么A是否依赖于{{{0}并不重要1}};图书馆应该包含两者。您显示的CMake代码将正确构建B

答案 1 :(得分:0)

是的,我支持回复@Pete Becker @。但是应该说那些库$<TARGET_OBJECTS:A>$<TARGET_OBJECTS:B>实际上根本不是库,而是cmake对象模块的内部列表。编译对象模块(自动生成的源除外)之间没有依赖关系,因此它们可以按任何顺序并行完成。

我想你的意图更正确的术语是在单个对象库下聚集几个TARGET_OBJECTS。你写不出add_library(B OBJECT b.cpp $<TARGET_OBJECTS:A>)真是太糟糕了。但是你总是可以自己实现这个:

add_library(A OBJECT a.cpp)
set(A_OBJECTS $<TARGET_OBJECTS:A>)

add_library(B OBJECT b.cpp)
set(B_OBJECTS $<TARGET_OBJECTS:B> ${A_OBJECTS})

add_library(foo ${B_OBJECTS})

即只要创建特殊变量_OBJECTS,只要您想将这些对象库包含在库中,可执行文件中,或者作为具有_OBJECTS风格的其他对象库的一部分,就可以使用它们。