依赖项更改时重建 CMake 目标

Posted

技术标签:

【中文标题】依赖项更改时重建 CMake 目标【英文标题】:Rebuild CMake target when dependency changes 【发布时间】:2021-10-25 16:31:43 【问题描述】:

这里有无数类似的问题,但我找不到能准确解决这个问题的问题:

我正在使用 CMake 构建共享库 ab 以及可执行文件 progprog 应该与a 链接,但不能与b 链接。但是,与此同时,我希望在 b 过时时重建 prog。实际上,b 是构建prog 时使用的编译器插件。

我试过了:

add_library(a a.cc)
add_library(b b.cc)
add_dependencies(a b)

add_executable(prog prog.cc)
target_link_libraries(prog PRIVATE a)

但这不起作用,当 b 需要重建时,这不会导致 prog 也被重建。

我也试过了:

add_library(a a.cc)
add_library(b b.cc)
target_link_libraries(a INTERFACE b)

add_executable(prog prog.cc)
target_link_libraries(prog PRIVATE a)

但这会导致prog 链接到b。有没有办法做到这一点?

【问题讨论】:

I want prog to be rebuilt whenever b is outdated 有什么用?他们是无关的。 b is a compiler plugin used while building prog“如何”究竟是“使用”?将prog.cc 构建到目标文件或将prog 链接在一起时? 【参考方案1】:

我发现生成器表达式在 OBJECT_DEPENDS 上下文中不起作用。触摸。无论如何,只要做一个小代理:

cmake_minimum_required(VERSION 3.11)
project(test)
add_library(a a.cpp)
add_library(b b.cpp)
add_executable(prog prog.cpp)
add_custom_command(
  OUTPUT $CMAKE_CURRENT_BINARY_DIR/b_is_build
  COMMAND $CMAKE_COMMAND -E touch  $CMAKE_CURRENT_BINARY_DIR/b_is_build
  DEPENDS $<TARGET_FILE:b>
)
set_source_files_properties(prog.cpp PROPERTIES
  OBJECT_DEPENDS $CMAKE_CURRENT_BINARY_DIR/b_is_build
)

然后触摸 b.cpp 重建 prog:

+ touch b.cpp
+ cmake --build _build --verbose
[1/5] /usr/bin/c++    -MD -MT CMakeFiles/b.dir/b.cpp.o -MF CMakeFiles/b.dir/b.cpp.o.d -o CMakeFiles/b.dir/b.cpp.o -c /dev/shm/.1000.home.tmp.dir/b.cpp
[2/5] : && /usr/bin/cmake -E rm -f libb.a && /usr/bin/ar qc libb.a  CMakeFiles/b.dir/b.cpp.o && /usr/bin/ranlib libb.a && :
[3/5] cd /dev/shm/.1000.home.tmp.dir/_build && /usr/bin/cmake -E touch /dev/shm/.1000.home.tmp.dir/_build/b_is_build
[4/5] /usr/bin/c++    -MD -MT CMakeFiles/prog.dir/prog.cpp.o -MF CMakeFiles/prog.dir/prog.cpp.o.d -o CMakeFiles/prog.dir/prog.cpp.o -c /dev/shm/.1000.home.tmp.dir/prog.cpp
[5/5] : && /usr/bin/c++   CMakeFiles/prog.dir/prog.cpp.o -o prog  liba.a && :

b 是构建 prog 时使用的编译器插件

理想情况下是告诉 CMake 目标文件 依赖于该插件 file,但是 $&lt;TARGET_FILE 在这里不起作用。

set_source_file_properties(prog.cc PROPERTIES
     OBJECT_DEPENDS $<TARGET_FILE:b>
)

或者告诉 CMake 链接生成的程序取决于插件,具体取决于该插件的使用位置。

set_target_properties(prog PROPERTIES
     LINK_DEPENDS $<TARGET_FILE:b>
)

依赖关系以文件为模型——例如可执行文件prog依赖于文件badd_dependencies 只进行排序(一个在另一个之前构建)。


【讨论】:

第一个选项听起来像我想要的。不幸的是,快速测试后它似乎不起作用,当 b 更改时,目标文件不会重建。 实际上 CMake 甚至拒绝扩展生成器表达式 $&lt;TARGET_FILE:b&gt;,这似乎是一个错误,因为它在其他地方工作,而不是在 set_source_files_properties 内部。 Och,然后先获取目标属性,使用属性中的文件路径。所以它不适用于多发电机,奇怪。总而言之,插件是用来创建目标文件的,对吧? @Peter 编辑了答案! ;) 这就是我现在所做的,它有效,非常感谢!

以上是关于依赖项更改时重建 CMake 目标的主要内容,如果未能解决你的问题,请参考以下文章

如果头文件被更改然后恢复,如何停止/欺骗cmake不重建?

尽管没有更改任何来源,但 CMake 会重建自定义目标 [重复]

如何从 CMake 或 make 输出编译依赖项?

cmake/make (OBJECT) 依赖问题——当标头改变时不重建

CMake、Ninja 和 Visual Studio 2019 重建一切

重建应用程序时会推送令牌更改吗?