Может ли CMake find_package быть "осведомленным о версии зависимостей"?

Эта проблема:

Я нахожусь в процессе переделки системы make в нашем унаследованном проекте, переходя с его нынешней загадочной версии на CMake. В настоящее время я воспринимаю CMake как один большой проект CMake, но наша кодовая база настолько велика, что нарушает большинство IDE, которые мы к ней добавляем.

Мы хотели бы разбить его на части, и CMake find_package "mode mode" кажется идеальным для разбиения его на "функциональные" куски. Основным кандидатом является большой кусок кода, который нужно поддерживать редко, и даже тогда его обычно выполняет другая команда. Это позволило бы нам поддерживать код, но не постоянно перекомпилировать его при обновлении другого кода.

Тем не менее, этот кусок кода использует совместно используемый указатель Boost в API, и, хотя различные версии совместно используемого указателя, вероятно, будут работать вместе, я бы не стал рисковать. Таким образом, в идеале пакет должен знать, какую версию "boost" использует система, какая версия boost использовалась при компиляции модуля, и иметь возможность перекомпилировать - или, по крайней мере, выдать ошибку или предупреждение в CMake - если два не совпадают.

Итак... как можно обеспечить соответствие версий общих зависимостей в модулях CMake find_package? Единственное, о чем я могу думать, это тестирование соответствующей переменной VERSION, но это кажется... громоздким. Я что-то упускаю?

Дополнительная информация:

Мы используем CMake 3.5.1, но мы можем перейти на 3.5.2, если это что-то изменит. Этот проект на самом деле представляет собой линейку программных продуктов (qv), поэтому мы планируем использовать более современные методы разработки программного обеспечения SPL в будущем (еще одна причина выбрать CMake). В настоящее время кодовая база находится в Redhat Linux, но в идеале методика должна быть кроссплатформенной.

1 ответ

Решение

Вы можете использовать режим конфигурации find_package Позволяет вашим модулям предоставлять некоторые внутренние свойства своему пользователю (корневой проект).

Если каждый ваш модуль предоставляет библиотечную цель, вы можете выставить эту цель со свойством, содержащим добавленную версию Boost, и перечислить это свойство в специальном свойстве COMPATIBLE_INTERFACE_STRING.

Ваш корневой проект будет включать модули через find_package() звонит и прочтет эти свойства. Когда он попытается связать библиотеки, предоставляемые такими модулями, совместимость версий будет автоматически выполняться CMake:

modA / CMakeLists.txt:

...
find_package(Boost)
add_library(modA_lib ...)
... # Link modA_lib with Boost
# Install modA_lib target and exports it for use in other project.
install(TARGETS modA_lib EXPORT modA_lib)
# Configured -config file is shown below
configure(modA-config.cmake.in modA-config.cmake)
install(EXPORT modA_lib
    DESTINATION share/cmake/modA)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/modA-config.cmake
    DESTINATION share/cmake/modA)

modA / modA-config.cmake.in:

include(@CMAKE_INSTALL_PREFIX@/share/cmake/modA/modA_lib.cmake) # Include file described library target
# Expose linked version of Boost via target's property.
set_property(TARGET modA_lib PROPERTY INTERFACE_BOOST_VERSION @Boost_VERSION@)
# Mark this property as compatibility requirement
set_property(TARGET modA_lib PROPERTY APPEND COMPATIBLE_INTERFACE_STRING BOOST_VERSION)

(modB реализован аналогичным образом)

root / CMakeLists.txt:

find_package(modA) # This imports target modA_lib
find_package(modB) # This imports target modB_lib

add_executable(root_exe <...>)

# Boost version check will be performed here
target_link_libraries(root_exe modA_lib modB_lib)

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

add_executable(root_exe <...>)
set_property(TARGET root_exe PROPERTY BOOST_VERSION <...>)

В этом случае CMake запрещает использовать библиотеки Boost с другими версиями.

Больше информации и примеры использования смотрите в описании системы сборки CMake.

Другие вопросы по тегам