diff options
author | Nicolas Despres <nicolas.despres@gmail.com> | 2012-07-07 17:54:16 (GMT) |
---|---|---|
committer | Peter Kümmel <syntheticpp@gmx.net> | 2012-07-17 12:03:07 (GMT) |
commit | a1b803349b51a9a814cd8e309832991306ef2cf0 (patch) | |
tree | 81e3c385a33cdc834cc2930d2b7da13283b2d045 /Source | |
parent | 3ba74ad9d586816f7c60cc6f527148edf982871c (diff) | |
download | CMake-a1b803349b51a9a814cd8e309832991306ef2cf0.zip CMake-a1b803349b51a9a814cd8e309832991306ef2cf0.tar.gz CMake-a1b803349b51a9a814cd8e309832991306ef2cf0.tar.bz2 |
Re-factor OS X bundle and framework generation.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeLists.txt | 2 | ||||
-rw-r--r-- | Source/cmMakefileExecutableTargetGenerator.cxx | 46 | ||||
-rw-r--r-- | Source/cmMakefileExecutableTargetGenerator.h | 7 | ||||
-rw-r--r-- | Source/cmMakefileLibraryTargetGenerator.cxx | 131 | ||||
-rw-r--r-- | Source/cmMakefileLibraryTargetGenerator.h | 7 | ||||
-rw-r--r-- | Source/cmNinjaNormalTargetGenerator.cxx | 157 | ||||
-rw-r--r-- | Source/cmNinjaNormalTargetGenerator.h | 10 | ||||
-rw-r--r-- | Source/cmOSXBundleGenerator.cxx | 171 | ||||
-rw-r--r-- | Source/cmOSXBundleGenerator.h | 52 |
9 files changed, 286 insertions, 297 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 14af796..543a64e 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -219,6 +219,8 @@ SET(SRCS cmMakefileExecutableTargetGenerator.cxx cmMakefileLibraryTargetGenerator.cxx cmMakefileUtilityTargetGenerator.cxx + cmOSXBundleGenerator.cxx + cmOSXBundleGenerator.h cmNewLineStyle.h cmNewLineStyle.cxx cmOrderDirectories.cxx diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 36e366e..d9ab334 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -18,24 +18,31 @@ #include "cmSourceFile.h" #include "cmTarget.h" #include "cmake.h" +#include "cmOSXBundleGenerator.h" //---------------------------------------------------------------------------- cmMakefileExecutableTargetGenerator ::cmMakefileExecutableTargetGenerator(cmTarget* target): - cmMakefileTargetGenerator(target) + cmMakefileTargetGenerator(target), + OSXBundleGenerator(0) { this->CustomCommandDriver = OnDepends; this->Target->GetExecutableNames( this->TargetNameOut, this->TargetNameReal, this->TargetNameImport, this->TargetNamePDB, this->ConfigName); - if(this->Target->IsAppBundleOnApple()) - { - this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); - this->MacContentDirectory += "/"; - this->MacContentDirectory += this->TargetNameOut; - this->MacContentDirectory += ".app/Contents/"; - } + this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target, + this->TargetNameOut, + this->ConfigName); + this->MacContentDirectory = + this->OSXBundleGenerator->GetMacContentDirectory(); +} + +//---------------------------------------------------------------------------- +cmMakefileExecutableTargetGenerator +::~cmMakefileExecutableTargetGenerator() +{ + delete this->OSXBundleGenerator; } //---------------------------------------------------------------------------- @@ -100,7 +107,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) outpath += "/"; if(this->Target->IsAppBundleOnApple()) { - this->CreateAppBundle(targetName, outpath); + this->OSXBundleGenerator->CreateAppBundle(targetName, outpath); } std::string outpathImp; if(relink) @@ -440,24 +447,3 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) exeCleanFiles.begin(), exeCleanFiles.end()); } - -//---------------------------------------------------------------------------- -void -cmMakefileExecutableTargetGenerator::CreateAppBundle(std::string& targetName, - std::string& outpath) -{ - // Compute bundle directory names. - outpath = this->MacContentDirectory; - outpath += "MacOS"; - cmSystemTools::MakeDirectory(outpath.c_str()); - this->Makefile->AddCMakeOutputFile(outpath.c_str()); - outpath += "/"; - - // 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()); -} diff --git a/Source/cmMakefileExecutableTargetGenerator.h b/Source/cmMakefileExecutableTargetGenerator.h index a9712ca..26dc72f 100644 --- a/Source/cmMakefileExecutableTargetGenerator.h +++ b/Source/cmMakefileExecutableTargetGenerator.h @@ -14,10 +14,13 @@ #include "cmMakefileTargetGenerator.h" +class cmOSXBundleGenerator; + class cmMakefileExecutableTargetGenerator: public cmMakefileTargetGenerator { public: cmMakefileExecutableTargetGenerator(cmTarget* target); + virtual ~cmMakefileExecutableTargetGenerator(); /* the main entry point for this class. Writes the Makefiles associated with this target */ @@ -25,7 +28,9 @@ public: protected: virtual void WriteExecutableRule(bool relink); - void CreateAppBundle(std::string& targetName, std::string& outpath); + +private: + cmOSXBundleGenerator* OSXBundleGenerator; }; #endif diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 0901e6f..4331af6 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -18,13 +18,15 @@ #include "cmSourceFile.h" #include "cmTarget.h" #include "cmake.h" +#include "cmOSXBundleGenerator.h" #include <memory> // auto_ptr //---------------------------------------------------------------------------- cmMakefileLibraryTargetGenerator ::cmMakefileLibraryTargetGenerator(cmTarget* target): - cmMakefileTargetGenerator(target) + cmMakefileTargetGenerator(target), + OSXBundleGenerator(0) { if(this->Target->IsCFBundleOnApple()) { @@ -37,30 +39,19 @@ cmMakefileLibraryTargetGenerator this->TargetNameOut, this->TargetNameSO, this->TargetNameReal, this->TargetNameImport, this->TargetNamePDB, this->ConfigName); - if(this->Target->IsFrameworkOnApple()) - { - this->FrameworkVersion = this->Target->GetFrameworkVersion(); - this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); - this->MacContentDirectory += "/"; - this->MacContentDirectory += this->TargetNameOut; - this->MacContentDirectory += ".framework/Versions/"; - this->MacContentDirectory += this->FrameworkVersion; - this->MacContentDirectory += "/"; - } - else if(this->Target->IsCFBundleOnApple()) - { - this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); - this->MacContentDirectory += "/"; - this->MacContentDirectory += this->TargetNameOut; - this->MacContentDirectory += "."; - const char *ext = this->Target->GetProperty("BUNDLE_EXTENSION"); - if (!ext) - { - ext = "bundle"; - } - this->MacContentDirectory += ext; - this->MacContentDirectory += "/Contents/"; - } + this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target, + this->TargetNameOut, + this->ConfigName); + this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + this->MacContentDirectory = + this->OSXBundleGenerator->GetMacContentDirectory(); +} + +//---------------------------------------------------------------------------- +cmMakefileLibraryTargetGenerator +::~cmMakefileLibraryTargetGenerator() +{ + delete this->OSXBundleGenerator; } //---------------------------------------------------------------------------- @@ -260,94 +251,6 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink) //---------------------------------------------------------------------------- void -cmMakefileLibraryTargetGenerator -::CreateFramework(std::string const& targetName) -{ - // 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 cmMakefileLibraryTargetGenerator::CreateCFBundle(std::string& targetName, std::string& outpath) { @@ -419,7 +322,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules if(this->Target->IsFrameworkOnApple()) { outpath = this->MacContentDirectory; - this->CreateFramework(targetName); + this->OSXBundleGenerator->CreateFramework(targetName); } else if(this->Target->IsCFBundleOnApple()) { diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h index ed79bd8..0d4d777 100644 --- a/Source/cmMakefileLibraryTargetGenerator.h +++ b/Source/cmMakefileLibraryTargetGenerator.h @@ -14,11 +14,14 @@ #include "cmMakefileTargetGenerator.h" +class cmOSXBundleGenerator; + class cmMakefileLibraryTargetGenerator: public cmMakefileTargetGenerator { public: cmMakefileLibraryTargetGenerator(cmTarget* target); + virtual ~cmMakefileLibraryTargetGenerator(); /* the main entry point for this class. Writes the Makefiles associated with this target */ @@ -33,7 +36,6 @@ protected: bool relink); // MacOSX Framework support methods void WriteFrameworkRules(bool relink); - void CreateFramework(std::string const& targetName); void CreateCFBundle(std::string& targetName, std::string& outpath); // Store the computd framework version for OS X Frameworks. @@ -41,6 +43,9 @@ protected: void AppendOSXVerFlag(std::string& flags, const char* lang, const char* name, bool so); + +private: + cmOSXBundleGenerator* OSXBundleGenerator; }; #endif diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 6a5fd6b..fecce14 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -16,6 +16,7 @@ #include "cmSourceFile.h" #include "cmGeneratedFileStream.h" #include "cmMakefile.h" +#include "cmOSXBundleGenerator.h" #include <assert.h> #include <algorithm> @@ -34,8 +35,8 @@ cmNinjaNormalTargetGenerator(cmTarget* target) , TargetNameImport() , TargetNamePDB() , TargetLinkLanguage(0) - , MacContentDirectory() - , FrameworkVersion() + , OSXBundleGenerator(0) + , MacContentFolders() { this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName()); if (target->GetType() == cmTarget::EXECUTABLE) @@ -59,43 +60,15 @@ cmNinjaNormalTargetGenerator(cmTarget* target) EnsureDirectoryExists(target->GetDirectory(this->GetConfigName())); } - // TODO: Factor with the cmMakefileExecutableTargetGenerator constructor. - if(target->IsAppBundleOnApple()) - { - this->MacContentDirectory = target->GetDirectory(this->GetConfigName()); - this->MacContentDirectory += "/"; - this->MacContentDirectory += this->TargetNameOut; - this->MacContentDirectory += ".app/Contents/"; - } - // TODO: Factor with the cmMakefileLibraryTargetGenerator constructor. - else if(target->IsFrameworkOnApple()) - { - this->FrameworkVersion = target->GetFrameworkVersion(); - this->MacContentDirectory = target->GetDirectory(this->GetConfigName()); - this->MacContentDirectory += "/"; - this->MacContentDirectory += this->TargetNameOut; - this->MacContentDirectory += ".framework/Versions/"; - this->MacContentDirectory += this->FrameworkVersion; - this->MacContentDirectory += "/"; - } - else if(target->IsCFBundleOnApple()) - { - this->MacContentDirectory = target->GetDirectory(this->GetConfigName()); - this->MacContentDirectory += "/"; - this->MacContentDirectory += this->TargetNameOut; - this->MacContentDirectory += "."; - const char *ext = target->GetProperty("BUNDLE_EXTENSION"); - if (!ext) - { - ext = "bundle"; - } - this->MacContentDirectory += ext; - this->MacContentDirectory += "/Contents/"; - } + this->OSXBundleGenerator = new cmOSXBundleGenerator(target, + this->TargetNameOut, + this->GetConfigName()); + this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); } cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() { + delete this->OSXBundleGenerator; } void cmNinjaNormalTargetGenerator::Generate() @@ -392,7 +365,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() { // Create the app bundle std::string outpath; - this->CreateAppBundle(this->TargetNameOut, outpath); + this->OSXBundleGenerator->CreateAppBundle(this->TargetNameOut, outpath); // Calculate the output path targetOutput = outpath + this->TargetNameOut; @@ -403,7 +376,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() else if (this->GetTarget()->IsFrameworkOnApple()) { // Create the library framework. - this->CreateFramework(this->TargetNameOut); + this->OSXBundleGenerator->CreateFramework(this->TargetNameOut); } // Write comments. @@ -631,113 +604,3 @@ void cmNinjaNormalTargetGenerator::WriteObjectLibStatement() this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(), this->GetTarget()); } - -// TODO: Factor with cmMakefileExecutableTargetGenerator::CreateAppBundle(). -void -cmNinjaNormalTargetGenerator::CreateAppBundle(const std::string& targetName, - std::string& outpath) -{ - // Compute bundle directory names. - outpath = this->MacContentDirectory; - outpath += "MacOS"; - cmSystemTools::MakeDirectory(outpath.c_str()); - this->GetMakefile()->AddCMakeOutputFile(outpath.c_str()); - outpath += "/"; - - // Configure the Info.plist file. Note that it needs the executable name - // to be set. - std::string plist = this->MacContentDirectory + "Info.plist"; - this->GetLocalGenerator()->GenerateAppleInfoPList(this->GetTarget(), - targetName.c_str(), - plist.c_str()); - this->GetMakefile()->AddCMakeOutputFile(plist.c_str()); -} - -// TODO: Factor with cmMakefileLibraryTargetGenerator::CreateFramework(). -void -cmNinjaNormalTargetGenerator::CreateFramework(std::string const& targetName) -{ - // Create the Resources directory. - std::string resources = this->MacContentDirectory + "Resources/"; - cmSystemTools::MakeDirectory(resources.c_str()); - - // Configure the Info.plist file into the Resources directory. - std::set<cmStdString> macContentFolders; - macContentFolders.insert("Resources"); - std::string plist = resources + "Info.plist"; - this->GetLocalGenerator()->GenerateFrameworkInfoPList(this->GetTarget(), - 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->GetTarget()->GetDirectory(this->GetConfigName()); - 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->GetMakefile()->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->GetMakefile()->AddCMakeOutputFile(newName.c_str()); - - // Resources -> Versions/Current/Resources - if(macContentFolders.find("Resources") != macContentFolders.end()) - { - oldName = "Versions/Current/Resources"; - newName = top; - newName += "Resources"; - cmSystemTools::RemoveFile(newName.c_str()); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->GetMakefile()->AddCMakeOutputFile(newName.c_str()); - } - - // Headers -> Versions/Current/Headers - if(macContentFolders.find("Headers") != macContentFolders.end()) - { - oldName = "Versions/Current/Headers"; - newName = top; - newName += "Headers"; - cmSystemTools::RemoveFile(newName.c_str()); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->GetMakefile()->AddCMakeOutputFile(newName.c_str()); - } - - // PrivateHeaders -> Versions/Current/PrivateHeaders - if(macContentFolders.find("PrivateHeaders") != macContentFolders.end()) - { - oldName = "Versions/Current/PrivateHeaders"; - newName = top; - newName += "PrivateHeaders"; - cmSystemTools::RemoveFile(newName.c_str()); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->GetMakefile()->AddCMakeOutputFile(newName.c_str()); - } -} diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h index c48a8ec..fb597c5 100644 --- a/Source/cmNinjaNormalTargetGenerator.h +++ b/Source/cmNinjaNormalTargetGenerator.h @@ -15,8 +15,12 @@ # include "cmNinjaTargetGenerator.h" # include "cmNinjaTypes.h" +# include "cmStandardIncludes.h" + +# include <set> class cmSourceFile; +class cmOSXBundleGenerator; class cmNinjaNormalTargetGenerator : public cmNinjaTargetGenerator { @@ -34,8 +38,6 @@ private: void WriteLinkStatement(); void WriteObjectLibStatement(); std::vector<std::string> ComputeLinkCmd(); - void CreateAppBundle(const std::string& targetName, std::string& outpath); - void CreateFramework(std::string const& targetName); private: // Target name info. @@ -45,8 +47,8 @@ private: std::string TargetNameImport; std::string TargetNamePDB; const char *TargetLinkLanguage; - std::string MacContentDirectory; - std::string FrameworkVersion; + cmOSXBundleGenerator* OSXBundleGenerator; + std::set<cmStdString> MacContentFolders; }; #endif // ! cmNinjaNormalTargetGenerator_h diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx new file mode 100644 index 0000000..d7afcd6 --- /dev/null +++ b/Source/cmOSXBundleGenerator.cxx @@ -0,0 +1,171 @@ +/*============================================================================ + 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> + +cmOSXBundleGenerator:: +cmOSXBundleGenerator(cmTarget* target, + std::string targetNameOut, + const char* configName) + : Target(target) + , Makefile(target->GetMakefile()) + , LocalGenerator(this->Makefile->GetLocalGenerator()) + , TargetNameOut(targetNameOut) + , ConfigName(configName) + , MacContentDirectory() + , FrameworkVersion() + , MacContentFolders(0) +{ + if(this->Target->IsAppBundleOnApple()) + { + this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); + this->MacContentDirectory += "/"; + this->MacContentDirectory += this->TargetNameOut; + this->MacContentDirectory += ".app/Contents/"; + } + else if(this->Target->IsFrameworkOnApple()) + { + this->FrameworkVersion = this->Target->GetFrameworkVersion(); + this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); + this->MacContentDirectory += "/"; + this->MacContentDirectory += this->TargetNameOut; + this->MacContentDirectory += ".framework/Versions/"; + this->MacContentDirectory += this->FrameworkVersion; + this->MacContentDirectory += "/"; + } + else if(this->Target->IsCFBundleOnApple()) + { + this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); + this->MacContentDirectory += "/"; + this->MacContentDirectory += this->TargetNameOut; + this->MacContentDirectory += "."; + const char *ext = this->Target->GetProperty("BUNDLE_EXTENSION"); + if (!ext) + { + ext = "bundle"; + } + this->MacContentDirectory += ext; + this->MacContentDirectory += "/Contents/"; + } +} + +//---------------------------------------------------------------------------- +void cmOSXBundleGenerator::CreateAppBundle(std::string& targetName, + std::string& outpath) +{ + // Compute bundle directory names. + outpath = this->MacContentDirectory; + outpath += "MacOS"; + cmSystemTools::MakeDirectory(outpath.c_str()); + this->Makefile->AddCMakeOutputFile(outpath.c_str()); + outpath += "/"; + + // 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) +{ + 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()); + } +} diff --git a/Source/cmOSXBundleGenerator.h b/Source/cmOSXBundleGenerator.h new file mode 100644 index 0000000..29ce7c4 --- /dev/null +++ b/Source/cmOSXBundleGenerator.h @@ -0,0 +1,52 @@ +/*============================================================================ + 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. +============================================================================*/ +#ifndef cmOSXBundleGenerator_h +#define cmOSXBundleGenerator_h + +#include "cmStandardIncludes.h" + +#include <string> +#include <set> + +class cmTarget; +class cmMakefile; +class cmLocalGenerator; + +class cmOSXBundleGenerator +{ +public: + cmOSXBundleGenerator(cmTarget* target, + std::string targetNameOut, + const char* configName); + + void CreateAppBundle(std::string& targetName, std::string& outpath); + void CreateFramework(std::string const& targetName); + + std::string GetMacContentDirectory() const + { return this->MacContentDirectory; } + std::string GetFrameworkVersion() const + { return this->FrameworkVersion; } + void SetMacContentFolders(std::set<cmStdString>* macContentFolders) + { this->MacContentFolders = macContentFolders; } + +private: + cmTarget* Target; + cmMakefile* Makefile; + cmLocalGenerator* LocalGenerator; + std::string TargetNameOut; + const char* ConfigName; + std::string MacContentDirectory; + std::string FrameworkVersion; + std::set<cmStdString>* MacContentFolders; +}; + +#endif |