cmCPackOSXX11Generator.cxx 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmCPackOSXX11Generator.h"
  14. #include "cmake.h"
  15. #include "cmGlobalGenerator.h"
  16. #include "cmLocalGenerator.h"
  17. #include "cmSystemTools.h"
  18. #include "cmMakefile.h"
  19. #include "cmGeneratedFileStream.h"
  20. #include "cmCPackLog.h"
  21. #include <cmsys/SystemTools.hxx>
  22. #include <cmsys/Glob.hxx>
  23. //----------------------------------------------------------------------
  24. cmCPackOSXX11Generator::cmCPackOSXX11Generator()
  25. {
  26. }
  27. //----------------------------------------------------------------------
  28. cmCPackOSXX11Generator::~cmCPackOSXX11Generator()
  29. {
  30. }
  31. //----------------------------------------------------------------------
  32. int cmCPackOSXX11Generator::CompressFiles(const char* outFileName,
  33. const char* toplevel,
  34. const std::vector<std::string>& files)
  35. {
  36. (void) files; // TODO: Fix api to not need files.
  37. (void) toplevel; // TODO: Use toplevel
  38. const char* cpackPackageExecutables
  39. = this->GetOption("CPACK_PACKAGE_EXECUTABLES");
  40. if ( cpackPackageExecutables )
  41. {
  42. cmCPackLogger(cmCPackLog::LOG_DEBUG, "The cpackPackageExecutables: "
  43. << cpackPackageExecutables << "." << std::endl);
  44. cmOStringStream str;
  45. cmOStringStream deleteStr;
  46. std::vector<std::string> cpackPackageExecutablesVector;
  47. cmSystemTools::ExpandListArgument(cpackPackageExecutables,
  48. cpackPackageExecutablesVector);
  49. if ( cpackPackageExecutablesVector.size() % 2 != 0 )
  50. {
  51. cmCPackLogger(cmCPackLog::LOG_ERROR,
  52. "CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and "
  53. "<icon name>." << std::endl);
  54. return 0;
  55. }
  56. std::vector<std::string>::iterator it;
  57. for ( it = cpackPackageExecutablesVector.begin();
  58. it != cpackPackageExecutablesVector.end();
  59. ++it )
  60. {
  61. std::string cpackExecutableName = *it;
  62. ++ it;
  63. this->SetOptionIfNotSet("CPACK_EXECUTABLE_NAME",
  64. cpackExecutableName.c_str());
  65. }
  66. }
  67. // Disk image directories
  68. std::string diskImageDirectory = toplevel;
  69. std::string diskImageBackgroundImageDir
  70. = diskImageDirectory + "/.background";
  71. // App bundle directories
  72. std::string packageDirFileName = toplevel;
  73. packageDirFileName += "/";
  74. packageDirFileName += this->GetOption("CPACK_PACKAGE_FILE_NAME");
  75. packageDirFileName += ".app";
  76. std::string contentsDirectory = packageDirFileName + "/Contents";
  77. std::string resourcesDirectory = contentsDirectory + "/Resources";
  78. std::string appDirectory = contentsDirectory + "/MacOS";
  79. const char* dir = resourcesDirectory.c_str();
  80. const char* appdir = appDirectory.c_str();
  81. const char* contDir = contentsDirectory.c_str();
  82. const char* iconFile = this->GetOption("CPACK_PACKAGE_ICON");
  83. if ( iconFile )
  84. {
  85. std::string iconFileName = cmsys::SystemTools::GetFilenameName(
  86. iconFile);
  87. if ( !cmSystemTools::FileExists(iconFile) )
  88. {
  89. cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find icon file: "
  90. << iconFile << ". Please check CPACK_PACKAGE_ICON setting."
  91. << std::endl);
  92. return 0;
  93. }
  94. std::string destFileName = resourcesDirectory + "/" + iconFileName;
  95. this->ConfigureFile(iconFile, destFileName.c_str(), true);
  96. this->SetOptionIfNotSet("CPACK_APPLE_GUI_ICON", iconFileName.c_str());
  97. }
  98. std::string applicationsLinkName = diskImageDirectory + "/Applications";
  99. cmSystemTools::CreateSymlink("/Applications", applicationsLinkName.c_str());
  100. if (
  101. !this->CopyResourcePlistFile("VolumeIcon.icns",
  102. diskImageDirectory.c_str(),
  103. ".VolumeIcon.icns", true ) ||
  104. !this->CopyResourcePlistFile("DS_Store", diskImageDirectory.c_str(),
  105. ".DS_Store", true ) ||
  106. !this->CopyResourcePlistFile("background.png",
  107. diskImageBackgroundImageDir.c_str(), "background.png", true ) ||
  108. !this->CopyResourcePlistFile("RuntimeScript", dir) ||
  109. !this->CopyResourcePlistFile("OSXX11.Info.plist", contDir,
  110. "Info.plist" ) ||
  111. !this->CopyResourcePlistFile("OSXScriptLauncher", appdir,
  112. this->GetOption("CPACK_PACKAGE_FILE_NAME"), true)
  113. )
  114. {
  115. cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying the resource files"
  116. << std::endl);
  117. return 0;
  118. }
  119. std::string output;
  120. std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  121. tmpFile += "/hdiutilOutput.log";
  122. cmOStringStream dmgCmd;
  123. dmgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE")
  124. << "\" create -ov -format UDZO -srcfolder \""
  125. << diskImageDirectory.c_str()
  126. << "\" \"" << outFileName << "\"";
  127. int retVal = 1;
  128. cmCPackLogger(cmCPackLog::LOG_VERBOSE,
  129. "Compress disk image using command: "
  130. << dmgCmd.str().c_str() << std::endl);
  131. bool res = cmSystemTools::RunSingleCommand(dmgCmd.str().c_str(), &output,
  132. &retVal, 0, this->GeneratorVerbose, 0);
  133. if ( !res || retVal )
  134. {
  135. cmGeneratedFileStream ofs(tmpFile.c_str());
  136. ofs << "# Run command: " << dmgCmd.str().c_str() << std::endl
  137. << "# Output:" << std::endl
  138. << output.c_str() << std::endl;
  139. cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running hdiutil command: "
  140. << dmgCmd.str().c_str() << std::endl
  141. << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
  142. return 0;
  143. }
  144. return 1;
  145. }
  146. //----------------------------------------------------------------------
  147. int cmCPackOSXX11Generator::InitializeInternal()
  148. {
  149. cmCPackLogger(cmCPackLog::LOG_DEBUG,
  150. "cmCPackOSXX11Generator::Initialize()" << std::endl);
  151. std::vector<std::string> path;
  152. std::string pkgPath = cmSystemTools::FindProgram("hdiutil", path, false);
  153. if ( pkgPath.empty() )
  154. {
  155. cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find hdiutil compiler"
  156. << std::endl);
  157. return 0;
  158. }
  159. this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM_DISK_IMAGE",
  160. pkgPath.c_str());
  161. return this->Superclass::InitializeInternal();
  162. }
  163. //----------------------------------------------------------------------
  164. /*
  165. bool cmCPackOSXX11Generator::CopyCreateResourceFile(const char* name)
  166. {
  167. std::string uname = cmSystemTools::UpperCase(name);
  168. std::string cpackVar = "CPACK_RESOURCE_FILE_" + uname;
  169. const char* inFileName = this->GetOption(cpackVar.c_str());
  170. if ( !inFileName )
  171. {
  172. cmCPackLogger(cmCPackLog::LOG_ERROR, "CPack option: " << cpackVar.c_str()
  173. << " not specified. It should point to "
  174. << (name ? name : "(NULL)")
  175. << ".rtf, " << name
  176. << ".html, or " << name << ".txt file" << std::endl);
  177. return false;
  178. }
  179. if ( !cmSystemTools::FileExists(inFileName) )
  180. {
  181. cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find "
  182. << (name ? name : "(NULL)")
  183. << " resource file: " << inFileName << std::endl);
  184. return false;
  185. }
  186. std::string ext = cmSystemTools::GetFilenameLastExtension(inFileName);
  187. if ( ext != ".rtfd" && ext != ".rtf" && ext != ".html" && ext != ".txt" )
  188. {
  189. cmCPackLogger(cmCPackLog::LOG_ERROR, "Bad file extension specified: "
  190. << ext << ". Currently only .rtfd, .rtf, .html, and .txt files allowed."
  191. << std::endl);
  192. return false;
  193. }
  194. std::string destFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  195. destFileName += "/Resources/";
  196. destFileName += name + ext;
  197. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: "
  198. << (inFileName ? inFileName : "(NULL)")
  199. << " to " << destFileName.c_str() << std::endl);
  200. this->ConfigureFile(inFileName, destFileName.c_str());
  201. return true;
  202. }
  203. */
  204. bool cmCPackOSXX11Generator::CopyResourcePlistFile(const char* name,
  205. const char* dir, const char* outputFileName /* = 0 */,
  206. bool copyOnly /* = false */)
  207. {
  208. std::string inFName = "CPack.";
  209. inFName += name;
  210. inFName += ".in";
  211. std::string inFileName = this->FindTemplate(inFName.c_str());
  212. if ( inFileName.empty() )
  213. {
  214. cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find input file: "
  215. << inFName << std::endl);
  216. return false;
  217. }
  218. if ( !outputFileName )
  219. {
  220. outputFileName = name;
  221. }
  222. std::string destFileName = dir;
  223. destFileName += "/";
  224. destFileName += outputFileName;
  225. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: "
  226. << inFileName.c_str() << " to " << destFileName.c_str() << std::endl);
  227. this->ConfigureFile(inFileName.c_str(), destFileName.c_str(), copyOnly);
  228. return true;
  229. }
  230. //----------------------------------------------------------------------
  231. const char* cmCPackOSXX11Generator::GetInstallPrefix()
  232. {
  233. this->InstallPrefix = "/";
  234. this->InstallPrefix += this->GetOption("CPACK_PACKAGE_FILE_NAME");
  235. this->InstallPrefix += ".app/Contents/Resources";
  236. return this->InstallPrefix.c_str();
  237. }