diff options
author | MyungJoo Ham <myungjoo.ham@samsung.com> | 2017-10-11 15:16:57 +0900 |
---|---|---|
committer | MyungJoo Ham <myungjoo.ham@samsung.com> | 2017-10-11 15:16:57 +0900 |
commit | 915c76ded744c0f5f151402b9fa69f3fd8452573 (patch) | |
tree | ca6a387466543248890f346847acaa8343989b22 /Source/cmFindProgramCommand.cxx | |
parent | 317dbdb79761ef65e45c7358cfc7571c6afa54ad (diff) | |
download | cmake-915c76ded744c0f5f151402b9fa69f3fd8452573.tar.gz cmake-915c76ded744c0f5f151402b9fa69f3fd8452573.tar.bz2 cmake-915c76ded744c0f5f151402b9fa69f3fd8452573.zip |
Imported Upstream version 3.9.4upstream/3.9.4
Diffstat (limited to 'Source/cmFindProgramCommand.cxx')
-rw-r--r-- | Source/cmFindProgramCommand.cxx | 291 |
1 files changed, 181 insertions, 110 deletions
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx index 909b333ff..9327c1805 100644 --- a/Source/cmFindProgramCommand.cxx +++ b/Source/cmFindProgramCommand.cxx @@ -1,145 +1,221 @@ -/*============================================================================ - CMake - Cross Platform Makefile Generator - Copyright 2000-2009 Kitware, Inc., Insight Software Consortium +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmFindProgramCommand.h" - Distributed under the OSI-approved BSD License (the "License"); - see accompanying file Copyright.txt for details. +#include "cmMakefile.h" +#include "cmStateTypes.h" +#include "cmSystemTools.h" - This software is distributed WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the License for more information. -============================================================================*/ -#include "cmFindProgramCommand.h" -#include "cmCacheManager.h" -#include <stdlib.h> +class cmExecutionStatus; #if defined(__APPLE__) #include <CoreFoundation/CoreFoundation.h> #endif -void cmFindProgramCommand::GenerateDocumentation() +struct cmFindProgramHelper { - this->cmFindBase::GenerateDocumentation(); - cmSystemTools::ReplaceString(this->GenericDocumentation, - "FIND_XXX", "find_program"); - cmSystemTools::ReplaceString(this->GenericDocumentation, - "CMAKE_XXX_PATH", "CMAKE_PROGRAM_PATH"); - cmSystemTools::ReplaceString(this->GenericDocumentation, - "CMAKE_XXX_MAC_PATH", - "CMAKE_APPBUNDLE_PATH"); - cmSystemTools::ReplaceString(this->GenericDocumentation, - "CMAKE_SYSTEM_XXX_MAC_PATH", - "CMAKE_SYSTEM_APPBUNDLE_PATH"); - cmSystemTools::ReplaceString(this->GenericDocumentation, - "XXX_SYSTEM", ""); - cmSystemTools::ReplaceString(this->GenericDocumentation, - "CMAKE_SYSTEM_XXX_PATH", - "CMAKE_SYSTEM_PROGRAM_PATH"); - cmSystemTools::ReplaceString(this->GenericDocumentation, - "SEARCH_XXX_DESC", "program"); - cmSystemTools::ReplaceString(this->GenericDocumentation, - "SEARCH_XXX", "program"); - cmSystemTools::ReplaceString(this->GenericDocumentation, - "XXX_SUBDIR", "[s]bin"); - cmSystemTools::ReplaceString(this->GenericDocumentation, - "XXX_EXTRA_PREFIX_ENTRY", ""); - cmSystemTools::ReplaceString(this->GenericDocumentation, - "CMAKE_FIND_ROOT_PATH_MODE_XXX", - "CMAKE_FIND_ROOT_PATH_MODE_PROGRAM"); + 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::cmFindProgramCommand() +{ + this->NamesPerDirAllowed = true; } // cmFindProgramCommand -bool cmFindProgramCommand -::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &) +bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn, + cmExecutionStatus&) { this->VariableDocumentation = "Path to a program."; this->CMakePathName = "PROGRAM"; // call cmFindBase::ParseArguments - if(!this->ParseArguments(argsIn)) - { + if (!this->ParseArguments(argsIn)) { return false; - } - if(this->AlreadyInCache) - { + } + if (this->AlreadyInCache) { // If the user specifies the entry on the command line without a // type we should add the type and docstring but keep the original // value. - if(this->AlreadyInCacheWithoutMetaInfo) - { - this->Makefile->AddCacheDefinition(this->VariableName.c_str(), "", + if (this->AlreadyInCacheWithoutMetaInfo) { + this->Makefile->AddCacheDefinition(this->VariableName, "", this->VariableDocumentation.c_str(), - cmCacheManager::FILEPATH); - } - return true; + cmStateEnums::FILEPATH); } + return true; + } - std::string result = FindProgram(this->Names); - if(result != "") - { + std::string result = FindProgram(); + if (result != "") { // Save the value in the cache - this->Makefile->AddCacheDefinition(this->VariableName.c_str(), - result.c_str(), + this->Makefile->AddCacheDefinition(this->VariableName, result.c_str(), this->VariableDocumentation.c_str(), - cmCacheManager::FILEPATH); + cmStateEnums::FILEPATH); return true; - } - this->Makefile->AddCacheDefinition(this->VariableName.c_str(), - (this->VariableName + "-NOTFOUND").c_str(), - this->VariableDocumentation.c_str(), - cmCacheManager::FILEPATH); + } + this->Makefile->AddCacheDefinition( + this->VariableName, (this->VariableName + "-NOTFOUND").c_str(), + this->VariableDocumentation.c_str(), cmStateEnums::FILEPATH); return true; } -std::string cmFindProgramCommand::FindProgram(std::vector<std::string> names) +std::string cmFindProgramCommand::FindProgram() { - std::string program = ""; + std::string program; + + if (this->SearchAppBundleFirst || this->SearchAppBundleOnly) { + program = FindAppBundle(); + } + if (program.empty() && !this->SearchAppBundleOnly) { + program = this->FindNormalProgram(); + } + + if (program.empty() && this->SearchAppBundleLast) { + program = this->FindAppBundle(); + } + return program; +} + +std::string cmFindProgramCommand::FindNormalProgram() +{ + if (this->NamesPerDir) { + return this->FindNormalProgramNamesPerDir(); + } + 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); + } + + // Check for the names themselves (e.g. absolute paths). + if (helper.CheckDirectory(std::string())) { + return helper.BestPath; + } - if(this->SearchAppBundleFirst || this->SearchAppBundleOnly) - { - program = FindAppBundle(names); + // 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; } - if(program.empty() && !this->SearchAppBundleOnly) - { - program = cmSystemTools::FindProgram(names, this->SearchPaths, true); + } + // 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(); + ni != this->Names.end(); ++ni) { + // Switch to searching for this name. + helper.SetName(*ni); + + // Check for the name by itself (e.g. an absolute path). + if (helper.CheckDirectory(std::string())) { + return helper.BestPath; } - if(program.empty() && this->SearchAppBundleLast) - { - program = this->FindAppBundle(names); + // 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; + } } - return program; + } + // Couldn't find the program. + return ""; } -std::string cmFindProgramCommand -::FindAppBundle(std::vector<std::string> names) +std::string cmFindProgramCommand::FindAppBundle() { - for(std::vector<std::string>::const_iterator name = names.begin(); - name != names.end() ; ++name) - { + for (std::vector<std::string>::const_iterator name = this->Names.begin(); + name != this->Names.end(); ++name) { std::string appName = *name + std::string(".app"); - std::string appPath = cmSystemTools::FindDirectory(appName.c_str(), - this->SearchPaths, - true); + std::string appPath = + cmSystemTools::FindDirectory(appName, this->SearchPaths, true); - if ( !appPath.empty() ) - { + if (!appPath.empty()) { std::string executable = GetBundleExecutable(appPath); - if (!executable.empty()) - { - return cmSystemTools::CollapseFullPath(executable.c_str()); - } + if (!executable.empty()) { + return cmSystemTools::CollapseFullPath(executable); } } + } // Couldn't find app bundle return ""; } -std::string cmFindProgramCommand::GetBundleExecutable(std::string bundlePath) +std::string cmFindProgramCommand::GetBundleExecutable( + std::string const& bundlePath) { - std::string executable = ""; + std::string executable; (void)bundlePath; #if defined(__APPLE__) // Started with an example on developer.apple.com about finding bundles @@ -147,45 +223,40 @@ std::string cmFindProgramCommand::GetBundleExecutable(std::string bundlePath) // Get a CFString of the app bundle path // XXX - Is it safe to assume everything is in UTF8? - CFStringRef bundlePathCFS = - CFStringCreateWithCString(kCFAllocatorDefault , - bundlePath.c_str(), kCFStringEncodingUTF8 ); + CFStringRef bundlePathCFS = CFStringCreateWithCString( + kCFAllocatorDefault, bundlePath.c_str(), kCFStringEncodingUTF8); // Make a CFURLRef from the CFString representation of the // bundle’s path. - CFURLRef bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, - bundlePathCFS, - kCFURLPOSIXPathStyle, - true ); + CFURLRef bundleURL = CFURLCreateWithFileSystemPath( + kCFAllocatorDefault, bundlePathCFS, kCFURLPOSIXPathStyle, true); // Make a bundle instance using the URLRef. - CFBundleRef appBundle = CFBundleCreate( kCFAllocatorDefault, bundleURL ); + CFBundleRef appBundle = CFBundleCreate(kCFAllocatorDefault, bundleURL); // returned executableURL is relative to <appbundle>/Contents/MacOS/ CFURLRef executableURL = CFBundleCopyExecutableURL(appBundle); - if (executableURL != NULL) - { + if (executableURL != NULL) { const int MAX_OSX_PATH_SIZE = 1024; char buffer[MAX_OSX_PATH_SIZE]; // Convert the CFString to a C string - CFStringGetCString( CFURLGetString(executableURL), buffer, - MAX_OSX_PATH_SIZE, kCFStringEncodingUTF8 ); + CFStringGetCString(CFURLGetString(executableURL), buffer, + MAX_OSX_PATH_SIZE, kCFStringEncodingUTF8); // And finally to a c++ string executable = bundlePath + "/Contents/MacOS/" + std::string(buffer); // Only release CFURLRef if it's not null - CFRelease( executableURL ); - } + CFRelease(executableURL); + } // Any CF objects returned from functions with "create" or // "copy" in their names must be released by us! - CFRelease( bundlePathCFS ); - CFRelease( bundleURL ); - CFRelease( appBundle ); + CFRelease(bundlePathCFS); + CFRelease(bundleURL); + CFRelease(appBundle); #endif return executable; } - |