summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/command/find_package.rst7
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/release/dev/find-package-prefer-config.rst6
-rw-r--r--Help/variable/CMAKE_FIND_PACKAGE_PREFER_CONFIG.rst27
-rw-r--r--Help/variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE.rst3
-rw-r--r--Source/cmFindPackageCommand.cxx95
-rw-r--r--Tests/FindPackageTest/CMakeLists.txt36
-rw-r--r--Tests/FindPackageTest/PreferConfig/ABCConfig.cmake1
-rw-r--r--Tests/FindPackageTest/PreferConfig/FindABC.cmake1
9 files changed, 134 insertions, 43 deletions
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index eb44eb2..e5e5b2c 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -59,6 +59,13 @@ for finding the package, checking the version, and producing any needed
messages. Some find-modules provide limited or no support for versioning;
check the module documentation.
+If the ``MODULE`` option is not specfied in the above signature,
+CMake first searches for the package using Module mode. Then, if the
+package is not found, it searches again using Config mode. A user
+may set the variable :variable:`CMAKE_FIND_PACKAGE_PREFER_CONFIG` to
+``TRUE`` to direct CMake first search using Config mode before falling
+back to Module mode.
+
Full Signature and Config Mode
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index fd5e28f..1011ed2 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -172,6 +172,7 @@ Variables that Change Behavior
/variable/CMAKE_FIND_NO_INSTALL_PREFIX
/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY
/variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY
+ /variable/CMAKE_FIND_PACKAGE_PREFER_CONFIG
/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS
/variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE
/variable/CMAKE_FIND_ROOT_PATH
diff --git a/Help/release/dev/find-package-prefer-config.rst b/Help/release/dev/find-package-prefer-config.rst
new file mode 100644
index 0000000..377e8c5
--- /dev/null
+++ b/Help/release/dev/find-package-prefer-config.rst
@@ -0,0 +1,6 @@
+find-package-prefer-config
+--------------------------
+
+* Variable :variable:`CMAKE_FIND_PACKAGE_PREFER_CONFIG` was added to tell
+ :command:`find_package` calls to look for a package configuration
+ file first even if a find module is available.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_PREFER_CONFIG.rst b/Help/variable/CMAKE_FIND_PACKAGE_PREFER_CONFIG.rst
new file mode 100644
index 0000000..db658a1
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_PACKAGE_PREFER_CONFIG.rst
@@ -0,0 +1,27 @@
+CMAKE_FIND_PACKAGE_PREFER_CONFIG
+---------------------------------
+
+Tell :command:`find_package` to try "Config" mode before "Module" mode if no
+mode was specified.
+
+The command :command:`find_package` operates without an explicit mode when
+the reduced signature is used without the ``MODULE`` option. In this case,
+by default, CMake first tries Module mode by searching for a
+``Find<pkg>.cmake`` module. If it fails, CMake then searches for the package
+using Config mode.
+
+Set ``CMAKE_FIND_PACKAGE_PREFER_CONFIG`` to ``TRUE`` to tell
+:command:`find_package` to first search using Config mode before falling back
+to Module mode.
+
+This variable may be useful when a developer has compiled a custom version of
+a common library and wishes to link it to a dependent project. If this
+variable is set to ``TRUE``, it would prevent a dependent project's call
+to :command:`find_package` from selecting the default library located by the
+system's ``Find<pkg>.cmake`` module before finding the developer's custom
+built library.
+
+Once this variable is set, it is the responsibility of the exported
+``<pkg>Config.cmake`` files to provide the same result variables as the
+``Find<pkg>.cmake`` modules so that dependent projects can use them
+interchangeably.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE.rst b/Help/variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE.rst
index f1116bb..5c4f23a 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE.rst
@@ -17,3 +17,6 @@ Set ``CMAKE_FIND_PACKAGE_WARN_NO_MODULE`` to ``TRUE`` to tell
:command:`find_package` to warn when it implicitly assumes Config mode. This
helps developers enforce use of an explicit mode in all calls to
:command:`find_package` within a project.
+
+This variable has no effect if :variable:`CMAKE_FIND_PACKAGE_PREFER_CONFIG` is
+set to ``TRUE``.
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 5310a1b..8eefaa7 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -499,50 +499,61 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
// See if there is a Find<PackageName>.cmake module.
bool loadedPackage = false;
- if (this->UseFindModules && this->FindPackageUsingModuleMode()) {
- loadedPackage = true;
- } else {
- // Handle CMAKE_FIND_PACKAGE_WARN_NO_MODULE (warn when CONFIG mode is
- // implicitly assumed)
- if (this->UseFindModules && this->UseConfigFiles &&
- this->Makefile->IsOn("CMAKE_FIND_PACKAGE_WARN_NO_MODULE")) {
- std::ostringstream aw;
- if (this->RequiredCMakeVersion >= CMake_VERSION_ENCODE(2, 8, 8)) {
- aw << "find_package called without either MODULE or CONFIG option and "
- "no Find"
- << this->Name
- << ".cmake module is in CMAKE_MODULE_PATH. "
- "Add MODULE to exclusively request Module mode and fail if "
- "Find"
- << this->Name
- << ".cmake is missing. "
- "Add CONFIG to exclusively request Config mode and search for a "
- "package configuration file provided by "
- << this->Name << " (" << this->Name << "Config.cmake or "
- << cmSystemTools::LowerCase(this->Name) << "-config.cmake). ";
- } else {
- aw << "find_package called without NO_MODULE option and no "
- "Find"
- << this->Name
- << ".cmake module is in CMAKE_MODULE_PATH. "
- "Add NO_MODULE to exclusively request Config mode and search "
- "for a "
- "package configuration file provided by "
- << this->Name << " (" << this->Name << "Config.cmake or "
- << cmSystemTools::LowerCase(this->Name)
- << "-config.cmake). "
- "Otherwise make Find"
- << this->Name
- << ".cmake available in "
- "CMAKE_MODULE_PATH.";
- }
- aw << "\n"
- "(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled this "
- "warning.)";
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, aw.str());
+ if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_PREFER_CONFIG")) {
+ if (this->UseConfigFiles && this->FindPackageUsingConfigMode()) {
+ loadedPackage = true;
+ } else if (this->FindPackageUsingModuleMode()) {
+ loadedPackage = true;
}
- if (this->FindPackageUsingConfigMode()) {
+ } else {
+ if (this->UseFindModules && this->FindPackageUsingModuleMode()) {
loadedPackage = true;
+ } else {
+ // Handle CMAKE_FIND_PACKAGE_WARN_NO_MODULE (warn when CONFIG mode is
+ // implicitly assumed)
+ if (this->UseFindModules && this->UseConfigFiles &&
+ this->Makefile->IsOn("CMAKE_FIND_PACKAGE_WARN_NO_MODULE")) {
+ std::ostringstream aw;
+ if (this->RequiredCMakeVersion >= CMake_VERSION_ENCODE(2, 8, 8)) {
+ aw << "find_package called without either MODULE or CONFIG option "
+ "and "
+ "no Find"
+ << this->Name
+ << ".cmake module is in CMAKE_MODULE_PATH. "
+ "Add MODULE to exclusively request Module mode and fail if "
+ "Find"
+ << this->Name
+ << ".cmake is missing. "
+ "Add CONFIG to exclusively request Config mode and search for "
+ "a "
+ "package configuration file provided by "
+ << this->Name << " (" << this->Name << "Config.cmake or "
+ << cmSystemTools::LowerCase(this->Name) << "-config.cmake). ";
+ } else {
+ aw << "find_package called without NO_MODULE option and no "
+ "Find"
+ << this->Name
+ << ".cmake module is in CMAKE_MODULE_PATH. "
+ "Add NO_MODULE to exclusively request Config mode and search "
+ "for a "
+ "package configuration file provided by "
+ << this->Name << " (" << this->Name << "Config.cmake or "
+ << cmSystemTools::LowerCase(this->Name)
+ << "-config.cmake). "
+ "Otherwise make Find"
+ << this->Name
+ << ".cmake available in "
+ "CMAKE_MODULE_PATH.";
+ }
+ aw << "\n"
+ "(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled this "
+ "warning.)";
+ this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, aw.str());
+ }
+
+ if (this->FindPackageUsingConfigMode()) {
+ loadedPackage = true;
+ }
}
}
diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt
index 6c876a7..8802b73 100644
--- a/Tests/FindPackageTest/CMakeLists.txt
+++ b/Tests/FindPackageTest/CMakeLists.txt
@@ -541,7 +541,41 @@ endif()
set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
unset(SortLib_VERSION)
-
unset(CMAKE_FIND_PACKAGE_SORT_ORDER)
unset(CMAKE_FIND_PACKAGE_SORT_DIRECTION)
set(CMAKE_PREFIX_PATH )
+
+############################################################################
+##Test FIND_PACKAGE CMAKE_FIND_PACKAGE_PREFER_CONFIG
+
+set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR}/PreferConfig)
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/PreferConfig)
+
+# prefer module mode
+set(CMAKE_FIND_PACKAGE_PREFER_CONFIG OFF)
+unset(ABC_FOUND)
+unset(ABC_CONFIG)
+
+find_package(ABC)
+if(NOT ABC_FOUND)
+ message(SEND_ERROR "Did not find ABC package")
+endif()
+if(ABC_CONFIG)
+ message(SEND_ERROR "Incorrectly found ABC in CONFIG mode, expected to find it with MODULE mode")
+endif()
+
+# Now prefer config mode
+set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
+unset(ABC_FOUND)
+unset(ABC_CONFIG)
+
+find_package(ABC)
+if(NOT ABC_FOUND)
+ message(SEND_ERROR "Did not find ABC package")
+endif()
+if(NOT ABC_CONFIG)
+ message(SEND_ERROR "Incorrectly found ABC in MODULE mode, expected to find it with CONFIG mode")
+endif()
+
+set(CMAKE_FIND_PACKAGE_PREFER_CONFIG OFF)
+set(CMAKE_PREFIX_PATH)
diff --git a/Tests/FindPackageTest/PreferConfig/ABCConfig.cmake b/Tests/FindPackageTest/PreferConfig/ABCConfig.cmake
new file mode 100644
index 0000000..281a5cd
--- /dev/null
+++ b/Tests/FindPackageTest/PreferConfig/ABCConfig.cmake
@@ -0,0 +1 @@
+set(ABC_FOUND TRUE)
diff --git a/Tests/FindPackageTest/PreferConfig/FindABC.cmake b/Tests/FindPackageTest/PreferConfig/FindABC.cmake
new file mode 100644
index 0000000..281a5cd
--- /dev/null
+++ b/Tests/FindPackageTest/PreferConfig/FindABC.cmake
@@ -0,0 +1 @@
+set(ABC_FOUND TRUE)