Как включить файлы CMake из исходного дерева включенного проекта - PullRequest
1 голос
/ 14 октября 2019

Я настраиваю систему сборки на основе CMake для старого фреймворка, написанного на C. Он состоит из одного двоичного файла, некоторых базовых библиотек и множества динамически связанных библиотек, которые построены на основе базовых библиотек. Моя цель состоит в том, чтобы структурировать эти библиотеки в нескольких проектах CMake («базовая структура», «библиотеки расширений»,…), поддерживая два сценария:

  • Независимая сборка библиотек расширений в сравнении со сборкой базовой инфраструктурыtree:

    - base_framework/
      - cmake/
        - functions.cmake
      - core_libraries/
      - CMakeLists.txt
    - extension_libs/
      - lib1/
      - lib2/
      - CMakeLists.txt
    

    Для этого сценария я использую

    export(EXPORT foo
      FILE FooFrameworkConfig.cmake)
    

    и

    find_package(FooFramework)
    

    и добавляю дерево сборки в CMAKE_PREFIX_PATH при настройке extension_libs project.

  • Использование базовой платформы и библиотек расширений в качестве подпроектов (например, в виде подмодулей git) конкретного проекта приложения:

    - my_project/
      - base_framework/
        - cmake/
          - functions.cmake
        - core_libraries/
        - CMakeLists.txt
      - extension_libs/
        - lib1/
        - lib2/
        - CMakeLists.txt
      - my_lib1/
      - CMakeLists.txt
    

    Для этого сценария,Я использую add_subdirectory() для базовой инфраструктуры и библиотек расширений.

(Третий сценарий - создание библиотек расширений на основе дерева установки базовой платформы. К сожалению, этоСценарий в настоящее время предотвращается другими проблемами CMake.)

Теперь я хочу включить файл base_framework/cmake/functions.cmake, содержащий некоторые пользовательские функции CMake для всех библиотек, в верхний уровень всех проектов CMakeLists.txt s в обоих сценариях.

Для второго сценария я просто устанавливаю кэшированную переменную CMake в base_framework/CMakeLists.txt:

set(BASE_FRAMEWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR}
    CACHE PATH "" FORCE)

и использую эту переменную для включения файла функций в extension_libraries/CMakeLists.txt, а также my_project/CMakeLists.txt:

include(${BASE_FRAMEWORK_DIR}/cmake/functions.cmake)

Но как мне найти файл function.cmake в исходном дереве базовой платформы из extenstion_libs/cmake в первом сценарии? Все каталоги (base_framework, extension_libs, дерево сборки базового фреймворка) могут находиться где угодно на моем компьютере.

1 Ответ

0 голосов
/ 16 октября 2019

Чтобы расширить мой комментарий относительно вашего первого сценария, похоже, что вы можете установить одно из свойств ваших экспортированных целей core_libraries, чтобы оно содержало путь к base_framework/cmake модулям. Таким образом, вы можете установить это в файле base_framework/CMakeLists.txt, давайте установим его в целевом свойстве LABELS. Затем мы сообщаем CMake экспортировать свойство LABELS, используя EXPORT_PROPERTIES:

Ваш base_framework/CMakeLists.txt файл:

# Define the path to 'base_framework/cmake'
set(BASE_FRAMEWORK_CMAKE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

add_library(CoreLibrary1 ...)
# Set the LABELS property, and tell CMake to export it.
set_target_properties(CoreLibrary1 PROPERTIES 
    LABELS "${BASE_FRAMEWORK_CMAKE_MODULES}"
    EXPORT_PROPERTIES "LABELS"
)
# Define the export 'foo'.
install(TARGETS CoreLibrary1 EXPORT foo DESTINATION /path/to/install/targets)
export(EXPORT foo FILE FooFrameworkConfig.cmake)

Это обеспечит путь кbase_framework модули CMake экспортируются в явном виде и могут быть доступны при импорте из другого проекта:

Ваш extension_libs/CMakeLists.txt файл:

find_package(FooFramework)
# Get the LABELS property from the imported target.
get_target_property(BASE_FRAMEWORK_MODULE_DIR CoreLibrary1 LABELS)
message(STATUS "BASE_FRAMEWORK_MODULE_DIR: ${BASE_FRAMEWORK_MODULE_DIR}")

При отладке message() мы можемубедитесь, что каталог модулей CMake был импортирован:

BASE_FRAMEWORK_MODULE_DIR: /your/path/to/base_framework/cmake

EDIT : вместо перехвата целевого свойства LABELS вы также можете использовать define_property() чтобы определить собственное свойство для цели.

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