【问题标题】:How to build object files only once with cmake?如何使用 cmake 只构建一次目标文件?
【发布时间】:2009-09-07 11:21:47
【问题描述】:

我有一个如下所示的 CMakeLists.txt 文件:

add_executable(exec1 exec1.c source1.c source2.c source3.c)
add_executable(exec2 exec2.c source1.c source2.c source3.c)
add_executable(exec3 exec3.c source1.c source2.c source3.c)

source1.o source2.o source3.o 文件需要很长时间才能构建,而且由于它们对所有可执行文件都是通用的,所以我希望每个文件只构建一次。然而,当前 cmake 的行为是为每个 exec 目标分别重建它们,这是不必要的重复工作。

有没有办法告诉 cmake 只构建一次目标文件?

【问题讨论】:

    标签: cmake


    【解决方案1】:

    没有。这将很难实现,因为源文件可以使用不同的编译器选项、构建后步骤等进行编译。

    您可以做的是将目标文件放入静态库并与之链接:

    add_library(mylib STATIC source1.c source2.c)
    add_executable(myexe source3.c)
    target_link_libraries(myexe mylib)
    

    编辑:当然,您也可以将其放入共享库中。

    【讨论】:

    • 小心这种方法。如果涉及很多 exe,共享库可能会更友好blog.flameeyes.eu/2008/01/21/what-to-do-with-shared-code
    • 是的,当然。我想我只是假设 OP 希望在每个可执行文件中复制代码。
    • 如果静态/对象库编译缓慢(例如,带有 Boost 或 Eigen 的 C++ 源代码)并且只包含少量源文件,那么这种方法会增加并行构建的构建时间,因为 myexe 目标会直到mylib 建成后才开始建设。在我的实际项目中,总构建时间的差异似乎是 22 秒与 38 秒(分别是重复编译与 OBJECT 库)。
    【解决方案2】:

    是的,在 CMake 2.8.8 中您可以使用对象库,它是一种虚拟库,具有与真实静态或共享库相同的组织和依赖属性,但不会在磁盘上生成文件。请参阅 CMake 教程:Object Library

    【讨论】:

      【解决方案3】:

      在最近的 CMake 版本中,您可以使用对象库。它的行为与任何库一样,但不会将其归档到静态库中:

      add_library(my_cpps OBJECT a.cpp b.cpp c.cpp)
      

      然后您可以将其“链接”到其他目标:

      add_library(my_lib1 d.cpp e.cpp f.cpp)
      target_link_libraries(my_lib1 PUBLIC my_cpps)
      
      add_library(my_lib2 f.cpp g.cpp h.cpp)
      target_link_libraries(my_lib2 PUBLIC my_cpps)
      

      【讨论】:

      • 如果静态/对象库编译缓慢(例如,带有 Boost 或 Eigen 的 C++ 源代码)并且只包含少量源文件,那么这种方法会增加并行构建的构建时间,因为 myexe 目标会在构建 mylib 之前不要开始构建。在我的实际项目中,总构建时间的差异似乎是 22 秒与 38 秒(分别是重复编译与 OBJECT 库)。
      • @Ruslan 不一定。使用 ninja 时,即使对象库尚未完成,也可以开始构建。我将推迟链接,直到对象库完成。
      猜你喜欢
      • 2012-10-15
      • 2016-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-19
      • 2017-09-27
      • 2017-10-07
      相关资源
      最近更新 更多