summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClinton Stimpson <clinton@elemtech.com>2013-05-05 20:19:05 -0600
committerBrad King <brad.king@kitware.com>2013-05-23 10:42:49 -0400
commit373faae5e1c936351b143b0561c61ef9884303e1 (patch)
treed5559e6ed2dea2570492c1004c493bfcba76cb1e
parent78185f598c152b1dbce632e953874ce8132c5fe9 (diff)
downloadcmake-373faae5e1c936351b143b0561c61ef9884303e1.tar.gz
Refactor how bundles and frameworks are supported.
Make handling of directory separators consistent between non-bundle and bundle code. Remove xcode specific flag from cmTarget when getting install_name. Add (more) consistent convenience functions in cmTarget to get directories inside of bundles and frameworks to add files to. This refactor also fixes bug #12263 where frameworks had the wrong install name when SKIP_BUILD_RPATH. Also make install_name for frameworks consistent between Makefile and Xcode generator.
-rw-r--r--Source/cmExportBuildFileGenerator.cxx2
-rw-r--r--Source/cmExportInstallFileGenerator.cxx8
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx9
-rw-r--r--Source/cmInstallTargetGenerator.cxx14
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx5
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx13
-rw-r--r--Source/cmMakefileTargetGenerator.cxx2
-rw-r--r--Source/cmMakefileTargetGenerator.h1
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.cxx3
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx19
-rw-r--r--Source/cmNinjaTargetGenerator.cxx2
-rw-r--r--Source/cmOSXBundleGenerator.cxx102
-rw-r--r--Source/cmOSXBundleGenerator.h22
-rw-r--r--Source/cmTarget.cxx160
-rw-r--r--Source/cmTarget.h33
-rw-r--r--Tests/BundleUtilities/CMakeLists.txt3
16 files changed, 229 insertions, 169 deletions
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 7147f86be8..f8a32c2d8e 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -143,7 +143,7 @@ cmExportBuildFileGenerator
std::string prop = "IMPORTED_LOCATION";
prop += suffix;
std::string value;
- if(target->IsFrameworkOnApple() || target->IsAppBundleOnApple())
+ if(target->IsAppBundleOnApple())
{
value = target->GetFullPath(config, false);
}
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index ad12b5a13c..fff807c074 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -351,13 +351,7 @@ cmExportInstallFileGenerator
prop += suffix;
// Append the installed file name.
- if(target->IsFrameworkOnApple())
- {
- value += itgen->GetInstallFilename(target, config);
- value += ".framework/";
- value += itgen->GetInstallFilename(target, config);
- }
- else if(target->IsCFBundleOnApple())
+ if(target->IsCFBundleOnApple())
{
const char *ext = target->GetProperty("BUNDLE_EXTENSION");
if (!ext)
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index ceac564035..240d60c48f 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1823,6 +1823,11 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
pndir = target.GetDirectory(configName);
}
+ if(target.IsFrameworkOnApple())
+ {
+ pnprefix = "";
+ }
+
buildSettings->AddAttribute("EXECUTABLE_PREFIX",
this->CreateString(pnprefix.c_str()));
buildSettings->AddAttribute("EXECUTABLE_SUFFIX",
@@ -2156,14 +2161,14 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
if(target.GetType() == cmTarget::SHARED_LIBRARY)
{
// Get the install_name directory for the build tree.
- install_name_dir = target.GetInstallNameDirForBuildTree(configName, true);
+ install_name_dir = target.GetInstallNameDirForBuildTree(configName);
if(install_name_dir.empty())
{
// Xcode will not pass the -install_name option at all if INSTALL_PATH
// is not given or is empty. We must explicitly put the flag in the
// link flags to create an install_name with just the library soname.
extraLinkOptions += " -install_name ";
- extraLinkOptions += target.GetFullName(configName);
+ extraLinkOptions += target.GetSOName(configName);
}
else
{
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index 5f9b6585eb..9aac4401c2 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -198,14 +198,12 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
// Install the whole framework directory.
type = cmInstallType_DIRECTORY;
literal_args += " USE_SOURCE_PERMISSIONS";
- std::string from1 = fromDirConfig + targetName + ".framework";
+
+ std::string from1 = fromDirConfig + targetName;
+ from1 = cmSystemTools::GetFilenamePath(from1);
// Tweaks apply to the binary inside the bundle.
- std::string to1 = toDir + targetName;
- to1 += ".framework/Versions/";
- to1 += this->Target->GetFrameworkVersion();
- to1 += "/";
- to1 += targetName;
+ std::string to1 = toDir + targetNameReal;
filesFrom.push_back(from1);
filesTo.push_back(to1);
@@ -528,7 +526,7 @@ cmInstallTargetGenerator
// components of the install_name field then we need to create a
// mapping to be applied after installation.
std::string for_build = tgt->GetInstallNameDirForBuildTree(config);
- std::string for_install = tgt->GetInstallNameDirForInstallTree(config);
+ std::string for_install = tgt->GetInstallNameDirForInstallTree();
if(for_build != for_install)
{
// The directory portions differ. Append the filename to
@@ -555,7 +553,7 @@ cmInstallTargetGenerator
std::string for_build =
this->Target->GetInstallNameDirForBuildTree(config);
std::string for_install =
- this->Target->GetInstallNameDirForInstallTree(config);
+ this->Target->GetInstallNameDirForInstallTree();
if(this->Target->IsFrameworkOnApple() && for_install.empty())
{
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index b7a454b17b..e4219a9459 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -30,11 +30,8 @@ cmMakefileExecutableTargetGenerator
this->TargetNamePDB, this->ConfigName);
this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target,
- this->TargetNameOut,
this->ConfigName);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
- this->MacContentDirectory =
- this->OSXBundleGenerator->GetMacContentDirectory();
}
//----------------------------------------------------------------------------
@@ -103,11 +100,11 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Construct the full path version of the names.
std::string outpath = this->Target->GetDirectory(this->ConfigName);
- outpath += "/";
if(this->Target->IsAppBundleOnApple())
{
this->OSXBundleGenerator->CreateAppBundle(targetName, outpath);
}
+ outpath += "/";
std::string outpathImp;
if(relink)
{
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 5b4e4d7743..3edaa44f10 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -32,11 +32,8 @@ cmMakefileLibraryTargetGenerator
this->TargetNameImport, this->TargetNamePDB, this->ConfigName);
this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target,
- this->TargetNameOut,
this->ConfigName);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
- this->MacContentDirectory =
- this->OSXBundleGenerator->GetMacContentDirectory();
}
//----------------------------------------------------------------------------
@@ -292,14 +289,15 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
std::string outpathImp;
if(this->Target->IsFrameworkOnApple())
{
- outpath = this->MacContentDirectory;
- this->OSXBundleGenerator->CreateFramework(targetName);
+ outpath = this->Target->GetDirectory(this->ConfigName);
+ this->OSXBundleGenerator->CreateFramework(targetName, outpath);
+ outpath += "/";
}
else if(this->Target->IsCFBundleOnApple())
{
outpath = this->Target->GetDirectory(this->ConfigName);
- outpath += "/";
this->OSXBundleGenerator->CreateCFBundle(targetName, outpath);
+ outpath += "/";
}
else if(relink)
{
@@ -727,7 +725,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
commands1.clear();
// Add a rule to create necessary symlinks for the library.
- if(targetOutPath != targetOutPathReal)
+ // Frameworks are handled by cmOSXBundleGenerator.
+ if(targetOutPath != targetOutPathReal && !this->Target->IsFrameworkOnApple())
{
std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_library ";
symlink += targetOutPathReal;
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 4220ae1486..6fc88d62de 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -357,7 +357,7 @@ cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()
(cmSourceFile& source, const char* pkgloc)
{
// Skip OS X content when not building a Framework or Bundle.
- if(this->Generator->MacContentDirectory.empty())
+ if(!this->Generator->GetTarget()->IsBundleOnApple())
{
return;
}
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 2798e5462c..f7a1e2e56a 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -233,7 +233,6 @@ protected:
std::string TargetNamePDB;
// Mac OS X content info.
- std::string MacContentDirectory;
std::set<cmStdString> MacContentFolders;
cmOSXBundleGenerator* OSXBundleGenerator;
MacOSXContentGeneratorType* MacOSXContentGenerator;
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index 4456aa7946..1fa4e95b6f 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -25,11 +25,8 @@ cmMakefileUtilityTargetGenerator
{
this->CustomCommandDriver = OnUtility;
this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target,
- this->TargetNameOut,
this->ConfigName);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
- this->MacContentDirectory =
- this->OSXBundleGenerator->GetMacContentDirectory();
}
//----------------------------------------------------------------------------
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 7e48cd716e..e5a6eabee4 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -61,7 +61,6 @@ cmNinjaNormalTargetGenerator(cmTarget* target)
}
this->OSXBundleGenerator = new cmOSXBundleGenerator(target,
- this->TargetNameOut,
this->GetConfigName());
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
}
@@ -383,24 +382,32 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
if (this->GetTarget()->IsAppBundleOnApple())
{
// Create the app bundle
- std::string outpath;
+ std::string outpath =
+ this->GetTarget()->GetDirectory(this->GetConfigName());
this->OSXBundleGenerator->CreateAppBundle(this->TargetNameOut, outpath);
// Calculate the output path
- targetOutput = outpath + this->TargetNameOut;
+ targetOutput = outpath;
+ targetOutput += "/";
+ targetOutput += this->TargetNameOut;
targetOutput = this->ConvertToNinjaPath(targetOutput.c_str());
- targetOutputReal = outpath + this->TargetNameReal;
+ targetOutputReal = outpath;
+ targetOutputReal += "/";
+ targetOutputReal += this->TargetNameReal;
targetOutputReal = this->ConvertToNinjaPath(targetOutputReal.c_str());
}
else if (this->GetTarget()->IsFrameworkOnApple())
{
// Create the library framework.
- this->OSXBundleGenerator->CreateFramework(this->TargetNameOut);
+ std::string outpath =
+ this->GetTarget()->GetDirectory(this->GetConfigName());
+ this->OSXBundleGenerator->CreateFramework(this->TargetNameOut, outpath);
}
else if(this->GetTarget()->IsCFBundleOnApple())
{
// Create the core foundation bundle.
- std::string outpath;
+ std::string outpath =
+ this->GetTarget()->GetDirectory(this->GetConfigName());
this->OSXBundleGenerator->CreateCFBundle(this->TargetNameOut, outpath);
}
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 3fb823cb03..38305e2706 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -701,7 +701,7 @@ cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
cmSourceFile& source, const char* pkgloc)
{
// Skip OS X content when not building a Framework or Bundle.
- if(this->Generator->OSXBundleGenerator->GetMacContentDirectory().empty())
+ if(!this->Generator->GetTarget()->IsBundleOnApple())
{
return;
}
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx
index 42fad07426..621a49fecc 100644
--- a/Source/cmOSXBundleGenerator.cxx
+++ b/Source/cmOSXBundleGenerator.cxx
@@ -28,26 +28,16 @@ void cmOSXBundleGenerator::PrepareTargetProperties(cmTarget* target)
//----------------------------------------------------------------------------
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();
}
//----------------------------------------------------------------------------
@@ -57,41 +47,60 @@ bool cmOSXBundleGenerator::MustSkip()
}
//----------------------------------------------------------------------------
-void cmOSXBundleGenerator::CreateAppBundle(std::string& targetName,
+void cmOSXBundleGenerator::CreateAppBundle(const 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());
+ std::string out = outpath;
+ out += "/";
+ out += this->Target->GetAppBundleDirectory(this->ConfigName, false);
+ cmSystemTools::MakeDirectory(out.c_str());
+ this->Makefile->AddCMakeOutputFile(out.c_str());
+
+ std::string newoutpath = out;
// Configure the Info.plist file. Note that it needs the executable name
// to be set.
- std::string plist = this->MacContentDirectory + "Info.plist";
+ std::string plist = outpath;
+ plist += "/";
+ plist += this->Target->GetAppBundleDirectory(this->ConfigName, true);
+ plist += "/Info.plist";
this->LocalGenerator->GenerateAppleInfoPList(this->Target,
targetName.c_str(),
plist.c_str());
this->Makefile->AddCMakeOutputFile(plist.c_str());
+ outpath = newoutpath;
}
//----------------------------------------------------------------------------
-void cmOSXBundleGenerator::CreateFramework(std::string const& targetName)
+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->Target->GetFrameworkDirectory(this->ConfigName, true);
+ contentdir += "/";
+
+ std::string newoutpath = outpath + "/" +
+ this->Target->GetFrameworkDirectory(this->ConfigName, false);
+
+ std::string frameworkVersion = this->Target->GetFrameworkVersion();
+
// Configure the Info.plist file into the Resources directory.
this->MacContentFolders->insert("Resources");
- std::string plist = this->MacContentDirectory + "Resources/Info.plist";
+ std::string plist = newoutpath;
+ plist += "/Resources/Info.plist";
+ std::string name = cmSystemTools::GetFilenameName(targetName);
this->LocalGenerator->GenerateFrameworkInfoPList(this->Target,
- targetName.c_str(),
+ name.c_str(),
plist.c_str());
// TODO: Use the cmMakefileTargetGenerator::ExtraFiles vector to
@@ -99,25 +108,17 @@ void cmOSXBundleGenerator::CreateFramework(std::string const& targetName)
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;
+ std::string versions = contentdir;
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());
+ cmSystemTools::MakeDirectory(newoutpath.c_str());
// Current -> version
- oldName = this->FrameworkVersion;
+ oldName = frameworkVersion;
newName = versions;
newName += "/Current";
cmSystemTools::RemoveFile(newName.c_str());
@@ -126,9 +127,9 @@ void cmOSXBundleGenerator::CreateFramework(std::string const& targetName)
// foo -> Versions/Current/foo
oldName = "Versions/Current/";
- oldName += this->TargetNameOut;
- newName = top;
- newName += this->TargetNameOut;
+ oldName += name;
+ newName = contentdir;
+ newName += name;
cmSystemTools::RemoveFile(newName.c_str());
cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
this->Makefile->AddCMakeOutputFile(newName.c_str());
@@ -138,7 +139,7 @@ void cmOSXBundleGenerator::CreateFramework(std::string const& targetName)
this->MacContentFolders->end())
{
oldName = "Versions/Current/Resources";
- newName = top;
+ newName = contentdir;
newName += "Resources";
cmSystemTools::RemoveFile(newName.c_str());
cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
@@ -150,7 +151,7 @@ void cmOSXBundleGenerator::CreateFramework(std::string const& targetName)
this->MacContentFolders->end())
{
oldName = "Versions/Current/Headers";
- newName = top;
+ newName = contentdir;
newName += "Headers";
cmSystemTools::RemoveFile(newName.c_str());
cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
@@ -162,7 +163,7 @@ void cmOSXBundleGenerator::CreateFramework(std::string const& targetName)
this->MacContentFolders->end())
{
oldName = "Versions/Current/PrivateHeaders";
- newName = top;
+ newName = contentdir;
newName += "PrivateHeaders";
cmSystemTools::RemoveFile(newName.c_str());
cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
@@ -171,27 +172,32 @@ void cmOSXBundleGenerator::CreateFramework(std::string const& targetName)
}
//----------------------------------------------------------------------------
-void cmOSXBundleGenerator::CreateCFBundle(std::string& targetName,
+void cmOSXBundleGenerator::CreateCFBundle(const 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());
+ std::string out = outpath;
+ out += "/";
+ out += this->Target->GetCFBundleDirectory(this->ConfigName, true);
+ std::string top = out;
+ out += "/MacOS";
+ cmSystemTools::MakeDirectory(out.c_str());
+ this->Makefile->AddCMakeOutputFile(out.c_str());
+
+ std::string newoutpath = out;
// Configure the Info.plist file. Note that it needs the executable name
// to be set.
- std::string plist = this->MacContentDirectory;
- plist += "Info.plist";
+ std::string plist = top;
+ plist += "/Info.plist";
this->LocalGenerator->GenerateAppleInfoPList(this->Target,
targetName.c_str(),
plist.c_str());
this->Makefile->AddCMakeOutputFile(plist.c_str());
+ outpath = newoutpath;
}
//----------------------------------------------------------------------------
@@ -220,7 +226,11 @@ std::string
cmOSXBundleGenerator::InitMacOSXContentDirectory(const char* pkgloc)
{
// Construct the full path to the content subdirectory.
- std::string macdir = this->MacContentDirectory;
+
+ std::string macdir =
+ this->Target->GetMacContentDirectory(this->ConfigName,
+ /*implib*/ false);
+ macdir += "/";
macdir += pkgloc;
cmSystemTools::MakeDirectory(macdir.c_str());
diff --git a/Source/cmOSXBundleGenerator.h b/Source/cmOSXBundleGenerator.h
index 01e3cbeb43..6cf81d25d5 100644
--- a/Source/cmOSXBundleGenerator.h
+++ b/Source/cmOSXBundleGenerator.h
@@ -28,12 +28,19 @@ public:
static void PrepareTargetProperties(cmTarget* target);
cmOSXBundleGenerator(cmTarget* target,
- std::string targetNameOut,
const char* configName);
- void CreateAppBundle(std::string& targetName, std::string& outpath);
- void CreateFramework(std::string const& targetName);
- void CreateCFBundle(std::string& targetName, std::string& outpath);
+ // create an app bundle at a given root, and return
+ // the directory within the bundle that contains the executable
+ void CreateAppBundle(const std::string& targetName, std::string& root);
+
+ // create a framework at a given root
+ void CreateFramework(const std::string& targetName,
+ const std::string& root);
+
+ // create a cf bundle at a given root and return the
+ // directory within the bundle that contains the library
+ void CreateCFBundle(const std::string& targetName, std::string& outpath);
struct MacOSXContentGeneratorType
{
@@ -46,10 +53,6 @@ public:
MacOSXContentGeneratorType* generator);
std::string InitMacOSXContentDirectory(const char* pkgloc);
- std::string GetMacContentDirectory() const
- { return this->MacContentDirectory; }
- std::string GetFrameworkVersion() const
- { return this->FrameworkVersion; }
void SetMacContentFolders(std::set<cmStdString>* macContentFolders)
{ this->MacContentFolders = macContentFolders; }
@@ -60,10 +63,7 @@ private:
cmTarget* Target;
cmMakefile* Makefile;
cmLocalGenerator* LocalGenerator;
- std::string TargetNameOut;
const char* ConfigName;
- std::string MacContentDirectory;
- std::string FrameworkVersion;
std::set<cmStdString>* MacContentFolders;
};
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 66c22b16e4..093b30e214 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -1656,6 +1656,13 @@ bool cmTarget::IsCFBundleOnApple()
}
//----------------------------------------------------------------------------
+bool cmTarget::IsBundleOnApple()
+{
+ return this->IsFrameworkOnApple() || this->IsAppBundleOnApple() ||
+ this->IsCFBundleOnApple();
+}
+
+//----------------------------------------------------------------------------
class cmTargetTraceDependencies
{
public:
@@ -3264,17 +3271,23 @@ const char* cmTarget::NormalGetLocation(const char* config)
// Now handle the deprecated build-time configuration location.
this->Location = this->GetDirectory();
- if(!this->Location.empty())
- {
- this->Location += "/";
- }
const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
if(cfgid && strcmp(cfgid, ".") != 0)
{
- this->Location += cfgid;
this->Location += "/";
+ this->Location += cfgid;
+ }
+
+ if(this->IsCFBundleOnApple() || this->IsAppBundleOnApple())
+ {
+ std::string macdir = this->BuildMacContentDirectory("", config, false);
+ if(!macdir.empty())
+ {
+ this->Location += "/";
+ this->Location += macdir;
+ }
}
- this->Location = this->BuildMacContentDirectory(this->Location, config);
+ this->Location += "/";
this->Location += this->GetFullName(config, false);
return this->Location.c_str();
}
@@ -3876,7 +3889,13 @@ std::string cmTarget::GetFullPath(const char* config, bool implib,
std::string cmTarget::NormalGetFullPath(const char* config, bool implib,
bool realname)
{
- std::string fpath = this->GetMacContentDirectory(config, implib);
+ std::string fpath = this->GetDirectory(config, implib);
+ fpath += "/";
+ if(this->IsCFBundleOnApple() || this->IsAppBundleOnApple())
+ {
+ fpath = this->BuildMacContentDirectory(fpath, config, false);
+ fpath += "/";
+ }
// Add the full name of the target.
if(implib)
@@ -4008,10 +4027,13 @@ void cmTarget::GetFullNameInternal(const char* config,
targetSuffix = this->Makefile->GetSafeDefinition(suffixVar);
}
- // frameworks do not have a prefix or a suffix
+ // frameworks have directory prefix but no suffix
+ std::string fw_prefix;
if(this->IsFrameworkOnApple())
{
- targetPrefix = 0;
+ fw_prefix = this->GetOutputName(config, false);
+ fw_prefix += ".framework/";
+ targetPrefix = fw_prefix.c_str();
targetSuffix = 0;
}
@@ -4091,13 +4113,24 @@ void cmTarget::GetLibraryNames(std::string& name,
// The library name.
name = prefix+base+suffix;
- // The library's soname.
- this->ComputeVersionedName(soName, prefix, base, suffix,
- name, soversion);
-
- // The library's real name on disk.
- this->ComputeVersionedName(realName, prefix, base, suffix,
- name, version);
+ if(this->IsFrameworkOnApple())
+ {
+ realName = prefix;
+ realName += "Versions/";
+ realName += this->GetFrameworkVersion();
+ realName += "/";
+ realName += base;
+ soName = realName;
+ }
+ else
+ {
+ // The library's soname.
+ this->ComputeVersionedName(soName, prefix, base, suffix,
+ name, soversion);
+ // The library's real name on disk.
+ this->ComputeVersionedName(realName, prefix, base, suffix,
+ name, version);
+ }
// The import library name.
if(this->GetType() == cmTarget::SHARED_LIBRARY ||
@@ -4385,14 +4418,13 @@ bool cmTarget::NeedRelinkBeforeInstall(const char* config)
}
//----------------------------------------------------------------------------
-std::string cmTarget::GetInstallNameDirForBuildTree(const char* config,
- bool for_xcode)
+std::string cmTarget::GetInstallNameDirForBuildTree(const char* config)
{
// If building directly for installation then the build tree install_name
// is the same as the install tree.
if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
{
- return GetInstallNameDirForInstallTree(config, for_xcode);
+ return GetInstallNameDirForInstallTree();
}
// Use the build tree directory for the target.
@@ -4402,10 +4434,6 @@ std::string cmTarget::GetInstallNameDirForBuildTree(const char* config,
{
std::string dir = this->GetDirectory(config);
dir += "/";
- if(this->IsFrameworkOnApple() && !for_xcode)
- {
- dir += this->GetFrameworkDirectory(config);
- }
return dir;
}
else
@@ -4415,8 +4443,7 @@ std::string cmTarget::GetInstallNameDirForBuildTree(const char* config,
}
//----------------------------------------------------------------------------
-std::string cmTarget::GetInstallNameDirForInstallTree(const char* config,
- bool for_xcode)
+std::string cmTarget::GetInstallNameDirForInstallTree()
{
if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
{
@@ -4432,12 +4459,6 @@ std::string cmTarget::GetInstallNameDirForInstallTree(const char* config,
dir += "/";
}
}
-
- if(this->IsFrameworkOnApple() && !for_xcode)
- {
- dir += this->GetFrameworkDirectory(config);
- }
-
return dir;
}
else
@@ -5896,59 +5917,86 @@ cmTarget::GetLinkInformation(const char* config, cmTarget *head)
}
//----------------------------------------------------------------------------
-std::string cmTarget::GetFrameworkDirectory(const char* config)
+std::string cmTarget::GetFrameworkDirectory(const char* config,
+ bool rootDir)
{
std::string fpath;
- fpath += this->GetFullName(config, false);
- fpath += ".framework/Versions/";
- fpath += this->GetFrameworkVersion();
- fpath += "/";
+ fpath += this->GetOutputName(config, false);
+ fpath += ".framework";
+ if(!rootDir)
+ {
+ fpath += "/Versions/";
+ fpath += this->GetFrameworkVersion();
+ }
+ return fpath;
+}
+
+//----------------------------------------------------------------------------
+std::string cmTarget::GetCFBundleDirectory(const char* config,
+ bool contentOnly)
+{
+ std::string fpath;
+ fpath += this->GetOutputName(config, false);
+ fpath += ".";
+ const char *ext = this->GetProperty("BUNDLE_EXTENSION");
+ if (!ext)
+ {
+ ext = "bundle";
+ }
+ fpath += ext;
+ fpath += "/Contents";
+ if(!contentOnly)
+ fpath += "/MacOS";
+ return fpath;
+}
+
+//----------------------------------------------------------------------------
+std::string cmTarget::GetAppBundleDirectory(const char* config,
+ bool contentOnly)
+{
+ std::string fpath = this->GetFullName(config, false);
+ fpath += ".app/Contents";
+ if(!contentOnly)
+ fpath += "/MacOS";
return fpath;
}
//----------------------------------------------------------------------------
std::string cmTarget::BuildMacContentDirectory(const std::string& base,
const char* config,
- bool includeMacOS)
+ bool contentOnly)
{
std::string fpath = base;
if(this->IsAppBundleOnApple())
{
- fpath += this->GetFullName(config, false);
- fpath += ".app/Contents/";
- if(includeMacOS)
- fpath += "MacOS/";
+ fpath += this->GetAppBundleDirectory(config, contentOnly);
}
if(this->IsFrameworkOnApple())
{
- fpath += this->GetFrameworkDirectory(config);
+ fpath += this->GetFrameworkDirectory(config, contentOnly);
}
if(this->IsCFBundleOnApple())
{
- fpath += this->GetFullName(config, false);
- fpath += ".";
- const char *ext = this->GetProperty("BUNDLE_EXTENSION");
- if (!ext)
- {
- ext = "bundle";
- }
- fpath += ext;
- fpath += "/Contents/";
- if(includeMacOS)
- fpath += "MacOS/";
+ fpath += this->GetCFBundleDirectory(config, contentOnly);
}
return fpath;
}
//----------------------------------------------------------------------------
std::string cmTarget::GetMacContentDirectory(const char* config,
- bool implib,
- bool includeMacOS)
+ bool implib)
{
// Start with the output directory for the target.
std::string fpath = this->GetDirectory(config, implib);
fpath += "/";
- fpath = this->BuildMacContentDirectory(fpath, config, includeMacOS);
+ bool contentOnly = true;
+ if(this->IsFrameworkOnApple())
+ {
+ // additional files with a framework go into the version specific
+ // directory
+ contentOnly = false;
+ }
+ fpath = this->BuildMacContentDirectory(fpath, config, contentOnly);
return fpath;
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index e25133e585..4264e76286 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -407,10 +407,8 @@ public:
/** Return true if builtin chrpath will work for this target */
bool IsChrpathUsed(const char* config);
- std::string GetInstallNameDirForBuildTree(const char* config,
- bool for_xcode = false);
- std::string GetInstallNameDirForInstallTree(const char* config,
- bool for_xcode = false);
+ std::string GetInstallNameDirForBuildTree(const char* config);
+ std::string GetInstallNameDirForInstallTree();
cmComputeLinkInformation* GetLinkInformation(const char* config,
cmTarget *head = 0);
@@ -462,6 +460,10 @@ public:
/** Return whether this target is an executable Bundle on Apple. */
bool IsAppBundleOnApple();
+ /** Return whether this target is an executable Bundle, a framework
+ or CFBundle on Apple. */
+ bool IsBundleOnApple();
+
/** Return the framework version string. Undefined if
IsFrameworkOnApple returns false. */
std::string GetFrameworkVersion();
@@ -476,21 +478,21 @@ public:
directory. */
bool UsesDefaultOutputDir(const char* config, bool implib);
- /** Append to @a base the mac content directory and return it. */
- std::string BuildMacContentDirectory(const std::string& base,
- const char* config = 0,
- bool includeMacOS = true);
-
/** @return the mac content directory for this target. */
- std::string GetMacContentDirectory(const char* config = 0,
- bool implib = false,
- bool includeMacOS = true);
+ std::string GetMacContentDirectory(const char* config,
+ bool implib);
/** @return whether this target have a well defined output file name. */
bool HaveWellDefinedOutputFiles();
/** @return the Mac framework directory without the base. */
- std::string GetFrameworkDirectory(const char* config = 0);
+ std::string GetFrameworkDirectory(const char* config, bool rootDir);
+
+ /** @return the Mac CFBundle directory without the base */
+ std::string GetCFBundleDirectory(const char* config, bool contentOnly);
+
+ /** @return the Mac App directory without the base */
+ std::string GetAppBundleDirectory(const char* config, bool contentOnly);
std::vector<std::string> GetIncludeDirectories(const char *config);
void InsertInclude(const cmValueWithOrigin &entry,
@@ -597,6 +599,11 @@ private:
the same as GetFullName. */
std::string NormalGetRealName(const char* config);
+ /** Append to @a base the mac content directory and return it. */
+ std::string BuildMacContentDirectory(const std::string& base,
+ const char* config,
+ bool contentOnly);
+
private:
std::string Name;
std::vector<cmCustomCommand> PreBuildCommands;
diff --git a/Tests/BundleUtilities/CMakeLists.txt b/Tests/BundleUtilities/CMakeLists.txt
index 8f24afe9ab..5cc7071b49 100644
--- a/Tests/BundleUtilities/CMakeLists.txt
+++ b/Tests/BundleUtilities/CMakeLists.txt
@@ -12,8 +12,7 @@ add_library(shared2 SHARED shared2.cpp shared2.h)
# a framework library
add_library(framework SHARED framework.cpp framework.h)
-# TODO: fix problems with local frameworks without rpaths
-#set_target_properties(framework PROPERTIES FRAMEWORK 1)
+set_target_properties(framework PROPERTIES FRAMEWORK 1)
# make sure rpaths are not helping BundleUtilities or the executables
set_target_properties(shared shared2 framework PROPERTIES