Поддержка пакетов CMake - включает и библиотеки не найдены - PullRequest
1 голос
/ 28 мая 2020

В настоящее время я разрабатываю программный пакет, для которого я хотел бы предоставить поддержку пакета cmake (чтобы пользователи могли найти его с помощью find_package(...)). Проблема в том, что пакет найден, но FOO_INCLUDE_DIR и FOO_LIBRARIES пуст.

В моем пакете у меня есть несколько модулей, каждый с файлом CMakeLists, который устанавливает соответствующую библиотеку и заголовки с:

install(TARGETS ${LIBRARY_NAME} EXPORT FooTargets
    RUNTIME       DESTINATION ${Foo_RUNTIME_INSTALL_DIR}
    LIBRARY       DESTINATION ${Foo_LIBRARY_INSTALL_DIR}
    ARCHIVE       DESTINATION ${Foo_ARCHIVE_INSTALL_DIR}
    FRAMEWORK     DESTINATION ${Foo_FRAMEWORK_INSTALL_DIR})

# Headers
install(
        DIRECTORY include/${LIBRARY_NAME}
        DESTINATION include/${PROJECT_NAME}
        FILES_MATCHING
            PATTERN "*.h"
            PATTERN "*.hpp"
)

Заголовки для библиотеки включены в target_include_directories следующим образом:

target_include_directories(${LIBRARY_NAME} PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> # for headers when building
        $<INSTALL_INTERFACE:${Foo_INC_INSTALL_DIR}> # for client in install mode
)

Я проверил папки, и все библиотеки и заголовки установлены правильно. В моих списках верхнего уровня CMakeLists я экспортирую свои цели с помощью:

install(
        EXPORT FooTargets
        DESTINATION ${Foo_CMAKE_CONFIG_INSTALL_DIR}
        FILE FooConfig.cmake
)

Конфигурация находится там, где я предполагаю (usr/local/lib/cmake/Foo). Так что вроде все правильно. Когда я смотрю в свой FooConfig.cmake, он говорит:

# Create imported target realm_densifier_base
add_library(FooLib1 SHARED IMPORTED)

set_target_properties(FooLib1 PROPERTIES
  INTERFACE_INCLUDE_DIRECTORIES "/usr/local/include/Foo"
  INTERFACE_LINK_LIBRARIES "...several libraries..."
)

... что абсолютно правильно и именно то, что я ожидал. Какая часть головоломки отсутствует? INTERFACE_INCLUDE_DIRECTORIES и INTERFACE_LINK_LIBRARIES - неправильный флаг для установки?

Спасибо за помощь и всего наилучшего,

Alex

Изменить:

@ Guillaume Racicot уже прояснил большинство вещей, я знал только "нецелевой" способ добавления заголовков в мой проект, который был с include_directories (Foo_INCLUDE_DIRS). Однако в целевом мире ссылки на мою библиотеку Foo было достаточно. Другое дело, что я испортил некоторые каталоги в команде target_include_directories(...), поэтому каталоги были неправильными и, следовательно, не могли быть найдены в другом моем проекте. Спасибо за помощь!

1 Ответ

2 голосов
/ 28 мая 2020

Почему нужно установить FOO_INCLUDE_DIR или FOO_LIBRARIES? Это может быть то, как старые модули поиска работали, но не то, как работают файлы конфигурации. Даже более новые модули поиска предоставляют цели вместо переменных каталога.

При создании файла XYZConfig.cmake будет экспортирована информация о целях , а не информация о каталоге.

При таком экспорте:

install(
    EXPORT FooTargets
    NAMESPACE Foo::
    DESTINATION ${Foo_CMAKE_CONFIG_INSTALL_DIR}
    FILE FooConfig.cmake
)

Вы ожидаете, что пользователи пакета будут использовать его так:

find_package(Foo REQUIRED)

#         or PUBLIC ------v
target_link_libraries(bar PRIVATE Foo::FooLib1)

Если ваш пакет имеет несколько целей в наборе экспорта, вы можете связать на оба или только на один

target_link_libraries(bar PRIVATE Foo::FooLib1 Foo::FooLib2)
target_link_libraries(baz PUBLIC  Foo::FooLib2) # link to lib2 only

Когда вы устанавливаете ссылку на экспортированную цель, например Foo::FooLib1, ее интерфейс publi c будет транзитивно передан пользователю. В приведенном выше примере bar унаследует свойства от связанной цели.

Таким образом, INTERFACE_INCLUDE_DIRECTORIES из Foo::FooLib1 и Foo::FooLib2 будет добавлено к bar INCLUDE_DIRECTORIES. То же самое для LINK_LIBRARIES.

Для baz не только его INCLUDE_DIRECTORIES будет содержать записи Foo::FooLib2, но и его собственный INTERFACE_INCLUDE_DIRECTORIES будет транзитивно передавать требования использования Foo::FooLib2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...