Подтвердить что ты не робот

Копировать CMake, если исходный файл изменен

В CMake у меня есть папка, содержащая предопределенные каталоги Gettext, которые во время сборки копируются в папку, а затем изменяют их. Но проблема в том, что каждый раз, когда я запускаю цель, она копирует предопределенный файл на локальную копию (что, вероятно, изменено). Есть ли способ копирования, если файл отличается от состояния, которым он был раньше, иначе оставьте его в покое?

Я также думал, что способ сделать это - это скопировать их в течение времени генерации CMake, но я чувствую себя немного уставшим от этого, поскольку люди могут удалить папки и повредить вещи. Также я не знаю, как выполнять команды во время генерации, только во время сборки.

4b9b3361

Ответ 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, и это может быть нежелательным из-за потребления времени.