find_package: Add variable to make package REQUIRED
Add a `CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>` variable is complement to `CMAKE_DISABLE_FIND_PACKAGE_<PackageName>` with just the opposite behaviour: it turns non-required find_package call into the required one. While optional package dependencies usually result in simple and clean build logic, sometimes people want to be sure those optional dependencies will be found and used. Examples are reproducible builds and build instructions for 3rd parties. People choose to make find_package calls REQUIRED and put them behind an option(). Such workarounds blend build logic with build environment management and do not look elegant.
This commit is contained in:
parent
d49b507bb6
commit
a2e9fe38e4
@ -2807,6 +2807,7 @@ syn keyword cmakeKWfind_package contained
|
||||
\ ABI
|
||||
\ BUNDLE
|
||||
\ CMAKE_DISABLE_FIND_PACKAGE_
|
||||
\ CMAKE_REQUIRE_FIND_PACKAGE_
|
||||
\ CMAKE_FIND_ROOT_PATH_BOTH
|
||||
\ COMPONENTS
|
||||
\ CONFIG
|
||||
|
@ -448,8 +448,15 @@ which the file is found. The :variable:`CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS`
|
||||
variable may be set to ``TRUE`` before calling ``find_package`` in order
|
||||
to resolve symbolic links and store the real path to the file.
|
||||
|
||||
Every non-REQUIRED ``find_package`` call can be disabled by setting the
|
||||
:variable:`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>` variable to ``TRUE``.
|
||||
Every non-REQUIRED ``find_package`` call can be disabled or made REQUIRED:
|
||||
|
||||
* Setting the :variable:`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>` variable
|
||||
to ``TRUE`` disables the package.
|
||||
|
||||
* Setting the :variable:`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>` variable
|
||||
to ``TRUE`` makes the package REQUIRED.
|
||||
|
||||
Setting both variables to ``TRUE`` simultaneously is an error.
|
||||
|
||||
Package File Interface Variables
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -74,7 +74,9 @@ package.
|
||||
|
||||
By setting the :variable:`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>` variable to
|
||||
``TRUE``, the ``<PackageName>`` package will not be searched, and will always
|
||||
be ``NOTFOUND``.
|
||||
be ``NOTFOUND``. Likewise, setting the
|
||||
:variable:`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>` to ``TRUE`` will make the
|
||||
package REQUIRED.
|
||||
|
||||
.. _`Config File Packages`:
|
||||
|
||||
|
@ -230,6 +230,7 @@ Variables that Change Behavior
|
||||
/variable/CMAKE_PROJECT_INCLUDE_BEFORE
|
||||
/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE
|
||||
/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE
|
||||
/variable/CMAKE_REQUIRE_FIND_PACKAGE_PackageName
|
||||
/variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY
|
||||
/variable/CMAKE_STAGING_PREFIX
|
||||
/variable/CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS
|
||||
|
5
Help/release/dev/find_package-required-var.rst
Normal file
5
Help/release/dev/find_package-required-var.rst
Normal file
@ -0,0 +1,5 @@
|
||||
find_package-required-var
|
||||
-------------------------
|
||||
|
||||
* The :variable:`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>` variable was added
|
||||
to turn a non-REQUIRED :command:`find_package` call into a REQUIRED one.
|
@ -14,3 +14,5 @@ the package has already been found in a previous CMake run, the
|
||||
variables which have been stored in the cache will still be there. In
|
||||
that case it is recommended to remove the cache variables for this
|
||||
package from the cache using the cache editor or :manual:`cmake(1)` ``-U``
|
||||
|
||||
See also the :variable:`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>` variable.
|
||||
|
14
Help/variable/CMAKE_REQUIRE_FIND_PACKAGE_PackageName.rst
Normal file
14
Help/variable/CMAKE_REQUIRE_FIND_PACKAGE_PackageName.rst
Normal file
@ -0,0 +1,14 @@
|
||||
CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>
|
||||
----------------------------------------
|
||||
|
||||
.. versionadded:: 3.22
|
||||
|
||||
Variable for making :command:`find_package` call ``REQUIRED``.
|
||||
|
||||
Every non-``REQUIRED`` :command:`find_package` call in a project can be
|
||||
turned into ``REQUIRED`` by setting the variable
|
||||
``CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>`` to ``TRUE``.
|
||||
This can be used to assert assumptions about build environment and to
|
||||
ensure the build will fail early if they do not hold.
|
||||
|
||||
See also the :variable:`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>` variable.
|
@ -478,17 +478,35 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
|
||||
this->VersionMaxPatch, this->VersionMaxTweak);
|
||||
}
|
||||
|
||||
const std::string makePackageRequiredVar =
|
||||
cmStrCat("CMAKE_REQUIRE_FIND_PACKAGE_", this->Name);
|
||||
const bool makePackageRequiredSet =
|
||||
this->Makefile->IsOn(makePackageRequiredVar);
|
||||
if (makePackageRequiredSet) {
|
||||
if (this->Required) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::WARNING,
|
||||
cmStrCat("for module ", this->Name,
|
||||
" already called with REQUIRED, thus ",
|
||||
makePackageRequiredVar, " has no effect."));
|
||||
} else {
|
||||
this->Required = true;
|
||||
}
|
||||
}
|
||||
|
||||
std::string disableFindPackageVar =
|
||||
cmStrCat("CMAKE_DISABLE_FIND_PACKAGE_", this->Name);
|
||||
if (this->Makefile->IsOn(disableFindPackageVar)) {
|
||||
if (this->Required) {
|
||||
this->SetError(
|
||||
cmStrCat("for module ", this->Name, " called with REQUIRED, but ",
|
||||
disableFindPackageVar,
|
||||
cmStrCat("for module ", this->Name,
|
||||
(makePackageRequiredSet
|
||||
? " was made REQUIRED with " + makePackageRequiredVar
|
||||
: " called with REQUIRED, "),
|
||||
" but ", disableFindPackageVar,
|
||||
" is enabled. A REQUIRED package cannot be disabled."));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1,20 @@
|
||||
CMake Error at MissingNormalForceRequired.cmake:2 \(find_package\):
|
||||
No "FindNotHere.cmake" found in CMAKE_MODULE_PATH\.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Warning \(dev\) at MissingNormalForceRequired.cmake:2 \(find_package\):
|
||||
FindNotHere.cmake must either be part of this project itself, in this case
|
||||
adjust CMAKE_MODULE_PATH so that it points to the correct location inside
|
||||
its source tree\.
|
||||
|
||||
Or it must be installed by a package which has already been found via
|
||||
find_package\(\)\. In this case make sure that package has indeed been found
|
||||
and adjust CMAKE_MODULE_PATH to contain the location where that package has
|
||||
installed FindNotHere\.cmake\. This must be a location provided by that
|
||||
package. This error in general means that the buildsystem of this project
|
||||
is relying on a Find-module without ensuring that it is actually available\.
|
||||
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:3 \(include\)
|
||||
This warning is for project developers. Use -Wno-dev to suppress it\.
|
@ -0,0 +1,3 @@
|
||||
set(CMAKE_REQUIRE_FIND_PACKAGE_NotHere ON)
|
||||
find_package(NotHere MODULE)
|
||||
message(FATAL_ERROR "This error must not be reachable.")
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1,11 @@
|
||||
CMake Error at RequiredOptionValuesClash.cmake:4 \(find_package\):
|
||||
find_package for module Foo was made REQUIRED with
|
||||
CMAKE_REQUIRE_FIND_PACKAGE_Foo but CMAKE_DISABLE_FIND_PACKAGE_Foo is
|
||||
enabled. A REQUIRED package cannot be disabled.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Error at RequiredOptionValuesClash.cmake:5 \(message\):
|
||||
This error must not be reachable\.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
@ -0,0 +1,5 @@
|
||||
set(CMAKE_DISABLE_FIND_PACKAGE_Foo ON)
|
||||
set(CMAKE_REQUIRE_FIND_PACKAGE_Foo ON)
|
||||
|
||||
find_package(Foo)
|
||||
message(FATAL_ERROR "This error must not be reachable.")
|
@ -6,6 +6,7 @@ run_cmake(ComponentRequiredAndOptional)
|
||||
run_cmake(FromPATHEnv)
|
||||
run_cmake(FromPrefixPath)
|
||||
run_cmake(MissingNormal)
|
||||
run_cmake(MissingNormalForceRequired)
|
||||
run_cmake(MissingNormalRequired)
|
||||
run_cmake(MissingNormalVersion)
|
||||
run_cmake(MissingNormalWarnNoModuleOld)
|
||||
@ -23,6 +24,7 @@ run_cmake(PackageRootNestedConfig)
|
||||
run_cmake(PackageRootNestedModule)
|
||||
run_cmake(PolicyPush)
|
||||
run_cmake(PolicyPop)
|
||||
run_cmake(RequiredOptionValuesClash)
|
||||
run_cmake(SetFoundFALSE)
|
||||
run_cmake(WrongVersion)
|
||||
run_cmake(WrongVersionConfig)
|
||||
|
Loading…
Reference in New Issue
Block a user