summaryrefslogtreecommitdiffstats
path: root/Source/cmFindProgramCommand.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2015-09-01 17:54:33 (GMT)
committerBrad King <brad.king@kitware.com>2015-09-02 14:17:22 (GMT)
commitfc1990c93384d1d2122cd4e11398a8197b006504 (patch)
treef95835266920c36dafec7fa341e2656537ec98a3 /Source/cmFindProgramCommand.cxx
parentfdbfc9f6777696bdba60feafb9bb9a2f3fe02828 (diff)
downloadCMake-fc1990c93384d1d2122cd4e11398a8197b006504.zip
CMake-fc1990c93384d1d2122cd4e11398a8197b006504.tar.gz
CMake-fc1990c93384d1d2122cd4e11398a8197b006504.tar.bz2
cmFindProgramCommand: Re-implement search using more flexible approach
Avoid using KWSys SystemTools::FindProgram because it does much more than we actually need for find_program and does not allow us to control the order of preference between directories and names. Create our own cmFindProgramHelper much like cmFindLibraryHelper but without all the find_library-specific parts.
Diffstat (limited to 'Source/cmFindProgramCommand.cxx')
-rw-r--r--Source/cmFindProgramCommand.cxx97
1 files changed, 96 insertions, 1 deletions
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index ef1c16b..c9bc56d 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -16,6 +16,75 @@
#include <CoreFoundation/CoreFoundation.h>
#endif
+//----------------------------------------------------------------------------
+struct cmFindProgramHelper
+{
+ cmFindProgramHelper()
+ {
+#if defined (_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
+ // Consider platform-specific extensions.
+ this->Extensions.push_back(".com");
+ this->Extensions.push_back(".exe");
+#endif
+ // Consider original name with no extensions.
+ this->Extensions.push_back("");
+ }
+
+ // List of valid extensions.
+ std::vector<std::string> Extensions;
+
+ // Keep track of the best program file found so far.
+ std::string BestPath;
+
+ // Current names under consideration.
+ std::vector<std::string> Names;
+
+ // Current full path under consideration.
+ std::string TestPath;
+
+ void AddName(std::string const& name)
+ {
+ this->Names.push_back(name);
+ }
+ void SetName(std::string const& name)
+ {
+ this->Names.clear();
+ this->AddName(name);
+ }
+ bool CheckDirectory(std::string const& path)
+ {
+ for (std::vector<std::string>::iterator i = this->Names.begin();
+ i != this->Names.end(); ++i)
+ {
+ if (this->CheckDirectoryForName(path, *i))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ bool CheckDirectoryForName(std::string const& path, std::string const& name)
+ {
+ for (std::vector<std::string>::iterator ext = this->Extensions.begin();
+ ext != this->Extensions.end(); ++ext)
+ {
+ this->TestPath = path;
+ this->TestPath += name;
+ if (!ext->empty() && cmSystemTools::StringEndsWith(name, ext->c_str()))
+ {
+ continue;
+ }
+ this->TestPath += *ext;
+ if (cmSystemTools::FileExists(this->TestPath, true))
+ {
+ this->BestPath = cmSystemTools::CollapseFullPath(this->TestPath);
+ return true;
+ }
+ }
+ return false;
+ }
+};
+
// cmFindProgramCommand
bool cmFindProgramCommand
::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &)
@@ -69,7 +138,7 @@ std::string cmFindProgramCommand::FindProgram()
}
if(program.empty() && !this->SearchAppBundleOnly)
{
- program = cmSystemTools::FindProgram(this->Names, this->SearchPaths, true);
+ program = this->FindNormalProgram();
}
if(program.empty() && this->SearchAppBundleLast)
@@ -79,6 +148,32 @@ std::string cmFindProgramCommand::FindProgram()
return program;
}
+//----------------------------------------------------------------------------
+std::string cmFindProgramCommand::FindNormalProgram()
+{
+ // Search the entire path for each name.
+ cmFindProgramHelper helper;
+ for (std::vector<std::string>::const_iterator ni = this->Names.begin();
+ ni != this->Names.end() ; ++ni)
+ {
+ // Switch to searching for this name.
+ helper.SetName(*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::FindAppBundle()
{
for(std::vector<std::string>::const_iterator name = this->Names.begin();