| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 | /*============================================================================  CMake - Cross Platform Makefile Generator  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium  Distributed under the OSI-approved BSD License (the "License");  see accompanying file Copyright.txt for details.  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>#if defined(__APPLE__)#include <CoreFoundation/CoreFoundation.h>#endifvoid cmFindProgramCommand::GenerateDocumentation(){  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,                               "CMAKE_FIND_ROOT_PATH_MODE_XXX",                               "CMAKE_FIND_ROOT_PATH_MODE_PROGRAM");}// cmFindProgramCommandbool 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))    {    return false;    }  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(), "",                                         this->VariableDocumentation.c_str(),                                         cmCacheManager::FILEPATH);      }    return true;    }  std::string result = FindProgram(this->Names);  if(result != "")    {    // Save the value in the cache    this->Makefile->AddCacheDefinition(this->VariableName.c_str(),                                       result.c_str(),                                       this->VariableDocumentation.c_str(),                                       cmCacheManager::FILEPATH);        return true;    }  this->Makefile->AddCacheDefinition(this->VariableName.c_str(),                                 (this->VariableName + "-NOTFOUND").c_str(),                                 this->VariableDocumentation.c_str(),                                 cmCacheManager::FILEPATH);  return true;}std::string cmFindProgramCommand::FindProgram(std::vector<std::string> names){  std::string program = "";  if(this->SearchAppBundleFirst || this->SearchAppBundleOnly)    {    program = FindAppBundle(names);    }  if(program.empty() && !this->SearchAppBundleOnly)    {    program = cmSystemTools::FindProgram(names, this->SearchPaths, true);    }  if(program.empty() && this->SearchAppBundleLast)    {    program = this->FindAppBundle(names);    }  return program;}std::string cmFindProgramCommand::FindAppBundle(std::vector<std::string> names){  for(std::vector<std::string>::const_iterator name = names.begin();      name != names.end() ; ++name)    {        std::string appName = *name + std::string(".app");    std::string appPath = cmSystemTools::FindDirectory(appName.c_str(),                                                        this->SearchPaths,                                                        true);    if ( !appPath.empty() )      {      std::string executable = GetBundleExecutable(appPath);      if (!executable.empty())         {        return cmSystemTools::CollapseFullPath(executable.c_str());        }      }     }   // Couldn't find app bundle  return "";}std::string cmFindProgramCommand::GetBundleExecutable(std::string bundlePath){  std::string executable = "";  (void)bundlePath;#if defined(__APPLE__)  // Started with an example on developer.apple.com about finding bundles   // and modified from that.    // 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 );    // Make a CFURLRef from the CFString representation of the  // bundle’s path.  CFURLRef bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,                                                      bundlePathCFS,                                                     kCFURLPOSIXPathStyle,                                                     true );    // Make a bundle instance using the URLRef.  CFBundleRef appBundle = CFBundleCreate( kCFAllocatorDefault, bundleURL );    // returned executableURL is relative to <appbundle>/Contents/MacOS/  CFURLRef executableURL = CFBundleCopyExecutableURL(appBundle);    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 );        // And finally to a c++ string    executable = bundlePath + "/Contents/MacOS/" + std::string(buffer);    }  // 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( executableURL );#endif  return executable;}
 |