diff options
Diffstat (limited to 'Source/cmOSXBundleGenerator.cxx')
-rw-r--r-- | Source/cmOSXBundleGenerator.cxx | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx new file mode 100644 index 0000000..dbfe6eb --- /dev/null +++ b/Source/cmOSXBundleGenerator.cxx @@ -0,0 +1,228 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Nicolas Despres <nicolas.despres@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmOSXBundleGenerator.h" + +#include "cmLocalGenerator.h" +#include "cmMakefile.h" +#include "cmTarget.h" + +#include <cassert> + +cmOSXBundleGenerator::cmOSXBundleGenerator(cmGeneratorTarget* target, + const std::string& configName) + : GT(target) + , Makefile(target->Target->GetMakefile()) + , LocalGenerator(target->GetLocalGenerator()) + , ConfigName(configName) + , MacContentFolders(CM_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, false); + cmSystemTools::MakeDirectory(out.c_str()); + this->Makefile->AddCMakeOutputFile(out); + + std::string newoutpath = 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, true); + plist += "/Info.plist"; + this->LocalGenerator->GenerateAppleInfoPList(this->GT, targetName, + plist.c_str()); + this->Makefile->AddCMakeOutputFile(plist); + outpath = newoutpath; +} + +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, true); + contentdir += "/"; + + std::string newoutpath = + outpath + "/" + this->GT->GetFrameworkDirectory(this->ConfigName, false); + + std::string frameworkVersion = this->GT->GetFrameworkVersion(); + + // Configure the Info.plist file + std::string plist = newoutpath; + if (!this->Makefile->PlatformIsAppleIos()) { + // 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->PlatformIsAppleIos()) { + 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.c_str()); + + // Make foo.framework/Versions/version + cmSystemTools::MakeDirectory(newoutpath.c_str()); + + // 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, false); + cmSystemTools::MakeDirectory(out.c_str()); + 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, true); + 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 (std::vector<cmSourceFile const*>::const_iterator si = sources.begin(); + si != sources.end(); ++si) { + cmGeneratorTarget::SourceFileFlags tsFlags = + this->GT->GetTargetSourceFileFlags(*si); + if (tsFlags.Type != cmGeneratorTarget::SourceFileTypeNormal) { + (*generator)(**si, 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, + /*implib*/ false); + macdir += "/"; + macdir += pkgloc; + cmSystemTools::MakeDirectory(macdir.c_str()); + + // 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; +} |