cmake/Source/cmOSXBundleGenerator.cxx

231 lines
7.1 KiB
C++
Raw Normal View History

2016-10-30 18:24:19 +01:00
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
2012-08-04 10:26:08 +03:00
#include "cmOSXBundleGenerator.h"
2016-07-09 11:21:54 +02:00
2017-07-20 19:35:53 +02:00
#include "cmConfigure.h"
2016-10-30 18:24:19 +01:00
#include "cmGeneratorTarget.h"
2016-07-09 11:21:54 +02:00
#include "cmLocalGenerator.h"
2012-08-04 10:26:08 +03:00
#include "cmMakefile.h"
2017-07-20 19:35:53 +02:00
#include "cmStateTypes.h"
2016-10-30 18:24:19 +01:00
#include "cmSystemTools.h"
2012-08-04 10:26:08 +03:00
#include "cmTarget.h"
#include <cassert>
2016-10-30 18:24:19 +01:00
class cmSourceFile;
2016-07-09 11:21:54 +02:00
cmOSXBundleGenerator::cmOSXBundleGenerator(cmGeneratorTarget* target,
const std::string& configName)
: GT(target)
, Makefile(target->Target->GetMakefile())
, LocalGenerator(target->GetLocalGenerator())
, ConfigName(configName)
2016-10-30 18:24:19 +01:00
, MacContentFolders(CM_NULLPTR)
2012-08-04 10:26:08 +03:00
{
2016-10-30 18:24:19 +01:00
if (this->MustSkip()) {
2012-08-04 10:26:08 +03:00
return;
2016-10-30 18:24:19 +01:00
}
2012-08-04 10:26:08 +03:00
}
bool cmOSXBundleGenerator::MustSkip()
{
2016-03-13 13:35:51 +01:00
return !this->GT->HaveWellDefinedOutputFiles();
2012-08-04 10:26:08 +03:00
}
2013-11-03 12:27:13 +02:00
void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
2012-08-04 10:26:08 +03:00
std::string& outpath)
{
2016-10-30 18:24:19 +01:00
if (this->MustSkip()) {
2012-08-04 10:26:08 +03:00
return;
2016-10-30 18:24:19 +01:00
}
2012-08-04 10:26:08 +03:00
// Compute bundle directory names.
2013-11-03 12:27:13 +02:00
std::string out = outpath;
out += "/";
2017-07-20 19:35:53 +02:00
out += this->GT->GetAppBundleDirectory(this->ConfigName,
cmGeneratorTarget::FullLevel);
2013-11-03 12:27:13 +02:00
cmSystemTools::MakeDirectory(out.c_str());
this->Makefile->AddCMakeOutputFile(out);
2012-08-04 10:26:08 +03:00
// Configure the Info.plist file. Note that it needs the executable name
// to be set.
2013-11-03 12:27:13 +02:00
std::string plist = outpath;
plist += "/";
2017-07-20 19:35:53 +02:00
plist += this->GT->GetAppBundleDirectory(this->ConfigName,
cmGeneratorTarget::ContentLevel);
2013-11-03 12:27:13 +02:00
plist += "/Info.plist";
2016-07-09 11:21:54 +02:00
this->LocalGenerator->GenerateAppleInfoPList(this->GT, targetName,
2012-08-04 10:26:08 +03:00
plist.c_str());
2013-11-03 12:27:13 +02:00
this->Makefile->AddCMakeOutputFile(plist);
2017-07-20 19:35:53 +02:00
outpath = out;
2012-08-04 10:26:08 +03:00
}
2016-07-09 11:21:54 +02:00
void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
const std::string& outpath)
2012-08-04 10:26:08 +03:00
{
2016-10-30 18:24:19 +01:00
if (this->MustSkip()) {
2012-08-04 10:26:08 +03:00
return;
2016-10-30 18:24:19 +01:00
}
2012-08-04 10:26:08 +03:00
assert(this->MacContentFolders);
2013-11-03 12:27:13 +02:00
// Compute the location of the top-level foo.framework directory.
2017-07-20 19:35:53 +02:00
std::string contentdir = outpath + "/" +
this->GT->GetFrameworkDirectory(this->ConfigName,
cmGeneratorTarget::ContentLevel);
2013-11-03 12:27:13 +02:00
contentdir += "/";
2017-07-20 19:35:53 +02:00
std::string newoutpath = outpath + "/" +
this->GT->GetFrameworkDirectory(this->ConfigName,
cmGeneratorTarget::FullLevel);
2013-11-03 12:27:13 +02:00
2016-03-13 13:35:51 +01:00
std::string frameworkVersion = this->GT->GetFrameworkVersion();
2013-11-03 12:27:13 +02:00
2016-03-13 13:35:51 +01:00
// Configure the Info.plist file
2013-11-03 12:27:13 +02:00
std::string plist = newoutpath;
2016-07-09 11:21:54 +02:00
if (!this->Makefile->PlatformIsAppleIos()) {
2016-03-13 13:35:51 +01:00
// Put the Info.plist file into the Resources directory.
this->MacContentFolders->insert("Resources");
plist += "/Resources";
2016-07-09 11:21:54 +02:00
}
2016-03-13 13:35:51 +01:00
plist += "/Info.plist";
2013-11-03 12:27:13 +02:00
std::string name = cmSystemTools::GetFilenameName(targetName);
2016-07-09 11:21:54 +02:00
this->LocalGenerator->GenerateFrameworkInfoPList(this->GT, name,
2012-08-04 10:26:08 +03:00
plist.c_str());
2016-03-13 13:35:51 +01:00
// Generate Versions directory only for MacOSX frameworks
2016-10-30 18:24:19 +01:00
if (this->Makefile->PlatformIsAppleIos()) {
2016-03-13 13:35:51 +01:00
return;
2016-10-30 18:24:19 +01:00
}
2016-03-13 13:35:51 +01:00
2012-08-04 10:26:08 +03:00
// 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
2013-11-03 12:27:13 +02:00
std::string versions = contentdir;
2012-08-04 10:26:08 +03:00
versions += "Versions";
cmSystemTools::MakeDirectory(versions.c_str());
// Make foo.framework/Versions/version
2013-11-03 12:27:13 +02:00
cmSystemTools::MakeDirectory(newoutpath.c_str());
2012-08-04 10:26:08 +03:00
// Current -> version
2013-11-03 12:27:13 +02:00
oldName = frameworkVersion;
2012-08-04 10:26:08 +03:00
newName = versions;
newName += "/Current";
2015-04-27 22:25:09 +02:00
cmSystemTools::RemoveFile(newName);
cmSystemTools::CreateSymlink(oldName, newName);
2013-11-03 12:27:13 +02:00
this->Makefile->AddCMakeOutputFile(newName);
2012-08-04 10:26:08 +03:00
// foo -> Versions/Current/foo
oldName = "Versions/Current/";
2013-11-03 12:27:13 +02:00
oldName += name;
newName = contentdir;
newName += name;
2015-04-27 22:25:09 +02:00
cmSystemTools::RemoveFile(newName);
cmSystemTools::CreateSymlink(oldName, newName);
2013-11-03 12:27:13 +02:00
this->Makefile->AddCMakeOutputFile(newName);
2012-08-04 10:26:08 +03:00
// Resources -> Versions/Current/Resources
2016-07-09 11:21:54 +02:00
if (this->MacContentFolders->find("Resources") !=
this->MacContentFolders->end()) {
2012-08-04 10:26:08 +03:00
oldName = "Versions/Current/Resources";
2013-11-03 12:27:13 +02:00
newName = contentdir;
2012-08-04 10:26:08 +03:00
newName += "Resources";
2015-04-27 22:25:09 +02:00
cmSystemTools::RemoveFile(newName);
cmSystemTools::CreateSymlink(oldName, newName);
2013-11-03 12:27:13 +02:00
this->Makefile->AddCMakeOutputFile(newName);
2016-07-09 11:21:54 +02:00
}
2012-08-04 10:26:08 +03:00
// Headers -> Versions/Current/Headers
2016-07-09 11:21:54 +02:00
if (this->MacContentFolders->find("Headers") !=
this->MacContentFolders->end()) {
2012-08-04 10:26:08 +03:00
oldName = "Versions/Current/Headers";
2013-11-03 12:27:13 +02:00
newName = contentdir;
2012-08-04 10:26:08 +03:00
newName += "Headers";
2015-04-27 22:25:09 +02:00
cmSystemTools::RemoveFile(newName);
cmSystemTools::CreateSymlink(oldName, newName);
2013-11-03 12:27:13 +02:00
this->Makefile->AddCMakeOutputFile(newName);
2016-07-09 11:21:54 +02:00
}
2012-08-04 10:26:08 +03:00
// PrivateHeaders -> Versions/Current/PrivateHeaders
2016-07-09 11:21:54 +02:00
if (this->MacContentFolders->find("PrivateHeaders") !=
this->MacContentFolders->end()) {
2012-08-04 10:26:08 +03:00
oldName = "Versions/Current/PrivateHeaders";
2013-11-03 12:27:13 +02:00
newName = contentdir;
2012-08-04 10:26:08 +03:00
newName += "PrivateHeaders";
2015-04-27 22:25:09 +02:00
cmSystemTools::RemoveFile(newName);
cmSystemTools::CreateSymlink(oldName, newName);
2013-11-03 12:27:13 +02:00
this->Makefile->AddCMakeOutputFile(newName);
2016-07-09 11:21:54 +02:00
}
2012-08-04 10:26:08 +03:00
}
2013-11-03 12:27:13 +02:00
void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
const std::string& root)
2012-08-04 10:26:08 +03:00
{
2016-10-30 18:24:19 +01:00
if (this->MustSkip()) {
2012-08-04 10:26:08 +03:00
return;
2016-10-30 18:24:19 +01:00
}
2012-08-04 10:26:08 +03:00
// Compute bundle directory names.
2013-11-03 12:27:13 +02:00
std::string out = root;
out += "/";
2017-07-20 19:35:53 +02:00
out += this->GT->GetCFBundleDirectory(this->ConfigName,
cmGeneratorTarget::FullLevel);
2013-11-03 12:27:13 +02:00
cmSystemTools::MakeDirectory(out.c_str());
this->Makefile->AddCMakeOutputFile(out);
2012-08-04 10:26:08 +03:00
// Configure the Info.plist file. Note that it needs the executable name
// to be set.
2017-07-20 19:35:53 +02:00
std::string plist = root + "/" +
this->GT->GetCFBundleDirectory(this->ConfigName,
cmGeneratorTarget::ContentLevel);
2013-11-03 12:27:13 +02:00
plist += "/Info.plist";
2015-08-17 11:37:30 +02:00
std::string name = cmSystemTools::GetFilenameName(targetName);
2016-07-09 11:21:54 +02:00
this->LocalGenerator->GenerateAppleInfoPList(this->GT, name, plist.c_str());
2013-11-03 12:27:13 +02:00
this->Makefile->AddCMakeOutputFile(plist);
2012-08-04 10:26:08 +03:00
}
2016-07-09 11:21:54 +02:00
void cmOSXBundleGenerator::GenerateMacOSXContentStatements(
std::vector<cmSourceFile const*> const& sources,
MacOSXContentGeneratorType* generator)
2012-08-04 10:26:08 +03:00
{
2016-10-30 18:24:19 +01:00
if (this->MustSkip()) {
2012-08-04 10:26:08 +03:00
return;
2016-10-30 18:24:19 +01:00
}
2012-08-04 10:26:08 +03:00
2016-07-09 11:21:54 +02:00
for (std::vector<cmSourceFile const*>::const_iterator si = sources.begin();
si != sources.end(); ++si) {
2015-04-27 22:25:09 +02:00
cmGeneratorTarget::SourceFileFlags tsFlags =
this->GT->GetTargetSourceFileFlags(*si);
2016-07-09 11:21:54 +02:00
if (tsFlags.Type != cmGeneratorTarget::SourceFileTypeNormal) {
2012-08-04 10:26:08 +03:00
(*generator)(**si, tsFlags.MacFolder);
}
2016-07-09 11:21:54 +02:00
}
2012-08-04 10:26:08 +03:00
}
2016-07-09 11:21:54 +02:00
std::string cmOSXBundleGenerator::InitMacOSXContentDirectory(
const char* pkgloc)
2012-08-04 10:26:08 +03:00
{
// Construct the full path to the content subdirectory.
2013-11-03 12:27:13 +02:00
2017-07-20 19:35:53 +02:00
std::string macdir = this->GT->GetMacContentDirectory(
this->ConfigName, cmStateEnums::RuntimeBinaryArtifact);
2013-11-03 12:27:13 +02:00
macdir += "/";
2012-08-04 10:26:08 +03:00
macdir += pkgloc;
cmSystemTools::MakeDirectory(macdir.c_str());
// Record use of this content location. Only the first level
// directory is needed.
{
2016-07-09 11:21:54 +02:00
std::string loc = pkgloc;
loc = loc.substr(0, loc.find('/'));
this->MacContentFolders->insert(loc);
2012-08-04 10:26:08 +03:00
}
return macdir;
}