find_*: Add support for REQUIRED keyword

In the same spirit as the REQUIRED keyword on find_package, this will
stop cmake execution with an error on a failed find_program, find_file,
find_path or find_library.
This commit is contained in:
Sylvain Joubert 2020-03-06 14:30:01 +01:00
parent cc070e66cd
commit dc00809596
27 changed files with 121 additions and 2 deletions

View File

@ -15,6 +15,7 @@ The general signature is:
[PATHS path1 [path2 ... ENV var]] [PATHS path1 [path2 ... ENV var]]
[PATH_SUFFIXES suffix1 [suffix2 ...]] [PATH_SUFFIXES suffix1 [suffix2 ...]]
[DOC "cache documentation string"] [DOC "cache documentation string"]
[REQUIRED]
[NO_DEFAULT_PATH] [NO_DEFAULT_PATH]
[NO_PACKAGE_ROOT_PATH] [NO_PACKAGE_ROOT_PATH]
[NO_CMAKE_PATH] [NO_CMAKE_PATH]
@ -31,8 +32,9 @@ A cache entry named by ``<VAR>`` is created to store the result
of this command. of this command.
If the |SEARCH_XXX| is found the result is stored in the variable If the |SEARCH_XXX| is found the result is stored in the variable
and the search will not be repeated unless the variable is cleared. and the search will not be repeated unless the variable is cleared.
If nothing is found, the result will be If nothing is found, the result will be ``<VAR>-NOTFOUND``.
``<VAR>-NOTFOUND``, and the search will be attempted again the The ``REQUIRED`` option stops processing with an error message if nothing
is found, otherwise the search will be attempted again the
next time |FIND_XXX| is invoked with the same variable. next time |FIND_XXX| is invoked with the same variable.
Options include: Options include:
@ -57,6 +59,9 @@ Options include:
``DOC`` ``DOC``
Specify the documentation string for the ``<VAR>`` cache entry. Specify the documentation string for the ``<VAR>`` cache entry.
``REQUIRED``
Stop processing with an error message if nothing is found.
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

@ -0,0 +1,6 @@
required_find_commands
----------------------
* The :command:`find_program`, :command:`find_library`, :command:`find_path`
and :command:`find_file` commands gained a new ``REQUIRED`` option that will
stop processing with an error message if nothing is found.

View File

@ -111,6 +111,10 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
} else if (args[j] == "NO_SYSTEM_PATH") { } else if (args[j] == "NO_SYSTEM_PATH") {
doing = DoingNone; doing = DoingNone;
this->NoDefaultPath = true; this->NoDefaultPath = true;
} else if (args[j] == "REQUIRED") {
doing = DoingNone;
this->Required = true;
newStyle = true;
} else if (this->CheckCommonArgument(args[j])) { } else if (this->CheckCommonArgument(args[j])) {
doing = DoingNone; doing = DoingNone;
} else { } else {

View File

@ -53,6 +53,8 @@ protected:
bool AlreadyInCache = false; bool AlreadyInCache = false;
bool AlreadyInCacheWithoutMetaInfo = false; bool AlreadyInCacheWithoutMetaInfo = false;
bool Required = false;
private: private:
// Add pieces of the search. // Add pieces of the search.
void FillPackageRootPath(); void FillPackageRootPath();

View File

@ -12,6 +12,7 @@
#include "cmGlobalGenerator.h" #include "cmGlobalGenerator.h"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmState.h" #include "cmState.h"
#include "cmStateTypes.h" #include "cmStateTypes.h"
#include "cmStringAlgorithms.h" #include "cmStringAlgorithms.h"
@ -84,6 +85,13 @@ bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn)
this->Makefile->AddCacheDefinition(this->VariableName, notfound.c_str(), this->Makefile->AddCacheDefinition(this->VariableName, notfound.c_str(),
this->VariableDocumentation.c_str(), this->VariableDocumentation.c_str(),
cmStateEnums::FILEPATH); cmStateEnums::FILEPATH);
if (this->Required) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"Could not find " + this->VariableName +
" using the following names: " + cmJoin(this->Names, ", "));
cmSystemTools::SetFatalErrorOccured();
}
return true; return true;
} }

View File

@ -5,6 +5,7 @@
#include "cmsys/Glob.hxx" #include "cmsys/Glob.hxx"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStateTypes.h" #include "cmStateTypes.h"
#include "cmStringAlgorithms.h" #include "cmStringAlgorithms.h"
#include "cmSystemTools.h" #include "cmSystemTools.h"
@ -51,6 +52,13 @@ bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn)
this->VariableName, (this->VariableName + "-NOTFOUND").c_str(), this->VariableName, (this->VariableName + "-NOTFOUND").c_str(),
this->VariableDocumentation.c_str(), this->VariableDocumentation.c_str(),
(this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH); (this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH);
if (this->Required) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"Could not find " + this->VariableName +
" using the following files: " + cmJoin(this->Names, ", "));
cmSystemTools::SetFatalErrorOccured();
}
return true; return true;
} }

View File

@ -3,6 +3,7 @@
#include "cmFindProgramCommand.h" #include "cmFindProgramCommand.h"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStateTypes.h" #include "cmStateTypes.h"
#include "cmStringAlgorithms.h" #include "cmStringAlgorithms.h"
#include "cmSystemTools.h" #include "cmSystemTools.h"
@ -136,6 +137,13 @@ bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn)
this->Makefile->AddCacheDefinition( this->Makefile->AddCacheDefinition(
this->VariableName, (this->VariableName + "-NOTFOUND").c_str(), this->VariableName, (this->VariableName + "-NOTFOUND").c_str(),
this->VariableDocumentation.c_str(), cmStateEnums::FILEPATH); this->VariableDocumentation.c_str(), cmStateEnums::FILEPATH);
if (this->Required) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"Could not find " + this->VariableName +
" using the following names: " + cmJoin(this->Names, ", "));
cmSystemTools::SetFatalErrorOccured();
}
return true; return true;
} }

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,4 @@
CMake Error at Required.cmake:9 \(find_file\):
Could not find FILE_doNotExists using the following files: doNotExists.h
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1 @@
-- FILE_exists='[^']*/Tests/RunCMake/find_file/include/PrefixInPATH.h'

View File

@ -0,0 +1,12 @@
find_file(FILE_exists
NAMES PrefixInPATH.h
PATHS ${CMAKE_CURRENT_SOURCE_DIR}/include
NO_DEFAULT_PATH
REQUIRED
)
message(STATUS "FILE_exists='${FILE_exists}'")
find_file(FILE_doNotExists
NAMES doNotExists.h
REQUIRED
)

View File

@ -3,3 +3,4 @@ include(RunCMake)
run_cmake(FromPATHEnv) run_cmake(FromPATHEnv)
run_cmake(FromPrefixPath) run_cmake(FromPrefixPath)
run_cmake(PrefixInPATH) run_cmake(PrefixInPATH)
run_cmake(Required)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,4 @@
CMake Error at Required.cmake:11 \(find_library\):
Could not find LIB_doNotExists using the following names: doNotExists
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1 @@
-- LIB_exists='[^']*/Tests/RunCMake/find_library/lib/libPrefixInPATH.a'

View File

@ -0,0 +1,14 @@
list(APPEND CMAKE_FIND_LIBRARY_PREFIXES lib)
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .a)
find_library(LIB_exists
NAMES PrefixInPATH
PATHS ${CMAKE_CURRENT_SOURCE_DIR}/lib
NO_DEFAULT_PATH
REQUIRED
)
message(STATUS "LIB_exists='${LIB_exists}'")
find_library(LIB_doNotExists
NAMES doNotExists
REQUIRED
)

View File

@ -7,3 +7,4 @@ if(CMAKE_HOST_UNIX)
run_cmake(LibArchLink) run_cmake(LibArchLink)
endif() endif()
run_cmake(PrefixInPATH) run_cmake(PrefixInPATH)
run_cmake(Required)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,4 @@
CMake Error at Required.cmake:9 \(find_path\):
Could not find PATH_doNotExists using the following files: doNotExists.h
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1 @@
-- PATH_exists='[^']*/Tests/RunCMake/find_path/include'

View File

@ -0,0 +1,12 @@
find_path(PATH_exists
NAMES PrefixInPATH.h
PATHS ${CMAKE_CURRENT_SOURCE_DIR}/include
NO_DEFAULT_PATH
REQUIRED
)
message(STATUS "PATH_exists='${PATH_exists}'")
find_path(PATH_doNotExists
NAMES doNotExists.h
REQUIRED
)

View File

@ -3,6 +3,7 @@ include(RunCMake)
run_cmake(EmptyOldStyle) run_cmake(EmptyOldStyle)
run_cmake(FromPATHEnv) run_cmake(FromPATHEnv)
run_cmake(PrefixInPATH) run_cmake(PrefixInPATH)
run_cmake(Required)
if(APPLE) if(APPLE)
run_cmake(FrameworksWithSubdirs) run_cmake(FrameworksWithSubdirs)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,4 @@
CMake Error at Required.cmake:9 \(find_program\):
Could not find PROG_AandB using the following names: testAandB
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1 @@
-- PROG_A='[^']*/Tests/RunCMake/find_program/A/testA'

View File

@ -0,0 +1,12 @@
find_program(PROG_A
NAMES testA
PATHS ${CMAKE_CURRENT_SOURCE_DIR}/A
NO_DEFAULT_PATH
REQUIRED
)
message(STATUS "PROG_A='${PROG_A}'")
find_program(PROG_AandB
NAMES testAandB
REQUIRED
)

View File

@ -4,6 +4,7 @@ run_cmake(EnvAndHints)
run_cmake(DirsPerName) run_cmake(DirsPerName)
run_cmake(NamesPerDir) run_cmake(NamesPerDir)
run_cmake(RelAndAbsPath) run_cmake(RelAndAbsPath)
run_cmake(Required)
if(CMAKE_SYSTEM_NAME MATCHES "^(Windows|CYGWIN)$") if(CMAKE_SYSTEM_NAME MATCHES "^(Windows|CYGWIN)$")
run_cmake(WindowsCom) run_cmake(WindowsCom)