1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-17 15:32:10 +08:00

find_*: Add variable to default calls to REQUIRED

This adds a `CMAKE_FIND_REQUIRED` variable which causes `find_package`,
`find_path`, `find_file`, `find_library` and `find_program` to be
considered `REQUIRED` by default.

It also introduces an `OPTIONAL` keyword to those commands, allowing
them to ignore the value of this variable.

Issue: #26576
This commit is contained in:
Martin Duffy
2025-02-20 15:24:04 -05:00
committed by Brad King
parent d3484a31c6
commit 857a039d66
38 changed files with 337 additions and 22 deletions

View File

@@ -18,7 +18,7 @@ The general signature is:
[VALIDATOR function] [VALIDATOR function]
[DOC "cache documentation string"] [DOC "cache documentation string"]
[NO_CACHE] [NO_CACHE]
[REQUIRED] [REQUIRED|OPTIONAL]
[NO_DEFAULT_PATH] [NO_DEFAULT_PATH]
[NO_PACKAGE_ROOT_PATH] [NO_PACKAGE_ROOT_PATH]
[NO_CMAKE_PATH] [NO_CMAKE_PATH]
@@ -118,6 +118,18 @@ Options include:
the search will be attempted again the next time |FIND_XXX| is invoked the search will be attempted again the next time |FIND_XXX| is invoked
with the same variable. with the same variable.
.. versionadded:: 4.1
Every |FIND_XXX| command will be treated as ``REQUIRED`` when the
:variable:`CMAKE_FIND_REQUIRED` variable is enabled.
``OPTIONAL``
.. versionadded:: 4.1
Ignore the value of :variable:`CMAKE_FIND_REQUIRED` and
continue without an error message if nothing is found.
Incompatible with ``REQUIRED``.
If ``NO_DEFAULT_PATH`` is specified, then no additional paths are If ``NO_DEFAULT_PATH`` is specified, then no additional paths are
added to the search. added to the search.
If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows: If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:

View File

@@ -132,7 +132,7 @@ Basic Signature
.. code-block:: cmake .. code-block:: cmake
find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE] find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
[REQUIRED] [[COMPONENTS] [components...]] [REQUIRED|OPTIONAL] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...] [OPTIONAL_COMPONENTS components...]
[REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)] [REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]
[GLOBAL] [GLOBAL]
@@ -159,6 +159,13 @@ otherwise execution still continues. As a form of shorthand, if the
``REQUIRED`` option is present, the ``COMPONENTS`` keyword can be omitted ``REQUIRED`` option is present, the ``COMPONENTS`` keyword can be omitted
and the required components can be listed directly after ``REQUIRED``. and the required components can be listed directly after ``REQUIRED``.
The :variable:`CMAKE_FIND_REQUIRED` variable can be enabled to make this call
``REQUIRED`` by default. This behavior can be overridden by providing the
``OPTIONAL`` keyword. As with the ``REQUIRED`` option, a list of components
can be listed directly after ``OPTIONAL``, which is equivalent to listing
them after the ``COMPONENTS`` keyword. When the ``OPTIONAL`` keyword is given,
the warning output when a package is not found is suppressed.
Additional optional components may be listed after Additional optional components may be listed after
``OPTIONAL_COMPONENTS``. If these cannot be satisfied, the package overall ``OPTIONAL_COMPONENTS``. If these cannot be satisfied, the package overall
can still be considered found, as long as all required components are can still be considered found, as long as all required components are
@@ -249,7 +256,7 @@ Full Signature
.. code-block:: cmake .. code-block:: cmake
find_package(<PackageName> [version] [EXACT] [QUIET] find_package(<PackageName> [version] [EXACT] [QUIET]
[REQUIRED] [[COMPONENTS] [components...]] [REQUIRED|OPTIONAL] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...] [OPTIONAL_COMPONENTS components...]
[CONFIG|NO_MODULE] [CONFIG|NO_MODULE]
[GLOBAL] [GLOBAL]
@@ -635,6 +642,9 @@ Every non-REQUIRED ``find_package`` call can be disabled or made REQUIRED:
Setting both variables to ``TRUE`` simultaneously is an error. Setting both variables to ``TRUE`` simultaneously is an error.
The :variable:`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>` variable takes priority
over the ``OPTIONAL`` keyword in determining whether a package is required.
.. _`version selection`: .. _`version selection`:
Config Mode Version Selection Config Mode Version Selection

View File

@@ -61,6 +61,7 @@ Variables that Provide Information
/variable/CMAKE_FIND_PACKAGE_REDIRECTS_DIR /variable/CMAKE_FIND_PACKAGE_REDIRECTS_DIR
/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION /variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION
/variable/CMAKE_FIND_PACKAGE_SORT_ORDER /variable/CMAKE_FIND_PACKAGE_SORT_ORDER
/variable/CMAKE_FIND_REQUIRED
/variable/CMAKE_GENERATOR /variable/CMAKE_GENERATOR
/variable/CMAKE_GENERATOR_INSTANCE /variable/CMAKE_GENERATOR_INSTANCE
/variable/CMAKE_GENERATOR_PLATFORM /variable/CMAKE_GENERATOR_PLATFORM

View File

@@ -0,0 +1,8 @@
cmake-find-required
-------------------
* The :variable:`CMAKE_FIND_REQUIRED` variable was added to tell
:command:`find_package`, :command:`find_path`, :command:`find_file`,
:command:`find_library`, and :command:`find_program` to be ``REQUIRED``
by default. The commands also gained an ``OPTIONAL`` keyword to ignore
the variable for a specific call.

View File

@@ -0,0 +1,27 @@
CMAKE_FIND_REQUIRED
-------------------
.. versionadded:: 4.1
If enabled, the following commands are treated as having the ``REQUIRED``
keyword unless provided with the ``OPTIONAL`` keyword:
* :command:`find_package`
* :command:`find_program`
* :command:`find_library`
* :command:`find_path`
* :command:`find_file`
When :command:`find_package` loads a ``Find<PackageName>.cmake``
or ``<PackageName>Config.cmake`` module, the ``CMAKE_FIND_REQUIRED``
variable is automatically unset within it to restore the default
behavior for nested find operations. The module is free to set the
``CMAKE_FIND_REQUIRED`` variable itself to opt-in to the behavior.
Note that enabling this variable breaks some commonly used patterns.
Multiple calls to :command:`find_package` are sometimes used to obtain a
different search order to the default.
See also the :variable:`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>` for making
a :command:`find_package` call ``REQUIRED``, and for additional information on
how enabling these variables can break commonly used patterns.

View File

@@ -94,6 +94,7 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
this->SelectDefaultMacMode(); this->SelectDefaultMacMode();
bool newStyle = false; bool newStyle = false;
bool haveRequiredOrOptional = false;
enum Doing enum Doing
{ {
DoingNone, DoingNone,
@@ -129,8 +130,21 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
this->NoDefaultPath = true; this->NoDefaultPath = true;
} else if (args[j] == "REQUIRED") { } else if (args[j] == "REQUIRED") {
doing = DoingNone; doing = DoingNone;
if (haveRequiredOrOptional && !this->Required) {
this->SetError("cannot be both REQUIRED and OPTIONAL");
return false;
}
this->Required = true; this->Required = true;
newStyle = true; newStyle = true;
haveRequiredOrOptional = true;
} else if (args[j] == "OPTIONAL") {
doing = DoingNone;
if (haveRequiredOrOptional && this->Required) {
this->SetError("cannot be both REQUIRED and OPTIONAL");
return false;
}
newStyle = true;
haveRequiredOrOptional = true;
} else if (args[j] == "REGISTRY_VIEW") { } else if (args[j] == "REGISTRY_VIEW") {
if (++j == args.size()) { if (++j == args.size()) {
this->SetError("missing required argument for REGISTRY_VIEW"); this->SetError("missing required argument for REGISTRY_VIEW");
@@ -187,6 +201,10 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
} }
} }
if (!haveRequiredOrOptional) {
this->Required = this->Makefile->IsOn("CMAKE_FIND_REQUIRED");
}
if (this->VariableDocumentation.empty()) { if (this->VariableDocumentation.empty()) {
this->VariableDocumentation = "Where can "; this->VariableDocumentation = "Where can ";
if (this->Names.empty()) { if (this->Names.empty()) {

View File

@@ -747,7 +747,18 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
configArgs.push_back(i); configArgs.push_back(i);
doing = DoingNone; doing = DoingNone;
} else if (args[i] == "REQUIRED") { } else if (args[i] == "REQUIRED") {
this->Required = true; if (this->Required == RequiredStatus::OptionalExplicit) {
this->SetError("cannot be both REQUIRED and OPTIONAL");
return false;
}
this->Required = RequiredStatus::RequiredExplicit;
doing = DoingComponents;
} else if (args[i] == "OPTIONAL") {
if (this->Required == RequiredStatus::RequiredExplicit) {
this->SetError("cannot be both REQUIRED and OPTIONAL");
return false;
}
this->Required = RequiredStatus::OptionalExplicit;
doing = DoingComponents; doing = DoingComponents;
} else if (args[i] == "COMPONENTS") { } else if (args[i] == "COMPONENTS") {
doing = DoingComponents; doing = DoingComponents;
@@ -844,6 +855,11 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
} }
} }
if (this->Required == RequiredStatus::Optional &&
this->Makefile->IsOn("CMAKE_FIND_REQUIRED")) {
this->Required = RequiredStatus::RequiredFromFindVar;
}
if (!this->GlobalScope) { if (!this->GlobalScope) {
cmValue value( cmValue value(
this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_TARGETS_GLOBAL")); this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_TARGETS_GLOBAL"));
@@ -978,21 +994,21 @@ bool cmFindPackageCommand::FindPackage(
bool const makePackageRequiredSet = bool const makePackageRequiredSet =
this->Makefile->IsOn(makePackageRequiredVar); this->Makefile->IsOn(makePackageRequiredVar);
if (makePackageRequiredSet) { if (makePackageRequiredSet) {
if (this->Required) { if (this->IsRequired()) {
this->Makefile->IssueMessage( this->Makefile->IssueMessage(
MessageType::WARNING, MessageType::WARNING,
cmStrCat("for module ", this->Name, cmStrCat("for module ", this->Name,
" already called with REQUIRED, thus ", " already called with REQUIRED, thus ",
makePackageRequiredVar, " has no effect.")); makePackageRequiredVar, " has no effect."));
} else { } else {
this->Required = true; this->Required = RequiredStatus::RequiredFromPackageVar;
} }
} }
std::string const disableFindPackageVar = std::string const disableFindPackageVar =
cmStrCat("CMAKE_DISABLE_FIND_PACKAGE_", this->Name); cmStrCat("CMAKE_DISABLE_FIND_PACKAGE_", this->Name);
if (this->Makefile->IsOn(disableFindPackageVar)) { if (this->Makefile->IsOn(disableFindPackageVar)) {
if (this->Required) { if (this->IsRequired()) {
this->SetError( this->SetError(
cmStrCat("for module ", this->Name, cmStrCat("for module ", this->Name,
(makePackageRequiredSet (makePackageRequiredSet
@@ -1310,6 +1326,9 @@ void cmFindPackageCommand::SetModuleVariables()
{ {
this->AddFindDefinition("CMAKE_FIND_PACKAGE_NAME", this->Name); this->AddFindDefinition("CMAKE_FIND_PACKAGE_NAME", this->Name);
// Nested find calls are not automatically required.
this->AddFindDefinition("CMAKE_FIND_REQUIRED", ""_s);
// Store the list of components and associated variable definitions. // Store the list of components and associated variable definitions.
std::string components_var = this->Name + "_FIND_COMPONENTS"; std::string components_var = this->Name + "_FIND_COMPONENTS";
this->AddFindDefinition(components_var, this->Components); this->AddFindDefinition(components_var, this->Components);
@@ -1329,7 +1348,7 @@ void cmFindPackageCommand::SetModuleVariables()
this->AddFindDefinition(quietly, "1"_s); this->AddFindDefinition(quietly, "1"_s);
} }
if (this->Required) { if (this->IsRequired()) {
// Tell the module that is about to be read that it should report // Tell the module that is about to be read that it should report
// a fatal error if the package is not found. // a fatal error if the package is not found.
std::string req = cmStrCat(this->Name, "_FIND_REQUIRED"); std::string req = cmStrCat(this->Name, "_FIND_REQUIRED");
@@ -1575,11 +1594,13 @@ bool cmFindPackageCommand::HandlePackageMode(
// package not found // package not found
if (result && !found) { if (result && !found) {
// warn if package required or neither quiet nor in config mode // warn if package required or
if (this->Required || // (neither quiet nor in config mode and not explicitly optional)
!(this->Quiet || if (this->IsRequired() ||
(this->UseConfigFiles && !this->UseFindModules && (!(this->Quiet ||
this->ConsideredConfigs.empty()))) { (this->UseConfigFiles && !this->UseFindModules &&
this->ConsideredConfigs.empty())) &&
this->Required != RequiredStatus::OptionalExplicit)) {
// The variable is not set. // The variable is not set.
std::ostringstream e; std::ostringstream e;
std::ostringstream aw; std::ostringstream aw;
@@ -1675,11 +1696,19 @@ bool cmFindPackageCommand::HandlePackageMode(
"without ensuring that it is actually available.\n"; "without ensuring that it is actually available.\n";
} }
} }
if (this->Required == RequiredStatus::RequiredFromFindVar) {
e << "\nThis package is considered required because the "
"CMAKE_FIND_REQUIRED variable has been enabled.\n";
} else if (this->Required == RequiredStatus::RequiredFromPackageVar) {
e << "\nThis package is considered required because the "
<< cmStrCat("CMAKE_REQUIRE_FIND_PACKAGE_", this->Name)
<< " variable has been enabled.\n";
}
this->Makefile->IssueMessage(this->Required ? MessageType::FATAL_ERROR this->Makefile->IssueMessage(
: MessageType::WARNING, this->IsRequired() ? MessageType::FATAL_ERROR : MessageType::WARNING,
e.str()); e.str());
if (this->Required) { if (this->IsRequired()) {
cmSystemTools::SetFatalErrorOccurred(); cmSystemTools::SetFatalErrorOccurred();
} }
@@ -1912,7 +1941,7 @@ bool cmFindPackageCommand::ReadPackage()
// Loop over appendices. // Loop over appendices.
auto iter = this->CpsAppendices.begin(); auto iter = this->CpsAppendices.begin();
while (iter != this->CpsAppendices.end()) { while (iter != this->CpsAppendices.end()) {
bool required = false; RequiredStatus required = RequiredStatus::Optional;
bool important = false; bool important = false;
// Check if this appendix provides any requested components. // Check if this appendix provides any requested components.
@@ -1972,7 +2001,7 @@ bool cmFindPackageCommand::ReadPackage()
bool cmFindPackageCommand::FindPackageDependencies( bool cmFindPackageCommand::FindPackageDependencies(
std::string const& fileName, cmPackageInfoReader const& reader, std::string const& fileName, cmPackageInfoReader const& reader,
bool required) RequiredStatus required)
{ {
// Get package requirements. // Get package requirements.
for (cmPackageRequirement const& dep : reader.GetRequirements()) { for (cmPackageRequirement const& dep : reader.GetRequirements()) {
@@ -2110,7 +2139,7 @@ void cmFindPackageCommand::AppendSuccessInformation()
} }
this->Makefile->GetState()->SetGlobalProperty(versionInfoPropName, this->Makefile->GetState()->SetGlobalProperty(versionInfoPropName,
versionInfo); versionInfo);
if (this->Required) { if (this->IsRequired()) {
std::string const requiredInfoPropName = std::string const requiredInfoPropName =
cmStrCat("_CMAKE_", this->Name, "_TYPE"); cmStrCat("_CMAKE_", this->Name, "_TYPE");
this->Makefile->GetState()->SetGlobalProperty(requiredInfoPropName, this->Makefile->GetState()->SetGlobalProperty(requiredInfoPropName,
@@ -3265,6 +3294,13 @@ bool cmFindPackageCommand::SearchEnvironmentPrefix(std::string const& prefix)
return TryGeneratedPaths(searchFn, pdt::Cps, prefix, pkgDirGen); return TryGeneratedPaths(searchFn, pdt::Cps, prefix, pkgDirGen);
} }
bool cmFindPackageCommand::IsRequired() const
{
return this->Required == RequiredStatus::RequiredExplicit ||
this->Required == RequiredStatus::RequiredFromPackageVar ||
this->Required == RequiredStatus::RequiredFromFindVar;
}
// TODO: Debug cmsys::Glob double slash problem. // TODO: Debug cmsys::Glob double slash problem.
bool cmFindPackage(std::vector<std::string> const& args, bool cmFindPackage(std::vector<std::string> const& args,

View File

@@ -151,9 +151,17 @@ private:
using AppendixMap = std::map<std::string, Appendix>; using AppendixMap = std::map<std::string, Appendix>;
AppendixMap FindAppendices(std::string const& base, AppendixMap FindAppendices(std::string const& base,
cmPackageInfoReader const& baseReader) const; cmPackageInfoReader const& baseReader) const;
enum RequiredStatus
{
Optional,
OptionalExplicit,
RequiredExplicit,
RequiredFromPackageVar,
RequiredFromFindVar
};
bool FindPackageDependencies(std::string const& fileName, bool FindPackageDependencies(std::string const& fileName,
cmPackageInfoReader const& reader, cmPackageInfoReader const& reader,
bool required); RequiredStatus required);
bool ImportPackageTargets(std::string const& fileName, bool ImportPackageTargets(std::string const& fileName,
cmPackageInfoReader& reader); cmPackageInfoReader& reader);
@@ -194,6 +202,8 @@ private:
bool SearchAppBundlePrefix(std::string const& prefix); bool SearchAppBundlePrefix(std::string const& prefix);
bool SearchEnvironmentPrefix(std::string const& prefix); bool SearchEnvironmentPrefix(std::string const& prefix);
bool IsRequired() const;
struct OriginalDef struct OriginalDef
{ {
bool exists; bool exists;
@@ -234,7 +244,7 @@ private:
unsigned int VersionFoundCount = 0; unsigned int VersionFoundCount = 0;
KWIML_INT_uint64_t RequiredCMakeVersion = 0; KWIML_INT_uint64_t RequiredCMakeVersion = 0;
bool Quiet = false; bool Quiet = false;
bool Required = false; RequiredStatus Required = RequiredStatus::Optional;
bool UseCpsFiles = false; bool UseCpsFiles = false;
bool UseConfigFiles = true; bool UseConfigFiles = true;
bool UseFindModules = true; bool UseFindModules = true;

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,10 @@
CMake Error at Optional.cmake:[0-9]+ \(find_file\):
find_file cannot be both REQUIRED and OPTIONAL
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
CMake Error at Optional\.cmake:[0-9]+ \(find_file\):
Could not find FILE_doNotExists using the following files: doNotExists.h
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,14 @@
set(CMAKE_FIND_REQUIRED ON)
find_file(FILE_doNotExists_Optional
NAMES doNotExists.h
OPTIONAL
)
find_file(FILE_doNotExists_OptionalRequired
NAMES doNotExists.h
OPTIONAL
REQUIRED
)
find_file(FILE_doNotExists
NAMES doNotExists.h
REQUIRED
)

View File

@@ -4,6 +4,7 @@ run_cmake(FromPATHEnv)
run_cmake(FromPrefixPath) run_cmake(FromPrefixPath)
run_cmake(PrefixInPATH) run_cmake(PrefixInPATH)
run_cmake(Required) run_cmake(Required)
run_cmake(Optional)
run_cmake(NO_CACHE) run_cmake(NO_CACHE)
run_cmake(REGISTRY_VIEW-no-view) run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view) run_cmake(REGISTRY_VIEW-wrong-view)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,10 @@
CMake Error at Optional.cmake:[0-9]+ \(find_library\):
find_library cannot be both REQUIRED and OPTIONAL
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
CMake Error at Optional\.cmake:[0-9]+ \(find_library\):
Could not find LIB_doNotExists using the following names: doNotExists
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,13 @@
set(CMAKE_FIND_REQUIRED ON)
find_library(LIB_doNotExists_Optional
NAMES doNotExists
OPTIONAL
)
find_library(LIB_doNotExists_OptionalRequired
NAMES doNotExists
OPTIONAL
REQUIRED
)
find_library(LIB_doNotExists
NAMES doNotExists
)

View File

@@ -12,6 +12,7 @@ if(UNIX AND NOT CYGWIN)
endif() endif()
run_cmake(PrefixInPATH) run_cmake(PrefixInPATH)
run_cmake(Required) run_cmake(Required)
run_cmake(Optional)
run_cmake(NO_CACHE) run_cmake(NO_CACHE)
run_cmake(REGISTRY_VIEW-no-view) run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view) run_cmake(REGISTRY_VIEW-wrong-view)

View File

@@ -1,5 +1,9 @@
CMake Error at MissingNormalForceRequired.cmake:2 \(find_package\): CMake Error at MissingNormalForceRequired.cmake:2 \(find_package\):
No "FindNotHere.cmake" found in CMAKE_MODULE_PATH\. No "FindNotHere.cmake" found in CMAKE_MODULE_PATH\.
This package is considered required because the
CMAKE_REQUIRE_FIND_PACKAGE_NotHere variable has been enabled.
Call Stack \(most recent call first\): Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\) CMakeLists.txt:3 \(include\)
+ +

View File

@@ -0,0 +1,20 @@
CMake Error at PackageVarOverridesOptional.cmake:[0-9]+ \(find_package\):
By not providing "FindFoo.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "Foo", but
CMake did not find one.
Could not find a package configuration file provided by "Foo" with any of
the following names:
FooConfig.cmake
foo-config.cmake
Add the installation prefix of "Foo" to CMAKE_PREFIX_PATH or set "Foo_DIR"
to a directory containing one of the above files. If "Foo" provides a
separate development package or SDK, be sure it has been installed.
This package is considered required because the
CMAKE_REQUIRE_FIND_PACKAGE_Foo variable has been enabled.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,2 @@
set(CMAKE_REQUIRE_FIND_PACKAGE_Foo ON)
find_package(Foo OPTIONAL)

View File

@@ -0,0 +1,4 @@
CMake Error at RequiredOptionalKeywordsClash.cmake:[0-9]+ \(find_package\):
find_package cannot be both REQUIRED and OPTIONAL
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1 @@
find_package(Foo OPTIONAL REQUIRED)

View File

@@ -0,0 +1,18 @@
CMake Warning at RequiredVarNestedConfig\.cmake:[0-9]+ \(find_package\):
By not providing "FindDoesNotExist\.cmake" in CMAKE_MODULE_PATH this project
has asked CMake to find a package configuration file provided by
"DoesNotExist", but CMake did not find one\.
Could not find a package configuration file provided by "DoesNotExist" with
any of the following names:
DoesNotExistConfig.cmake
doesnotexist-config.cmake
Add the installation prefix of "DoesNotExist" to CMAKE_PREFIX_PATH or set
"DoesNotExist_DIR" to a directory containing one of the above files\. If
"DoesNotExist" provides a separate development package or SDK, be sure it
has been installed\.
Call Stack \(most recent call first\):
RequiredVarNested.cmake:[0-9]+ \(find_package\)
CMakeLists\.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,3 @@
set(CMAKE_FIND_REQUIRED ON CACHE BOOL "") # The cache entry must be shadowed by a nested definition.
set(RequiredVarNested_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
find_package(RequiredVarNested CONFIG)

View File

@@ -0,0 +1,8 @@
if (CMAKE_FIND_REQUIRED)
message(FATAL_ERROR "CMAKE_FIND_REQUIRED enabled in Config.cmake")
endif()
find_package(DoesNotExist)
find_library(library DoesNotExist)
find_program(program DoesNotExist)
find_path(path DoesNotExist)
find_file(file DoesNotExist)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,21 @@
CMake Error at RequiredVarOptional.cmake:[0-9]+ \(find_package\):
By not providing "FindDoesNotExist.cmake" in CMAKE_MODULE_PATH this project
has asked CMake to find a package configuration file provided by
"DoesNotExist", but CMake did not find one.
Could not find a package configuration file provided by "DoesNotExist" with
any of the following names:
DoesNotExistConfig.cmake
doesnotexist-config.cmake
Add the installation prefix of "DoesNotExist" to CMAKE_PREFIX_PATH or set
"DoesNotExist_DIR" to a directory containing one of the above files. If
"DoesNotExist" provides a separate development package or SDK, be sure it
has been installed.
This package is considered required because the CMAKE_FIND_REQUIRED
variable has been enabled.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,4 @@
set(CMAKE_FIND_REQUIRED ON)
find_package(DoesNotExist-Optional OPTIONAL CompA CompB CompC)
find_package(DoesNotExist)
message(FATAL_ERROR "This error must not be reachable.")

View File

@@ -27,9 +27,13 @@ run_cmake_with_options(ModuleModeDebugPkg --debug-find-pkg=Foo,Zot)
run_cmake(PackageRoot) run_cmake(PackageRoot)
run_cmake(PackageRootNestedConfig) run_cmake(PackageRootNestedConfig)
run_cmake(PackageRootNestedModule) run_cmake(PackageRootNestedModule)
run_cmake(PackageVarOverridesOptional)
run_cmake(PolicyPush) run_cmake(PolicyPush)
run_cmake(PolicyPop) run_cmake(PolicyPop)
run_cmake(RequiredOptionValuesClash) run_cmake(RequiredOptionValuesClash)
run_cmake(RequiredOptionalKeywordsClash)
run_cmake(RequiredVarOptional)
run_cmake(RequiredVarNested)
run_cmake(FindRootPathAndPrefixPathAreEqual) run_cmake(FindRootPathAndPrefixPathAreEqual)
run_cmake(SetFoundFALSE) run_cmake(SetFoundFALSE)
run_cmake(WrongVersion) run_cmake(WrongVersion)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,10 @@
CMake Error at Optional.cmake:[0-9]+ \(find_path\):
find_path cannot be both REQUIRED and OPTIONAL
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
CMake Error at Optional\.cmake:[0-9]+ \(find_path\):
Could not find PATH_doNotExists using the following files: doNotExists.h
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,13 @@
set(CMAKE_FIND_REQUIRED ON)
find_path(PATH_doNotExists_Optional
NAMES doNotExists.h
OPTIONAL
)
find_path(PATH_doNotExists_OptionalRequired
NAMES doNotExists.h
OPTIONAL
REQUIRED
)
find_path(PATH_doNotExists
NAMES doNotExists.h
)

View File

@@ -4,6 +4,7 @@ run_cmake(EmptyOldStyle)
run_cmake(FromPATHEnv) run_cmake(FromPATHEnv)
run_cmake(PrefixInPATH) run_cmake(PrefixInPATH)
run_cmake(Required) run_cmake(Required)
run_cmake(Optional)
run_cmake(NO_CACHE) run_cmake(NO_CACHE)
run_cmake(REGISTRY_VIEW-no-view) run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view) run_cmake(REGISTRY_VIEW-wrong-view)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,10 @@
CMake Error at Optional.cmake:[0-9]+ \(find_program\):
find_program cannot be both REQUIRED and OPTIONAL
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
CMake Error at Optional\.cmake:[0-9]+ \(find_program\):
Could not find PROG_AandB using the following names: testAandB
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,13 @@
set(CMAKE_FIND_REQUIRED ON)
find_program(PROG_AandB_Optional
NAMES testAandB
OPTIONAL
)
find_program(PROG_AandB_OptionalRequired
NAMES testAandB
OPTIONAL
REQUIRED
)
find_program(PROG_AandB
NAMES testAandB
)

View File

@@ -5,6 +5,7 @@ run_cmake(DirsPerName)
run_cmake(NamesPerDir) run_cmake(NamesPerDir)
run_cmake(RelAndAbsPath) run_cmake(RelAndAbsPath)
run_cmake(Required) run_cmake(Required)
run_cmake(Optional)
run_cmake(NO_CACHE) run_cmake(NO_CACHE)
run_cmake(IgnorePrefixPath) run_cmake(IgnorePrefixPath)
run_cmake(REGISTRY_VIEW-no-view) run_cmake(REGISTRY_VIEW-no-view)