在先决条件更改后,Cmake不会重建依赖项

时间:2016-10-13 23:23:05

标签: cmake dependencies rules

我有以下依赖关系图

a.txt <- prereq <- stamp <- dest

其中prereqdest是目标,a.txtstamp是文件。我想在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命令?

1 个答案:

答案 0 :(得分:2)

DEPENDSadd_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()参数仅用于确定目标/自定义呼叫依赖关系。

编辑:“后期依赖注入”的替代方法

  1. 如果您在同一个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
    )
    
  2. 您可以添加一些虚拟输出以获得prereq目标的自定义命令,但要重新触发dest的构建,您需要触摸某些输入或删除输出destadd_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})
    
  3. <强>参考