Как сообщить CMake, что каталог установки зависит от фальшивой цели?

#dependencies #installation #cmake #target

#зависимости #установка #cmake #цель

Вопрос:

Как мне достичь следующего в CMake (используя версию 2.8.5)? У меня есть документация, сгенерированная пользовательским целевым именем doc , выходные данные которого я хотел бы включить при установке или упаковке.

 add_custom_target( doc "${DOXYGEN_EXECUTABLE}" Doxyfile )
install( DIRECTORY ${CMAKE_BINARY_DIR}/doc DESTINATION doc )
  

Doxyfile Сообщает Doxygen, чтобы он разместил документацию по адресу ${CMAKE_BINARY_DIR}/doc .

Если я сделаю это в каталоге сборки:

 make doc
cpack
  

все работает нормально, потому что первая строка создает каталог, от которого install зависит цель.

Однако, если у меня есть свежая сборка (so ${CMAKE_BINARY_DIR}/doc еще не существует), и я вызываю CPack напрямую:

 cpack
  

затем он жалуется, что не может найти ${CMAKE_BINARY_DIR}/doc :

 CMake Error at <snip>/build/cmake_install.cmake:36 (FILE):
  file INSTALL cannot find "<snip>/build/doc".
  

Я также попробовал следующее:

 add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/doc COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile )
install( DIRECTORY ${CMAKE_BINARY_DIR}/doc DESTINATION doc )
  

но я все равно получаю ту же ошибку CPack, и выполнение make doc в каталоге сборки тоже не работает.

Итак, если я сделаю make doc это вручную, прежде cpack чем он будет работать с конфигурацией в верхней части этого сообщения, но как я могу сообщить cmake / cpack, что install директива зависит от пользовательской цели doc , чтобы создание документации происходило автоматически при вызове cpack или make install ?

Спасибо!

Ответ №1:

Возможно, вам нужно ALL ключевое слово:

 add_custom_target( doc ALL "${DOXYGEN_EXECUTABLE}" Doxyfile )
  

Обновить:

В настоящее время cmake не предоставляет возможности добавлять пользовательские зависимости к своим встроенным целям (таким как all , install , test , и т.д.). И похоже, что в ближайшем будущем он не предоставит эту опцию — см. http://public.kitware.com/Bug/view.php?id=8438

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

Так что используйте на свой страх и риск:

 add_custom_target(hack ${CMAKE_COMMAND} -E echo "Hacking install target")
if("${CMAKE_GENERATOR}" MATCHES Make)
    install(CODE "execute_process(COMMAND ${CMAKE_BUILD_TOOL} hack WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")")
endif()
  

Комментарии:

1. Спасибо, это действительно возможное решение. Однако ALL ключевое слово всегда приводит к созданию цели. В данном случае это не проблема, но меня все равно интересовало бы общее решение, в котором я мог бы добавить явную зависимость между целью установки (которая неявно зависит от ALL ) и моей пользовательской целью.

2. @ysnikraz Я обновил свой ответ. К сожалению, в cmake нет четкого способа установить зависимости между пользовательскими и встроенными целями.

3. Большое спасибо за ваше обновление и обходной путь! Просто протестировал его, и он работает хорошо. Именно то, что я искал!

Ответ №2:

Я немного изменил это в своем CMakeList.txt для того, чтобы работать как на Linux, так и на Windows

 install(CODE "execute_process(COMMAND ${CMAKE_BUILD_TOOL} hack WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")") endif()
  

Это мое решение. Он не создает документацию всегда «ВСЮ», только когда требуется документ или цель установки (в Visual Studio, когда проект УСТАНОВКИ скомпилирован).
Это решение не является полным. Это не будет работать, например, с MinGW, но…

 set( DOXYFILE_OUTPUT_DIR ${PROJECT_BINARY_DIR}/doc )
#-- Configure the Template Doxyfile
configure_file(Doxyfile.in ${PROJECT_BINARY_DIR}/Doxyfile  @ONLY IMMEDIATE)

#-- Add a custom target to run Doxygen
add_custom_target (doc
    COMMAND ${DOXYGEN_EXECUTABLE} ${PROJECT_BINARY_DIR}/Doxyfile
    SOURCES ${PROJECT_BINARY_DIR}/Doxyfile
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

if(WIN32)
    install(
        CODE "execute_process(COMMAND ${CMAKE_BUILD_TOOL} /Build Debug ABIHex.sln /project doc.vcproj
                              WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")"
    )
else(WIN32)
    install(
        CODE "execute_process(COMMAND ${CMAKE_BUILD_TOOL} --build --target doc
                              WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")"
    )
endif(WIN32)
  

Надеюсь, это будет кому-то полезно.

С уважением, Алекс