1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmCPackOSXX11Generator.cxx,v $
6 Date: $Date: 2007/10/31 12:50:17 $
7 Version: $Revision: 1.5 $
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"
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
,
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
);
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
);
66 std::vector
<std::string
>::iterator it
;
67 for ( it
= cpackPackageExecutablesVector
.begin();
68 it
!= cpackPackageExecutablesVector
.end();
71 std::string cpackExecutableName
= *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";
93 const char* dir
= resourcesDirectory
.c_str();
94 const char* appdir
= appDirectory
.c_str();
95 const char* contDir
= contentsDirectory
.c_str();
96 const char* iconFile
= this->GetOption("CPACK_PACKAGE_ICON");
99 std::string iconFileName
= cmsys::SystemTools::GetFilenameName(
101 if ( !cmSystemTools::FileExists(iconFile
) )
103 cmCPackLogger(cmCPackLog::LOG_ERROR
, "Cannot find icon file: "
104 << iconFile
<< ". Please check CPACK_PACKAGE_ICON setting."
108 std::string destFileName
= resourcesDirectory
+ "/" + iconFileName
;
109 this->ConfigureFile(iconFile
, destFileName
.c_str(), true);
110 this->SetOptionIfNotSet("CPACK_APPLE_GUI_ICON", iconFileName
.c_str());
113 std::string applicationsLinkName
= diskImageDirectory
+ "/Applications";
114 cmSystemTools::CreateSymlink("/Applications", applicationsLinkName
.c_str());
117 !this->CopyResourcePlistFile("VolumeIcon.icns",
118 diskImageDirectory
.c_str(),
119 ".VolumeIcon.icns", true ) ||
120 !this->CopyResourcePlistFile("DS_Store", diskImageDirectory
.c_str(),
121 ".DS_Store", true ) ||
122 !this->CopyResourcePlistFile("background.png",
123 diskImageBackgroundImageDir
.c_str(), "background.png", true ) ||
124 !this->CopyResourcePlistFile("RuntimeScript", dir
) ||
125 !this->CopyResourcePlistFile("OSXX11.Info.plist", contDir
,
127 !this->CopyResourcePlistFile("OSXScriptLauncher", appdir
,
128 this->GetOption("CPACK_PACKAGE_FILE_NAME"), true)
131 cmCPackLogger(cmCPackLog::LOG_ERROR
, "Problem copying the resource files"
137 std::string tmpFile
= this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
138 tmpFile
+= "/hdiutilOutput.log";
139 cmOStringStream dmgCmd
;
140 dmgCmd
<< "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE")
141 << "\" create -ov -format UDZO -srcfolder \""
142 << diskImageDirectory
.c_str()
143 << "\" \"" << outFileName
<< "\"";
145 cmCPackLogger(cmCPackLog::LOG_VERBOSE
,
146 "Compress disk image using command: "
147 << dmgCmd
.str().c_str() << std::endl
);
148 bool res
= cmSystemTools::RunSingleCommand(dmgCmd
.str().c_str(), &output
,
149 &retVal
, 0, this->GeneratorVerbose
, 0);
150 if ( !res
|| retVal
)
152 cmGeneratedFileStream
ofs(tmpFile
.c_str());
153 ofs
<< "# Run command: " << dmgCmd
.str().c_str() << std::endl
154 << "# Output:" << std::endl
155 << output
.c_str() << std::endl
;
156 cmCPackLogger(cmCPackLog::LOG_ERROR
, "Problem running hdiutil command: "
157 << dmgCmd
.str().c_str() << std::endl
158 << "Please check " << tmpFile
.c_str() << " for errors" << std::endl
);
165 //----------------------------------------------------------------------
166 int cmCPackOSXX11Generator::InitializeInternal()
168 cmCPackLogger(cmCPackLog::LOG_DEBUG
,
169 "cmCPackOSXX11Generator::Initialize()" << std::endl
);
170 std::vector
<std::string
> path
;
171 std::string pkgPath
= cmSystemTools::FindProgram("hdiutil", path
, false);
172 if ( pkgPath
.empty() )
174 cmCPackLogger(cmCPackLog::LOG_ERROR
, "Cannot find hdiutil compiler"
178 this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM_DISK_IMAGE",
181 return this->Superclass::InitializeInternal();
184 //----------------------------------------------------------------------
186 bool cmCPackOSXX11Generator::CopyCreateResourceFile(const char* name)
188 std::string uname = cmSystemTools::UpperCase(name);
189 std::string cpackVar = "CPACK_RESOURCE_FILE_" + uname;
190 const char* inFileName = this->GetOption(cpackVar.c_str());
193 cmCPackLogger(cmCPackLog::LOG_ERROR, "CPack option: " << cpackVar.c_str()
194 << " not specified. It should point to "
195 << (name ? name : "(NULL)")
197 << ".html, or " << name << ".txt file" << std::endl);
200 if ( !cmSystemTools::FileExists(inFileName) )
202 cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find "
203 << (name ? name : "(NULL)")
204 << " resource file: " << inFileName << std::endl);
207 std::string ext = cmSystemTools::GetFilenameLastExtension(inFileName);
208 if ( ext != ".rtfd" && ext != ".rtf" && ext != ".html" && ext != ".txt" )
210 cmCPackLogger(cmCPackLog::LOG_ERROR, "Bad file extension specified: "
211 << ext << ". Currently only .rtfd, .rtf, .html, and .txt files allowed."
216 std::string destFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
217 destFileName += "/Resources/";
218 destFileName += name + ext;
221 cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: "
222 << (inFileName ? inFileName : "(NULL)")
223 << " to " << destFileName.c_str() << std::endl);
224 this->ConfigureFile(inFileName, destFileName.c_str());
229 //----------------------------------------------------------------------
230 bool cmCPackOSXX11Generator::CopyResourcePlistFile(const char* name
,
231 const char* dir
, const char* outputFileName
/* = 0 */,
232 bool copyOnly
/* = false */)
234 std::string inFName
= "CPack.";
237 std::string inFileName
= this->FindTemplate(inFName
.c_str());
238 if ( inFileName
.empty() )
240 cmCPackLogger(cmCPackLog::LOG_ERROR
, "Cannot find input file: "
241 << inFName
<< std::endl
);
245 if ( !outputFileName
)
247 outputFileName
= name
;
250 std::string destFileName
= dir
;
252 destFileName
+= outputFileName
;
254 cmCPackLogger(cmCPackLog::LOG_VERBOSE
, "Configure file: "
255 << inFileName
.c_str() << " to " << destFileName
.c_str() << std::endl
);
256 this->ConfigureFile(inFileName
.c_str(), destFileName
.c_str(), copyOnly
);
260 //----------------------------------------------------------------------
261 const char* cmCPackOSXX11Generator::GetPackagingInstallPrefix()
263 this->InstallPrefix
= "/";
264 this->InstallPrefix
+= this->GetOption("CPACK_PACKAGE_FILE_NAME");
265 this->InstallPrefix
+= ".app/Contents/Resources";
266 return this->InstallPrefix
.c_str();