Есть два возможных поведения, которые немного отличаются друг от друга.Это различие представляет мой особый интерес, и я хотел бы исследовать его причину и возможные подводные камни с вашей помощью.
Реализация:
macro(COPY_IF_DIFFERENT SRC_FILES SRC_DIR DST_DIR DST_FILE_TARGETS)
foreach(SRC_FILE ${SRC_FILES})
set(DST_FILE ${SRC_FILE}) # Currently names of original and copy are the same.
# set(DST_FILE_TARGET ${DST_DIR}/${DST_FILE}) # <--- A
# set(DST_FILE_TARGET ${SRC_FILE}) # <--- B
add_custom_command(
OUTPUT ${DST_FILE_TARGET}
COMMAND ${CMAKE_COMMAND}
ARGS -E copy_if_different ${SRC_DIR}/${SRC_FILE} ${DST_DIR}/${DST_FILE}
# MAIN_DEPENDENCY ${SRC_DIR}/${SRC_FILE} # <--- C
# DEPENDS ${SRC_DIR}/${SRC_FILE} # <--- D
)
set(dstFileTargets ${dstFileTargets} ${DST_FILE_TARGET})
endforeach()
set(${DST_FILE_TARGETS} ${dstFileTargets})
set(CUSTOM_TARGET ${ARGV4})
if(CUSTOM_TARGET)
add_custom_target(${CUSTOM_TARGET} ALL DEPENDS ${dstFileTargets})
endif()
endmacro()
Просто по порядкуЧтобы уточнить назначение макроса, рассмотрим типичное использование:
set(H_FILES header1.h header2.h ...)
COPY_IF_DIFFERENT(${H_FILES} ${CMAKE_CURRENT_SOURCE_DIR} ${MY_AWESOME_INCLUDE_DIR} H_FILE_TARGETS "MyAwesomeIncludeTarget")
По сути, этот макрос будет просто копировать перечисленные файлы $ {H_FILES} из $ {CMAKE_CURRENT_SOURCE_DIR} в $ {MY_AWESOME_INCLUDE_DIR}.Он также вернет список целей для каждой копии назначения в $ {H_FILE_TARGETS}.
ПРИМЕЧАНИЕ: Если присутствует последний параметр макроса (как в случае выше), тогда макросавтоматически создаст пользовательскую цель с именем, предоставленным этим последним параметром («MyAwesomeIncludeTarget»), чтобы создать реальные правила копирования для каждой цели из $ {H_FILE_TARGETS} в make-файлах.В противном случае, если последний параметр отсутствует, необходимо вручную создать настраиваемую цель для $ {H_FILE_TARGETS} или присоединить $ {H_FILE_TARGETS} к другой цели, например ADD_EXECUTABLE(whatever ${SOURCES_OF_WHATEVER} ${H_FILE_TARGETS})
.Вы можете найти больше информации об этой тонкой детали здесь .
Вернитесь на путь.Прежде всего, обратите внимание на A, B, C и D. в комментариях, потому что они понадобятся нам для дальнейшего обсуждения.
Поведение # 1 присутствует, когда мы раскомментируем A и (или C, или Dили и то, и другое):
- , если копия еще не создана (т.е. вызывается впервые), тогда происходит копирование (конечно);
- , если я редактирую оригинал, а копия уже естькопирование тоже происходит (действительно);
- если я редактирую копию, копирование НЕ ПРОИЗОЙДЕТ .Это странно, так как я использую команду copy_if_different .(*) Однако я подозреваю, что эта команда даже не вызывается в этом случае, потому что отметка времени редактирования копии на всегда выше, чем у оригинала, что приводит к мертвой цели.
- , если яоставьте и оригинал, и копию нетронутой, копирование НЕ ПРОИСХОДИТ из-за временных меток снова.
Поведение # 2 присутствует, когда мы раскомментируем только B (ниC и D не нужны - воу!):
, если копия еще не существует (т.е. вызывается в первый раз), тогда происходит копирование (конечно);
если я редактирую оригинал, а копия уже есть, копирование также происходит;
, если я редактирую копию, копирование СЛУЧАЕТСЯ .И это то, что меня особенно интересует, потому что я хочу именно такое поведение.Тем не менее, в начале я ожидал этого от # 1, но кажется невозможным в соответствии с моим аргументом, помеченным (*) (кстати, прокомментируйте это).Я обнаружил # 2 случайно во время экспериментов, но я не понимаю, почему это так работает?Это безопасно?Есть ли какие-либо подводные камни с этим?
, если я оставлю оригинал и копию нетронутыми, копирование НЕ ПРОИСХОДИТ , как предполагает команда copy_if_different (независимо от отметок времени).
Я понимаю, что пост довольно большой, но это был единственный способ донести тему:)
Заранее спасибо, ребята