Копировать CMake, если исходный файл изменен
В CMake у меня есть папка, содержащая предопределенные каталоги Gettext, которые во время сборки копируются в папку, а затем изменяют их. Но проблема в том, что каждый раз, когда я запускаю цель, она копирует предопределенный файл на локальную копию (что, вероятно, изменено). Есть ли способ копирования, если файл отличается от состояния, которым он был раньше, иначе оставьте его в покое?
Я также думал, что способ сделать это - это скопировать их в течение времени генерации CMake, но я чувствую себя немного уставшим от этого, поскольку люди могут удалить папки и повредить вещи. Также я не знаю, как выполнять команды во время генерации, только во время сборки.
Ответы
Ответ 1
Хорошо, мне удалось это исправить, но забыл об этом ответе. Извините всех людей, которые пропустили это и не получили ответа!
# ----- 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, которые не предназначены для редактирования пользователем (если только они не привязаны к репо). langDir находится в каталоге сборки в разделе "lang". Он проходит и копирует или обновляет его в зависимости от возраста файлов.
Ответ 2
Я считаю, что вы должны использовать пользовательскую команду, которая зависит от файла. Что-то вроде:
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
.
Конечно, подробности см. в документации CMake.
Ответ 3
Другой вариант - использовать configure_file
с аргументом COPYONLY
.
configure_file(input_file output_file COPYONLY)
Это не будет выполнять никакой замены переменных и будет копировать "input_file" при запуске make
. Но это вызывает запуск cmake, и это может быть нежелательным из-за потребления времени.