У меня есть проект, который зависит от 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 я хочу позволить разработчикам полагаться на FreeType, установленный vcpkg:
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 и связать его с 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, определяет цель 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
, который становится еще более уродливым.