Introduce "generator expressions" to add_test()
[cmake.git] / Source / CPack / cmCPackOSXX11Generator.cxx
blobf4b849a0685127c129c1e8e96d0bb521c633e194
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmCPackOSXX11Generator.cxx,v $
5 Language: C++
6 Date: $Date: 2009-01-21 16:54:30 $
7 Version: $Revision: 1.6 $
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 "cmCPackOSXX11Generator.h"
19 #include "cmake.h"
20 #include "cmGlobalGenerator.h"
21 #include "cmLocalGenerator.h"
22 #include "cmSystemTools.h"
23 #include "cmMakefile.h"
24 #include "cmGeneratedFileStream.h"
25 #include "cmCPackLog.h"
27 #include <cmsys/SystemTools.hxx>
28 #include <cmsys/Glob.hxx>
30 //----------------------------------------------------------------------
31 cmCPackOSXX11Generator::cmCPackOSXX11Generator()
35 //----------------------------------------------------------------------
36 cmCPackOSXX11Generator::~cmCPackOSXX11Generator()
40 //----------------------------------------------------------------------
41 int cmCPackOSXX11Generator::CompressFiles(const char* outFileName,
42 const char* toplevel,
43 const std::vector<std::string>& files)
45 (void) files; // TODO: Fix api to not need files.
46 (void) toplevel; // TODO: Use toplevel
48 const char* cpackPackageExecutables
49 = this->GetOption("CPACK_PACKAGE_EXECUTABLES");
50 if ( cpackPackageExecutables )
52 cmCPackLogger(cmCPackLog::LOG_DEBUG, "The cpackPackageExecutables: "
53 << cpackPackageExecutables << "." << std::endl);
54 cmOStringStream str;
55 cmOStringStream deleteStr;
56 std::vector<std::string> cpackPackageExecutablesVector;
57 cmSystemTools::ExpandListArgument(cpackPackageExecutables,
58 cpackPackageExecutablesVector);
59 if ( cpackPackageExecutablesVector.size() % 2 != 0 )
61 cmCPackLogger(cmCPackLog::LOG_ERROR,
62 "CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and "
63 "<icon name>." << std::endl);
64 return 0;
66 std::vector<std::string>::iterator it;
67 for ( it = cpackPackageExecutablesVector.begin();
68 it != cpackPackageExecutablesVector.end();
69 ++it )
71 std::string cpackExecutableName = *it;
72 ++ it;
73 this->SetOptionIfNotSet("CPACK_EXECUTABLE_NAME",
74 cpackExecutableName.c_str());
78 // Disk image directories
79 std::string diskImageDirectory = toplevel;
80 std::string diskImageBackgroundImageDir
81 = diskImageDirectory + "/.background";
84 // App bundle directories
85 std::string packageDirFileName = toplevel;
86 packageDirFileName += "/";
87 packageDirFileName += this->GetOption("CPACK_PACKAGE_FILE_NAME");
88 packageDirFileName += ".app";
89 std::string contentsDirectory = packageDirFileName + "/Contents";
90 std::string resourcesDirectory = contentsDirectory + "/Resources";
91 std::string appDirectory = contentsDirectory + "/MacOS";
92 std::string scriptDirectory = resourcesDirectory + "/Scripts";
93 std::string resourceFileName = this->GetOption("CPACK_PACKAGE_FILE_NAME");
94 resourceFileName += ".rsrc";
96 const char* dir = resourcesDirectory.c_str();
97 const char* appdir = appDirectory.c_str();
98 const char* scrDir = scriptDirectory.c_str();
99 const char* contDir = contentsDirectory.c_str();
100 const char* rsrcFile = resourceFileName.c_str();
101 const char* iconFile = this->GetOption("CPACK_PACKAGE_ICON");
102 if ( iconFile )
104 std::string iconFileName = cmsys::SystemTools::GetFilenameName(
105 iconFile);
106 if ( !cmSystemTools::FileExists(iconFile) )
108 cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find icon file: "
109 << iconFile << ". Please check CPACK_PACKAGE_ICON setting."
110 << std::endl);
111 return 0;
113 std::string destFileName = resourcesDirectory + "/" + iconFileName;
114 this->ConfigureFile(iconFile, destFileName.c_str(), true);
115 this->SetOptionIfNotSet("CPACK_APPLE_GUI_ICON", iconFileName.c_str());
118 std::string applicationsLinkName = diskImageDirectory + "/Applications";
119 cmSystemTools::CreateSymlink("/Applications", applicationsLinkName.c_str());
121 if (
122 !this->CopyResourcePlistFile("VolumeIcon.icns",
123 diskImageDirectory.c_str(),
124 ".VolumeIcon.icns", true ) ||
125 !this->CopyResourcePlistFile("DS_Store", diskImageDirectory.c_str(),
126 ".DS_Store", true ) ||
127 !this->CopyResourcePlistFile("background.png",
128 diskImageBackgroundImageDir.c_str(), "background.png", true ) ||
129 !this->CopyResourcePlistFile("RuntimeScript", dir) ||
130 !this->CopyResourcePlistFile("OSXX11.Info.plist", contDir,
131 "Info.plist" ) ||
132 !this->CopyResourcePlistFile("OSXX11.main.scpt", scrDir,
133 "main.scpt", true ) ||
134 !this->CopyResourcePlistFile("OSXScriptLauncher.rsrc", dir,
135 rsrcFile, true) ||
136 !this->CopyResourcePlistFile("OSXScriptLauncher", appdir,
137 this->GetOption("CPACK_PACKAGE_FILE_NAME"), true)
140 cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying the resource files"
141 << std::endl);
142 return 0;
145 std::string output;
146 std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
147 tmpFile += "/hdiutilOutput.log";
148 cmOStringStream dmgCmd;
149 dmgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE")
150 << "\" create -ov -format UDZO -srcfolder \""
151 << diskImageDirectory.c_str()
152 << "\" \"" << outFileName << "\"";
153 int retVal = 1;
154 cmCPackLogger(cmCPackLog::LOG_VERBOSE,
155 "Compress disk image using command: "
156 << dmgCmd.str().c_str() << std::endl);
157 bool res = cmSystemTools::RunSingleCommand(dmgCmd.str().c_str(), &output,
158 &retVal, 0, this->GeneratorVerbose, 0);
159 if ( !res || retVal )
161 cmGeneratedFileStream ofs(tmpFile.c_str());
162 ofs << "# Run command: " << dmgCmd.str().c_str() << std::endl
163 << "# Output:" << std::endl
164 << output.c_str() << std::endl;
165 cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running hdiutil command: "
166 << dmgCmd.str().c_str() << std::endl
167 << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
168 return 0;
171 return 1;
174 //----------------------------------------------------------------------
175 int cmCPackOSXX11Generator::InitializeInternal()
177 cmCPackLogger(cmCPackLog::LOG_DEBUG,
178 "cmCPackOSXX11Generator::Initialize()" << std::endl);
179 std::vector<std::string> path;
180 std::string pkgPath = cmSystemTools::FindProgram("hdiutil", path, false);
181 if ( pkgPath.empty() )
183 cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find hdiutil compiler"
184 << std::endl);
185 return 0;
187 this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM_DISK_IMAGE",
188 pkgPath.c_str());
190 return this->Superclass::InitializeInternal();
193 //----------------------------------------------------------------------
195 bool cmCPackOSXX11Generator::CopyCreateResourceFile(const char* name)
197 std::string uname = cmSystemTools::UpperCase(name);
198 std::string cpackVar = "CPACK_RESOURCE_FILE_" + uname;
199 const char* inFileName = this->GetOption(cpackVar.c_str());
200 if ( !inFileName )
202 cmCPackLogger(cmCPackLog::LOG_ERROR, "CPack option: " << cpackVar.c_str()
203 << " not specified. It should point to "
204 << (name ? name : "(NULL)")
205 << ".rtf, " << name
206 << ".html, or " << name << ".txt file" << std::endl);
207 return false;
209 if ( !cmSystemTools::FileExists(inFileName) )
211 cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find "
212 << (name ? name : "(NULL)")
213 << " resource file: " << inFileName << std::endl);
214 return false;
216 std::string ext = cmSystemTools::GetFilenameLastExtension(inFileName);
217 if ( ext != ".rtfd" && ext != ".rtf" && ext != ".html" && ext != ".txt" )
219 cmCPackLogger(cmCPackLog::LOG_ERROR, "Bad file extension specified: "
220 << ext << ". Currently only .rtfd, .rtf, .html, and .txt files allowed."
221 << std::endl);
222 return false;
225 std::string destFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
226 destFileName += "/Resources/";
227 destFileName += name + ext;
230 cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: "
231 << (inFileName ? inFileName : "(NULL)")
232 << " to " << destFileName.c_str() << std::endl);
233 this->ConfigureFile(inFileName, destFileName.c_str());
234 return true;
238 //----------------------------------------------------------------------
239 bool cmCPackOSXX11Generator::CopyResourcePlistFile(const char* name,
240 const char* dir, const char* outputFileName /* = 0 */,
241 bool copyOnly /* = false */)
243 std::string inFName = "CPack.";
244 inFName += name;
245 inFName += ".in";
246 std::string inFileName = this->FindTemplate(inFName.c_str());
247 if ( inFileName.empty() )
249 cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find input file: "
250 << inFName << std::endl);
251 return false;
254 if ( !outputFileName )
256 outputFileName = name;
259 std::string destFileName = dir;
260 destFileName += "/";
261 destFileName += outputFileName;
263 cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: "
264 << inFileName.c_str() << " to " << destFileName.c_str() << std::endl);
265 this->ConfigureFile(inFileName.c_str(), destFileName.c_str(), copyOnly);
266 return true;
269 //----------------------------------------------------------------------
270 const char* cmCPackOSXX11Generator::GetPackagingInstallPrefix()
272 this->InstallPrefix = "/";
273 this->InstallPrefix += this->GetOption("CPACK_PACKAGE_FILE_NAME");
274 this->InstallPrefix += ".app/Contents/Resources";
275 return this->InstallPrefix.c_str();