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