summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/command/find_program.rst7
-rw-r--r--Help/release/dev/find_program-NAMES_PER_DIR.rst6
-rw-r--r--Source/cmFindProgramCommand.cxx41
-rw-r--r--Source/cmFindProgramCommand.h3
-rw-r--r--Tests/RunCMake/find_program/NamesPerDir-stdout.txt1
-rw-r--r--Tests/RunCMake/find_program/NamesPerDir.cmake6
-rw-r--r--Tests/RunCMake/find_program/RunCMakeTest.cmake1
7 files changed, 64 insertions, 1 deletions
diff --git a/Help/command/find_program.rst b/Help/command/find_program.rst
index 2a5ce9a..d3430c0 100644
--- a/Help/command/find_program.rst
+++ b/Help/command/find_program.rst
@@ -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.
diff --git a/Help/release/dev/find_program-NAMES_PER_DIR.rst b/Help/release/dev/find_program-NAMES_PER_DIR.rst
new file mode 100644
index 0000000..04cd170
--- /dev/null
+++ b/Help/release/dev/find_program-NAMES_PER_DIR.rst
@@ -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.
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index c9bc56d..e64ed87 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -85,6 +85,11 @@ struct cmFindProgramHelper
}
};
+cmFindProgramCommand::cmFindProgramCommand()
+{
+ this->NamesPerDirAllowed = true;
+}
+
// cmFindProgramCommand
bool cmFindProgramCommand
::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &)
@@ -151,6 +156,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;
for (std::vector<std::string>::const_iterator ni = this->Names.begin();
diff --git a/Source/cmFindProgramCommand.h b/Source/cmFindProgramCommand.h
index df39b14..f88186b 100644
--- a/Source/cmFindProgramCommand.h
+++ b/Source/cmFindProgramCommand.h
@@ -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);
diff --git a/Tests/RunCMake/find_program/NamesPerDir-stdout.txt b/Tests/RunCMake/find_program/NamesPerDir-stdout.txt
new file mode 100644
index 0000000..964e259
--- /dev/null
+++ b/Tests/RunCMake/find_program/NamesPerDir-stdout.txt
@@ -0,0 +1 @@
+-- PROG='[^']*/Tests/RunCMake/find_program/A/testA'
diff --git a/Tests/RunCMake/find_program/NamesPerDir.cmake b/Tests/RunCMake/find_program/NamesPerDir.cmake
new file mode 100644
index 0000000..49ce49d
--- /dev/null
+++ b/Tests/RunCMake/find_program/NamesPerDir.cmake
@@ -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}'")
diff --git a/Tests/RunCMake/find_program/RunCMakeTest.cmake b/Tests/RunCMake/find_program/RunCMakeTest.cmake
index 1a99f0a..2adec11 100644
--- a/Tests/RunCMake/find_program/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_program/RunCMakeTest.cmake
@@ -1,6 +1,7 @@
include(RunCMake)
run_cmake(DirsPerName)
+run_cmake(NamesPerDir)
if(CMAKE_SYSTEM_NAME MATCHES "^(Windows|CYGWIN)$")
run_cmake(WindowsCom)