Skip to content

find_package macro breaks CMake policy propagation #28960

Open

Description

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 💣
    • 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) # 💥
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

  1. global: Fix vcpkg.cmake
    I don't know if this can be done for the macro.

  2. gdal: Fix the FindModule.cmake
    Adding cmake_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.

  3. libosmium: Bump cmake_minimum_required
    Using cmake_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.

  4. 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.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Labels

category:vcpkg-bugThe issue is with the vcpkg system (including helper scripts in `scripts/cmake/`)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions