diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt index ab96bd3826..299c761094 100644 --- a/Help/command/FIND_XXX.txt +++ b/Help/command/FIND_XXX.txt @@ -18,7 +18,7 @@ The general signature is: [VALIDATOR function] [DOC "cache documentation string"] [NO_CACHE] - [REQUIRED] + [REQUIRED|OPTIONAL] [NO_DEFAULT_PATH] [NO_PACKAGE_ROOT_PATH] [NO_CMAKE_PATH] @@ -118,6 +118,18 @@ Options include: the search will be attempted again the next time |FIND_XXX| is invoked 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 added to the search. If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows: diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst index cae71503c0..7ec0f6a869 100644 --- a/Help/command/find_package.rst +++ b/Help/command/find_package.rst @@ -132,7 +132,7 @@ Basic Signature .. code-block:: cmake find_package( [version] [EXACT] [QUIET] [MODULE] - [REQUIRED] [[COMPONENTS] [components...]] + [REQUIRED|OPTIONAL] [[COMPONENTS] [components...]] [OPTIONAL_COMPONENTS components...] [REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)] [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 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 ``OPTIONAL_COMPONENTS``. If these cannot be satisfied, the package overall can still be considered found, as long as all required components are @@ -249,7 +256,7 @@ Full Signature .. code-block:: cmake find_package( [version] [EXACT] [QUIET] - [REQUIRED] [[COMPONENTS] [components...]] + [REQUIRED|OPTIONAL] [[COMPONENTS] [components...]] [OPTIONAL_COMPONENTS components...] [CONFIG|NO_MODULE] [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. +The :variable:`CMAKE_REQUIRE_FIND_PACKAGE_` variable takes priority +over the ``OPTIONAL`` keyword in determining whether a package is required. + .. _`version selection`: Config Mode Version Selection diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index cbf8a920ce..02331474be 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -61,6 +61,7 @@ Variables that Provide Information /variable/CMAKE_FIND_PACKAGE_REDIRECTS_DIR /variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION /variable/CMAKE_FIND_PACKAGE_SORT_ORDER + /variable/CMAKE_FIND_REQUIRED /variable/CMAKE_GENERATOR /variable/CMAKE_GENERATOR_INSTANCE /variable/CMAKE_GENERATOR_PLATFORM diff --git a/Help/release/dev/cmake-find-required.rst b/Help/release/dev/cmake-find-required.rst new file mode 100644 index 0000000000..20e50e6b4e --- /dev/null +++ b/Help/release/dev/cmake-find-required.rst @@ -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. diff --git a/Help/variable/CMAKE_FIND_REQUIRED.rst b/Help/variable/CMAKE_FIND_REQUIRED.rst new file mode 100644 index 0000000000..0518edb57f --- /dev/null +++ b/Help/variable/CMAKE_FIND_REQUIRED.rst @@ -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.cmake`` +or ``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_` for making +a :command:`find_package` call ``REQUIRED``, and for additional information on +how enabling these variables can break commonly used patterns. diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index 8733e3c2d3..083422cf68 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -94,6 +94,7 @@ bool cmFindBase::ParseArguments(std::vector const& argsIn) this->SelectDefaultMacMode(); bool newStyle = false; + bool haveRequiredOrOptional = false; enum Doing { DoingNone, @@ -129,8 +130,21 @@ bool cmFindBase::ParseArguments(std::vector const& argsIn) this->NoDefaultPath = true; } else if (args[j] == "REQUIRED") { doing = DoingNone; + if (haveRequiredOrOptional && !this->Required) { + this->SetError("cannot be both REQUIRED and OPTIONAL"); + return false; + } this->Required = 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") { if (++j == args.size()) { this->SetError("missing required argument for REGISTRY_VIEW"); @@ -187,6 +201,10 @@ bool cmFindBase::ParseArguments(std::vector const& argsIn) } } + if (!haveRequiredOrOptional) { + this->Required = this->Makefile->IsOn("CMAKE_FIND_REQUIRED"); + } + if (this->VariableDocumentation.empty()) { this->VariableDocumentation = "Where can "; if (this->Names.empty()) { diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 07060d66ee..8eeb9205ba 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -747,7 +747,18 @@ bool cmFindPackageCommand::InitialPass(std::vector const& args) configArgs.push_back(i); doing = DoingNone; } 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; } else if (args[i] == "COMPONENTS") { doing = DoingComponents; @@ -844,6 +855,11 @@ bool cmFindPackageCommand::InitialPass(std::vector const& args) } } + if (this->Required == RequiredStatus::Optional && + this->Makefile->IsOn("CMAKE_FIND_REQUIRED")) { + this->Required = RequiredStatus::RequiredFromFindVar; + } + if (!this->GlobalScope) { cmValue value( this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_TARGETS_GLOBAL")); @@ -978,21 +994,21 @@ bool cmFindPackageCommand::FindPackage( bool const makePackageRequiredSet = this->Makefile->IsOn(makePackageRequiredVar); if (makePackageRequiredSet) { - if (this->Required) { + if (this->IsRequired()) { this->Makefile->IssueMessage( MessageType::WARNING, cmStrCat("for module ", this->Name, " already called with REQUIRED, thus ", makePackageRequiredVar, " has no effect.")); } else { - this->Required = true; + this->Required = RequiredStatus::RequiredFromPackageVar; } } std::string const disableFindPackageVar = cmStrCat("CMAKE_DISABLE_FIND_PACKAGE_", this->Name); if (this->Makefile->IsOn(disableFindPackageVar)) { - if (this->Required) { + if (this->IsRequired()) { this->SetError( cmStrCat("for module ", this->Name, (makePackageRequiredSet @@ -1310,6 +1326,9 @@ void cmFindPackageCommand::SetModuleVariables() { 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. std::string components_var = this->Name + "_FIND_COMPONENTS"; this->AddFindDefinition(components_var, this->Components); @@ -1329,7 +1348,7 @@ void cmFindPackageCommand::SetModuleVariables() this->AddFindDefinition(quietly, "1"_s); } - if (this->Required) { + if (this->IsRequired()) { // Tell the module that is about to be read that it should report // a fatal error if the package is not found. std::string req = cmStrCat(this->Name, "_FIND_REQUIRED"); @@ -1575,11 +1594,13 @@ bool cmFindPackageCommand::HandlePackageMode( // package not found if (result && !found) { - // warn if package required or neither quiet nor in config mode - if (this->Required || - !(this->Quiet || - (this->UseConfigFiles && !this->UseFindModules && - this->ConsideredConfigs.empty()))) { + // warn if package required or + // (neither quiet nor in config mode and not explicitly optional) + if (this->IsRequired() || + (!(this->Quiet || + (this->UseConfigFiles && !this->UseFindModules && + this->ConsideredConfigs.empty())) && + this->Required != RequiredStatus::OptionalExplicit)) { // The variable is not set. std::ostringstream e; std::ostringstream aw; @@ -1675,11 +1696,19 @@ bool cmFindPackageCommand::HandlePackageMode( "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 - : MessageType::WARNING, - e.str()); - if (this->Required) { + this->Makefile->IssueMessage( + this->IsRequired() ? MessageType::FATAL_ERROR : MessageType::WARNING, + e.str()); + if (this->IsRequired()) { cmSystemTools::SetFatalErrorOccurred(); } @@ -1912,7 +1941,7 @@ bool cmFindPackageCommand::ReadPackage() // Loop over appendices. auto iter = this->CpsAppendices.begin(); while (iter != this->CpsAppendices.end()) { - bool required = false; + RequiredStatus required = RequiredStatus::Optional; bool important = false; // Check if this appendix provides any requested components. @@ -1972,7 +2001,7 @@ bool cmFindPackageCommand::ReadPackage() bool cmFindPackageCommand::FindPackageDependencies( std::string const& fileName, cmPackageInfoReader const& reader, - bool required) + RequiredStatus required) { // Get package requirements. for (cmPackageRequirement const& dep : reader.GetRequirements()) { @@ -2110,7 +2139,7 @@ void cmFindPackageCommand::AppendSuccessInformation() } this->Makefile->GetState()->SetGlobalProperty(versionInfoPropName, versionInfo); - if (this->Required) { + if (this->IsRequired()) { std::string const requiredInfoPropName = cmStrCat("_CMAKE_", this->Name, "_TYPE"); this->Makefile->GetState()->SetGlobalProperty(requiredInfoPropName, @@ -3265,6 +3294,13 @@ bool cmFindPackageCommand::SearchEnvironmentPrefix(std::string const& prefix) 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. bool cmFindPackage(std::vector const& args, diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index 75a4243fa0..b2db69e383 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -151,9 +151,17 @@ private: using AppendixMap = std::map; AppendixMap FindAppendices(std::string const& base, cmPackageInfoReader const& baseReader) const; + enum RequiredStatus + { + Optional, + OptionalExplicit, + RequiredExplicit, + RequiredFromPackageVar, + RequiredFromFindVar + }; bool FindPackageDependencies(std::string const& fileName, cmPackageInfoReader const& reader, - bool required); + RequiredStatus required); bool ImportPackageTargets(std::string const& fileName, cmPackageInfoReader& reader); @@ -194,6 +202,8 @@ private: bool SearchAppBundlePrefix(std::string const& prefix); bool SearchEnvironmentPrefix(std::string const& prefix); + bool IsRequired() const; + struct OriginalDef { bool exists; @@ -234,7 +244,7 @@ private: unsigned int VersionFoundCount = 0; KWIML_INT_uint64_t RequiredCMakeVersion = 0; bool Quiet = false; - bool Required = false; + RequiredStatus Required = RequiredStatus::Optional; bool UseCpsFiles = false; bool UseConfigFiles = true; bool UseFindModules = true; diff --git a/Tests/RunCMake/find_file/Optional-result.txt b/Tests/RunCMake/find_file/Optional-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/find_file/Optional-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/find_file/Optional-stderr.txt b/Tests/RunCMake/find_file/Optional-stderr.txt new file mode 100644 index 0000000000..beb8a668a1 --- /dev/null +++ b/Tests/RunCMake/find_file/Optional-stderr.txt @@ -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\) diff --git a/Tests/RunCMake/find_file/Optional.cmake b/Tests/RunCMake/find_file/Optional.cmake new file mode 100644 index 0000000000..dbc8de9263 --- /dev/null +++ b/Tests/RunCMake/find_file/Optional.cmake @@ -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 +) diff --git a/Tests/RunCMake/find_file/RunCMakeTest.cmake b/Tests/RunCMake/find_file/RunCMakeTest.cmake index 2d59e38473..54840d1384 100644 --- a/Tests/RunCMake/find_file/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_file/RunCMakeTest.cmake @@ -4,6 +4,7 @@ run_cmake(FromPATHEnv) run_cmake(FromPrefixPath) run_cmake(PrefixInPATH) run_cmake(Required) +run_cmake(Optional) run_cmake(NO_CACHE) run_cmake(REGISTRY_VIEW-no-view) run_cmake(REGISTRY_VIEW-wrong-view) diff --git a/Tests/RunCMake/find_library/Optional-result.txt b/Tests/RunCMake/find_library/Optional-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/find_library/Optional-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/find_library/Optional-stderr.txt b/Tests/RunCMake/find_library/Optional-stderr.txt new file mode 100644 index 0000000000..d75143843a --- /dev/null +++ b/Tests/RunCMake/find_library/Optional-stderr.txt @@ -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\) diff --git a/Tests/RunCMake/find_library/Optional.cmake b/Tests/RunCMake/find_library/Optional.cmake new file mode 100644 index 0000000000..05cc8d0662 --- /dev/null +++ b/Tests/RunCMake/find_library/Optional.cmake @@ -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 +) diff --git a/Tests/RunCMake/find_library/RunCMakeTest.cmake b/Tests/RunCMake/find_library/RunCMakeTest.cmake index f9c85280e4..3f2b10beef 100644 --- a/Tests/RunCMake/find_library/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_library/RunCMakeTest.cmake @@ -12,6 +12,7 @@ if(UNIX AND NOT CYGWIN) endif() run_cmake(PrefixInPATH) run_cmake(Required) +run_cmake(Optional) run_cmake(NO_CACHE) run_cmake(REGISTRY_VIEW-no-view) run_cmake(REGISTRY_VIEW-wrong-view) diff --git a/Tests/RunCMake/find_package/MissingNormalForceRequired-stderr.txt b/Tests/RunCMake/find_package/MissingNormalForceRequired-stderr.txt index f6c0b44a03..02a8e0a062 100644 --- a/Tests/RunCMake/find_package/MissingNormalForceRequired-stderr.txt +++ b/Tests/RunCMake/find_package/MissingNormalForceRequired-stderr.txt @@ -1,5 +1,9 @@ CMake Error at MissingNormalForceRequired.cmake:2 \(find_package\): 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\): CMakeLists.txt:3 \(include\) + diff --git a/Tests/RunCMake/find_package/PackageVarOverridesOptional-result.txt b/Tests/RunCMake/find_package/PackageVarOverridesOptional-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/find_package/PackageVarOverridesOptional-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/find_package/PackageVarOverridesOptional-stderr.txt b/Tests/RunCMake/find_package/PackageVarOverridesOptional-stderr.txt new file mode 100644 index 0000000000..4f3d1810f6 --- /dev/null +++ b/Tests/RunCMake/find_package/PackageVarOverridesOptional-stderr.txt @@ -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\) diff --git a/Tests/RunCMake/find_package/PackageVarOverridesOptional.cmake b/Tests/RunCMake/find_package/PackageVarOverridesOptional.cmake new file mode 100644 index 0000000000..8362a4d133 --- /dev/null +++ b/Tests/RunCMake/find_package/PackageVarOverridesOptional.cmake @@ -0,0 +1,2 @@ +set(CMAKE_REQUIRE_FIND_PACKAGE_Foo ON) +find_package(Foo OPTIONAL) diff --git a/Tests/RunCMake/find_package/RequiredOptionalKeywordsClash-result.txt b/Tests/RunCMake/find_package/RequiredOptionalKeywordsClash-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/find_package/RequiredOptionalKeywordsClash-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/find_package/RequiredOptionalKeywordsClash-stderr.txt b/Tests/RunCMake/find_package/RequiredOptionalKeywordsClash-stderr.txt new file mode 100644 index 0000000000..6bf3a8c317 --- /dev/null +++ b/Tests/RunCMake/find_package/RequiredOptionalKeywordsClash-stderr.txt @@ -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\) diff --git a/Tests/RunCMake/find_package/RequiredOptionalKeywordsClash.cmake b/Tests/RunCMake/find_package/RequiredOptionalKeywordsClash.cmake new file mode 100644 index 0000000000..964d65927f --- /dev/null +++ b/Tests/RunCMake/find_package/RequiredOptionalKeywordsClash.cmake @@ -0,0 +1 @@ +find_package(Foo OPTIONAL REQUIRED) diff --git a/Tests/RunCMake/find_package/RequiredVarNested-stderr.txt b/Tests/RunCMake/find_package/RequiredVarNested-stderr.txt new file mode 100644 index 0000000000..367149f7af --- /dev/null +++ b/Tests/RunCMake/find_package/RequiredVarNested-stderr.txt @@ -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\) diff --git a/Tests/RunCMake/find_package/RequiredVarNested.cmake b/Tests/RunCMake/find_package/RequiredVarNested.cmake new file mode 100644 index 0000000000..58caed0138 --- /dev/null +++ b/Tests/RunCMake/find_package/RequiredVarNested.cmake @@ -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) diff --git a/Tests/RunCMake/find_package/RequiredVarNestedConfig.cmake b/Tests/RunCMake/find_package/RequiredVarNestedConfig.cmake new file mode 100644 index 0000000000..c3c9973b6b --- /dev/null +++ b/Tests/RunCMake/find_package/RequiredVarNestedConfig.cmake @@ -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) diff --git a/Tests/RunCMake/find_package/RequiredVarOptional-result.txt b/Tests/RunCMake/find_package/RequiredVarOptional-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/find_package/RequiredVarOptional-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/find_package/RequiredVarOptional-stderr.txt b/Tests/RunCMake/find_package/RequiredVarOptional-stderr.txt new file mode 100644 index 0000000000..40dc5ef915 --- /dev/null +++ b/Tests/RunCMake/find_package/RequiredVarOptional-stderr.txt @@ -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\) diff --git a/Tests/RunCMake/find_package/RequiredVarOptional.cmake b/Tests/RunCMake/find_package/RequiredVarOptional.cmake new file mode 100644 index 0000000000..8653440ec2 --- /dev/null +++ b/Tests/RunCMake/find_package/RequiredVarOptional.cmake @@ -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.") diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake index 76a0d105f9..0c05d2dd3c 100644 --- a/Tests/RunCMake/find_package/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake @@ -27,9 +27,13 @@ run_cmake_with_options(ModuleModeDebugPkg --debug-find-pkg=Foo,Zot) run_cmake(PackageRoot) run_cmake(PackageRootNestedConfig) run_cmake(PackageRootNestedModule) +run_cmake(PackageVarOverridesOptional) run_cmake(PolicyPush) run_cmake(PolicyPop) run_cmake(RequiredOptionValuesClash) +run_cmake(RequiredOptionalKeywordsClash) +run_cmake(RequiredVarOptional) +run_cmake(RequiredVarNested) run_cmake(FindRootPathAndPrefixPathAreEqual) run_cmake(SetFoundFALSE) run_cmake(WrongVersion) diff --git a/Tests/RunCMake/find_path/Optional-result.txt b/Tests/RunCMake/find_path/Optional-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/find_path/Optional-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/find_path/Optional-stderr.txt b/Tests/RunCMake/find_path/Optional-stderr.txt new file mode 100644 index 0000000000..45c4bc0ec6 --- /dev/null +++ b/Tests/RunCMake/find_path/Optional-stderr.txt @@ -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\) diff --git a/Tests/RunCMake/find_path/Optional.cmake b/Tests/RunCMake/find_path/Optional.cmake new file mode 100644 index 0000000000..0fff24181c --- /dev/null +++ b/Tests/RunCMake/find_path/Optional.cmake @@ -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 +) diff --git a/Tests/RunCMake/find_path/RunCMakeTest.cmake b/Tests/RunCMake/find_path/RunCMakeTest.cmake index 2ed4d7db06..dc4b692717 100644 --- a/Tests/RunCMake/find_path/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_path/RunCMakeTest.cmake @@ -4,6 +4,7 @@ run_cmake(EmptyOldStyle) run_cmake(FromPATHEnv) run_cmake(PrefixInPATH) run_cmake(Required) +run_cmake(Optional) run_cmake(NO_CACHE) run_cmake(REGISTRY_VIEW-no-view) run_cmake(REGISTRY_VIEW-wrong-view) diff --git a/Tests/RunCMake/find_program/Optional-result.txt b/Tests/RunCMake/find_program/Optional-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/find_program/Optional-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/find_program/Optional-stderr.txt b/Tests/RunCMake/find_program/Optional-stderr.txt new file mode 100644 index 0000000000..06b836e7e4 --- /dev/null +++ b/Tests/RunCMake/find_program/Optional-stderr.txt @@ -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\) diff --git a/Tests/RunCMake/find_program/Optional.cmake b/Tests/RunCMake/find_program/Optional.cmake new file mode 100644 index 0000000000..7ef995db43 --- /dev/null +++ b/Tests/RunCMake/find_program/Optional.cmake @@ -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 +) diff --git a/Tests/RunCMake/find_program/RunCMakeTest.cmake b/Tests/RunCMake/find_program/RunCMakeTest.cmake index f8ecb8fedf..c7a10bbc2e 100644 --- a/Tests/RunCMake/find_program/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_program/RunCMakeTest.cmake @@ -5,6 +5,7 @@ run_cmake(DirsPerName) run_cmake(NamesPerDir) run_cmake(RelAndAbsPath) run_cmake(Required) +run_cmake(Optional) run_cmake(NO_CACHE) run_cmake(IgnorePrefixPath) run_cmake(REGISTRY_VIEW-no-view)