#cmake #cpack
Вопрос:
Я работаю над проектом, в котором в качестве подмодуля используется сторонний источник. В стороннем источнике CMakeLists.txt они имеют include(CPack)
в своем CMakeLists.txt, и это вызывает проблемы, потому что, когда я пишу свое собственное include(CPack)
в CMakeLists.txt в моем проекте я получаю предупреждения конфигурации cmake, такие как
CPack.cmake has already been included!!
и все переменные CPack, которые я написал, перезаписаны сторонним источником, что вызывает ошибки при запуске make package
Я попытался add_subdirectory(third-party-source EXCLUDE_FROM_ALL)
, который игнорирует все install
вызовы в стороннем источнике, но, к сожалению, он не игнорировал вызовы CPack.
Есть ли способ для меня добавить что-то вроде
if(CPACK_ALREADY_INCLUDED)
include(CPack)
endif()
в стороннем источнике, чтобы обойти эту проблему?
Комментарии:
1.
EXCLUDE_FROM_ALL
применяется только к целям, созданным в этом каталоге и ниже, поэтому нет абсолютно никаких причин, по которым он игнорировалinclude()
бы директиву.
Ответ №1:
Преодолеть неправильное поведение третьих лиц никогда не бывает легко. Вот почему я лично не одобряю add_subdirectory
и предпочитаю использовать vcpkg
или другой инструмент оркестровки сборки (например, Conan) вместо этого.
Однако следующий фрагмент кода должен работать:
function (add_third_party)
# Write an empty CPack module
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/override/CPack.cmake" "")
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_BINARY_DIR}/override;${CMAKE_MODULE_PATH}")
add_subdirectory(third-party-source)
endfunction ()
add_third_party()
Это создаст пустой модуль CPack и заставит сторонний код включить его вместо стандартного модуля. Функция существует для того, чтобы убедиться, что это переопределяющее поведение не может просочиться в остальную часть вашей сборки.
Я неправильно истолковал ваш вопрос. Я думал, что вы контролируете проект, который включает CPack
в себя .
Да, переменная имеет имя CPack_CMake_INCLUDED
. Тем не менее, лучше проверить, являетесь ли вы проектом верхнего уровня, и условно включить свои правила упаковки, как это:
string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}" is_top_level)
option(MyProj_INCLUDE_PACKAGING "Include packaging rules for MyProj" "${is_top_level}")
if (MyProj_INCLUDE_PACKAGING)
# ...
include(CPack)
endif ()
Комментарии:
1.
CPack_CMake_INCLUDED
на самом деле работает. Интересно, почему это не упоминается в cmake.org/cmake/help/latest/module/CPack.html2. Не уверен. Хотя это было в источниках целую вечность.