首页 > 解决方案 > CMAKE:强制如果文件存在则它是最新的(在构建时)

问题描述

我正在使用 cmake 来构建一篇论文,其中涉及到构建过程。

  1. 构建一个exe
  2. 运行 exe 生成一些数据(在 ${PROJECT_BINARY_DIR}/data 中)
  3. 运行一些 python 将数据处理成数字(Postscript 图像)。这些保存在 ${CMAKE_SOURCE_DIR}/fig 中。
  4. 将图像转换为png
  5. 用这些数字构建一个乳胶文档

这一切都可以在 cmake 中通过将 custom_commands 的输出链接到自定义目标来完成:

#This is the command that does the work (run python, or some executable etc.).  Will only run if ${CUSTOM_DEPENDS} is newer that ${CUSTOM_OUTPUT}
add_custom_command( OUTPUT ${CUSTOM_OUTPUT}
        COMMAND ${CUSTOM_COMMAND}
        DEPENDS ${CUSTOM_DEPENDS}
        WORKING_DIRECTORY ${CUSTOM_WORKING_DIRECTORY}
        USES_TERMINAL
        VERBATIM
        )

#This target allows one to depend on the custom command from another file
add_custom_target(${name} 
    DEPENDS ${CUSTOM_OUTPUT}
    VERBATIM
    )

问题是,当我实际处理这个问题时,我在一台机器上生成图形,将 Postscript 图像文件保存到 git 存储库,然后在笔记本电脑上处理实际的 Latex 文档。笔记本电脑无法处理运行可执行文件,老实说,我希望对是否以及何时重新生成图形进行一些相当严格的控制。 理想情况下,Postscript 文件只有在丢失时才会生成。 如果依赖项(例如,可执行源文件)自第一次配置以来发生了变化,如果 Postscript 文件重新构建也会很好,但这可能要求太多。

这在配置时很容易做到,但在配置后删除文件的情况下并非如此。

我尝试过这样的事情(输出是 Postscript 文件):


#same custom command as before, but we also generate a copy.  This copy should always be newer that the output
add_custom_command( OUTPUT ${CUSTOM_OUTPUT}
        COMMAND ${CUSTOM_COMMAND}
        COMMAND ${CMAKE_COMMAND} -E copy ${CUSTOM_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/copy/
        DEPENDS ${CUSTOM_DEPENDS}
        WORKING_DIRECTORY ${CUSTOM_WORKING_DIRECTORY} #usually this is ${CMAKE_CURRENT_LIST_DIR}
        ${USES_TERMINAL}
        VERBATIM
        )


#for every output make a command that makes the copy depends on the original output.  So that they are always up to date if they exist.
foreach(arg IN ITEMS ${CUSTOM_OUTPUT})

    if(EXISTS ${COPY_OBJ})
         file(COPY ${arg} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/copy/")
    endif()
    list(APPEND CUSTOM_TARGET_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/copy/${arg}")


    add_custom_command( OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/copy/${arg}
         DEPENDS "${arg}"
    )

            
endforeach()

#now have the target depend on the copies which are always up to date with the original outputs
add_custom_target(${name}
    ${CUSTOM_ALL}   
    DEPENDS ${CUSTOM_TARGET_DEPENDS}
    VERBATIM
    )

这不起作用,我不确定这是因为这些操作发生在源文件夹中,还是我误解了 add_custom_command 最新逻辑。

注意:这与仅测试存在性的This Question不同。我正在尝试改变存在的最新性。

标签: cmake

解决方案


推荐阅读