From 87a661a916f05d0334c8f9ef4e8719a6ca157c3e Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 1 Oct 2025 12:21:50 -0400 Subject: [PATCH] find_package: Fix regression on `_ROOT` relative to CWD In commit 9d44a77454 (find_*: Explicitly normalize found paths as they exist on disk, 2024-10-17, v4.0.0-rc1~597^2~1), we removed path normalization from the internal `cmSearchPath::AddPathInternal` helper. Most call sites were updated to normalize input paths first, but search paths derived from `_ROOT` CMake variables are no longer normalized. Instead we normalize the path to the file found after searching. When `find_package` "config" mode considers a candidate CMake package configuration file, normalize its path before loading the adjacent package version file so that the latter is loaded by absolute path. Otherwise `cmMakefile::ReadDependentFile` interprets a relative path with respect to the current source directory rather than the current working directory. Fixes: #27279 --- Source/cmFindPackageCommand.cxx | 13 ++++++------- .../find_package/PackageRootRelative-stdout.txt | 2 ++ .../RunCMake/find_package/PackageRootRelative.cmake | 7 +++++++ Tests/RunCMake/find_package/RunCMakeTest.cmake | 1 + 4 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 Tests/RunCMake/find_package/PackageRootRelative-stdout.txt create mode 100644 Tests/RunCMake/find_package/PackageRootRelative.cmake diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index f75361fbab..23083b0146 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -2873,14 +2873,13 @@ bool cmFindPackageCommand::FindConfigFile(std::string const& dir, this->DebugBuffer = cmStrCat(this->DebugBuffer, " ", file, '\n'); } if (cmSystemTools::FileExists(file, true)) { + // Allow resolving symlinks when the config file is found through a link + if (this->UseRealPath) { + file = cmSystemTools::GetRealPath(file); + } else { + file = cmSystemTools::ToNormalizedPathOnDisk(file); + } if (this->CheckVersion(file)) { - // Allow resolving symlinks when the config file is found through a - // link - if (this->UseRealPath) { - file = cmSystemTools::GetRealPath(file); - } else { - file = cmSystemTools::ToNormalizedPathOnDisk(file); - } foundMode = cmFindPackageCommand::FoundMode(config.Type); return true; } diff --git a/Tests/RunCMake/find_package/PackageRootRelative-stdout.txt b/Tests/RunCMake/find_package/PackageRootRelative-stdout.txt new file mode 100644 index 0000000000..e99d37d447 --- /dev/null +++ b/Tests/RunCMake/find_package/PackageRootRelative-stdout.txt @@ -0,0 +1,2 @@ +-- Relative_ROOT='root' +-- Relative_DIR='[^']*/Tests/RunCMake/find_package/PackageRootRelative-build/root' diff --git a/Tests/RunCMake/find_package/PackageRootRelative.cmake b/Tests/RunCMake/find_package/PackageRootRelative.cmake new file mode 100644 index 0000000000..3d63753477 --- /dev/null +++ b/Tests/RunCMake/find_package/PackageRootRelative.cmake @@ -0,0 +1,7 @@ +cmake_policy(SET CMP0074 NEW) +set(Relative_ROOT root) +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/root/RelativeConfig.cmake" "") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/root/RelativeConfigVersion.cmake" "set(PACKAGE_VERSION 1)") +find_package(Relative) +message(STATUS "Relative_ROOT='${Relative_ROOT}'") +message(STATUS "Relative_DIR='${Relative_DIR}'") diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake index 10f3453514..969d6d7bc1 100644 --- a/Tests/RunCMake/find_package/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake @@ -39,6 +39,7 @@ run_cmake_with_options(ModuleModeDebugPkg --debug-find-pkg=Foo,Zot) run_cmake(PackageRoot) run_cmake(PackageRootNestedConfig) run_cmake(PackageRootNestedModule) +run_cmake(PackageRootRelative) run_cmake(PackageVarOverridesOptional) run_cmake(PolicyPush) run_cmake(PolicyPop)