CMake: создание макроса COPY_IF_DIFFERENT с различным поведением - PullRequest
0 голосов
/ 01 февраля 2012

Есть два возможных поведения, которые немного отличаются друг от друга.Это различие представляет мой особый интерес, и я хотел бы исследовать его причину и возможные подводные камни с вашей помощью.

Реализация:

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 (независимо от отметок времени).

Я понимаю, что пост довольно большой, но это был единственный способ донести тему:)

Заранее спасибо, ребята

...