Initial commit.
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / cmFindProgramCommand.cxx
bloba7af2177ef96f0ed49d6a6d3b2df813ea1e07f6b
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmFindProgramCommand.cxx,v $
5 Language: C++
6 Date: $Date: 2008/01/23 15:27:59 $
7 Version: $Revision: 1.42 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmFindProgramCommand.h"
18 #include "cmCacheManager.h"
19 #include <stdlib.h>
21 #if defined(__APPLE__)
22 #include <CoreFoundation/CoreFoundation.h>
23 #endif
25 cmFindProgramCommand::cmFindProgramCommand()
27 cmSystemTools::ReplaceString(this->GenericDocumentation,
28 "FIND_XXX", "find_program");
29 cmSystemTools::ReplaceString(this->GenericDocumentation,
30 "CMAKE_XXX_PATH", "CMAKE_PROGRAM_PATH");
31 cmSystemTools::ReplaceString(this->GenericDocumentation,
32 "CMAKE_XXX_MAC_PATH",
33 "CMAKE_APPBUNDLE_PATH");
34 cmSystemTools::ReplaceString(this->GenericDocumentation,
35 "CMAKE_SYSTEM_XXX_MAC_PATH",
36 "CMAKE_SYSTEM_APPBUNDLE_PATH");
37 cmSystemTools::ReplaceString(this->GenericDocumentation,
38 "XXX_SYSTEM", "");
39 cmSystemTools::ReplaceString(this->GenericDocumentation,
40 "CMAKE_SYSTEM_XXX_PATH",
41 "CMAKE_SYSTEM_PROGRAM_PATH");
42 cmSystemTools::ReplaceString(this->GenericDocumentation,
43 "SEARCH_XXX_DESC", "program");
44 cmSystemTools::ReplaceString(this->GenericDocumentation,
45 "SEARCH_XXX", "program");
46 cmSystemTools::ReplaceString(this->GenericDocumentation,
47 "XXX_SUBDIR", "[s]bin");
48 cmSystemTools::ReplaceString(this->GenericDocumentation,
49 "CMAKE_FIND_ROOT_PATH_MODE_XXX",
50 "CMAKE_FIND_ROOT_PATH_MODE_PROGRAM");
53 // cmFindProgramCommand
54 bool cmFindProgramCommand
55 ::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &)
57 this->VariableDocumentation = "Path to a program.";
58 this->CMakePathName = "PROGRAM";
59 // call cmFindBase::ParseArguments
60 if(!this->ParseArguments(argsIn))
62 return false;
64 if(this->AlreadyInCache)
66 // If the user specifies the entry on the command line without a
67 // type we should add the type and docstring but keep the original
68 // value.
69 if(this->AlreadyInCacheWithoutMetaInfo)
71 this->Makefile->AddCacheDefinition(this->VariableName.c_str(), "",
72 this->VariableDocumentation.c_str(),
73 cmCacheManager::FILEPATH);
75 return true;
78 std::string result = FindProgram(this->Names);
79 if(result != "")
81 // Save the value in the cache
82 this->Makefile->AddCacheDefinition(this->VariableName.c_str(),
83 result.c_str(),
84 this->VariableDocumentation.c_str(),
85 cmCacheManager::FILEPATH);
87 return true;
89 this->Makefile->AddCacheDefinition(this->VariableName.c_str(),
90 (this->VariableName + "-NOTFOUND").c_str(),
91 this->VariableDocumentation.c_str(),
92 cmCacheManager::FILEPATH);
93 return true;
96 std::string cmFindProgramCommand::FindProgram(std::vector<std::string> names)
98 std::string program = "";
100 // First/last order taken care of in cmFindBase when the paths are setup.
101 if(this->SearchAppBundleFirst || this->SearchAppBundleLast)
103 program = FindAppBundle(names);
105 if(program.empty() && !this->SearchAppBundleOnly)
107 program = cmSystemTools::FindProgram(names, this->SearchPaths, true);
110 return program;
113 std::string cmFindProgramCommand
114 ::FindAppBundle(std::vector<std::string> names)
116 for(std::vector<std::string>::const_iterator name = names.begin();
117 name != names.end() ; ++name)
120 std::string appName = *name + std::string(".app");
121 std::string appPath = cmSystemTools::FindDirectory(appName.c_str(),
122 this->SearchPaths,
123 true);
125 if ( !appPath.empty() )
127 std::string executable = GetBundleExecutable(appPath);
128 if (!executable.empty())
130 return cmSystemTools::CollapseFullPath(executable.c_str());
135 // Couldn't find app bundle
136 return "";
139 std::string cmFindProgramCommand::GetBundleExecutable(std::string bundlePath)
141 std::string executable = "";
142 (void)bundlePath;
143 #if defined(__APPLE__)
144 // Started with an example on developer.apple.com about finding bundles
145 // and modified from that.
147 // Get a CFString of the app bundle path
148 // XXX - Is it safe to assume everything is in UTF8?
149 CFStringRef bundlePathCFS =
150 CFStringCreateWithCString(kCFAllocatorDefault ,
151 bundlePath.c_str(), kCFStringEncodingUTF8 );
153 // Make a CFURLRef from the CFString representation of the
154 // bundle’s path.
155 CFURLRef bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
156 bundlePathCFS,
157 kCFURLPOSIXPathStyle,
158 true );
160 // Make a bundle instance using the URLRef.
161 CFBundleRef appBundle = CFBundleCreate( kCFAllocatorDefault, bundleURL );
163 // returned executableURL is relative to <appbundle>/Contents/MacOS/
164 CFURLRef executableURL = CFBundleCopyExecutableURL(appBundle);
166 if (executableURL != NULL)
168 const int MAX_OSX_PATH_SIZE = 1024;
169 char buffer[MAX_OSX_PATH_SIZE];
171 // Convert the CFString to a C string
172 CFStringGetCString( CFURLGetString(executableURL), buffer,
173 MAX_OSX_PATH_SIZE, kCFStringEncodingUTF8 );
175 // And finally to a c++ string
176 executable = bundlePath + "/Contents/MacOS/" + std::string(buffer);
179 // Any CF objects returned from functions with "create" or
180 // "copy" in their names must be released by us!
181 CFRelease( bundlePathCFS );
182 CFRelease( bundleURL );
183 CFRelease( appBundle );
184 CFRelease( executableURL );
185 #endif
187 return executable;