ExternalProject_Add: как использовать зависимости сборки в вашем проекте?

Я пытаюсь создать стороннюю зависимость, используя ExternalProject_Add (в данном случае libpqxx):

ExternalProject_Add(libpqxx_ext
    GIT_REPOSITORY
        https://github.com/jtv/libpqxx
    GIT_TAG
        tags/7.4.1
    GIT_SHALLOW
        true
    PREFIX
        ext
    BINARY_DIR
        build
    CMAKE_ARGS
        -DSKIP_BUILD_TEST=on
    INSTALL_COMMAND
        ""
    BUILD_ALWAYS
        OFF
    )

После завершения этого шага артефакты libpqxx, которые мне нужно использовать в моем проекте, будут расположены по адресу:

  • заголовочные файлы: ${CMAKE_CURRENT_BINARY_DIR}/ext/src/libpqxx_ext/include
  • статическая библиотека: ${CMAKE_CURRENT_BINARY_DIR}/build/src/libpqxx.a

Использовать результаты в моем проекте:

Как сделать эти артефакты доступными для моего проекта?

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

set(LIB_PQXX_SRC_DIR   ${CMAKE_CURRENT_BINARY_DIR}/ext/src/libpqxx_ext)
set(LIB_PQXX_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/build/src)

add_library(libpqxx STATIC IMPORTED GLOBAL)
set_property(TARGET libpqxx APPEND PROPERTY IMPORTED_LOCATION             ${LIB_PQXX_BIN_DIR}/libpqxx.a)
set_property(TARGET libpqxx APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${LIB_PQXX_SRC_DIR}/include)
set_property(TARGET libpqxx APPEND PROPERTY INTERFACE_LINK_LIBRARIES      ${PostgreSQL_LIBRARIES})

add_dependencies(libpqxx libpqxx_ext)

Это не работает, потому что во время настройки ${LIB_PQXX_SRC_DIR}/include еще не существует.

Ошибка CMake в foo/CMakeLists.txt: импортированная цель libpqxx включает несуществующий путь

"/home/steve/src/foo/build/3rd-party/pqxx/ext/src/libpqxx_ext/include"

в его INTERFACE_INCLUDE_DIRECTORIES. Возможные причины включают в себя:

  • Путь был удален, переименован или перемещен в другое место.

  • Процедура установки или удаления не завершилась успешно.

  • Инсталляционный пакет неисправен и ссылается на файлы, которые он не предоставляет.

Добавление add_dependencies, чтобы сообщить cmake, что libpqxx_ext нужно собрать до libpqxx, не работает.

Обратите внимание, что если я полностью удалю libpqxx, а затем соберу свой проект (чтобы был построен libpqxx_ext) и затем добавлю его, теперь все работает, потому что шаг ExternalProject_Add выполнен... но, очевидно, это ломает когда я делаю чистую проверку, так что это нежизнеспособно.

Я также пытался сказать cmake, что создается директория включения, но это не дало никакого эффекта.

set_source_files_properties(${LIB_PQXX_SRC_DIR}/include PROPERTIES GENERATED TRUE)

Вопросы:

  • Является ли мое использование add_library(libpqxx STATIC IMPORTED GLOBAL) для импорта артефактов правильным/рекомендуемым способом использования результата ExternalProject_Add?

  • Если это так, как я могу сказать cmake, что ${LIB_PQXX_SRC_DIR}/include является сгенерированным каталогом?

  • Если это не так, каков рекомендуемый способ сделать результат ExternalProject_Add доступным для моего проекта?


person Steve Lorimer    schedule 17.03.2021    source источник
comment
попробуйте добавить ExternalProject_Add(... BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/build/src/libpqxx.a)   -  person KamilCuk    schedule 17.03.2021
comment
Это не работает, потому что во время настройки ${LIB_PQXX_SRC_DIR}/include еще не существует. - Зачем вам нужен этот каталог во время настройки? Если исполняемый файл нуждается в этих заголовках для компиляции, то компиляция происходит во время сборки, а не во время настройки.   -  person Tsyvarev    schedule 17.03.2021
comment
@KamilCuk, который не работает, потому что ошибка связана с несуществующим путем включения   -  person Steve Lorimer    schedule 17.03.2021
comment
@Tsyvarev Я обновил вопрос с ошибкой, выброшенной cmake. Проблема в том, что когда я пытаюсь связать libpqxx с одной из моих целей проекта, во время настройки cmake не может найти включаемый каталог... даже если он будет существовать после создания цели libpqxx_ext   -  person Steve Lorimer    schedule 17.03.2021
comment
Вы проверили этот вопрос? Похоже, именно о вашей проблеме. (И кажется, что красивого решения проблемы нет).   -  person Tsyvarev    schedule 17.03.2021
comment
@Tsyvarev А, спасибо! Похоже, это сработает, но какой уродливый хак - file(MAKE_DIRECTORY Ааааа! :)   -  person Steve Lorimer    schedule 17.03.2021
comment
На самом деле, ссылка из ответа содержит другое решение: объявить ИМПОРТИРОВАННУЮ библиотеку чтобы ссылаться только на файл библиотеки, и объявить библиотеку INTERFACE для ссылки на включаемые каталоги. Похоже, CMake проверяет наличие включаемых каталогов только для ИМПОРТИРОВАННОЙ библиотеки, но не для ИНТЕРФЕЙСНОЙ.   -  person Tsyvarev    schedule 17.03.2021
comment
@Tsyvarev Я нашел способ объединить FetchContent и ExternalProject_Add, чтобы обойти проблему. Добавлен ответ на другой вопрос SO, который вы связали   -  person Steve Lorimer    schedule 17.03.2021