如果原始文件更改,则进行CMake复制

时间:2011-12-08 16:15:30

标签: cmake

在CMake中我有一个包含预定义Gettext目录的文件夹,在构建时我将其复制到文件夹然后进行修改。但问题是,每次运行目标时,它都会复制本地副本上的预定义文件(可能已修改)。如果文件与以前的状态不同,有没有办法复制,否则不管它?

我还在想,这样做的一种方法是在CMake生成时间复制它们,但我觉得有点厌倦这样做,因为人们可能会删除文件夹并搞砸了。此外,我不知道如何在生成时执行命令,仅在构建时执行。

3 个答案:

答案 0 :(得分:21)

我相信你应该能够使用依赖于文件的自定义命令。类似的东西:

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/output.file
    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/input.file ${CMAKE_CURRENT_BINARY_DIR}/output.file
    MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/input.file)

如果不这样做,请告诉我。提供您当前使用的CMake代码可能会有所帮助。

您也可以尝试“$ {CMAKE_COMMAND} -E copy_if_different”;鉴于命令的依赖性,我不清楚这是否会有所不同,但我当然可能会遗漏某些内容,或者如果您不使用“make”输出则可能会有所不同。


如果您想尝试在“生成时”(当您运行cmake时)执行复制,您可以使用此命令(我认为我的语法是正确的但我没有测试它):

file(COPY
    ${CMAKE_CURRENT_SOURCE_DIR}/input.file
    DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)

使用INSTALL而不是COPY会产生稍微不同的行为。

如果您需要在生成时运行任意进程,请尝试execute_process命令。

当然,有关详细信息,请参阅the CMake documentation

答案 1 :(得分:9)

另一个选择是configure_file使用COPYONLY参数。

configure_file(input_file output_file COPYONLY)

这不会执行任何变量替换,并且会在您运行make时复制“input_file”。但它会触发cmake运行,由于时间消耗,这可能是不受欢迎的。

答案 2 :(得分:5)

好吧,我曾经设法解决这个问题,但忘记了这个答案。对不起所有跳过这个但没有答案的人!

# ----- Copy and merge across the po files that come with the source.

message("Copying and updating stock translations...")

file(GLOB poFiles "${stockDir}/*.po")

foreach(file ${poFiles})
  # Get the language name, like en_US or zh_CN from the name of the po file, so
  # 'en_US.po' or 'zh_CN.po' become 'en_US' or 'zh_CN.po'
  get_filename_component(langName ${file} NAME_WE)

  set(newFile "${langDir}/${langName}.po")

  if(NOT EXISTS ${newFile})
    execute_process(COMMAND ${MSGMERGE_EXECUTABLE}
      "--output-file" ${newFile} ${file} ${potFile}
      OUTPUT_QUIET ERROR_VARIABLE error RESULT_VARIABLE ret)

    if(ret) # Have to do this hack as msgmerge prints to stderr.
      message(SEND_ERROR "${error}")
    endif()

    message(" '${langName}' copied.")
  elseif(${file} IS_NEWER_THAN ${newFile})
     execute_process(COMMAND ${MSGMERGE_EXECUTABLE}
       "--update" ${newFile} ${file}
       OUTPUT_QUIET ERROR_VARIABLE error RESULT_VARIABLE ret)

     if(ret) # Have to do this hack as msgmerge prints to stderr.
       message(SEND_ERROR "${error}")
     endif()

     message(" '${langName}' merged.")
  endif()
endforeach()

stockDir是包含库存po文件的目录,这些文件不是用户编辑的(除非提交到repo)。 langDir位于'lang'下的构建目录中。它会通过,并根据文件的年龄进行复制或更新。