Как создать внешнюю библиотеку, загруженную с помощью CMake fetchContent?

#cmake

#cmake

Вопрос:

У меня есть программа, которая зависит от внешней библиотеки (например, SDL). Я хочу, чтобы CMake позаботился об этой зависимости для меня, поэтому я изучал FetchContent . Насколько я понимаю, этот модуль просто загружает исходный код, чтобы информация о внешней библиотеке была доступна во время настройки. Например:

 include(FetchContent)

FetchContent_Declare(sdl
  GIT_REPOSITORY <...>
)

FetchContent_GetProperties(sdl)

# sdl_POPULATED, sdl_SOURCE_DIR and sdl_BINARY_DIR are ready now

if(NOT sdl_POPULATED)
  FetchContent_Populate(sdl)
endif()
  

Однако в какой-то момент я хочу создать этот исходный код и связать его с моим основным исполняемым файлом. Как это сделать «современным способом CMake»?

Комментарии:

1. Это зависит от того, что предоставляет внешняя библиотека для сборки. Например, если она создается с помощью cmake, вы можете добавить библиотеку в свою сборку с помощью add_subdirectory(${libname_SOURCE_DIR}) вызова. Я быстро взглянул на SDL. Похоже, что она не создается с помощью cmake. В этом случае вы могли бы попробовать использовать cmake.org/cmake/help/latest/command/add_custom_target.html для создания SDL (используйте ключевое слово COMMAND для вызова собственной команды сборки SDL), а затем настройте пользовательскую цель, чтобы другие цели могли зависеть от нее. Отличная статья о том, как это сделать: pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right

2. @Matt итак, в принципе, если библиотека основана на CMake, я могу просто add_subdirectory позволить CMake выполнить эту работу за меня. В противном случае мне придется создавать ее «вручную» с помощью add_custom_target . Это полезно знать, вы могли бы превратить свой комментарий в ответ 🙂

3. Я опубликовал ответ. После второго взгляда на SDL кажется, что он действительно создается с помощью cmake… возможно, я остановился на устаревшей версии или изначально посмотрел на неправильный репозиторий. Надеюсь, это упростит ее интеграцию в вашу сборку.

Ответ №1:

Рекомендуемый способ создания внешних библиотек из исходного кода в рамках вашей сборки зависит от того, что внешняя библиотека предоставляет для сборки.

Внешняя библиотека создается с помощью cmake

Если внешняя библиотека создается с помощью cmake, вы можете добавить библиотеку в свою сборку с помощью вызова add_subdirectory(${libname_SOURCE_DIR}). Таким образом, cmake создаст внешнюю библиотеку в виде вложенной папки («подпроект»). В CMakeLists.txt файле внешней библиотеки будут некоторые add_library(ext_lib_name ...) инструкции. Для того, чтобы затем использовать внешнюю библиотеку в ваших целях (приложение или библиотека, которая зависит от внешней библиотеки), вы можете просто вызвать target_link_libraries(your_application <PRIVATE|PUBLIC|INTERFACE> ext_lib_name) https://cmake.org/cmake/help/latest/command/target_link_libraries.html

Я быстро просмотрел это репозиторий github https://github.com/rantoniello/sdl — (дайте мне знать, если вы имеете в виду другую библиотеку) и на самом деле похоже, что она создается с помощью cmake и позволяет клиентам статически или динамически связываться с ней:https://github.com/rantoniello/sdl/blob/master/CMakeLists.txt#L1688-L1740

Итак, в идеале ваше приложение должно уметь делать

 add_executable(myapp ...)
target_link_libraries(myapp PRIVATE SDL2-static) // Statically link againt SDL2
  

Из-за их CMakeLists.txt файл SDL2-static поставляется со свойствами (включая каталоги, флаги компоновщика / команды), которые будут автоматически подключены к myapp .

Внешняя библиотека не создается с помощью cmake

Если внешняя библиотека не создается с помощью cmake, можно попробовать использовать add_custom_target https://cmake.org/cmake/help/latest/command/add_custom_target.html для создания библиотеки. Что-то вроде:

 add_custom_target(myExternalTarget COMMAND <invoke the repo's build system>)
  

Затем вам нужно будет самостоятельно установить целевые свойства, которые важны для клиентов, с помощью соответствующих функций cmake set_target_properties , target_include_directories … Отличная статья о том, как начать работу с такими вещами:https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right /