在CMake中我有一个包含预定义Gettext目录的文件夹,在构建时我将其复制到文件夹然后进行修改。但问题是,每次运行目标时,它都会复制本地副本上的预定义文件(可能已修改)。如果文件与以前的状态不同,有没有办法复制,否则不管它?
我还在想,这样做的一种方法是在CMake生成时间复制它们,但我觉得有点厌倦这样做,因为人们可能会删除文件夹并搞砸了。此外,我不知道如何在生成时执行命令,仅在构建时执行。
答案 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'下的构建目录中。它会通过,并根据文件的年龄进行复制或更新。