I have a project which depends on FreeType, and uses CMake as build system. CMake has a FindFreeType built-in module which is supposed to be used like this, see for example this other SO question:
find_package(Freetype REQUIRED)
target_link_libraries(mylib ${FREETYPE_LIBRARIES})
target_include_directories(mylib PRIVATE ${FREETYPE_INCLUDE_DIRS})
Since CMake 3.10, there is also the Freetype::Freetype
imported target so we can avoid the target_include_directories
:
find_package(Freetype REQUIRED)
target_link_libraries(mylib Freetype::Freetype)
This worked great on Ubuntu 18.04 with FreeType installed via apt install libfreetype6-dev
. I assume it also works on macOS when the package is installed via homebrew (I haven't tested yet).
However, on Windows, I wish to allow developers to depend on a vcpkg-installed FreeType:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
.\bootstrap-vcpkg.bat
.\vcpkg integrate install
.\vcpkg install freetype:x64-windows
Which they would target by running the following CMake command:
cmake .. -G "Visual Studio 15 2017" -A x64 -DCMAKE_TOOLCHAIN_FILE=C:/Users/Boris/vcpkg/scripts/buildsystems/vcpkg.cmake
Unfortunately, the above CMake command won't work with any of the two CMakeLists.txt at the beginning of this question, because the proper way to find and link to FreeType when it is installed via vcpkg is the following:
find_package(freetype CONFIG REQUIRED) # `Freetype` works too, but vcpkg doc recommends `freetype`
target_link_libraries(mylib freetype) # Here, all-lowercase is required
In particular, the freetype-config.cmake
config file provided by vcpkg defines the target freetype
(not Freetype::Freetype
like the builtin find module), and doesn't define any of the FREETYPE_LIBRARIES
or FREETYPE_INCLUDE_DIRS
variables.
What would be a proper way to keep my CMakeLists.txt
compatible with both "traditional" ways of finding FreeType, but also vcpkg?
Assuming pre-CMake 3.10, I'm thinking of something along the lines of:
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})
Would that seem like good practice? Any better idea?
It feels ugly, and besides, there is always the possibility of a developer wanting to use vcpkg for some other dependencies but not for FreeType (e.g., explicitly providing FREETYPE_DIR
instead), so this trick wouldn't even be enough in all situations, and we would need another CMake option like MYLIB_IGNORE_VCPKG_FREETYPE
which starts to be even uglier.