c ++ - 项目,比如说,foo
由cmake维护。
一个人想要创建一个库libfoo.a
(在整个源树中创建所有类/方法/函数),以便创建可以使用-lfoo
链接到库的程序。
foo
(项目的根目录)包含目录a
和b
。创建了两个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_sources
,b_sources
被排除在外。
在使用相同项目构建可执行文件的情况下,这是可以的:在创建可执行文件时,如果链接到a
,则“猜测”必须链接b
和foo
。
但是在可执行文件创建“外部”项目以使用库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 ..)
的几种组合尝试将A
和B
与foo
联系起来但没有成功(cmake-process期间出错)。 )
我一定要放松一些简单的东西,请帮助,谢谢! 我不确定它是否重要:项目是在linux上维护的。
答案 0 :(得分:3)
我认为你在这个词中纠缠不清&#34;取决于&#34;。如果您正在构建名为foo
的库,并且它包含A
和B
两个部分,那么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
风格的其他对象库的一部分,就可以使用它们。