Description
openedon Jan 15, 2023
Describe the bug
The vcpkg.cmake
toolchain file defines a find_package
macro in order to inject extra behaviours.
This macro changes the active CMake policies as seen by called Find modules and Config files
...from the state of policies when find_package
is called (late, project configuration)
...to the state of policies which was active when the macro is defined (early, toolchain initialization).
This change can break configuration in particular for projects which apply a low minimum CMake version.
The key difficulty is the fact that the interaction is not obvious. It may be a rare case, but this makes it even more puzzling when it happens.
Exampe
From #28929:
- Install gdal with libkml support.
- Build libosmium. Simplified:
- CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.12)
# 🏛️ - CMakeLists.txt:
project(libosmium)
- vcpkg.cmake:
macro(find_package)
# CMP0057 OLD 💣
- vcpkg.cmake:
- CMakeLists.txt:
find_package(GDAL REQUIRED)
- gdal/vcpkg-cmake-wrapper.cmake:
cmake_policy(SET CMP0057 NEW)
# 🚒 - gdal/vcpkg-cmake-wrapper.cmake:
find_dependency(LibKML)
# CMP0057 NEW 😇- vcpkg.cmake:
_find_package(LibKML)
# in macro, CMP0057 OLD ⚡- gdal/FindLibKML.cmake:
if(comp IN_LIST LibKML_FIND_COMPONENTS)
# 💥
- gdal/FindLibKML.cmake:
- vcpkg.cmake:
- gdal/vcpkg-cmake-wrapper.cmake:
- CMakeLists.txt:
CMake Error at /mnt/vcpkg-ci/installed/x64-linux/share/gdal/packages/FindLibKML.cmake:61 (if):
if given arguments:
"DOM" "IN_LIST" "LibKML_FIND_COMPONENTS"
Unknown arguments specified
Alternative solutions for the given example
-
global: Fix vcpkg.cmake
I don't know if this can be done for the macro. -
gdal: Fix the FindModule.cmake
Addingcmake_policy(SET CMP0057 NEW)
to FindLibKML.cmake` will fix the problem for all users.
It may be possible to upstream the change. But the problem is specific to vcpkg's macro in combination with particular downstreams, so upstream might be unwilling to accept a patch. -
libosmium: Bump
cmake_minimum_required
Usingcmake_minimum_required(VERSION 2.8.12...3.25)
will enable new policies as possible since CMake 3.12 and is compatible with CMake older than 3.12, so it may be possible to upstream the change. However, new policies may come with extra side effects, positive and negative, so it is not without risk.
The fix has to be applied to every affected port. -
libosmium: Configure with
-DCMAKE_POLICY_DEFAULT_CMP0057=NEW
No patching, just portfile changes.
The fix has to be applied to every affected port.
(In this particular example, no. 2 is a good choice because we need to carry a patch for this module anyways.)