【问题标题】:make one static library from whole project with cmake使用 cmake 从整个项目中创建一个静态库
【发布时间】:2012-12-01 18:38:50
【问题描述】:

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_sources,b_sources 被排除在外。 这在使用相同项目构建可执行文件的情况下是可以的:在创建可执行文件时,cmake “猜测”ab 如果链接到 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 ..) 的组合,试图将AB 链接到foo,但均未成功(cmake 过程中出错。)

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

【问题讨论】:

    标签: linux cmake


    【解决方案1】:

    我认为您对“依赖于”这个词感到困惑。如果你正在构建一个名为foo 的库,它有两个部分,AB,那么A 是否依赖于B 并不重要;图书馆应该包含两者。您显示的 CMake 代码将正确构建 foo

    【讨论】:

      【解决方案2】:

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

      我想你的意图更正确的术语是在单个对象库下聚集几个 TARGET_OBJECTS。不能写add_library(B OBJECT b.cpp $&lt;TARGET_OBJECTS:A&gt;)真是太糟糕了。但是您始终可以自己实现:

      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 风格的其他对象库的一部分时使用它们。

      【讨论】:

        猜你喜欢
        • 2017-10-02
        • 2012-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-17
        • 1970-01-01
        • 2018-03-26
        相关资源
        最近更新 更多