From 91ec6eee58cdde3ad7994b5c7f96994427e65b68 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Wed, 20 Oct 2021 13:26:25 +0200 Subject: find_package: Don't reroot prefix that is equal to a root path When both CMAKE_FIND_ROOT_PATH and CMAKE_PREFIX_PATH are set to /opt/my_device_sysroot, cmFindCommon::RerootPaths would only look for packages in /opt/my_device_sysroot/opt/my_device_sysroot but would not try to look in /opt/my_device_sysroot. Make sure to not reroot the prefix path in such a case. Fixes: #21937 --- Source/cmFindCommon.cxx | 10 ++++++++-- .../find_package/FindRootPathAndPrefixPathAreEqual.cmake | 16 ++++++++++++++++ .../lib/cmake/Foo/FooConfig.cmake | 0 Tests/RunCMake/find_package/RunCMakeTest.cmake | 1 + 4 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 Tests/RunCMake/find_package/FindRootPathAndPrefixPathAreEqual.cmake create mode 100644 Tests/RunCMake/find_package/FindRootPathAndPrefixPathAreEqual/lib/cmake/Foo/FooConfig.cmake diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index bdc9207..e896a87 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -240,14 +240,20 @@ void cmFindCommon::RerootPaths(std::vector& paths) std::vector unrootedPaths = paths; paths.clear(); + auto isSameDirectoryOrSubDirectory = [](std::string const& l, + std::string const& r) { + return (cmSystemTools::GetRealPath(l) == cmSystemTools::GetRealPath(r)) || + cmSystemTools::IsSubDirectory(l, r); + }; + for (std::string const& r : roots) { for (std::string const& up : unrootedPaths) { // Place the unrooted path under the current root if it is not // already inside. Skip the unrooted path if it is relative to // a user home directory or is empty. std::string rootedDir; - if (cmSystemTools::IsSubDirectory(up, r) || - (stagePrefix && cmSystemTools::IsSubDirectory(up, *stagePrefix))) { + if (isSameDirectoryOrSubDirectory(up, r) || + (stagePrefix && isSameDirectoryOrSubDirectory(up, *stagePrefix))) { rootedDir = up; } else if (!up.empty() && up[0] != '~') { // Start with the new root. diff --git a/Tests/RunCMake/find_package/FindRootPathAndPrefixPathAreEqual.cmake b/Tests/RunCMake/find_package/FindRootPathAndPrefixPathAreEqual.cmake new file mode 100644 index 0000000..2994fc2 --- /dev/null +++ b/Tests/RunCMake/find_package/FindRootPathAndPrefixPathAreEqual.cmake @@ -0,0 +1,16 @@ +set(root "${CMAKE_CURRENT_SOURCE_DIR}/FindRootPathAndPrefixPathAreEqual") +set(CMAKE_FIND_ROOT_PATH "${root}") +set(CMAKE_PREFIX_PATH "${root}") +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE "ONLY") + +find_package(Foo + REQUIRED + CONFIG + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + # Important because CMAKE_SYSTEM_PREFIX_PATH might contain "/" as a prefix + # And when "/" is rerooted onto the root above, the package is found even if + # CMAKE_PREFIX_PATH is empty. We want to ensure that we hit + # the CMAKE_FIND_ROOT_PATH == CMAKE_PREFIX_PATH code path. + NO_CMAKE_SYSTEM_PATH + ) diff --git a/Tests/RunCMake/find_package/FindRootPathAndPrefixPathAreEqual/lib/cmake/Foo/FooConfig.cmake b/Tests/RunCMake/find_package/FindRootPathAndPrefixPathAreEqual/lib/cmake/Foo/FooConfig.cmake new file mode 100644 index 0000000..e69de29 diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake index b20a889..ad9757d 100644 --- a/Tests/RunCMake/find_package/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake @@ -25,6 +25,7 @@ run_cmake(PackageRootNestedModule) run_cmake(PolicyPush) run_cmake(PolicyPop) run_cmake(RequiredOptionValuesClash) +run_cmake(FindRootPathAndPrefixPathAreEqual) run_cmake(SetFoundFALSE) run_cmake(WrongVersion) run_cmake(WrongVersionConfig) -- cgit v0.12