7

例如,c++-projectfoo由 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_sources,b_sources被排除在外。在使用同一个项目构建可执行文件的情况下,这是可以的:在创建可执行文件时,cmake“猜测”a并且b如果它链接到foo. 但是如果在“外部”项目中创建可执行文件以使用foo必须链接的库-lfoo -la -lb,现在想象一个有很多子目录的项目 - 如何处理它?所以问题是“如何创建一个库,使用 cmake 聚合整个项目的方法?”

谷歌搜索让我找到了最近嵌入(出现在 2.8.8 中)的OBJECT library机会。这里展示了使用它的好例子。现在可以解决上面的问题:

# 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,问题仍然存在。那是因为,

对象库可能只包含编译成对象文件的源(和头文件)。

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

(引用来自同一链接

我尝试了几种组合,target_link_library()尝试add_library(), add_library(... OBJECT ..)链接A和链接但没有成功(cmake-process期间出错。)Bfoo

我必须失去一些简单的东西,请帮忙,谢谢!我不确定它是否重要:项目在 linux 上维护。

4

2 回答 2

3

我认为你在“取决于”这个词上纠结了。如果您正在构建一个名为的库foo,它有两个部分,Aand ,是否依赖于;B无关紧要。图书馆应该包含两者。您显示的 CMake 代码将正确构建。ABfoo

于 2012-12-01T21:09:10.160 回答
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风格的其他对象库的一部分,只需创建特殊变量即可使用它们。

于 2013-04-12T04:31:41.573 回答