cmake/Source/cmOSXBundleGenerator.cxx

229 lines
7.2 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
2020-02-01 23:06:01 +01:00
#include <cassert>
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"
2020-02-01 23:06:01 +01:00
#include "cmStringAlgorithms.h"
2016-10-30 18:24:19 +01:00
#include "cmSystemTools.h"
2012-08-04 10:26:08 +03:00
#include "cmTarget.h"
2023-07-02 19:51:09 +02:00
#include "cmValue.h"
2012-08-04 10:26:08 +03:00
2016-10-30 18:24:19 +01:00
class cmSourceFile;
2020-08-30 11:54:41 +02:00
cmOSXBundleGenerator::cmOSXBundleGenerator(cmGeneratorTarget* target)
2016-07-09 11:21:54 +02:00
: GT(target)
, Makefile(target->Target->GetMakefile())
, LocalGenerator(target->GetLocalGenerator())
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,
2020-08-30 11:54:41 +02:00
std::string& outpath,
const std::string& config)
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.
2020-08-30 11:54:41 +02:00
std::string out = cmStrCat(
outpath, '/',
this->GT->GetAppBundleDirectory(config, cmGeneratorTarget::FullLevel));
2018-04-23 21:13:27 +02:00
cmSystemTools::MakeDirectory(out);
2013-11-03 12:27:13 +02:00
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.
2020-08-30 11:54:41 +02:00
std::string plist = cmStrCat(
outpath, '/',
this->GT->GetAppBundleDirectory(config, cmGeneratorTarget::ContentLevel),
"/Info.plist");
2019-11-11 23:01:05 +01:00
this->LocalGenerator->GenerateAppleInfoPList(this->GT, targetName, plist);
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
}
2020-08-30 11:54:41 +02:00
void cmOSXBundleGenerator::CreateFramework(
const std::string& targetName, const std::string& outpath,
const std::string& config, const cmOSXBundleGenerator::SkipParts& skipParts)
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.
2020-08-30 11:54:41 +02:00
std::string contentdir = cmStrCat(
outpath, '/',
this->GT->GetFrameworkDirectory(config, cmGeneratorTarget::ContentLevel),
'/');
2013-11-03 12:27:13 +02:00
2017-07-20 19:35:53 +02:00
std::string newoutpath = outpath + "/" +
2020-08-30 11:54:41 +02:00
this->GT->GetFrameworkDirectory(config, 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
std::string name = cmSystemTools::GetFilenameName(targetName);
2023-07-02 19:51:09 +02:00
if (!skipParts.InfoPlist) {
2020-08-30 11:54:41 +02:00
// 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";
this->LocalGenerator->GenerateFrameworkInfoPList(this->GT, name, plist);
}
2012-08-04 10:26:08 +03:00
2016-03-13 13:35:51 +01:00
// Generate Versions directory only for MacOSX frameworks
2018-04-23 21:13:27 +02:00
if (this->Makefile->PlatformIsAppleEmbedded()) {
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
2020-02-01 23:06:01 +01:00
std::string versions = cmStrCat(contentdir, "Versions");
2018-04-23 21:13:27 +02:00
cmSystemTools::MakeDirectory(versions);
2012-08-04 10:26:08 +03:00
// Make foo.framework/Versions/version
2018-04-23 21:13:27 +02:00
cmSystemTools::MakeDirectory(newoutpath);
2012-08-04 10:26:08 +03:00
// Current -> version
2013-11-03 12:27:13 +02:00
oldName = frameworkVersion;
2020-02-01 23:06:01 +01:00
newName = cmStrCat(versions, "/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
2020-02-01 23:06:01 +01:00
oldName = cmStrCat("Versions/Current/", name);
newName = cmStrCat(contentdir, 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
2023-07-02 19:51:09 +02:00
if (!skipParts.TextStubs) {
// foo.tbd -> Versions/Current/foo.tbd
cmValue tbdSuffix =
this->Makefile->GetDefinition("CMAKE_APPLE_IMPORT_FILE_SUFFIX");
oldName = cmStrCat("Versions/Current/", name, tbdSuffix);
newName = cmStrCat(contentdir, name, tbdSuffix);
cmSystemTools::RemoveFile(newName);
cmSystemTools::CreateSymlink(oldName, newName);
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";
2020-02-01 23:06:01 +01:00
newName = cmStrCat(contentdir, "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";
2020-02-01 23:06:01 +01:00
newName = cmStrCat(contentdir, "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";
2020-02-01 23:06:01 +01:00
newName = cmStrCat(contentdir, "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,
2020-08-30 11:54:41 +02:00
const std::string& root,
const std::string& config)
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.
2020-08-30 11:54:41 +02:00
std::string out = cmStrCat(
root, '/',
this->GT->GetCFBundleDirectory(config, cmGeneratorTarget::FullLevel));
2018-04-23 21:13:27 +02:00
cmSystemTools::MakeDirectory(out);
2013-11-03 12:27:13 +02:00
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.
2020-08-30 11:54:41 +02:00
std::string plist = cmStrCat(
root, '/',
this->GT->GetCFBundleDirectory(config, cmGeneratorTarget::ContentLevel),
"/Info.plist");
2015-08-17 11:37:30 +02:00
std::string name = cmSystemTools::GetFilenameName(targetName);
2019-11-11 23:01:05 +01:00
this->LocalGenerator->GenerateAppleInfoPList(this->GT, name, plist);
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,
2020-08-30 11:54:41 +02:00
MacOSXContentGeneratorType* generator, const std::string& config)
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
2018-01-26 17:06:56 +01:00
for (cmSourceFile const* source : sources) {
2015-04-27 22:25:09 +02:00
cmGeneratorTarget::SourceFileFlags tsFlags =
2018-01-26 17:06:56 +01:00
this->GT->GetTargetSourceFileFlags(source);
2016-07-09 11:21:54 +02:00
if (tsFlags.Type != cmGeneratorTarget::SourceFileTypeNormal) {
2020-08-30 11:54:41 +02:00
(*generator)(*source, tsFlags.MacFolder, config);
2012-08-04 10:26:08 +03:00
}
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(
2020-08-30 11:54:41 +02:00
const char* pkgloc, const std::string& config)
2012-08-04 10:26:08 +03:00
{
// Construct the full path to the content subdirectory.
2013-11-03 12:27:13 +02:00
2020-08-30 11:54:41 +02:00
std::string macdir = cmStrCat(this->GT->GetMacContentDirectory(
config, cmStateEnums::RuntimeBinaryArtifact),
'/', pkgloc);
2018-04-23 21:13:27 +02:00
cmSystemTools::MakeDirectory(macdir);
2012-08-04 10:26:08 +03:00
// 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;
}