diff options
author | Brad King <brad.king@kitware.com> | 2017-03-31 14:39:59 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2017-03-31 14:40:02 (GMT) |
commit | c791fb12544926bc5870a61735dc2ec62940a6f6 (patch) | |
tree | f4cfb4a96b5a855e259240511530425b38ff01fb /Source | |
parent | 4a553ecb8e52dfd3ca605cd94ef8033e5febe937 (diff) | |
parent | d1dac1acc502af2f2b766cc9b262a4f1294be39b (diff) | |
download | CMake-c791fb12544926bc5870a61735dc2ec62940a6f6.zip CMake-c791fb12544926bc5870a61735dc2ec62940a6f6.tar.gz CMake-c791fb12544926bc5870a61735dc2ec62940a6f6.tar.bz2 |
Merge topic '16733-bundle-genex'
d1dac1ac Xcode: Execute RunCMake.Framework also for Xcode generator
d02709d7 Genex: Add `TARGET_BUNDLE_[CONTENT_]_DIR` generator expressions
013ffe76 cmGeneratorTarget: Call GetFrameworkDirectory in GetFullNameInternal
32e9d0ca cmGeneratorTarget: Use enum to describe bundle directory query level
Acked-by: Kitware Robot <kwrobot@kitware.com>
Reviewed-by: Craig Scott <craig.scott@crascit.com>
Merge-request: !635
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmGeneratorExpressionNode.cxx | 61 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 64 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.h | 23 | ||||
-rw-r--r-- | Source/cmOSXBundleGenerator.cxx | 24 |
4 files changed, 127 insertions, 45 deletions
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 66202df..4443499 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -1504,6 +1504,8 @@ class ArtifactNameTag; class ArtifactPathTag; class ArtifactPdbTag; class ArtifactSonameTag; +class ArtifactBundleDirTag; +class ArtifactBundleContentDirTag; template <typename ArtifactT> struct TargetFilesystemArtifactResultCreator @@ -1600,6 +1602,56 @@ struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag> }; template <> +struct TargetFilesystemArtifactResultCreator<ArtifactBundleDirTag> +{ + static std::string Create(cmGeneratorTarget* target, + cmGeneratorExpressionContext* context, + const GeneratorExpressionContent* content) + { + if (target->IsImported()) { + ::reportError(context, content->GetOriginalExpression(), + "TARGET_BUNDLE_DIR not allowed for IMPORTED targets."); + return std::string(); + } + if (!target->IsBundleOnApple()) { + ::reportError(context, content->GetOriginalExpression(), + "TARGET_BUNDLE_DIR is allowed only for Bundle targets."); + return std::string(); + } + + std::string outpath = target->GetDirectory(context->Config) + '/'; + return target->BuildBundleDirectory(outpath, context->Config, + cmGeneratorTarget::BundleDirLevel); + } +}; + +template <> +struct TargetFilesystemArtifactResultCreator<ArtifactBundleContentDirTag> +{ + static std::string Create(cmGeneratorTarget* target, + cmGeneratorExpressionContext* context, + const GeneratorExpressionContent* content) + { + if (target->IsImported()) { + ::reportError( + context, content->GetOriginalExpression(), + "TARGET_BUNDLE_CONTENT_DIR not allowed for IMPORTED targets."); + return std::string(); + } + if (!target->IsBundleOnApple()) { + ::reportError( + context, content->GetOriginalExpression(), + "TARGET_BUNDLE_CONTENT_DIR is allowed only for Bundle targets."); + return std::string(); + } + + std::string outpath = target->GetDirectory(context->Config) + '/'; + return target->BuildBundleDirectory(outpath, context->Config, + cmGeneratorTarget::ContentLevel); + } +}; + +template <> struct TargetFilesystemArtifactResultCreator<ArtifactNameTag> { static std::string Create(cmGeneratorTarget* target, @@ -1716,6 +1768,13 @@ static const TargetFilesystemArtifactNodeGroup<ArtifactSonameTag> static const TargetFilesystemArtifactNodeGroup<ArtifactPdbTag> targetPdbNodeGroup; +static const TargetFilesystemArtifact<ArtifactBundleDirTag, ArtifactPathTag> + targetBundleDirNode; + +static const TargetFilesystemArtifact<ArtifactBundleContentDirTag, + ArtifactPathTag> + targetBundleContentDirNode; + static const struct ShellPathNode : public cmGeneratorExpressionNode { ShellPathNode() {} @@ -1772,6 +1831,8 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode( nodeMap["TARGET_LINKER_FILE_DIR"] = &targetLinkerNodeGroup.FileDir; nodeMap["TARGET_SONAME_FILE_DIR"] = &targetSoNameNodeGroup.FileDir; nodeMap["TARGET_PDB_FILE_DIR"] = &targetPdbNodeGroup.FileDir; + nodeMap["TARGET_BUNDLE_DIR"] = &targetBundleDirNode; + nodeMap["TARGET_BUNDLE_CONTENT_DIR"] = &targetBundleContentDirNode; nodeMap["STREQUAL"] = &strEqualNode; nodeMap["EQUAL"] = &equalNode; nodeMap["LOWER_CASE"] = &lowerCaseNode; diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 73d2009..88f3978 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -914,7 +914,7 @@ const char* cmGeneratorTarget::GetLocationForBuild() const } if (this->IsAppBundleOnApple()) { - std::string macdir = this->BuildMacContentDirectory("", "", false); + std::string macdir = this->BuildBundleDirectory("", "", FullLevel); if (!macdir.empty()) { location += "/"; location += macdir; @@ -1544,8 +1544,19 @@ std::string cmGeneratorTarget::GetSOName(const std::string& config) const return soName; } -std::string cmGeneratorTarget::GetAppBundleDirectory(const std::string& config, - bool contentOnly) const +static bool shouldAddFullLevel(cmGeneratorTarget::BundleDirectoryLevel level) +{ + return level == cmGeneratorTarget::FullLevel; +} + +static bool shouldAddContentLevel( + cmGeneratorTarget::BundleDirectoryLevel level) +{ + return level == cmGeneratorTarget::ContentLevel || shouldAddFullLevel(level); +} + +std::string cmGeneratorTarget::GetAppBundleDirectory( + const std::string& config, BundleDirectoryLevel level) const { std::string fpath = this->GetFullName(config, false); fpath += "."; @@ -1554,9 +1565,9 @@ std::string cmGeneratorTarget::GetAppBundleDirectory(const std::string& config, ext = "app"; } fpath += ext; - if (!this->Makefile->PlatformIsAppleIos()) { + if (shouldAddContentLevel(level) && !this->Makefile->PlatformIsAppleIos()) { fpath += "/Contents"; - if (!contentOnly) { + if (shouldAddFullLevel(level)) { fpath += "/MacOS"; } } @@ -1569,8 +1580,8 @@ bool cmGeneratorTarget::IsBundleOnApple() const this->IsCFBundleOnApple(); } -std::string cmGeneratorTarget::GetCFBundleDirectory(const std::string& config, - bool contentOnly) const +std::string cmGeneratorTarget::GetCFBundleDirectory( + const std::string& config, BundleDirectoryLevel level) const { std::string fpath; fpath += this->GetOutputName(config, false); @@ -1584,17 +1595,17 @@ std::string cmGeneratorTarget::GetCFBundleDirectory(const std::string& config, } } fpath += ext; - if (!this->Makefile->PlatformIsAppleIos()) { + if (shouldAddContentLevel(level) && !this->Makefile->PlatformIsAppleIos()) { fpath += "/Contents"; - if (!contentOnly) { + if (shouldAddFullLevel(level)) { fpath += "/MacOS"; } } return fpath; } -std::string cmGeneratorTarget::GetFrameworkDirectory(const std::string& config, - bool rootDir) const +std::string cmGeneratorTarget::GetFrameworkDirectory( + const std::string& config, BundleDirectoryLevel level) const { std::string fpath; fpath += this->GetOutputName(config, false); @@ -1604,7 +1615,7 @@ std::string cmGeneratorTarget::GetFrameworkDirectory(const std::string& config, ext = "framework"; } fpath += ext; - if (!rootDir && !this->Makefile->PlatformIsAppleIos()) { + if (shouldAddFullLevel(level) && !this->Makefile->PlatformIsAppleIos()) { fpath += "/Versions/"; fpath += this->GetFrameworkVersion(); } @@ -1919,18 +1930,19 @@ void cmGeneratorTarget::GetFullNameComponents(std::string& prefix, this->GetFullNameInternal(config, implib, prefix, base, suffix); } -std::string cmGeneratorTarget::BuildMacContentDirectory( - const std::string& base, const std::string& config, bool contentOnly) const +std::string cmGeneratorTarget::BuildBundleDirectory( + const std::string& base, const std::string& config, + BundleDirectoryLevel level) const { std::string fpath = base; if (this->IsAppBundleOnApple()) { - fpath += this->GetAppBundleDirectory(config, contentOnly); + fpath += this->GetAppBundleDirectory(config, level); } if (this->IsFrameworkOnApple()) { - fpath += this->GetFrameworkDirectory(config, contentOnly); + fpath += this->GetFrameworkDirectory(config, level); } if (this->IsCFBundleOnApple()) { - fpath += this->GetCFBundleDirectory(config, contentOnly); + fpath += this->GetCFBundleDirectory(config, level); } return fpath; } @@ -1941,13 +1953,13 @@ std::string cmGeneratorTarget::GetMacContentDirectory( // Start with the output directory for the target. std::string fpath = this->GetDirectory(config, implib); fpath += "/"; - bool contentOnly = true; + BundleDirectoryLevel level = ContentLevel; if (this->IsFrameworkOnApple()) { // additional files with a framework go into the version specific // directory - contentOnly = false; + level = FullLevel; } - fpath = this->BuildMacContentDirectory(fpath, config, contentOnly); + fpath = this->BuildBundleDirectory(fpath, config, level); return fpath; } @@ -2997,7 +3009,7 @@ std::string cmGeneratorTarget::NormalGetFullPath(const std::string& config, std::string fpath = this->GetDirectory(config, implib); fpath += "/"; if (this->IsAppBundleOnApple()) { - fpath = this->BuildMacContentDirectory(fpath, config, false); + fpath = this->BuildBundleDirectory(fpath, config, FullLevel); fpath += "/"; } @@ -3281,20 +3293,14 @@ void cmGeneratorTarget::GetFullNameInternal(const std::string& config, // frameworks have directory prefix but no suffix std::string fw_prefix; if (this->IsFrameworkOnApple()) { - fw_prefix = this->GetOutputName(config, false); - fw_prefix += "."; - const char* ext = this->GetProperty("BUNDLE_EXTENSION"); - if (!ext) { - ext = "framework"; - } - fw_prefix += ext; + fw_prefix = this->GetFrameworkDirectory(config, ContentLevel); fw_prefix += "/"; targetPrefix = fw_prefix.c_str(); targetSuffix = CM_NULLPTR; } if (this->IsCFBundleOnApple()) { - fw_prefix = this->GetCFBundleDirectory(config, false); + fw_prefix = this->GetCFBundleDirectory(config, FullLevel); fw_prefix += "/"; targetPrefix = fw_prefix.c_str(); targetSuffix = CM_NULLPTR; diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index fcab4aa..255b89b 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -160,9 +160,17 @@ public: bool realname) const; std::string NormalGetRealName(const std::string& config) const; + /** What hierarchy level should the reported directory contain */ + enum BundleDirectoryLevel + { + BundleDirLevel, + ContentLevel, + FullLevel + }; + /** @return the Mac App directory without the base */ std::string GetAppBundleDirectory(const std::string& config, - bool contentOnly) const; + BundleDirectoryLevel level) const; /** Return whether this target is an executable Bundle, a framework or CFBundle on Apple. */ @@ -175,7 +183,7 @@ public: /** @return the Mac framework directory without the base. */ std::string GetFrameworkDirectory(const std::string& config, - bool rootDir) const; + BundleDirectoryLevel level) const; /** Return the framework version string. Undefined if IsFrameworkOnApple returns false. */ @@ -183,7 +191,7 @@ public: /** @return the Mac CFBundle directory without the base */ std::string GetCFBundleDirectory(const std::string& config, - bool contentOnly) const; + BundleDirectoryLevel level) const; /** Return the install name directory for the target in the * build tree. For example: "\@rpath/", "\@loader_path/", @@ -218,10 +226,11 @@ public: const std::string& config = "", bool implib = false) const; - /** Append to @a base the mac content directory and return it. */ - std::string BuildMacContentDirectory(const std::string& base, - const std::string& config = "", - bool contentOnly = true) const; + /** Append to @a base the bundle directory hierarchy up to a certain @a level + * and return it. */ + std::string BuildBundleDirectory(const std::string& base, + const std::string& config, + BundleDirectoryLevel level) const; /** @return the mac content directory for this target. */ std::string GetMacContentDirectory(const std::string& config = CM_NULLPTR, diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx index 8139be4..c9f6ceb 100644 --- a/Source/cmOSXBundleGenerator.cxx +++ b/Source/cmOSXBundleGenerator.cxx @@ -42,7 +42,8 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName, // Compute bundle directory names. std::string out = outpath; out += "/"; - out += this->GT->GetAppBundleDirectory(this->ConfigName, false); + out += this->GT->GetAppBundleDirectory(this->ConfigName, + cmGeneratorTarget::FullLevel); cmSystemTools::MakeDirectory(out.c_str()); this->Makefile->AddCMakeOutputFile(out); @@ -52,7 +53,8 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName, // to be set. std::string plist = outpath; plist += "/"; - plist += this->GT->GetAppBundleDirectory(this->ConfigName, true); + plist += this->GT->GetAppBundleDirectory(this->ConfigName, + cmGeneratorTarget::ContentLevel); plist += "/Info.plist"; this->LocalGenerator->GenerateAppleInfoPList(this->GT, targetName, plist.c_str()); @@ -70,12 +72,14 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName, assert(this->MacContentFolders); // Compute the location of the top-level foo.framework directory. - std::string contentdir = - outpath + "/" + this->GT->GetFrameworkDirectory(this->ConfigName, true); + std::string contentdir = outpath + "/" + + this->GT->GetFrameworkDirectory(this->ConfigName, + cmGeneratorTarget::ContentLevel); contentdir += "/"; - std::string newoutpath = - outpath + "/" + this->GT->GetFrameworkDirectory(this->ConfigName, false); + std::string newoutpath = outpath + "/" + + this->GT->GetFrameworkDirectory(this->ConfigName, + cmGeneratorTarget::FullLevel); std::string frameworkVersion = this->GT->GetFrameworkVersion(); @@ -170,14 +174,16 @@ void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName, // Compute bundle directory names. std::string out = root; out += "/"; - out += this->GT->GetCFBundleDirectory(this->ConfigName, false); + out += this->GT->GetCFBundleDirectory(this->ConfigName, + cmGeneratorTarget::FullLevel); cmSystemTools::MakeDirectory(out.c_str()); this->Makefile->AddCMakeOutputFile(out); // Configure the Info.plist file. Note that it needs the executable name // to be set. - std::string plist = - root + "/" + this->GT->GetCFBundleDirectory(this->ConfigName, true); + std::string plist = root + "/" + + this->GT->GetCFBundleDirectory(this->ConfigName, + cmGeneratorTarget::ContentLevel); plist += "/Info.plist"; std::string name = cmSystemTools::GetFilenameName(targetName); this->LocalGenerator->GenerateAppleInfoPList(this->GT, name, plist.c_str()); |