我有以下依赖关系图
a.txt <- prereq <- stamp <- dest
其中prereq
和dest
是目标,a.txt
和stamp
是文件。我想在a.txt
更改时更新戳记。
为实现这一目标,我有以下CMakeLists.txt文件:
cmake_minimum_required(VERSION 3.6)
project(sample)
# variable holding location of stamp and a.txt file
set(STAMP ${CMAKE_CURRENT_SOURCE_DIR}/stamp)
set(ATXT ${CMAKE_CURRENT_SOURCE_DIR}/a.txt)
add_custom_target(
prereq
DEPENDS ${ATXT}
)
add_custom_command(
OUTPUT ${STAMP}
COMMAND ${CMAKE_COMMAND} -E echo "Update stamp."
COMMAND ${CMAKE_COMMAND} -E touch ${STAMP}
DEPENDS prereq
)
add_custom_target(dest ALL DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/stamp)
最初,我有以下文件
$ ls
a.txt
CMakeLists.txt
在第一次运行cmake并make之后我们得到了预期的行为,
$ cmake .
$ make
[ 0%] Built target prereq
[100%] Generating stamp
Update stamp.
[100%] Built target dest
但是,在触摸a.txt
之后,我希望stamp
能够更新,但事实并非如此。
$ touch a.txt
$ make
[ 0%] Built target prereq
[100%] Built target dest
这是cmake中的错误还是预期的行为?每次prereq
更改时,我们如何强制cmake运行touch命令?
答案 0 :(得分:2)
DEPENDS
和add_custom_target()
来电中的{p> add_custom_command()
行为有所不同。
只需移动ATXT
作为add_custom_command(OUTPUT ${STAMP} ...)
调用的依赖关系即可解决问题,因为在add_custom_target()
中命名非输出文件将无效。
请参阅add_custom_command()
documentation:
DEPENDS
:指定命令所依赖的文件。如果任何依赖项是同一目录(OUTPUT
文件)中另一个自定义命令的CMakeLists.txt
,则CMake会自动将另一个自定义命令带入构建此命令的目标中。如果未指定DEPENDS
,则只要缺少OUTPUT,该命令就会运行。
请参阅add_custom_target()
documentation:
DEPENDS
:使用add_custom_command()
命令调用在同一目录(CMakeLists.txt
文件)中创建的自定义命令的参考文件和输出。
DEPENDS
中的add_custom_target()
参数仅用于确定目标/自定义呼叫依赖关系。
编辑:“后期依赖注入”的替代方法
如果您在同一个CMakeLists.txt
文件中,则可以APPEND
依赖于以前的自定义命令OUTPUT
:
add_custom_command(
OUTPUT ${STAMP}
COMMAND ${CMAKE_COMMAND} -E echo "Update stamp."
COMMAND ${CMAKE_COMMAND} -E touch ${STAMP}
)
add_custom_target(dest ALL DEPENDS ${STAMP})
add_custom_command(
OUTPUT ${STAMP}
DEPENDS ${ATXT}
APPEND
)
您可以添加一些虚拟输出以获得prereq
目标的自定义命令,但要重新触发dest
的构建,您需要触摸某些输入或删除输出dest
(add_dependencies()
本身不会重新触发自定义目标,只是确保在另一个目标之前调用一个目标:
add_custom_command(
OUTPUT ATxtCheck
COMMAND ${CMAKE_COMMAND} -E remove ${STAMP}
COMMAND ${CMAKE_COMMAND} -E touch ATxtCheck
DEPENDS ${ATXT}
)
add_custom_target(prereq DEPENDS ATxtCheck)
add_custom_command(
OUTPUT ${STAMP}
COMMAND ${CMAKE_COMMAND} -E echo "Update stamp."
COMMAND ${CMAKE_COMMAND} -E touch ${STAMP}
DEPENDS prereq
)
add_custom_target(dest ALL DEPENDS ${STAMP})
<强>参考强>