Добавьте зависимость FreeType с помощью cmake, поддерживающего все vcpkg / apt-get / brew - PullRequest
0 голосов
/ 04 марта 2020

У меня есть проект, который зависит от FreeType и использует CMake в качестве системы сборки. CMake имеет встроенный модуль FindFreeType , который должен использоваться следующим образом, см., Например, этот другой вопрос SO :

find_package(Freetype REQUIRED)
target_link_libraries(mylib ${FREETYPE_LIBRARIES})
target_include_directories(mylib PRIVATE ${FREETYPE_INCLUDE_DIRS})

Начиная с CMake 3.10, есть также импортированная цель Freetype::Freetype, поэтому мы можем избежать target_include_directories:

find_package(Freetype REQUIRED)
target_link_libraries(mylib Freetype::Freetype)

Это прекрасно работает в Ubuntu 18.04 с FreeType, установленным через apt install libfreetype6-dev. Я предполагаю, что это также работает на macOS, когда пакет установлен через homebrew (я еще не тестировал).

Однако на Windows я sh, чтобы позволить разработчикам зависеть от vcpkg- установлен FreeType:

git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
.\bootstrap-vcpkg.bat
.\vcpkg integrate install
.\vcpkg install freetype:x64-windows

На что они нацелятся, выполнив следующую команду CMake:

cmake .. -G "Visual Studio 15 2017" -A x64 -DCMAKE_TOOLCHAIN_FILE=C:/Users/Boris/vcpkg/scripts/buildsystems/vcpkg.cmake

К сожалению, приведенная выше команда CMake не будет работать ни с одним из двух CMakeLists.txt. в начале этого вопроса, потому что правильный способ поиска и ссылки на FreeType при его установке через vcpkg заключается в следующем:

find_package(freetype CONFIG REQUIRED) # `Freetype` works too, but vcpkg doc recommends `freetype`
target_link_libraries(mylib freetype)  # Here, all-lowercase is required

В частности, файл конфигурации freetype-config.cmake, предоставленный vcpkg, определяет target freetype (не Freetype::Freetype, как встроенный модуль поиска), и не определяет ни одну из FREETYPE_LIBRARIES или FREETYPE_INCLUDE_DIRS переменных.

Что было бы правильным способом сохранить мой CMakeLists.txt совместим с обоими "традиционными" способами поиска FreeType, но также и с vcpkg?

Предполагая предварительную версию CMake 3.10, я думаю о чем-то вроде:

if(DEFINED VCPKG_TARGET_TRIPLET)
    find_package(freetype CONFIG REQUIRED)
    set(FREETYPE_LIBRARIES freetype)
    set(FREETYPE_INCLUDE_DIRS "")
else()
    find_package(Freetype REQUIRED)
endif()
target_link_libraries(mylib ${FREETYPE_LIBRARIES})
target_include_directories(mylib PRIVATE ${FREETYPE_INCLUDE_DIRS})

Будет ли это кажется хорошей практикой? Есть идея получше?

Это выглядит ужасно, и, кроме того, всегда есть возможность, что разработчик захочет использовать vcpkg для некоторых других зависимостей, но не для FreeType (например, явно предоставив FREETYPE_DIR вместо этого), так что этот трюк не будет даже будет достаточно во всех ситуациях, и нам понадобится еще одна опция CMake, такая как MYLIB_IGNORE_VCPKG_FREETYPE, которая станет еще страшнее.

1 Ответ

1 голос
/ 09 апреля 2020

Это может показаться хорошей практикой? Любая лучшая идея?

Не будь агности c о возможном менеджере пакетов.

Выполните следующие действия:

find_package(Freetype CONFIG REQUIRED) # should find freetype-config.cmake if available
find_package(Freetype REQUIRED) # Will not be executed if Freetype_FOUND ist already set

Затем проверьте, существует ли цель Freetype::Freetype или freetype

 if(TARGET freetype AND NOT TARGET Freetype::Freetype)
     add_library(Freetype::Freetype ALIAS freetype) # target freetype is defined by freetype-targets.cmake
     # might need to add freetype to global scope if cmake errors here
 endif()
 if(NOT TARGET Freetype::Freetype)
     # insert error here
 endif()
 target_link_libraries(mylib PRIVATE Freetype::Freetype)

, если вы не хотите использовать псевдоним target Вы также можете определить переменную с именем FREETYPE_TARGET и установить для нее правильную цель для связывания.

...