diff options
Diffstat (limited to 'Source/cmOSXBundleGenerator.cxx')
-rw-r--r-- | Source/cmOSXBundleGenerator.cxx | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx new file mode 100644 index 0000000..42fad07 --- /dev/null +++ b/Source/cmOSXBundleGenerator.cxx @@ -0,0 +1,236 @@ +/*============================================================================ + 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 "cmMakefile.h" +#include "cmTarget.h" +#include "cmLocalGenerator.h" + +#include <cassert> + +void cmOSXBundleGenerator::PrepareTargetProperties(cmTarget* target) +{ + if(target->IsCFBundleOnApple()) + { + target->SetProperty("PREFIX", ""); + target->SetProperty("SUFFIX", ""); + } +} + +//---------------------------------------------------------------------------- +cmOSXBundleGenerator:: +cmOSXBundleGenerator(cmTarget* target, + std::string targetNameOut, + const char* configName) + : Target(target) + , Makefile(target->GetMakefile()) + , LocalGenerator(Makefile->GetLocalGenerator()) + , TargetNameOut(targetNameOut) + , ConfigName(configName) + , MacContentDirectory() + , FrameworkVersion() + , MacContentFolders(0) +{ + if (this->MustSkip()) + return; + + this->MacContentDirectory = + this->Target->GetMacContentDirectory(this->ConfigName, + /*implib*/ false, + /*includeMacOS*/ false); + if(this->Target->IsFrameworkOnApple()) + this->FrameworkVersion = this->Target->GetFrameworkVersion(); +} + +//---------------------------------------------------------------------------- +bool cmOSXBundleGenerator::MustSkip() +{ + return !this->Target->HaveWellDefinedOutputFiles(); +} + +//---------------------------------------------------------------------------- +void cmOSXBundleGenerator::CreateAppBundle(std::string& targetName, + std::string& outpath) +{ + if (this->MustSkip()) + return; + + // Compute bundle directory names. + outpath = this->MacContentDirectory; + outpath += "MacOS"; + cmSystemTools::MakeDirectory(outpath.c_str()); + outpath += "/"; + this->Makefile->AddCMakeOutputFile(outpath.c_str()); + + // Configure the Info.plist file. Note that it needs the executable name + // to be set. + std::string plist = this->MacContentDirectory + "Info.plist"; + this->LocalGenerator->GenerateAppleInfoPList(this->Target, + targetName.c_str(), + plist.c_str()); + this->Makefile->AddCMakeOutputFile(plist.c_str()); +} + +//---------------------------------------------------------------------------- +void cmOSXBundleGenerator::CreateFramework(std::string const& targetName) +{ + if (this->MustSkip()) + return; + + assert(this->MacContentFolders); + + // Configure the Info.plist file into the Resources directory. + this->MacContentFolders->insert("Resources"); + std::string plist = this->MacContentDirectory + "Resources/Info.plist"; + this->LocalGenerator->GenerateFrameworkInfoPList(this->Target, + targetName.c_str(), + plist.c_str()); + + // TODO: Use the cmMakefileTargetGenerator::ExtraFiles vector to + // drive rules to create these files at build time. + std::string oldName; + std::string newName; + + // Compute the location of the top-level foo.framework directory. + std::string top = this->Target->GetDirectory(this->ConfigName); + top += "/"; + top += this->TargetNameOut; + top += ".framework/"; + + // Make foo.framework/Versions + std::string versions = top; + versions += "Versions"; + cmSystemTools::MakeDirectory(versions.c_str()); + + // Make foo.framework/Versions/version + std::string version = versions; + version += "/"; + version += this->FrameworkVersion; + cmSystemTools::MakeDirectory(version.c_str()); + + // Current -> version + oldName = this->FrameworkVersion; + newName = versions; + newName += "/Current"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + + // foo -> Versions/Current/foo + oldName = "Versions/Current/"; + oldName += this->TargetNameOut; + newName = top; + newName += this->TargetNameOut; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + + // Resources -> Versions/Current/Resources + if(this->MacContentFolders->find("Resources") != + this->MacContentFolders->end()) + { + oldName = "Versions/Current/Resources"; + newName = top; + newName += "Resources"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + } + + // Headers -> Versions/Current/Headers + if(this->MacContentFolders->find("Headers") != + this->MacContentFolders->end()) + { + oldName = "Versions/Current/Headers"; + newName = top; + newName += "Headers"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + } + + // PrivateHeaders -> Versions/Current/PrivateHeaders + if(this->MacContentFolders->find("PrivateHeaders") != + this->MacContentFolders->end()) + { + oldName = "Versions/Current/PrivateHeaders"; + newName = top; + newName += "PrivateHeaders"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + } +} + +//---------------------------------------------------------------------------- +void cmOSXBundleGenerator::CreateCFBundle(std::string& targetName, + std::string& outpath) +{ + if (this->MustSkip()) + return; + + // Compute bundle directory names. + outpath = this->MacContentDirectory; + outpath += "MacOS"; + cmSystemTools::MakeDirectory(outpath.c_str()); + outpath += "/"; + this->Makefile->AddCMakeOutputFile(outpath.c_str()); + + // Configure the Info.plist file. Note that it needs the executable name + // to be set. + std::string plist = this->MacContentDirectory; + plist += "Info.plist"; + this->LocalGenerator->GenerateAppleInfoPList(this->Target, + targetName.c_str(), + plist.c_str()); + this->Makefile->AddCMakeOutputFile(plist.c_str()); +} + +//---------------------------------------------------------------------------- +void +cmOSXBundleGenerator:: +GenerateMacOSXContentStatements(std::vector<cmSourceFile*> const& sources, + MacOSXContentGeneratorType* generator) +{ + if (this->MustSkip()) + return; + + for(std::vector<cmSourceFile*>::const_iterator + si = sources.begin(); si != sources.end(); ++si) + { + cmTarget::SourceFileFlags tsFlags = + this->Target->GetTargetSourceFileFlags(*si); + if(tsFlags.Type != cmTarget::SourceFileTypeNormal) + { + (*generator)(**si, tsFlags.MacFolder); + } + } +} + +//---------------------------------------------------------------------------- +std::string +cmOSXBundleGenerator::InitMacOSXContentDirectory(const char* pkgloc) +{ + // Construct the full path to the content subdirectory. + std::string macdir = this->MacContentDirectory; + 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; +} |