123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
- #include "cmOSXBundleGenerator.h"
- #include "cmGeneratorTarget.h"
- #include "cmLocalGenerator.h"
- #include "cmMakefile.h"
- #include "cmStateTypes.h"
- #include "cmSystemTools.h"
- #include "cmTarget.h"
- #include <cassert>
- class cmSourceFile;
- cmOSXBundleGenerator::cmOSXBundleGenerator(cmGeneratorTarget* target,
- const std::string& configName)
- : GT(target)
- , Makefile(target->Target->GetMakefile())
- , LocalGenerator(target->GetLocalGenerator())
- , ConfigName(configName)
- , MacContentFolders(nullptr)
- {
- if (this->MustSkip()) {
- return;
- }
- }
- bool cmOSXBundleGenerator::MustSkip()
- {
- return !this->GT->HaveWellDefinedOutputFiles();
- }
- void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
- std::string& outpath)
- {
- if (this->MustSkip()) {
- return;
- }
- // Compute bundle directory names.
- std::string out = outpath;
- out += "/";
- out += this->GT->GetAppBundleDirectory(this->ConfigName,
- cmGeneratorTarget::FullLevel);
- cmSystemTools::MakeDirectory(out);
- this->Makefile->AddCMakeOutputFile(out);
- // Configure the Info.plist file. Note that it needs the executable name
- // to be set.
- std::string plist = outpath;
- plist += "/";
- plist += this->GT->GetAppBundleDirectory(this->ConfigName,
- cmGeneratorTarget::ContentLevel);
- plist += "/Info.plist";
- this->LocalGenerator->GenerateAppleInfoPList(this->GT, targetName,
- plist.c_str());
- this->Makefile->AddCMakeOutputFile(plist);
- outpath = out;
- }
- void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
- const std::string& outpath)
- {
- if (this->MustSkip()) {
- return;
- }
- assert(this->MacContentFolders);
- // Compute the location of the top-level foo.framework directory.
- std::string contentdir = outpath + "/" +
- this->GT->GetFrameworkDirectory(this->ConfigName,
- cmGeneratorTarget::ContentLevel);
- contentdir += "/";
- std::string newoutpath = outpath + "/" +
- this->GT->GetFrameworkDirectory(this->ConfigName,
- cmGeneratorTarget::FullLevel);
- std::string frameworkVersion = this->GT->GetFrameworkVersion();
- // Configure the Info.plist file
- std::string plist = newoutpath;
- if (!this->Makefile->PlatformIsAppleEmbedded()) {
- // Put the Info.plist file into the Resources directory.
- this->MacContentFolders->insert("Resources");
- plist += "/Resources";
- }
- plist += "/Info.plist";
- std::string name = cmSystemTools::GetFilenameName(targetName);
- this->LocalGenerator->GenerateFrameworkInfoPList(this->GT, name,
- plist.c_str());
- // Generate Versions directory only for MacOSX frameworks
- if (this->Makefile->PlatformIsAppleEmbedded()) {
- return;
- }
- // TODO: Use the cmMakefileTargetGenerator::ExtraFiles vector to
- // drive rules to create these files at build time.
- std::string oldName;
- std::string newName;
- // Make foo.framework/Versions
- std::string versions = contentdir;
- versions += "Versions";
- cmSystemTools::MakeDirectory(versions);
- // Make foo.framework/Versions/version
- cmSystemTools::MakeDirectory(newoutpath);
- // Current -> version
- oldName = frameworkVersion;
- newName = versions;
- newName += "/Current";
- cmSystemTools::RemoveFile(newName);
- cmSystemTools::CreateSymlink(oldName, newName);
- this->Makefile->AddCMakeOutputFile(newName);
- // foo -> Versions/Current/foo
- oldName = "Versions/Current/";
- oldName += name;
- newName = contentdir;
- newName += name;
- cmSystemTools::RemoveFile(newName);
- cmSystemTools::CreateSymlink(oldName, newName);
- this->Makefile->AddCMakeOutputFile(newName);
- // Resources -> Versions/Current/Resources
- if (this->MacContentFolders->find("Resources") !=
- this->MacContentFolders->end()) {
- oldName = "Versions/Current/Resources";
- newName = contentdir;
- newName += "Resources";
- cmSystemTools::RemoveFile(newName);
- cmSystemTools::CreateSymlink(oldName, newName);
- this->Makefile->AddCMakeOutputFile(newName);
- }
- // Headers -> Versions/Current/Headers
- if (this->MacContentFolders->find("Headers") !=
- this->MacContentFolders->end()) {
- oldName = "Versions/Current/Headers";
- newName = contentdir;
- newName += "Headers";
- cmSystemTools::RemoveFile(newName);
- cmSystemTools::CreateSymlink(oldName, newName);
- this->Makefile->AddCMakeOutputFile(newName);
- }
- // PrivateHeaders -> Versions/Current/PrivateHeaders
- if (this->MacContentFolders->find("PrivateHeaders") !=
- this->MacContentFolders->end()) {
- oldName = "Versions/Current/PrivateHeaders";
- newName = contentdir;
- newName += "PrivateHeaders";
- cmSystemTools::RemoveFile(newName);
- cmSystemTools::CreateSymlink(oldName, newName);
- this->Makefile->AddCMakeOutputFile(newName);
- }
- }
- void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
- const std::string& root)
- {
- if (this->MustSkip()) {
- return;
- }
- // Compute bundle directory names.
- std::string out = root;
- out += "/";
- out += this->GT->GetCFBundleDirectory(this->ConfigName,
- cmGeneratorTarget::FullLevel);
- cmSystemTools::MakeDirectory(out);
- this->Makefile->AddCMakeOutputFile(out);
- // Configure the Info.plist file. Note that it needs the executable name
- // to be set.
- std::string plist = root + "/" +
- this->GT->GetCFBundleDirectory(this->ConfigName,
- cmGeneratorTarget::ContentLevel);
- plist += "/Info.plist";
- std::string name = cmSystemTools::GetFilenameName(targetName);
- this->LocalGenerator->GenerateAppleInfoPList(this->GT, name, plist.c_str());
- this->Makefile->AddCMakeOutputFile(plist);
- }
- void cmOSXBundleGenerator::GenerateMacOSXContentStatements(
- std::vector<cmSourceFile const*> const& sources,
- MacOSXContentGeneratorType* generator)
- {
- if (this->MustSkip()) {
- return;
- }
- for (cmSourceFile const* source : sources) {
- cmGeneratorTarget::SourceFileFlags tsFlags =
- this->GT->GetTargetSourceFileFlags(source);
- if (tsFlags.Type != cmGeneratorTarget::SourceFileTypeNormal) {
- (*generator)(*source, tsFlags.MacFolder);
- }
- }
- }
- std::string cmOSXBundleGenerator::InitMacOSXContentDirectory(
- const char* pkgloc)
- {
- // Construct the full path to the content subdirectory.
- std::string macdir = this->GT->GetMacContentDirectory(
- this->ConfigName, cmStateEnums::RuntimeBinaryArtifact);
- macdir += "/";
- macdir += pkgloc;
- cmSystemTools::MakeDirectory(macdir);
- // Record use of this content location. Only the first level
- // directory is needed.
- {
- std::string loc = pkgloc;
- loc = loc.substr(0, loc.find('/'));
- this->MacContentFolders->insert(loc);
- }
- return macdir;
- }
|