summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2022-01-26 16:35:54 -0500
committerKyle Edwards <kyle.edwards@kitware.com>2022-02-02 11:09:00 -0500
commit201d8c429843e9e57f833fcca8794f532e6d3028 (patch)
treea66090c1d5445466e189f149a11c1b1bfde84667
parentbd805a51ae4b5be5be6bbadf4afab108fcf4ddb3 (diff)
downloadcmake-201d8c429843e9e57f833fcca8794f532e6d3028.tar.gz
find_*(): Add CMAKE_IGNORE_PREFIX_PATH variable
Fixes: #20878
-rw-r--r--Help/manual/cmake-variables.7.rst2
-rw-r--r--Help/release/dev/cmake-ignore-prefix-path.rst7
-rw-r--r--Help/variable/CMAKE_IGNORE_PREFIX_PATH.rst17
-rw-r--r--Help/variable/CMAKE_SYSTEM_IGNORE_PREFIX_PATH.rst18
-rw-r--r--Source/cmFindCommon.cxx46
-rw-r--r--Source/cmFindCommon.h4
-rw-r--r--Source/cmFindPackageCommand.cxx13
-rw-r--r--Source/cmFindPackageCommand.h1
-rw-r--r--Source/cmSearchPath.cxx6
-rw-r--r--Source/cmSearchPath.h3
-rw-r--r--Tests/RunCMake/find_package/IgnorePrefixPath.cmake26
-rw-r--r--Tests/RunCMake/find_package/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/find_program/IgnorePrefixPath.cmake30
-rwxr-xr-xTests/RunCMake/find_program/Prefix/bin/prog1
-rw-r--r--Tests/RunCMake/find_program/RunCMakeTest.cmake1
-rwxr-xr-xTests/RunCMake/find_program/SystemPrefix/bin/prog1
16 files changed, 165 insertions, 12 deletions
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 04c5a533c3..59566b50a4 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -212,6 +212,7 @@ Variables that Change Behavior
/variable/CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY
/variable/CMAKE_FRAMEWORK_PATH
/variable/CMAKE_IGNORE_PATH
+ /variable/CMAKE_IGNORE_PREFIX_PATH
/variable/CMAKE_INCLUDE_DIRECTORIES_BEFORE
/variable/CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE
/variable/CMAKE_INCLUDE_PATH
@@ -250,6 +251,7 @@ Variables that Change Behavior
/variable/CMAKE_SYSTEM_APPBUNDLE_PATH
/variable/CMAKE_SYSTEM_FRAMEWORK_PATH
/variable/CMAKE_SYSTEM_IGNORE_PATH
+ /variable/CMAKE_SYSTEM_IGNORE_PREFIX_PATH
/variable/CMAKE_SYSTEM_INCLUDE_PATH
/variable/CMAKE_SYSTEM_LIBRARY_PATH
/variable/CMAKE_SYSTEM_PREFIX_PATH
diff --git a/Help/release/dev/cmake-ignore-prefix-path.rst b/Help/release/dev/cmake-ignore-prefix-path.rst
new file mode 100644
index 0000000000..780e04f488
--- /dev/null
+++ b/Help/release/dev/cmake-ignore-prefix-path.rst
@@ -0,0 +1,7 @@
+cmake-ignore-prefix-path
+------------------------
+
+* :command:`find_package`, :command:`find_program`, :command:`find_library`,
+ :command:`find_path`, and :command:`find_file` now recognize the
+ :variable:`CMAKE_IGNORE_PREFIX_PATH` and
+ :variable:`CMAKE_SYSTEM_IGNORE_PREFIX_PATH` variables.
diff --git a/Help/variable/CMAKE_IGNORE_PREFIX_PATH.rst b/Help/variable/CMAKE_IGNORE_PREFIX_PATH.rst
new file mode 100644
index 0000000000..45e51ddd54
--- /dev/null
+++ b/Help/variable/CMAKE_IGNORE_PREFIX_PATH.rst
@@ -0,0 +1,17 @@
+CMAKE_IGNORE_PREFIX_PATH
+------------------------
+
+:ref:`Semicolon-separated list <CMake Language Lists>` of prefix to be *ignored* by
+the :command:`find_program`, :command:`find_library`, :command:`find_file`,
+:command:`find_path`, and :command:`find_package` commands. This is useful in cross-compiling
+environments where some system directories contain incompatible but
+possibly linkable libraries. For example, on cross-compiled cluster
+environments, this allows a user to ignore directories containing
+libraries meant for the front-end machine.
+
+By default this is empty; it is intended to be set by the project.
+Note that ``CMAKE_IGNORE_PREFIX_PATH`` takes a list of prefixes, *not*
+a list of directory names.
+
+See also the :variable:`CMAKE_PREFIX_PATH`, :variable:`CMAKE_LIBRARY_PATH`,
+:variable:`CMAKE_INCLUDE_PATH`, and :variable:`CMAKE_PROGRAM_PATH` variables.
diff --git a/Help/variable/CMAKE_SYSTEM_IGNORE_PREFIX_PATH.rst b/Help/variable/CMAKE_SYSTEM_IGNORE_PREFIX_PATH.rst
new file mode 100644
index 0000000000..b17783423b
--- /dev/null
+++ b/Help/variable/CMAKE_SYSTEM_IGNORE_PREFIX_PATH.rst
@@ -0,0 +1,18 @@
+CMAKE_SYSTEM_IGNORE_PREFIX_PATH
+-------------------------------
+
+:ref:`Semicolon-separated list <CMake Language Lists>` of prefixes to be *ignored* by
+the :command:`find_program`, :command:`find_library`, :command:`find_file`,
+:command:`find_path`, and :command:`find_package` commands. This is useful in cross-compiling
+environments where some system directories contain incompatible but
+possibly linkable libraries. For example, on cross-compiled cluster
+environments, this allows a user to ignore directories containing
+libraries meant for the front-end machine.
+
+By default this contains a list of directories containing incompatible
+binaries for the host system. See the :variable:`CMAKE_IGNORE_PREFIX_PATH` variable
+that is intended to be set by the project.
+
+See also the :variable:`CMAKE_SYSTEM_PREFIX_PATH`,
+:variable:`CMAKE_SYSTEM_LIBRARY_PATH`, :variable:`CMAKE_SYSTEM_INCLUDE_PATH`,
+and :variable:`CMAKE_SYSTEM_PROGRAM_PATH` variables.
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index c58db1e67e..1bb98ea7fe 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -262,11 +262,13 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
(stagePrefix && isSameDirectoryOrSubDirectory(up, *stagePrefix))) {
rootedDir = up;
} else if (!up.empty() && up[0] != '~') {
- // Start with the new root.
- rootedDir = cmStrCat(r, '/');
-
- // Append the original path with its old root removed.
- rootedDir += cmSystemTools::SplitPathRootComponent(up);
+ auto const* split = cmSystemTools::SplitPathRootComponent(up);
+ if (split && *split) {
+ // Start with the new root.
+ rootedDir = cmStrCat(r, '/', split);
+ } else {
+ rootedDir = r;
+ }
}
// Store the new path.
@@ -306,6 +308,31 @@ void cmFindCommon::GetIgnoredPaths(std::set<std::string>& ignore)
ignore.insert(ignoreVec.begin(), ignoreVec.end());
}
+void cmFindCommon::GetIgnoredPrefixPaths(std::vector<std::string>& ignore)
+{
+ static constexpr const char* paths[] = {
+ "CMAKE_SYSTEM_IGNORE_PREFIX_PATH",
+ "CMAKE_IGNORE_PREFIX_PATH",
+ };
+
+ // Construct the list of path roots with no trailing slashes.
+ for (const char* pathName : paths) {
+ // Get the list of paths to ignore from the variable.
+ this->Makefile->GetDefExpandList(pathName, ignore);
+ }
+
+ for (std::string& i : ignore) {
+ cmSystemTools::ConvertToUnixSlashes(i);
+ }
+}
+
+void cmFindCommon::GetIgnoredPrefixPaths(std::set<std::string>& ignore)
+{
+ std::vector<std::string> ignoreVec;
+ this->GetIgnoredPrefixPaths(ignoreVec);
+ ignore.insert(ignoreVec.begin(), ignoreVec.end());
+}
+
bool cmFindCommon::CheckCommonArgument(std::string const& arg)
{
if (arg == "NO_DEFAULT_PATH") {
@@ -369,16 +396,19 @@ static void AddTrailingSlash(std::string& s)
void cmFindCommon::ComputeFinalPaths(IgnorePaths ignorePaths)
{
// Filter out ignored paths from the prefix list
- std::set<std::string> ignored;
+ std::set<std::string> ignoredPaths;
+ std::set<std::string> ignoredPrefixes;
if (ignorePaths == IgnorePaths::Yes) {
- this->GetIgnoredPaths(ignored);
+ this->GetIgnoredPaths(ignoredPaths);
+ this->GetIgnoredPrefixPaths(ignoredPrefixes);
}
// Combine the separate path types, filtering out ignores
this->SearchPaths.clear();
std::vector<PathLabel>& allLabels = this->PathGroupLabelMap[PathGroup::All];
for (PathLabel const& l : allLabels) {
- this->LabeledPaths[l].ExtractWithout(ignored, this->SearchPaths);
+ this->LabeledPaths[l].ExtractWithout(ignoredPaths, ignoredPrefixes,
+ this->SearchPaths);
}
// Expand list of paths inside all search roots.
diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h
index 6649c350e3..5d9b3e1a47 100644
--- a/Source/cmFindCommon.h
+++ b/Source/cmFindCommon.h
@@ -86,6 +86,10 @@ protected:
void GetIgnoredPaths(std::vector<std::string>& ignore);
void GetIgnoredPaths(std::set<std::string>& ignore);
+ /** Get ignored paths from CMAKE_[SYSTEM_]IGNORE_PREFIX_PATH variables. */
+ void GetIgnoredPrefixPaths(std::vector<std::string>& ignore);
+ void GetIgnoredPrefixPaths(std::set<std::string>& ignore);
+
/** Compute final search path list (reroot + trailing slash). */
enum class IgnorePaths
{
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 85badf6810..fac0e08eee 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -665,6 +665,16 @@ bool cmFindPackageCommand::FindPackageUsingConfigMode()
this->IgnoredPaths.clear();
this->IgnoredPaths.insert(ignored.begin(), ignored.end());
+ // get igonored prefix paths from vars and reroot them.
+ std::vector<std::string> ignoredPrefixes;
+ this->GetIgnoredPrefixPaths(ignoredPrefixes);
+ this->RerootPaths(ignoredPrefixes);
+
+ // Construct a set of ignored prefix paths
+ this->IgnoredPrefixPaths.clear();
+ this->IgnoredPrefixPaths.insert(ignoredPrefixes.begin(),
+ ignoredPrefixes.end());
+
// Find and load the package.
return this->HandlePackageMode(HandlePackageModeType::Config);
}
@@ -2291,7 +2301,8 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
if (prefixWithoutSlash != "/" && prefixWithoutSlash.back() == '/') {
prefixWithoutSlash.erase(prefixWithoutSlash.length() - 1);
}
- if (this->IgnoredPaths.count(prefixWithoutSlash)) {
+ if (this->IgnoredPaths.count(prefixWithoutSlash) ||
+ this->IgnoredPrefixPaths.count(prefixWithoutSlash)) {
return false;
}
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 9d6eddf82a..439d93415c 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -205,6 +205,7 @@ private:
std::vector<std::string> Names;
std::vector<std::string> Configs;
std::set<std::string> IgnoredPaths;
+ std::set<std::string> IgnoredPrefixPaths;
std::string DebugBuffer;
/*! the selected sortOrder (None by default)*/
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
index ff54a8a7f7..bfee64c961 100644
--- a/Source/cmSearchPath.cxx
+++ b/Source/cmSearchPath.cxx
@@ -19,7 +19,8 @@ cmSearchPath::cmSearchPath(cmFindCommon* findCmd)
cmSearchPath::~cmSearchPath() = default;
-void cmSearchPath::ExtractWithout(const std::set<std::string>& ignore,
+void cmSearchPath::ExtractWithout(const std::set<std::string>& ignorePaths,
+ const std::set<std::string>& ignorePrefixes,
std::vector<std::string>& outPaths,
bool clear) const
{
@@ -27,7 +28,8 @@ void cmSearchPath::ExtractWithout(const std::set<std::string>& ignore,
outPaths.clear();
}
for (auto const& path : this->Paths) {
- if (ignore.count(path.Path) == 0) {
+ if (ignorePaths.count(path.Path) == 0 &&
+ ignorePrefixes.count(path.Prefix) == 0) {
outPaths.push_back(path.Path);
}
}
diff --git a/Source/cmSearchPath.h b/Source/cmSearchPath.h
index 08f9cfa92d..4c0cabbf3f 100644
--- a/Source/cmSearchPath.h
+++ b/Source/cmSearchPath.h
@@ -43,7 +43,8 @@ public:
const std::vector<PathWithPrefix>& GetPaths() const { return this->Paths; }
std::size_t size() const { return this->Paths.size(); }
- void ExtractWithout(const std::set<std::string>& ignore,
+ void ExtractWithout(const std::set<std::string>& ignorePaths,
+ const std::set<std::string>& ignorePrefixes,
std::vector<std::string>& outPaths,
bool clear = false) const;
diff --git a/Tests/RunCMake/find_package/IgnorePrefixPath.cmake b/Tests/RunCMake/find_package/IgnorePrefixPath.cmake
new file mode 100644
index 0000000000..65709a2342
--- /dev/null
+++ b/Tests/RunCMake/find_package/IgnorePrefixPath.cmake
@@ -0,0 +1,26 @@
+set(CMAKE_PREFIX_PATH
+ ${CMAKE_SOURCE_DIR}/PackageRoot/foo/cmake_root
+ ${CMAKE_SOURCE_DIR}/PackageRoot/foo/env_root
+ )
+set(CMAKE_IGNORE_PREFIX_PATH
+ ${CMAKE_SOURCE_DIR}/PackageRoot//foo/cmake_root// # Test double slashes
+ )
+set(CMAKE_SYSTEM_IGNORE_PREFIX_PATH
+ ${CMAKE_SOURCE_DIR}/PackageRoot/foo/env_root
+ )
+find_package(Bar QUIET CONFIG)
+if(Bar_FOUND)
+ message(SEND_ERROR "Bar should not be found, was found in ${Bar_DIR}")
+endif()
+
+set(CMAKE_PREFIX_PATH)
+set(CMAKE_FIND_ROOT_PATH
+ ${CMAKE_SOURCE_DIR}/PackageRoot/foo/cmake_root
+ ${CMAKE_SOURCE_DIR}/PackageRoot/foo/env_root
+ )
+set(CMAKE_IGNORE_PREFIX_PATH /)
+set(CMAKE_SYSTEM_IGNORE_PREFIX_PATH)
+find_package(Bar2 NAMES Bar QUIET CONFIG)
+if(Bar2_FOUND)
+ message(SEND_ERROR "Bar2 should not be found, was found in ${Bar2_DIR}")
+endif()
diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake
index 12701dc022..037502f623 100644
--- a/Tests/RunCMake/find_package/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake
@@ -45,6 +45,7 @@ run_cmake(VersionRangeConfig02)
run_cmake(VersionRangeConfigStd)
run_cmake(VersionRangeConfigStd2)
run_cmake(IgnorePath)
+run_cmake(IgnorePrefixPath)
if(UNIX
AND NOT MSYS # FIXME: This works on CYGWIN but not on MSYS
)
diff --git a/Tests/RunCMake/find_program/IgnorePrefixPath.cmake b/Tests/RunCMake/find_program/IgnorePrefixPath.cmake
new file mode 100644
index 0000000000..5f0dba9d5b
--- /dev/null
+++ b/Tests/RunCMake/find_program/IgnorePrefixPath.cmake
@@ -0,0 +1,30 @@
+function(assert_eq var value)
+ if(NOT "${${var}}" STREQUAL "${value}")
+ message(SEND_ERROR "Expected value of ${var}:\n ${value}\nActual value:\n ${${var}}")
+ endif()
+endfunction()
+
+set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH FALSE)
+
+set(CMAKE_PREFIX_PATH ${CMAKE_SOURCE_DIR}/Prefix)
+set(_old_CMAKE_SYSTEM_PREFIX_PATH ${CMAKE_SYSTEM_PREFIX_PATH})
+set(CMAKE_SYSTEM_PREFIX_PATH ${CMAKE_SOURCE_DIR}/SystemPrefix)
+set(prog_ROOT
+ ${CMAKE_SOURCE_DIR}/Prefix
+ ${CMAKE_SOURCE_DIR}/SystemPrefix
+ )
+
+set(CMAKE_IGNORE_PREFIX_PATH ${CMAKE_SOURCE_DIR}/Prefix)
+set(CMAKE_SYSTEM_IGNORE_PREFIX_PATH ${CMAKE_SOURCE_DIR}/SystemPrefix)
+find_program(prog prog)
+assert_eq(prog "prog-NOTFOUND")
+
+set(CMAKE_PREFIX_PATH)
+set(CMAKE_SYSTEM_PREFIX_PATH ${_old_CMAKE_SYSTEM_PREFIX_PATH})
+set(CMAKE_IGNORE_PREFIX_PATH /)
+set(CMAKE_FIND_ROOT_PATH
+ ${CMAKE_SOURCE_DIR}/Prefix
+ ${CMAKE_SOURCE_DIR}/SystemPrefix
+ )
+find_program(prog2 prog)
+assert_eq(prog2 "prog2-NOTFOUND")
diff --git a/Tests/RunCMake/find_program/Prefix/bin/prog b/Tests/RunCMake/find_program/Prefix/bin/prog
new file mode 100755
index 0000000000..1a2485251c
--- /dev/null
+++ b/Tests/RunCMake/find_program/Prefix/bin/prog
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/Tests/RunCMake/find_program/RunCMakeTest.cmake b/Tests/RunCMake/find_program/RunCMakeTest.cmake
index 2a1dae475f..c2c07afa56 100644
--- a/Tests/RunCMake/find_program/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_program/RunCMakeTest.cmake
@@ -6,6 +6,7 @@ run_cmake(NamesPerDir)
run_cmake(RelAndAbsPath)
run_cmake(Required)
run_cmake(NO_CACHE)
+run_cmake(IgnorePrefixPath)
if(CMAKE_SYSTEM_NAME MATCHES "^(Windows|CYGWIN|MSYS)$")
run_cmake(WindowsCom)
diff --git a/Tests/RunCMake/find_program/SystemPrefix/bin/prog b/Tests/RunCMake/find_program/SystemPrefix/bin/prog
new file mode 100755
index 0000000000..1a2485251c
--- /dev/null
+++ b/Tests/RunCMake/find_program/SystemPrefix/bin/prog
@@ -0,0 +1 @@
+#!/bin/sh