diff options
author | Robert Maynard <rmaynard@nvidia.com> | 2022-03-21 19:05:39 (GMT) |
---|---|---|
committer | Robert Maynard <rmaynard@nvidia.com> | 2022-04-15 13:33:55 (GMT) |
commit | 42f7e397894c5132b4706f478e62ce5d648119c1 (patch) | |
tree | cbc53e9c4fad5d12e3c724011770a377fc572890 | |
parent | 7fc248bde34c529c6f1312a56c7e82303238b9c1 (diff) | |
download | CMake-42f7e397894c5132b4706f478e62ce5d648119c1.zip CMake-42f7e397894c5132b4706f478e62ce5d648119c1.tar.gz CMake-42f7e397894c5132b4706f478e62ce5d648119c1.tar.bz2 |
Find: Support per call disabling of CMAKE_INSTALL_PREFIX
Fixes #23359
38 files changed, 328 insertions, 13 deletions
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim index c53d094..0dadafa 100644 --- a/Auxiliary/vim/syntax/cmake.vim +++ b/Auxiliary/vim/syntax/cmake.vim @@ -1046,6 +1046,7 @@ syn keyword cmakeVariable contained \ CMAKE_FIND_ROOT_PATH_MODE_PACKAGE \ CMAKE_FIND_ROOT_PATH_MODE_PROGRAM \ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH + \ CMAKE_FIND_USE_INSTALL_PREFIX \ CMAKE_FIND_USE_CMAKE_PATH \ CMAKE_FIND_USE_CMAKE_SYSTEM_PATH \ CMAKE_FIND_USE_PACKAGE_REGISTRY diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt index ee6c1cc..1e75dc9 100644 --- a/Help/command/FIND_XXX.txt +++ b/Help/command/FIND_XXX.txt @@ -23,6 +23,7 @@ The general signature is: [NO_CMAKE_ENVIRONMENT_PATH] [NO_SYSTEM_ENVIRONMENT_PATH] [NO_CMAKE_SYSTEM_PATH] + [NO_CMAKE_INSTALL_PREFIX] [CMAKE_FIND_ROOT_PATH_BOTH | ONLY_CMAKE_FIND_ROOT_PATH | NO_CMAKE_FIND_ROOT_PATH] @@ -154,9 +155,11 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows: * |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| 6. Search cmake variables defined in the Platform files - for the current system. This can be skipped if ``NO_CMAKE_SYSTEM_PATH`` - is passed or by setting the :variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH` - to ``FALSE``. + for the current system. The searching of ``CMAKE_INSTALL_PREFIX` can be + skipped if ``NO_CMAKE_INSTALL_PREFIX`` is passed or by setting the + :variable:`CMAKE_FIND_USE_INSTALL_PREFIX` to ``FALSE. All these locations + can be skipped if ``NO_CMAKE_SYSTEM_PATH`` is passed or by setting the + :variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH` to ``FALSE``. * |CMAKE_SYSTEM_PREFIX_PATH_XXX| * |CMAKE_SYSTEM_XXX_PATH| diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst index e43b7bd..2e7b01b 100644 --- a/Help/command/find_package.rst +++ b/Help/command/find_package.rst @@ -175,6 +175,7 @@ Full Signature [NO_CMAKE_PACKAGE_REGISTRY] [NO_CMAKE_BUILDS_PATH] # Deprecated; does nothing. [NO_CMAKE_SYSTEM_PATH] + [NO_CMAKE_INSTALL_PREFIX] [NO_CMAKE_SYSTEM_PACKAGE_REGISTRY] [CMAKE_FIND_ROOT_PATH_BOTH | ONLY_CMAKE_FIND_ROOT_PATH | @@ -345,9 +346,11 @@ enabled. package registry. 7. Search cmake variables defined in the Platform files for the - current system. This can be skipped if ``NO_CMAKE_SYSTEM_PATH`` is - passed or by setting the :variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH` - to ``FALSE``: + current system. The searching of ``CMAKE_INSTALL_PREFIX` can be skipped + if ``NO_CMAKE_INSTALL_PREFIX`` is passed or by setting the + :variable:`CMAKE_FIND_USE_INSTALL_PREFIX` to ``FALSE. All these locations + can be skipped if ``NO_CMAKE_SYSTEM_PATH`` is passed or by setting the + :variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH` to ``FALSE``: * :variable:`CMAKE_SYSTEM_PREFIX_PATH` * :variable:`CMAKE_SYSTEM_FRAMEWORK_PATH` diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 7d68d4e..70dfc35 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -206,6 +206,7 @@ Variables that Change Behavior /variable/CMAKE_FIND_ROOT_PATH_MODE_PACKAGE /variable/CMAKE_FIND_ROOT_PATH_MODE_PROGRAM /variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH + /variable/CMAKE_FIND_USE_INSTALL_PREFIX /variable/CMAKE_FIND_USE_CMAKE_PATH /variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH /variable/CMAKE_FIND_USE_PACKAGE_REGISTRY diff --git a/Help/release/dev/find-calls-search-install-prefix.rst b/Help/release/dev/find-calls-search-install-prefix.rst new file mode 100644 index 0000000..a111a91 --- /dev/null +++ b/Help/release/dev/find-calls-search-install-prefix.rst @@ -0,0 +1,12 @@ +find-calls-search-install-prefix +-------------------------------- + +* The :command:`find_file`, :command:`find_library`, :command:`find_path`, + :command:`find_package`, and :command:`find_program` commands have gained + the `NO_CMAKE_INSTALL_PREFIX` option to control searching + `CMAKE_INSTALL_PREFIX`. + +* Adds support for :variable:`CMAKE_FIND_USE_INSTALL_PREFIX` to toggle + behavior of the :command:`find_file`, :command:`find_library`, :command:`find_path`, + :command:`find_package`, and :command:`find_program` commands new + `NO_CMAKE_INSTALL_PREFIX` option. diff --git a/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst b/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst index de1bad7..f72fd65 100644 --- a/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst +++ b/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst @@ -20,6 +20,7 @@ take precedence over this variable. See also the :variable:`CMAKE_FIND_USE_CMAKE_PATH`, :variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH`, +:variable:`CMAKE_FIND_USE_INSTALL_PREFIX`, :variable:`CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH`, :variable:`CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY`, :variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY`, diff --git a/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst b/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst index 2fd00df..2c1d237 100644 --- a/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst +++ b/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst @@ -20,6 +20,7 @@ take precedence over this variable. See also the :variable:`CMAKE_FIND_USE_CMAKE_PATH`, :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH`, +:variable:`CMAKE_FIND_USE_INSTALL_PREFIX`, :variable:`CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH`, :variable:`CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY`, :variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY`, diff --git a/Help/variable/CMAKE_FIND_USE_INSTALL_PREFIX.rst b/Help/variable/CMAKE_FIND_USE_INSTALL_PREFIX.rst new file mode 100644 index 0000000..8494e95 --- /dev/null +++ b/Help/variable/CMAKE_FIND_USE_INSTALL_PREFIX.rst @@ -0,0 +1,39 @@ +CMAKE_FIND_USE_INSTALL_PREFIX +----------------------------------- + +.. versionadded:: 3.24 + +Controls the default behavior of the following commands for whether or not to +search the install location: + +* :command:`find_program` +* :command:`find_library` +* :command:`find_file` +* :command:`find_path` +* :command:`find_package` + +This is useful in cross-compiling environments. + +Due to backwards compatibility with :variable:`CMAKE_FIND_NO_INSTALL_PREFIX`, +the behavior of the find command change based on if this variable exists. + +============================== ============================ =========== + CMAKE_FIND_USE_INSTALL_PREFIX CMAKE_FIND_NO_INSTALL_PREFIX Search +============================== ============================ =========== + Not Defined On NO + Not Defined Off || Not Defined YES + Off On NO + Off Off || Not Defined NO + On On YES + On Off || Not Defined YES +============================== ============================ =========== + +By default this variable is not defined. Explicit options given to the above +commands take precedence over this variable. + +See also the :variable:`CMAKE_FIND_USE_CMAKE_PATH`, +:variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH`, +:variable:`CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH`, +:variable:`CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY`, +:variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY`, +and :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` variables. diff --git a/Help/variable/CMAKE_FIND_USE_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_FIND_USE_PACKAGE_REGISTRY.rst index 3127206..a5eec7a 100644 --- a/Help/variable/CMAKE_FIND_USE_PACKAGE_REGISTRY.rst +++ b/Help/variable/CMAKE_FIND_USE_PACKAGE_REGISTRY.rst @@ -26,6 +26,7 @@ the :ref:`User Package Registry` as if they were called with the See also :ref:`Disabling the Package Registry` and the :variable:`CMAKE_FIND_USE_CMAKE_PATH`, :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH`, +:variable:`CMAKE_FIND_USE_INSTALL_PREFIX`, :variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH`, :variable:`CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH`, :variable:`CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY`, diff --git a/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst b/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst index 64e5c6d..1f876a9 100644 --- a/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst +++ b/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst @@ -18,6 +18,7 @@ take precedence over this variable. See also the :variable:`CMAKE_FIND_USE_CMAKE_PATH`, :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH`, +:variable:`CMAKE_FIND_USE_INSTALL_PREFIX`, :variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH`, :variable:`CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH`, :variable:`CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY`, diff --git a/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst b/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst index a0a86e4..65edd10 100644 --- a/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst +++ b/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst @@ -20,6 +20,7 @@ take precedence over this variable. See also the :variable:`CMAKE_FIND_USE_CMAKE_PATH`, :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH`, +:variable:`CMAKE_FIND_USE_INSTALL_PREFIX`, :variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH`, :variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY`, :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH`, diff --git a/Help/variable/CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY.rst index 504b7e8..2527904 100644 --- a/Help/variable/CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY.rst +++ b/Help/variable/CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY.rst @@ -27,6 +27,7 @@ See also :ref:`Disabling the Package Registry`. See also the :variable:`CMAKE_FIND_USE_CMAKE_PATH`, :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH`, +:variable:`CMAKE_FIND_USE_INSTALL_PREFIX`, :variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH`, :variable:`CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH`, :variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY`, diff --git a/Modules/CMakeSystemSpecificInformation.cmake b/Modules/CMakeSystemSpecificInformation.cmake index 0ded568..59f552a 100644 --- a/Modules/CMakeSystemSpecificInformation.cmake +++ b/Modules/CMakeSystemSpecificInformation.cmake @@ -17,6 +17,16 @@ set(CYGWIN ) set(MSYS ) set(WIN32 ) +function(_cmake_record_install_prefix ) + set(_CMAKE_SYSTEM_PREFIX_PATH_INSTALL_PREFIX_VALUE "${CMAKE_INSTALL_PREFIX}" PARENT_SCOPE) + set(count 0) + foreach(value IN LISTS CMAKE_SYSTEM_PREFIX_PATH) + if(value STREQUAL CMAKE_INSTALL_PREFIX) + math(EXPR count "${count}+1") + endif() + endforeach() + set(_CMAKE_SYSTEM_PREFIX_PATH_INSTALL_PREFIX_COUNT "${count}" PARENT_SCOPE) +endfunction() # include Generic system information include(CMakeGenericSystem) diff --git a/Modules/Platform/CrayLinuxEnvironment.cmake b/Modules/Platform/CrayLinuxEnvironment.cmake index f2aaf3f..b982b3f 100644 --- a/Modules/Platform/CrayLinuxEnvironment.cmake +++ b/Modules/Platform/CrayLinuxEnvironment.cmake @@ -68,6 +68,7 @@ if (NOT CMAKE_FIND_NO_INSTALL_PREFIX) ) endif() endif() +_cmake_record_install_prefix() list(APPEND CMAKE_SYSTEM_INCLUDE_PATH $ENV{SYSROOT_DIR}/usr/include/X11 diff --git a/Modules/Platform/UnixPaths.cmake b/Modules/Platform/UnixPaths.cmake index b9381c3..8a0ad23 100644 --- a/Modules/Platform/UnixPaths.cmake +++ b/Modules/Platform/UnixPaths.cmake @@ -44,6 +44,7 @@ if (NOT CMAKE_FIND_NO_INSTALL_PREFIX) ) endif() endif() +_cmake_record_install_prefix() # Non "standard" but common install prefixes list(APPEND CMAKE_SYSTEM_PREFIX_PATH diff --git a/Modules/Platform/WindowsPaths.cmake b/Modules/Platform/WindowsPaths.cmake index b9e2f17..de93338 100644 --- a/Modules/Platform/WindowsPaths.cmake +++ b/Modules/Platform/WindowsPaths.cmake @@ -67,6 +67,7 @@ if (NOT CMAKE_FIND_NO_INSTALL_PREFIX) ) endif() endif() +_cmake_record_install_prefix() if(CMAKE_CROSSCOMPILING AND NOT CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") # MinGW (useful when cross compiling from linux with CMAKE_FIND_ROOT_PATH set) diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index efc4e3a..a8db63d 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -267,8 +267,61 @@ void cmFindBase::FillCMakeSystemVariablePath() { cmSearchPath& paths = this->LabeledPaths[PathLabel::CMakeSystem]; + const bool install_prefix_in_list = + !this->Makefile->IsOn("CMAKE_FIND_NO_INSTALL_PREFIX"); + const bool remove_install_prefix = this->NoCMakeInstallPath; + const bool add_install_prefix = !this->NoCMakeInstallPath && + this->Makefile->IsDefinitionSet("CMAKE_FIND_USE_INSTALL_PREFIX"); + + // We have 3 possible states for `CMAKE_SYSTEM_PREFIX_PATH` and + // `CMAKE_INSTALL_PREFIX`. + // Either we need to remove `CMAKE_INSTALL_PREFIX`, add + // `CMAKE_INSTALL_PREFIX`, or do nothing. + // + // When we need to remove `CMAKE_INSTALL_PREFIX` we remove the Nth occurrence + // of `CMAKE_INSTALL_PREFIX` from `CMAKE_SYSTEM_PREFIX_PATH`, where `N` is + // computed by `CMakeSystemSpecificInformation.cmake` while constructing + // `CMAKE_SYSTEM_PREFIX_PATH`. This ensures that if projects / toolchains + // have removed `CMAKE_INSTALL_PREFIX` from the list, we don't remove + // some other entry by mistake + long install_prefix_count = -1; + std::string install_path_to_remove; + if (cmValue to_skip = this->Makefile->GetDefinition( + "_CMAKE_SYSTEM_PREFIX_PATH_INSTALL_PREFIX_COUNT")) { + cmStrToLong(to_skip, &install_prefix_count); + } + if (cmValue install_value = this->Makefile->GetDefinition( + "_CMAKE_SYSTEM_PREFIX_PATH_INSTALL_PREFIX_VALUE")) { + install_path_to_remove = *install_value; + } + + if (remove_install_prefix && install_prefix_in_list && + install_prefix_count > 0 && !install_path_to_remove.empty()) { + cmValue prefix_paths = + this->Makefile->GetDefinition("CMAKE_SYSTEM_PREFIX_PATH"); + + // remove entry from CMAKE_SYSTEM_PREFIX_PATH + std::vector<std::string> expanded = cmExpandedList(*prefix_paths); + long index_to_remove = 0; + for (const auto& path : expanded) { + if (path == install_path_to_remove && --install_prefix_count == 0) { + break; + } + ++index_to_remove; + } + expanded.erase(expanded.begin() + index_to_remove); + paths.AddPrefixPaths(expanded, + this->Makefile->GetCurrentSourceDirectory().c_str()); + } else if (add_install_prefix && !install_prefix_in_list) { + + paths.AddCMakePrefixPath("CMAKE_INSTALL_PREFIX"); + paths.AddCMakePrefixPath("CMAKE_SYSTEM_PREFIX_PATH"); + } else { + // Otherwise the current setup of `CMAKE_SYSTEM_PREFIX_PATH` is correct + paths.AddCMakePrefixPath("CMAKE_SYSTEM_PREFIX_PATH"); + } + std::string var = cmStrCat("CMAKE_SYSTEM_", this->CMakePathName, "_PATH"); - paths.AddCMakePrefixPath("CMAKE_SYSTEM_PREFIX_PATH"); paths.AddCMakePath(var); if (this->CMakePathName == "PROGRAM") { @@ -496,7 +549,9 @@ cmFindBaseDebugState::~cmFindBaseDebugState() " CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: ", !this->FindCommand->NoSystemEnvironmentPath, "\n", " CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: ", - !this->FindCommand->NoCMakeSystemPath, "\n"); + !this->FindCommand->NoCMakeSystemPath, "\n", + " CMAKE_FIND_USE_INSTALL_PREFIX: ", + !this->FindCommand->NoCMakeInstallPath, "\n"); } buffer += diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index 7106e4b..9fd712a 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -39,6 +39,7 @@ cmFindCommon::cmFindCommon(cmExecutionStatus& status) this->NoCMakeEnvironmentPath = false; this->NoSystemEnvironmentPath = false; this->NoCMakeSystemPath = false; + this->NoCMakeInstallPath = false; // OS X Bundle and Framework search policy. The default is to // search frameworks first on apple. @@ -179,14 +180,15 @@ void cmFindCommon::SelectDefaultMacMode() void cmFindCommon::SelectDefaultSearchModes() { - const std::array<std::pair<bool&, std::string>, 5> search_paths = { + const std::array<std::pair<bool&, std::string>, 6> search_paths = { { { this->NoPackageRootPath, "CMAKE_FIND_USE_PACKAGE_ROOT_PATH" }, { this->NoCMakePath, "CMAKE_FIND_USE_CMAKE_PATH" }, { this->NoCMakeEnvironmentPath, "CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH" }, { this->NoSystemEnvironmentPath, "CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH" }, - { this->NoCMakeSystemPath, "CMAKE_FIND_USE_CMAKE_SYSTEM_PATH" } } + { this->NoCMakeSystemPath, "CMAKE_FIND_USE_CMAKE_SYSTEM_PATH" }, + { this->NoCMakeInstallPath, "CMAKE_FIND_USE_INSTALL_PREFIX" } } }; for (auto const& path : search_paths) { @@ -348,6 +350,8 @@ bool cmFindCommon::CheckCommonArgument(std::string const& arg) this->NoSystemEnvironmentPath = true; } else if (arg == "NO_CMAKE_SYSTEM_PATH") { this->NoCMakeSystemPath = true; + } else if (arg == "NO_CMAKE_INSTALL_PREFIX") { + this->NoCMakeInstallPath = true; } else if (arg == "NO_CMAKE_FIND_ROOT_PATH") { this->FindRootPathMode = RootPathModeNever; } else if (arg == "ONLY_CMAKE_FIND_ROOT_PATH") { diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h index 5d9b3e1..4c02df0 100644 --- a/Source/cmFindCommon.h +++ b/Source/cmFindCommon.h @@ -130,6 +130,7 @@ protected: bool NoCMakeEnvironmentPath; bool NoSystemEnvironmentPath; bool NoCMakeSystemPath; + bool NoCMakeInstallPath; std::vector<std::string> SearchPathSuffixes; diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 18457a7..9a89935 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -1682,7 +1682,57 @@ void cmFindPackageCommand::FillPrefixesCMakeSystemVariable() { cmSearchPath& paths = this->LabeledPaths[PathLabel::CMakeSystem]; - paths.AddCMakePath("CMAKE_SYSTEM_PREFIX_PATH"); + const bool install_prefix_in_list = + !this->Makefile->IsOn("CMAKE_FIND_NO_INSTALL_PREFIX"); + const bool remove_install_prefix = this->NoCMakeInstallPath; + const bool add_install_prefix = !this->NoCMakeInstallPath && + this->Makefile->IsDefinitionSet("CMAKE_FIND_USE_INSTALL_PREFIX"); + + // We have 3 possible states for `CMAKE_SYSTEM_PREFIX_PATH` and + // `CMAKE_INSTALL_PREFIX`. + // Either we need to remove `CMAKE_INSTALL_PREFIX`, add + // `CMAKE_INSTALL_PREFIX`, or do nothing. + // + // When we need to remove `CMAKE_INSTALL_PREFIX` we remove the Nth occurrence + // of `CMAKE_INSTALL_PREFIX` from `CMAKE_SYSTEM_PREFIX_PATH`, where `N` is + // computed by `CMakeSystemSpecificInformation.cmake` while constructing + // `CMAKE_SYSTEM_PREFIX_PATH`. This ensures that if projects / toolchains + // have removed `CMAKE_INSTALL_PREFIX` from the list, we don't remove + // some other entry by mistake + long install_prefix_count = -1; + std::string install_path_to_remove; + if (cmValue to_skip = this->Makefile->GetDefinition( + "_CMAKE_SYSTEM_PREFIX_PATH_INSTALL_PREFIX_COUNT")) { + cmStrToLong(to_skip, &install_prefix_count); + } + if (cmValue install_value = this->Makefile->GetDefinition( + "_CMAKE_SYSTEM_PREFIX_PATH_INSTALL_PREFIX_VALUE")) { + install_path_to_remove = *install_value; + } + + if (remove_install_prefix && install_prefix_in_list && + install_prefix_count > 0 && !install_path_to_remove.empty()) { + + cmValue prefix_paths = + this->Makefile->GetDefinition("CMAKE_SYSTEM_PREFIX_PATH"); + // remove entry from CMAKE_SYSTEM_PREFIX_PATH + std::vector<std::string> expanded = cmExpandedList(*prefix_paths); + long count = 0; + for (const auto& path : expanded) { + bool to_add = + !(path == install_path_to_remove && ++count == install_prefix_count); + if (to_add) { + paths.AddPath(path); + } + } + } else if (add_install_prefix && !install_prefix_in_list) { + paths.AddCMakePath("CMAKE_INSTALL_PREFIX"); + paths.AddCMakePath("CMAKE_SYSTEM_PREFIX_PATH"); + } else { + // Otherwise the current setup of `CMAKE_SYSTEM_PREFIX_PATH` is correct + paths.AddCMakePath("CMAKE_SYSTEM_PREFIX_PATH"); + } + paths.AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH"); paths.AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH"); diff --git a/Tests/RunCMake/find_file/FromPATHEnvDebugVar-stderr.txt b/Tests/RunCMake/find_file/FromPATHEnvDebugVar-stderr.txt index 38ed98c..edf2cab 100644 --- a/Tests/RunCMake/find_file/FromPATHEnvDebugVar-stderr.txt +++ b/Tests/RunCMake/find_file/FromPATHEnvDebugVar-stderr.txt @@ -8,6 +8,7 @@ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 0 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 1 find_file considered the following locations:.* The item was not found.* @@ -21,5 +22,6 @@ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 0 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 1 find_file considered the following locations:.* diff --git a/Tests/RunCMake/find_file/PrefixInPATH-stderr.txt b/Tests/RunCMake/find_file/PrefixInPATH-stderr.txt index 0d77571..93e6253 100644 --- a/Tests/RunCMake/find_file/PrefixInPATH-stderr.txt +++ b/Tests/RunCMake/find_file/PrefixInPATH-stderr.txt @@ -8,6 +8,7 @@ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 1 find_file considered the following locations:.* .*include/PrefixInPATH.* diff --git a/Tests/RunCMake/find_library/FromPATHEnv-stderr.txt b/Tests/RunCMake/find_library/FromPATHEnv-stderr.txt index a690eec..f367b3f 100644 --- a/Tests/RunCMake/find_library/FromPATHEnv-stderr.txt +++ b/Tests/RunCMake/find_library/FromPATHEnv-stderr.txt @@ -9,6 +9,7 @@ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 0 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 1 find_library considered the following locations:.* The item was not found.* @@ -22,6 +23,7 @@ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 1 find_library considered the following locations:.* The item was found at.* diff --git a/Tests/RunCMake/find_library/FromPATHEnvDebugVar-stderr.txt b/Tests/RunCMake/find_library/FromPATHEnvDebugVar-stderr.txt index a690eec..f367b3f 100644 --- a/Tests/RunCMake/find_library/FromPATHEnvDebugVar-stderr.txt +++ b/Tests/RunCMake/find_library/FromPATHEnvDebugVar-stderr.txt @@ -9,6 +9,7 @@ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 0 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 1 find_library considered the following locations:.* The item was not found.* @@ -22,6 +23,7 @@ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 1 find_library considered the following locations:.* The item was found at.* diff --git a/Tests/RunCMake/find_library/IgnoreInstallPrefix-stderr.txt b/Tests/RunCMake/find_library/IgnoreInstallPrefix-stderr.txt new file mode 100644 index 0000000..e977374 --- /dev/null +++ b/Tests/RunCMake/find_library/IgnoreInstallPrefix-stderr.txt @@ -0,0 +1,43 @@ + find_library called with the following settings:.* + VAR: CREATED_LIBRARY + NAMES: \"created\" + Documentation.* + Framework.* + AppBundle.* + CMAKE_FIND_USE_CMAKE_PATH: 1 + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 1 + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 0 + + find_library considered the following locations:.* + The item was not found.* + find_library called with the following settings:.* + VAR: CREATED_LIBRARY + NAMES: \"created\" + Documentation.* + Framework.* + AppBundle.* + CMAKE_FIND_USE_CMAKE_PATH: 1 + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 1 + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 1 + + find_library considered the following locations:.* + The item was found at.* + .*IgnoreInstallPrefix-build/lib.* + find_library called with the following settings:.* + VAR: CREATED_LIBRARY + NAMES: \"created\" + Documentation.* + Framework.* + AppBundle.* + CMAKE_FIND_USE_CMAKE_PATH: 1 + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 1 + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 0 + + find_library considered the following locations:.* + The item was not found.* diff --git a/Tests/RunCMake/find_library/IgnoreInstallPrefix-stdout.txt b/Tests/RunCMake/find_library/IgnoreInstallPrefix-stdout.txt new file mode 100644 index 0000000..0c28243 --- /dev/null +++ b/Tests/RunCMake/find_library/IgnoreInstallPrefix-stdout.txt @@ -0,0 +1,3 @@ +-- CREATED_LIBRARY='CREATED_LIBRARY-NOTFOUND' +-- CREATED_LIBRARY='[^']*/Tests/RunCMake/find_library/IgnoreInstallPrefix-build/lib/libcreated.a' +-- CREATED_LIBRARY='CREATED_LIBRARY-NOTFOUND' diff --git a/Tests/RunCMake/find_library/IgnoreInstallPrefix.cmake b/Tests/RunCMake/find_library/IgnoreInstallPrefix.cmake new file mode 100644 index 0000000..7ca8bcf --- /dev/null +++ b/Tests/RunCMake/find_library/IgnoreInstallPrefix.cmake @@ -0,0 +1,32 @@ +set(ENV_PATH "$ENV{PATH}") +set(ENV_CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH}") +set(ENV{PATH} "") +set(ENV{CMAKE_PREFIX_PATH} "") + +list(APPEND CMAKE_FIND_LIBRARY_PREFIXES lib) +list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .a) + +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib) +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib/libcreated.a" "created") + +set(CMAKE_FIND_DEBUG_MODE 1) +set(CMAKE_FIND_USE_INSTALL_PREFIX OFF) + +find_library(CREATED_LIBRARY NAMES created) +message(STATUS "CREATED_LIBRARY='${CREATED_LIBRARY}'") + +set(CMAKE_FIND_USE_INSTALL_PREFIX ON) +find_library(CREATED_LIBRARY NAMES created) +message(STATUS "CREATED_LIBRARY='${CREATED_LIBRARY}'") + +unset(CREATED_LIBRARY) +unset(CREATED_LIBRARY CACHE) + +unset(CMAKE_FIND_USE_INSTALL_PREFIX) +find_library(CREATED_LIBRARY NAMES created NO_CMAKE_INSTALL_PREFIX) +message(STATUS "CREATED_LIBRARY='${CREATED_LIBRARY}'") + +set(CMAKE_FIND_DEBUG_MODE 0) + +set(ENV{PATH} "${ENV_PATH}") +set(ENV{CMAKE_PREFIX_PATH} "${ENV_CMAKE_PREFIX_PATH}") diff --git a/Tests/RunCMake/find_library/PrefixInPATH-stderr.txt b/Tests/RunCMake/find_library/PrefixInPATH-stderr.txt index 1d24c84..899b471 100644 --- a/Tests/RunCMake/find_library/PrefixInPATH-stderr.txt +++ b/Tests/RunCMake/find_library/PrefixInPATH-stderr.txt @@ -8,6 +8,7 @@ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 1 find_library considered the following locations:.* .*/does_not_exist.* diff --git a/Tests/RunCMake/find_library/RunCMakeTest.cmake b/Tests/RunCMake/find_library/RunCMakeTest.cmake index eaaecf0..ef1ede6 100644 --- a/Tests/RunCMake/find_library/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_library/RunCMakeTest.cmake @@ -3,6 +3,7 @@ include(RunCMake) run_cmake(Created) run_cmake(FromPrefixPath) run_cmake(FromPATHEnv) +run_cmake_with_options(IgnoreInstallPrefix "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/IgnoreInstallPrefix-build/") if(UNIX AND NOT CYGWIN) run_cmake(LibArchLink) run_cmake(LibSymLink) diff --git a/Tests/RunCMake/find_package/IgnoreInstallPrefix.cmake b/Tests/RunCMake/find_package/IgnoreInstallPrefix.cmake new file mode 100644 index 0000000..ee40d88 --- /dev/null +++ b/Tests/RunCMake/find_package/IgnoreInstallPrefix.cmake @@ -0,0 +1,17 @@ + +find_package(Bar QUIET CONFIG NO_CMAKE_INSTALL_PREFIX) +if(Bar_FOUND) + message(SEND_ERROR "Bar should not be found, was found in ${Bar_DIR}") +endif() + +set(CMAKE_FIND_USE_INSTALL_PREFIX OFF) +find_package(Bar QUIET CONFIG) +if(Bar_FOUND) + message(SEND_ERROR "Bar should not be found, was found in ${Bar_DIR}") +endif() + +set(CMAKE_FIND_USE_INSTALL_PREFIX ON) +find_package(Bar QUIET CONFIG) +if(NOT Bar_FOUND) + message(SEND_ERROR "Bar should be found via CMAKE_INSTALL_PREFIX") +endif() diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake index 2b5fb1f..b2d1bf6 100644 --- a/Tests/RunCMake/find_package/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake @@ -48,6 +48,7 @@ run_cmake(VersionRangeConfig2) run_cmake(VersionRangeConfig02) run_cmake(VersionRangeConfigStd) run_cmake(VersionRangeConfigStd2) +run_cmake_with_options(IgnoreInstallPrefix "-DCMAKE_INSTALL_PREFIX=${RunCMake_SOURCE_DIR}/PackageRoot/foo/cmake_root") run_cmake(IgnorePath) run_cmake(IgnorePrefixPath) if(UNIX diff --git a/Tests/RunCMake/find_path/FromPATHEnv-stderr.txt b/Tests/RunCMake/find_path/FromPATHEnv-stderr.txt index 088efd5..9340c7a 100644 --- a/Tests/RunCMake/find_path/FromPATHEnv-stderr.txt +++ b/Tests/RunCMake/find_path/FromPATHEnv-stderr.txt @@ -8,6 +8,7 @@ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 0 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 1 find_path considered the following locations:.* The item was not found.* @@ -21,6 +22,7 @@ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 1 find_path considered the following locations:.* The item was found at.* diff --git a/Tests/RunCMake/find_path/FromPATHEnvDebugVar-stderr.txt b/Tests/RunCMake/find_path/FromPATHEnvDebugVar-stderr.txt index 088efd5..9340c7a 100644 --- a/Tests/RunCMake/find_path/FromPATHEnvDebugVar-stderr.txt +++ b/Tests/RunCMake/find_path/FromPATHEnvDebugVar-stderr.txt @@ -8,6 +8,7 @@ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 0 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 1 find_path considered the following locations:.* The item was not found.* @@ -21,6 +22,7 @@ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 1 find_path considered the following locations:.* The item was found at.* diff --git a/Tests/RunCMake/find_program/EnvAndHints-stderr.txt b/Tests/RunCMake/find_program/EnvAndHints-stderr.txt index 8951345..83263e4 100644 --- a/Tests/RunCMake/find_program/EnvAndHints-stderr.txt +++ b/Tests/RunCMake/find_program/EnvAndHints-stderr.txt @@ -8,6 +8,7 @@ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 1 find_program considered the following locations:.* The item was found at.* @@ -23,6 +24,7 @@ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 0 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 1 find_program considered the following locations:.* The item was not found.* diff --git a/Tests/RunCMake/find_program/EnvAndHintsDebugVar-stderr.txt b/Tests/RunCMake/find_program/EnvAndHintsDebugVar-stderr.txt index 8951345..83263e4 100644 --- a/Tests/RunCMake/find_program/EnvAndHintsDebugVar-stderr.txt +++ b/Tests/RunCMake/find_program/EnvAndHintsDebugVar-stderr.txt @@ -8,6 +8,7 @@ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 1 find_program considered the following locations:.* The item was found at.* @@ -23,6 +24,7 @@ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 0 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1 + CMAKE_FIND_USE_INSTALL_PREFIX: 1 find_program considered the following locations:.* The item was not found.* diff --git a/Tests/RunCMake/no_install_prefix/RunCMakeTest.cmake b/Tests/RunCMake/no_install_prefix/RunCMakeTest.cmake index 2923449..eb0ff23 100644 --- a/Tests/RunCMake/no_install_prefix/RunCMakeTest.cmake +++ b/Tests/RunCMake/no_install_prefix/RunCMakeTest.cmake @@ -11,5 +11,5 @@ run_cmake(with_install_prefix) file(REMOVE_RECURSE "${RunCMake_BINARY_DIR}/prefix") file(MAKE_DIRECTORY "${RunCMake_BINARY_DIR}/prefix/NoPrefix") file(WRITE "${RunCMake_BINARY_DIR}/prefix/NoPrefix/NoPrefixConfig.cmake" "") -list(APPEND RunCMake_TEST_OPTIONS "-DCMAKE_FIND_NO_INSTALL_PREFIX=1") +list(APPEND RunCMake_TEST_OPTIONS "-DCMAKE_FIND_NO_INSTALL_PREFIX=1" "-DCMAKE_INSTALL_PREFIX:PATH=${RunCMake_BINARY_DIR}/prefix") run_cmake(no_install_prefix) diff --git a/Tests/RunCMake/no_install_prefix/do_test.cmake b/Tests/RunCMake/no_install_prefix/do_test.cmake index 340c7dc..ce94b50 100644 --- a/Tests/RunCMake/no_install_prefix/do_test.cmake +++ b/Tests/RunCMake/no_install_prefix/do_test.cmake @@ -1,2 +1,16 @@ +find_package(NoPrefix NO_CMAKE_INSTALL_PREFIX) +if(NoPrefix_FOUND) + message(FATAL_ERROR "Should not find package when NO_CMAKE_INSTALL_PREFIX specified") +endif() + +set(CMAKE_FIND_USE_INSTALL_PREFIX ON) +find_package(NoPrefix) +if(NOT NoPrefix_FOUND) + message(FATAL_ERROR "Should always find package when CMAKE_FIND_USE_INSTALL_PREFIX is enabled") +endif() + +unset(CMAKE_FIND_USE_INSTALL_PREFIX) +unset(NoPrefix_DIR CACHE) + find_package(NoPrefix REQUIRED) diff --git a/Tests/RunCMake/no_install_prefix/no_install_prefix-stderr.txt b/Tests/RunCMake/no_install_prefix/no_install_prefix-stderr.txt index 66c6241..52bd094 100644 --- a/Tests/RunCMake/no_install_prefix/no_install_prefix-stderr.txt +++ b/Tests/RunCMake/no_install_prefix/no_install_prefix-stderr.txt @@ -1,4 +1,4 @@ -CMake Error at do_test.cmake:2 \(find_package\): +CMake Error at do_test.cmake:16 \(find_package\): By not providing "FindNoPrefix.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "NoPrefix", but CMake did not find one. |