diff options
author | Brad King <brad.king@kitware.com> | 2015-09-01 17:54:33 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2015-09-02 14:17:22 (GMT) |
commit | fc1990c93384d1d2122cd4e11398a8197b006504 (patch) | |
tree | f95835266920c36dafec7fa341e2656537ec98a3 /Source/cmFindProgramCommand.cxx | |
parent | fdbfc9f6777696bdba60feafb9bb9a2f3fe02828 (diff) | |
download | CMake-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.cxx | 97 |
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(); |