find_(program,library,file,path): add validation function

Fixes: #23603
This commit is contained in:
Marc Chevrier
2022-06-11 16:25:45 +02:00
committed by Brad King
parent b78624fd29
commit f3b5a7d6df
59 changed files with 424 additions and 17 deletions

View File

@@ -15,6 +15,7 @@ The general signature is:
[PATHS [path | ENV var]... ]
[REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[VALIDATOR function]
[DOC "cache documentation string"]
[NO_CACHE]
[REQUIRED]
@@ -66,6 +67,26 @@ Options include:
Specify additional subdirectories to check below each directory
location otherwise considered.
``VALIDATOR``
.. versionadded:: 3.25
Specify a :command:`function` (a :command:`macro` is not an acceptable
choice) which will be called for each found item. The search ends when
the validation function returns a successful status.
The validation function expects two arguments: output variable name and item
value. By default, the output variable name already holds a ``TRUE`` value.
.. parsed-literal::
function (MY_CHECK output_status item)
if (NOT item MATCHES ...)
set(${output_status} FALSE PARENT_SCOPE)
endif()
endfunction()
|FIND_XXX| (result NAMES ... VALIDATOR my_check)
``DOC``
Specify the documentation string for the ``<VAR>`` cache entry.

View File

@@ -0,0 +1,6 @@
find_item-VALIDATOR
-------------------
* :command:`find_file`, :command:`find_path`, :command:`find_library`, and
:command:`find_program` commands gain the capability to specify a function
which will be called for each found item to validate it.

View File

@@ -2,15 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFindBase.h"
#include <algorithm>
#include <cstddef>
#include <deque>
#include <functional>
#include <map>
#include <utility>
#include <cm/optional>
#include <cmext/algorithm>
#include <cmext/string_view>
#include "cmCMakePath.h"
#include "cmExecutionStatus.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
@@ -24,8 +29,6 @@
#include "cmWindowsRegistry.h"
#include "cmake.h"
class cmExecutionStatus;
cmFindBase::cmFindBase(std::string findCommandName, cmExecutionStatus& status)
: cmFindCommon(status)
, FindCommandName(std::move(findCommandName))
@@ -138,6 +141,31 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
cmStrCat("given invalid value for \"REGISTRY_VIEW\": ", args[j]));
return false;
}
} else if (args[j] == "VALIDATOR") {
if (++j == args.size()) {
this->SetError("missing required argument for \"VALIDATOR\"");
return false;
}
auto command = this->Makefile->GetState()->GetCommand(args[j]);
if (command == nullptr) {
this->SetError(cmStrCat(
"command specified for \"VALIDATOR\" is undefined: ", args[j], '.'));
return false;
}
// ensure a macro is not specified as validator
const auto& validatorName = args[j];
auto macros = cmExpandedList(this->Makefile->GetProperty("MACROS"));
if (std::find_if(macros.begin(), macros.end(),
[&validatorName](const std::string& item) {
return cmSystemTools::Strucmp(validatorName.c_str(),
item.c_str()) == 0;
}) != macros.end()) {
this->SetError(cmStrCat(
"command specified for \"VALIDATOR\" is not a function: ", args[j],
'.'));
return false;
}
this->ValidatorName = args[j];
} else if (this->CheckCommonArgument(args[j])) {
doing = DoingNone;
} else {
@@ -188,6 +216,36 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
return true;
}
bool cmFindBase::Validate(const std::string& path) const
{
if (this->ValidatorName.empty()) {
return true;
}
// The validator command will be executed in an isolated scope.
cmMakefile::ScopePushPop varScope(this->Makefile);
cmMakefile::PolicyPushPop polScope(this->Makefile);
static_cast<void>(varScope);
static_cast<void>(polScope);
auto resultName =
cmStrCat("CMAKE_"_s, cmSystemTools::UpperCase(this->FindCommandName),
"_VALIDATOR_STATUS"_s);
this->Makefile->AddDefinitionBool(resultName, true);
cmListFileFunction validator(
this->ValidatorName, 0, 0,
{ cmListFileArgument(resultName, cmListFileArgument::Unquoted, 0),
cmListFileArgument(path, cmListFileArgument::Quoted, 0) });
cmExecutionStatus status(*this->Makefile);
if (this->Makefile->ExecuteCommand(validator, status)) {
return this->Makefile->GetDefinition(resultName).IsOn();
}
return false;
}
void cmFindBase::ExpandPaths()
{
if (!this->NoDefaultPath) {

View File

@@ -31,6 +31,11 @@ public:
*/
virtual bool ParseArguments(std::vector<std::string> const& args);
/**
* To check validity of a found path using user's validator, if any
*/
bool Validate(const std::string& path) const;
protected:
friend class cmFindBaseDebugState;
void ExpandPaths();
@@ -63,6 +68,8 @@ protected:
bool Required = false;
std::string ValidatorName;
private:
// Add pieces of the search.
void FillPackageRootPath();

View File

@@ -192,6 +192,7 @@ struct cmFindLibraryHelper
// Context information.
cmMakefile* Makefile;
cmFindBase const* FindBase;
cmGlobalGenerator* GG;
// List of valid prefixes and suffixes.
@@ -239,6 +240,11 @@ struct cmFindLibraryHelper
bool CheckDirectory(std::string const& path);
bool CheckDirectoryForName(std::string const& path, Name& name);
bool Validate(const std::string& path) const
{
return this->FindBase->Validate(path);
}
cmFindBaseDebugState DebugSearches;
void DebugLibraryFailed(std::string const& name, std::string const& path)
@@ -291,6 +297,7 @@ std::string const& get_suffixes(cmMakefile* mf)
cmFindLibraryHelper::cmFindLibraryHelper(std::string debugName, cmMakefile* mf,
cmFindBase const* base)
: Makefile(mf)
, FindBase(base)
, DebugMode(base->DebugModeEnabled())
, DebugSearches(std::move(debugName), base)
{
@@ -416,10 +423,13 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
if (!exists) {
this->DebugLibraryFailed(name.Raw, path);
} else {
this->DebugLibraryFound(name.Raw, path);
this->BestPath = cmSystemTools::CollapseFullPath(this->TestPath);
cmSystemTools::ConvertToUnixSlashes(this->BestPath);
return true;
auto testPath = cmSystemTools::CollapseFullPath(this->TestPath);
if (this->Validate(testPath)) {
this->DebugLibraryFound(name.Raw, path);
this->BestPath = testPath;
return true;
}
this->DebugLibraryFailed(name.Raw, path);
}
}
@@ -443,8 +453,11 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
this->TestPath = cmStrCat(path, origName);
// Make sure the path is readable and is not a directory.
if (cmSystemTools::FileExists(this->TestPath, true)) {
this->DebugLibraryFound(name.Raw, dir);
if (!this->Validate(cmSystemTools::CollapseFullPath(this->TestPath))) {
continue;
}
this->DebugLibraryFound(name.Raw, dir);
// This is a matching file. Check if it is better than the
// best name found so far. Earlier prefixes are preferred,
// followed by earlier suffixes. For OpenBSD, shared library
@@ -541,7 +554,10 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryNamesPerDir()
for (std::string const& n : this->Names) {
fwPath = cmStrCat(d, n, ".framework");
if (cmSystemTools::FileIsDirectory(fwPath)) {
return cmSystemTools::CollapseFullPath(fwPath);
auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
if (this->Validate(finalPath)) {
return finalPath;
}
}
}
}
@@ -558,7 +574,10 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryDirsPerName()
for (std::string const& d : this->SearchPaths) {
fwPath = cmStrCat(d, n, ".framework");
if (cmSystemTools::FileIsDirectory(fwPath)) {
return cmSystemTools::CollapseFullPath(fwPath);
auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
if (this->Validate(finalPath)) {
return finalPath;
}
}
}
}

View File

@@ -88,7 +88,8 @@ std::string cmFindPathCommand::FindHeaderInFramework(
if (!frameWorkName.empty()) {
std::string fpath = cmStrCat(dir, frameWorkName, ".framework");
std::string intPath = cmStrCat(fpath, "/Headers/", fileName);
if (cmSystemTools::FileExists(intPath)) {
if (cmSystemTools::FileExists(intPath) &&
this->Validate(this->IncludeFileInPath ? intPath : fpath)) {
debug.FoundAt(intPath);
if (this->IncludeFileInPath) {
return intPath;
@@ -124,7 +125,8 @@ std::string cmFindPathCommand::FindNormalHeader(cmFindBaseDebugState& debug)
for (std::string const& n : this->Names) {
for (std::string const& sp : this->SearchPaths) {
tryPath = cmStrCat(sp, n);
if (cmSystemTools::FileExists(tryPath)) {
if (cmSystemTools::FileExists(tryPath) &&
this->Validate(this->IncludeFileInPath ? tryPath : sp)) {
debug.FoundAt(tryPath);
if (this->IncludeFileInPath) {
return tryPath;

View File

@@ -27,6 +27,7 @@ struct cmFindProgramHelper
cmFindBase const* base)
: DebugSearches(std::move(debugName), base)
, Makefile(makefile)
, FindBase(base)
, PolicyCMP0109(makefile->GetPolicyStatus(cmPolicies::CMP0109))
{
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
@@ -56,6 +57,7 @@ struct cmFindProgramHelper
// Debug state
cmFindBaseDebugState DebugSearches;
cmMakefile* Makefile;
cmFindBase const* FindBase;
cmPolicies::PolicyStatus PolicyCMP0109;
@@ -94,7 +96,7 @@ struct cmFindProgramHelper
this->TestNameExt = cmStrCat(name, ext);
this->TestPath = cmSystemTools::CollapseFullPath(
this->TestNameExt, path);
bool exists = this->FileIsExecutable(this->TestPath);
bool exists = this->FileIsValid(this->TestPath);
exists ? this->DebugSearches.FoundAt(this->TestPath)
: this->DebugSearches.FailedAt(this->TestPath);
if (exists) {
@@ -104,12 +106,12 @@ struct cmFindProgramHelper
return false;
});
}
bool FileIsExecutable(std::string const& file) const
bool FileIsValid(std::string const& file) const
{
#ifdef _WIN32
if (!this->FileIsExecutableCMP0109(file)) {
return false;
}
#ifdef _WIN32
// Pretend the Windows "python" app installer alias does not exist.
if (cmSystemTools::LowerCase(file).find("/windowsapps/python") !=
std::string::npos) {
@@ -119,10 +121,8 @@ struct cmFindProgramHelper
return false;
}
}
return true;
#else
return this->FileIsExecutableCMP0109(file);
#endif
return this->FindBase->Validate(file);
}
bool FileIsExecutableCMP0109(std::string const& file) const
{

View File

@@ -7,6 +7,10 @@ run_cmake(Required)
run_cmake(NO_CACHE)
run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view)
run_cmake(VALIDATOR-no-function)
run_cmake(VALIDATOR-undefined-function)
run_cmake(VALIDATOR-specify-macro)
run_cmake(VALIDATOR)
run_cmake_with_options(FromPATHEnvDebugVar --debug-find-var=PrefixInPATH_File)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,4 @@
CMake Error at VALIDATOR-no-function.cmake:[0-9]+ \(find_file\):
find_file missing required argument for "VALIDATOR"
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,2 @@
find_file(result NAMES input.txt VALIDATOR)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,4 @@
CMake Error at VALIDATOR-specify-macro.cmake:[0-9]+ \(find_file\):
find_file command specified for "VALIDATOR" is not a function: check.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,5 @@
macro(CHECK result path)
endmacro()
find_file(result NAMES input.txt VALIDATOR check)

View File

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

View File

@@ -0,0 +1,3 @@
-- FILE='[^']+/Tests/RunCMake/find_file/include/PrefixInPATH.h'
-- FILE='[^']+/Tests/RunCMake/find_file/include/PrefixInPATH.h'
-- FILE='FILE-NOTFOUND'

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,4 @@
CMake Error at VALIDATOR-undefined-function.cmake:[0-9]+ \(find_file\):
find_file command specified for "VALIDATOR" is undefined: undefined.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,2 @@
find_file(result NAMES input.txt VALIDATOR undefined)

View File

@@ -0,0 +1,39 @@
function(CHECK_DEFAULT result filename)
message("CHECK='${filename}'")
endfunction()
function(CHECK_OK result filename)
message("CHECK='${filename}'")
set(${result} TRUE PARENT_SCOPE)
endfunction()
function(CHECK_KO result filename)
message("CHECK='${filename}'")
set(${result} FALSE PARENT_SCOPE)
endfunction()
find_file(FILE
NAMES PrefixInPATH.h
HINTS ${CMAKE_CURRENT_SOURCE_DIR}/include
VALIDATOR check_default
)
message(STATUS "FILE='${FILE}'")
unset(FILE CACHE)
find_file(FILE
NAMES PrefixInPATH.h
HINTS ${CMAKE_CURRENT_SOURCE_DIR}/include
VALIDATOR check_ok
)
message(STATUS "FILE='${FILE}'")
unset(FILE CACHE)
find_file(FILE
NAMES PrefixInPATH.h
HINTS ${CMAKE_CURRENT_SOURCE_DIR}/include
VALIDATOR check_ko
)
message(STATUS "FILE='${FILE}'")
unset(FILE CACHE)

View File

@@ -13,6 +13,10 @@ run_cmake(Required)
run_cmake(NO_CACHE)
run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view)
run_cmake(VALIDATOR-no-function)
run_cmake(VALIDATOR-undefined-function)
run_cmake(VALIDATOR-specify-macro)
run_cmake(VALIDATOR)
run_cmake_script(FromScriptMode "-DTEMP_DIR=${RunCMake_BINARY_DIR}/FromScriptMode-temp")

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,4 @@
CMake Error at VALIDATOR-no-function.cmake:[0-9]+ \(find_library\):
find_library missing required argument for "VALIDATOR"
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,2 @@
find_library(result NAMES input.txt VALIDATOR)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,4 @@
CMake Error at VALIDATOR-specify-macro.cmake:[0-9]+ \(find_library\):
find_library command specified for "VALIDATOR" is not a function: check.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,5 @@
macro(CHECK result path)
endmacro()
find_library(result NAMES input.txt VALIDATOR check)

View File

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

View File

@@ -0,0 +1,3 @@
-- LIB='[^']+/Tests/RunCMake/find_library/lib/libPrefixInPATH.a'
-- LIB='[^']+/Tests/RunCMake/find_library/lib/libPrefixInPATH.a'
-- LIB='LIB-NOTFOUND'

View File

@@ -0,0 +1,4 @@
CMake Error at VALIDATOR-undefined-function.cmake:[0-9]+ \(find_library\):
find_library command specified for "VALIDATOR" is undefined: undefined.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,2 @@
find_library(result NAMES input.txt VALIDATOR undefined)

View File

@@ -0,0 +1,41 @@
list(APPEND CMAKE_FIND_LIBRARY_PREFIXES lib)
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .a)
function(CHECK_DEFAULT result filename)
message("CHECK='${filename}'")
endfunction()
function(CHECK_OK result filename)
message("CHECK='${filename}'")
set(${result} TRUE PARENT_SCOPE)
endfunction()
function(CHECK_KO result filename)
message("CHECK='${filename}'")
set(${result} FALSE PARENT_SCOPE)
endfunction()
find_library(LIB
NAMES PrefixInPATH
HINTS ${CMAKE_CURRENT_SOURCE_DIR}/lib
VALIDATOR check_default
)
message(STATUS "LIB='${LIB}'")
unset(LIB CACHE)
find_library(LIB
NAMES PrefixInPATH
HINTS ${CMAKE_CURRENT_SOURCE_DIR}/lib
VALIDATOR check_ok
)
message(STATUS "LIB='${LIB}'")
unset(LIB CACHE)
find_library(LIB
NAMES PrefixInPATH
HINTS ${CMAKE_CURRENT_SOURCE_DIR}/lib
VALIDATOR check_ko
)
message(STATUS "LIB='${LIB}'")
unset(LIB CACHE)

View File

@@ -7,6 +7,10 @@ run_cmake(Required)
run_cmake(NO_CACHE)
run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view)
run_cmake(VALIDATOR-no-function)
run_cmake(VALIDATOR-undefined-function)
run_cmake(VALIDATOR-specify-macro)
run_cmake(VALIDATOR)
if(APPLE)
run_cmake(FrameworksWithSubdirs)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,4 @@
CMake Error at VALIDATOR-no-function.cmake:[0-9]+ \(find_path\):
find_path missing required argument for "VALIDATOR"
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,2 @@
find_path(result NAMES input.txt VALIDATOR)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,4 @@
CMake Error at VALIDATOR-specify-macro.cmake:[0-9]+ \(find_path\):
find_path command specified for "VALIDATOR" is not a function: check.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,5 @@
macro(CHECK result path)
endmacro()
find_path(result NAMES input.txt VALIDATOR check)

View File

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

View File

@@ -0,0 +1,3 @@
-- DIR='[^']+/Tests/RunCMake/find_path/include'
-- DIR='[^']+/Tests/RunCMake/find_path/include'
-- DIR='DIR-NOTFOUND'

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,4 @@
CMake Error at VALIDATOR-undefined-function.cmake:[0-9]+ \(find_path\):
find_path command specified for "VALIDATOR" is undefined: undefined.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,2 @@
find_path(result NAMES input.txt VALIDATOR undefined)

View File

@@ -0,0 +1,39 @@
function(CHECK_DEFAULT result filename)
message("CHECK='${filename}'")
endfunction()
function(CHECK_OK result filename)
message("CHECK='${filename}'")
set(${result} TRUE PARENT_SCOPE)
endfunction()
function(CHECK_KO result filename)
message("CHECK='${filename}'")
set(${result} FALSE PARENT_SCOPE)
endfunction()
find_path(DIR
NAMES PrefixInPATH.h
HINTS ${CMAKE_CURRENT_SOURCE_DIR}/include
VALIDATOR check_default
)
message(STATUS "DIR='${DIR}'")
unset(DIR CACHE)
find_path(DIR
NAMES PrefixInPATH.h
HINTS ${CMAKE_CURRENT_SOURCE_DIR}/include
VALIDATOR check_ok
)
message(STATUS "DIR='${DIR}'")
unset(DIR CACHE)
find_path(DIR
NAMES PrefixInPATH.h
HINTS ${CMAKE_CURRENT_SOURCE_DIR}/include
VALIDATOR check_ko
)
message(STATUS "DIR='${DIR}'")
unset(DIR CACHE)

View File

@@ -9,6 +9,10 @@ run_cmake(NO_CACHE)
run_cmake(IgnorePrefixPath)
run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view)
run_cmake(VALIDATOR-no-function)
run_cmake(VALIDATOR-undefined-function)
run_cmake(VALIDATOR-specify-macro)
run_cmake(VALIDATOR)
if(CMAKE_SYSTEM_NAME MATCHES "^(Windows|CYGWIN|MSYS)$")
run_cmake(WindowsCom)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,4 @@
CMake Error at VALIDATOR-no-function.cmake:[0-9]+ \(find_program\):
find_program missing required argument for "VALIDATOR"
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,2 @@
find_program(result NAMES input.txt VALIDATOR)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,4 @@
CMake Error at VALIDATOR-specify-macro.cmake:[0-9]+ \(find_program\):
find_program command specified for "VALIDATOR" is not a function: check.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,5 @@
macro(CHECK result path)
endmacro()
find_program(result NAMES input.txt VALIDATOR check)

View File

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

View File

@@ -0,0 +1,3 @@
-- PROG='[^']+/Tests/RunCMake/find_program/A/testA'
-- PROG='[^']+/Tests/RunCMake/find_program/A/testA'
-- PROG='PROG-NOTFOUND'

View File

@@ -0,0 +1,4 @@
CMake Error at VALIDATOR-undefined-function.cmake:[0-9]+ \(find_program\):
find_program command specified for "VALIDATOR" is undefined: undefined.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,2 @@
find_program(result NAMES input.txt VALIDATOR undefined)

View File

@@ -0,0 +1,39 @@
function(CHECK_DEFAULT result filename)
message("CHECK='${filename}'")
endfunction()
function(CHECK_OK result filename)
message("CHECK='${filename}'")
set(${result} TRUE PARENT_SCOPE)
endfunction()
function(CHECK_KO result filename)
message("CHECK='${filename}'")
set(${result} FALSE PARENT_SCOPE)
endfunction()
find_program(PROG
NAMES testA
HINTS ${CMAKE_CURRENT_SOURCE_DIR}/A
VALIDATOR check_default
)
message(STATUS "PROG='${PROG}'")
unset(PROG CACHE)
find_program(PROG
NAMES testA
HINTS ${CMAKE_CURRENT_SOURCE_DIR}/A
VALIDATOR check_ok
)
message(STATUS "PROG='${PROG}'")
unset(PROG CACHE)
find_program(PROG
NAMES testA
HINTS ${CMAKE_CURRENT_SOURCE_DIR}/A
VALIDATOR check_ko
)
message(STATUS "PROG='${PROG}'")
unset(PROG CACHE)