find_program: Optionally consider all names in each directory

When more than one value is given to the NAMES option this command by
default will consider one name at a time and search every directory for
it.  Add a NAMES_PER_DIR option to tell this command to consider one
directory at a time and search for all names in it.
This commit is contained in:
Brad King 2015-09-01 16:25:57 -04:00
parent fc1990c933
commit 8ea7611bc3
7 changed files with 64 additions and 1 deletions

View File

@ -2,7 +2,7 @@ find_program
------------
.. |FIND_XXX| replace:: find_program
.. |NAMES| replace:: NAMES name1 [name2 ...]
.. |NAMES| replace:: NAMES name1 [name2 ...] [NAMES_PER_DIR]
.. |SEARCH_XXX| replace:: program
.. |SEARCH_XXX_DESC| replace:: program
.. |prefix_XXX_SUBDIR| replace:: ``<prefix>/[s]bin``
@ -26,3 +26,8 @@ find_program
:variable:`CMAKE_FIND_ROOT_PATH_MODE_PROGRAM`
.. include:: FIND_XXX.txt
When more than one value is given to the ``NAMES`` option this command by
default will consider one name at a time and search every directory
for it. The ``NAMES_PER_DIR`` option tells this command to consider one
directory at a time and search for all names in it.

View File

@ -0,0 +1,6 @@
find_program-NAMES_PER_DIR
--------------------------
* The :command:`find_program` command learned a ``NAMES_PER_DIR``
option to consdier all given ``NAMES`` in each directory before
moving on to the next directory.

View File

@ -85,6 +85,11 @@ struct cmFindProgramHelper
}
};
cmFindProgramCommand::cmFindProgramCommand()
{
this->NamesPerDirAllowed = true;
}
// cmFindProgramCommand
bool cmFindProgramCommand
::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &)
@ -150,6 +155,42 @@ std::string cmFindProgramCommand::FindProgram()
//----------------------------------------------------------------------------
std::string cmFindProgramCommand::FindNormalProgram()
{
if(this->NamesPerDir)
{
return this->FindNormalProgramNamesPerDir();
}
else
{
return this->FindNormalProgramDirsPerName();
}
}
//----------------------------------------------------------------------------
std::string cmFindProgramCommand::FindNormalProgramNamesPerDir()
{
// Search for all names in each directory.
cmFindProgramHelper helper;
for (std::vector<std::string>::const_iterator ni = this->Names.begin();
ni != this->Names.end() ; ++ni)
{
helper.AddName(*ni);
}
// Search every directory.
for (std::vector<std::string>::const_iterator
p = this->SearchPaths.begin(); p != this->SearchPaths.end(); ++p)
{
if(helper.CheckDirectory(*p))
{
return helper.BestPath;
}
}
// Couldn't find the program.
return "";
}
//----------------------------------------------------------------------------
std::string cmFindProgramCommand::FindNormalProgramDirsPerName()
{
// Search the entire path for each name.
cmFindProgramHelper helper;

View File

@ -25,6 +25,7 @@
class cmFindProgramCommand : public cmFindBase
{
public:
cmFindProgramCommand();
/**
* This is a virtual constructor for the command.
*/
@ -55,6 +56,8 @@ public:
private:
std::string FindProgram();
std::string FindNormalProgram();
std::string FindNormalProgramDirsPerName();
std::string FindNormalProgramNamesPerDir();
std::string FindAppBundle();
std::string GetBundleExecutable(std::string bundlePath);

View File

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

View File

@ -0,0 +1,6 @@
find_program(PROG
NAMES testB testA NAMES_PER_DIR
PATHS ${CMAKE_CURRENT_SOURCE_DIR}/A ${CMAKE_CURRENT_SOURCE_DIR}/B
NO_DEFAULT_PATH
)
message(STATUS "PROG='${PROG}'")

View File

@ -1,6 +1,7 @@
include(RunCMake)
run_cmake(DirsPerName)
run_cmake(NamesPerDir)
if(CMAKE_SYSTEM_NAME MATCHES "^(Windows|CYGWIN)$")
run_cmake(WindowsCom)