cmOSXBundleGenerator.cxx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmOSXBundleGenerator.h"
  4. #include "cmConfigure.h"
  5. #include "cmGeneratorTarget.h"
  6. #include "cmLocalGenerator.h"
  7. #include "cmMakefile.h"
  8. #include "cmStateTypes.h"
  9. #include "cmSystemTools.h"
  10. #include "cmTarget.h"
  11. #include <cassert>
  12. class cmSourceFile;
  13. cmOSXBundleGenerator::cmOSXBundleGenerator(cmGeneratorTarget* target,
  14. const std::string& configName)
  15. : GT(target)
  16. , Makefile(target->Target->GetMakefile())
  17. , LocalGenerator(target->GetLocalGenerator())
  18. , ConfigName(configName)
  19. , MacContentFolders(CM_NULLPTR)
  20. {
  21. if (this->MustSkip()) {
  22. return;
  23. }
  24. }
  25. bool cmOSXBundleGenerator::MustSkip()
  26. {
  27. return !this->GT->HaveWellDefinedOutputFiles();
  28. }
  29. void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
  30. std::string& outpath)
  31. {
  32. if (this->MustSkip()) {
  33. return;
  34. }
  35. // Compute bundle directory names.
  36. std::string out = outpath;
  37. out += "/";
  38. out += this->GT->GetAppBundleDirectory(this->ConfigName,
  39. cmGeneratorTarget::FullLevel);
  40. cmSystemTools::MakeDirectory(out.c_str());
  41. this->Makefile->AddCMakeOutputFile(out);
  42. // Configure the Info.plist file. Note that it needs the executable name
  43. // to be set.
  44. std::string plist = outpath;
  45. plist += "/";
  46. plist += this->GT->GetAppBundleDirectory(this->ConfigName,
  47. cmGeneratorTarget::ContentLevel);
  48. plist += "/Info.plist";
  49. this->LocalGenerator->GenerateAppleInfoPList(this->GT, targetName,
  50. plist.c_str());
  51. this->Makefile->AddCMakeOutputFile(plist);
  52. outpath = out;
  53. }
  54. void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
  55. const std::string& outpath)
  56. {
  57. if (this->MustSkip()) {
  58. return;
  59. }
  60. assert(this->MacContentFolders);
  61. // Compute the location of the top-level foo.framework directory.
  62. std::string contentdir = outpath + "/" +
  63. this->GT->GetFrameworkDirectory(this->ConfigName,
  64. cmGeneratorTarget::ContentLevel);
  65. contentdir += "/";
  66. std::string newoutpath = outpath + "/" +
  67. this->GT->GetFrameworkDirectory(this->ConfigName,
  68. cmGeneratorTarget::FullLevel);
  69. std::string frameworkVersion = this->GT->GetFrameworkVersion();
  70. // Configure the Info.plist file
  71. std::string plist = newoutpath;
  72. if (!this->Makefile->PlatformIsAppleIos()) {
  73. // Put the Info.plist file into the Resources directory.
  74. this->MacContentFolders->insert("Resources");
  75. plist += "/Resources";
  76. }
  77. plist += "/Info.plist";
  78. std::string name = cmSystemTools::GetFilenameName(targetName);
  79. this->LocalGenerator->GenerateFrameworkInfoPList(this->GT, name,
  80. plist.c_str());
  81. // Generate Versions directory only for MacOSX frameworks
  82. if (this->Makefile->PlatformIsAppleIos()) {
  83. return;
  84. }
  85. // TODO: Use the cmMakefileTargetGenerator::ExtraFiles vector to
  86. // drive rules to create these files at build time.
  87. std::string oldName;
  88. std::string newName;
  89. // Make foo.framework/Versions
  90. std::string versions = contentdir;
  91. versions += "Versions";
  92. cmSystemTools::MakeDirectory(versions.c_str());
  93. // Make foo.framework/Versions/version
  94. cmSystemTools::MakeDirectory(newoutpath.c_str());
  95. // Current -> version
  96. oldName = frameworkVersion;
  97. newName = versions;
  98. newName += "/Current";
  99. cmSystemTools::RemoveFile(newName);
  100. cmSystemTools::CreateSymlink(oldName, newName);
  101. this->Makefile->AddCMakeOutputFile(newName);
  102. // foo -> Versions/Current/foo
  103. oldName = "Versions/Current/";
  104. oldName += name;
  105. newName = contentdir;
  106. newName += name;
  107. cmSystemTools::RemoveFile(newName);
  108. cmSystemTools::CreateSymlink(oldName, newName);
  109. this->Makefile->AddCMakeOutputFile(newName);
  110. // Resources -> Versions/Current/Resources
  111. if (this->MacContentFolders->find("Resources") !=
  112. this->MacContentFolders->end()) {
  113. oldName = "Versions/Current/Resources";
  114. newName = contentdir;
  115. newName += "Resources";
  116. cmSystemTools::RemoveFile(newName);
  117. cmSystemTools::CreateSymlink(oldName, newName);
  118. this->Makefile->AddCMakeOutputFile(newName);
  119. }
  120. // Headers -> Versions/Current/Headers
  121. if (this->MacContentFolders->find("Headers") !=
  122. this->MacContentFolders->end()) {
  123. oldName = "Versions/Current/Headers";
  124. newName = contentdir;
  125. newName += "Headers";
  126. cmSystemTools::RemoveFile(newName);
  127. cmSystemTools::CreateSymlink(oldName, newName);
  128. this->Makefile->AddCMakeOutputFile(newName);
  129. }
  130. // PrivateHeaders -> Versions/Current/PrivateHeaders
  131. if (this->MacContentFolders->find("PrivateHeaders") !=
  132. this->MacContentFolders->end()) {
  133. oldName = "Versions/Current/PrivateHeaders";
  134. newName = contentdir;
  135. newName += "PrivateHeaders";
  136. cmSystemTools::RemoveFile(newName);
  137. cmSystemTools::CreateSymlink(oldName, newName);
  138. this->Makefile->AddCMakeOutputFile(newName);
  139. }
  140. }
  141. void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
  142. const std::string& root)
  143. {
  144. if (this->MustSkip()) {
  145. return;
  146. }
  147. // Compute bundle directory names.
  148. std::string out = root;
  149. out += "/";
  150. out += this->GT->GetCFBundleDirectory(this->ConfigName,
  151. cmGeneratorTarget::FullLevel);
  152. cmSystemTools::MakeDirectory(out.c_str());
  153. this->Makefile->AddCMakeOutputFile(out);
  154. // Configure the Info.plist file. Note that it needs the executable name
  155. // to be set.
  156. std::string plist = root + "/" +
  157. this->GT->GetCFBundleDirectory(this->ConfigName,
  158. cmGeneratorTarget::ContentLevel);
  159. plist += "/Info.plist";
  160. std::string name = cmSystemTools::GetFilenameName(targetName);
  161. this->LocalGenerator->GenerateAppleInfoPList(this->GT, name, plist.c_str());
  162. this->Makefile->AddCMakeOutputFile(plist);
  163. }
  164. void cmOSXBundleGenerator::GenerateMacOSXContentStatements(
  165. std::vector<cmSourceFile const*> const& sources,
  166. MacOSXContentGeneratorType* generator)
  167. {
  168. if (this->MustSkip()) {
  169. return;
  170. }
  171. for (std::vector<cmSourceFile const*>::const_iterator si = sources.begin();
  172. si != sources.end(); ++si) {
  173. cmGeneratorTarget::SourceFileFlags tsFlags =
  174. this->GT->GetTargetSourceFileFlags(*si);
  175. if (tsFlags.Type != cmGeneratorTarget::SourceFileTypeNormal) {
  176. (*generator)(**si, tsFlags.MacFolder);
  177. }
  178. }
  179. }
  180. std::string cmOSXBundleGenerator::InitMacOSXContentDirectory(
  181. const char* pkgloc)
  182. {
  183. // Construct the full path to the content subdirectory.
  184. std::string macdir = this->GT->GetMacContentDirectory(
  185. this->ConfigName, cmStateEnums::RuntimeBinaryArtifact);
  186. macdir += "/";
  187. macdir += pkgloc;
  188. cmSystemTools::MakeDirectory(macdir.c_str());
  189. // Record use of this content location. Only the first level
  190. // directory is needed.
  191. {
  192. std::string loc = pkgloc;
  193. loc = loc.substr(0, loc.find('/'));
  194. this->MacContentFolders->insert(loc);
  195. }
  196. return macdir;
  197. }