Просмотр исходного кода

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.
Brad King 10 лет назад
Родитель
Сommit
8ea7611bc3

+ 6 - 1
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.

+ 6 - 0
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.

+ 41 - 0
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 &)
@@ -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;

+ 3 - 0
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);
 

+ 1 - 0
Tests/RunCMake/find_program/NamesPerDir-stdout.txt

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

+ 6 - 0
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}'")

+ 1 - 0
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)