summaryrefslogtreecommitdiffstats
path: root/Source/cmGeneratorExpressionNode.cxx
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@gmail.com>2019-04-03 15:27:39 (GMT)
committerBrad King <brad.king@kitware.com>2019-04-08 11:49:08 (GMT)
commit1889ed923ea8c2dd204ca38b8109efdf1963c578 (patch)
tree85921aa33294bc3b2d488a5ba4ad84882128782b /Source/cmGeneratorExpressionNode.cxx
parent26b6d2aff0076b44fac605de0d3dbfc3f55e64fb (diff)
downloadCMake-1889ed923ea8c2dd204ca38b8109efdf1963c578.zip
CMake-1889ed923ea8c2dd204ca38b8109efdf1963c578.tar.gz
CMake-1889ed923ea8c2dd204ca38b8109efdf1963c578.tar.bz2
Genex: Add capability to retrieve base name for various target artifacts
This new capability is required to solve efficiently issue #18771
Diffstat (limited to 'Source/cmGeneratorExpressionNode.cxx')
-rw-r--r--Source/cmGeneratorExpressionNode.cxx123
1 files changed, 123 insertions, 0 deletions
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 481ea9e..cef36fc 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -2131,6 +2131,126 @@ static const TargetFilesystemArtifact<ArtifactBundleContentDirTag,
ArtifactPathTag>
targetBundleContentDirNode;
+//
+// To retrieve base name for various artifacts
+//
+template <typename ArtifactT>
+struct TargetOutputNameArtifactResultGetter
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content);
+};
+
+template <>
+struct TargetOutputNameArtifactResultGetter<ArtifactNameTag>
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* /*unused*/)
+ {
+ return target->GetOutputName(context->Config,
+ cmStateEnums::RuntimeBinaryArtifact);
+ }
+};
+
+template <>
+struct TargetOutputNameArtifactResultGetter<ArtifactLinkerTag>
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content)
+ {
+ // The file used to link to the target (.so, .lib, .a).
+ if (!target->IsLinkable()) {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_LINKER_OUTPUT_NAME is allowed only for libraries "
+ "and executables with ENABLE_EXPORTS.");
+ return std::string();
+ }
+ cmStateEnums::ArtifactType artifact =
+ target->HasImportLibrary(context->Config)
+ ? cmStateEnums::ImportLibraryArtifact
+ : cmStateEnums::RuntimeBinaryArtifact;
+ return target->GetOutputName(context->Config, artifact);
+ }
+};
+
+template <>
+struct TargetOutputNameArtifactResultGetter<ArtifactPdbTag>
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content)
+ {
+ if (target->IsImported()) {
+ ::reportError(
+ context, content->GetOriginalExpression(),
+ "TARGET_PDB_OUTPUT_NAME not allowed for IMPORTED targets.");
+ return std::string();
+ }
+
+ std::string language = target->GetLinkerLanguage(context->Config);
+
+ std::string pdbSupportVar = "CMAKE_" + language + "_LINKER_SUPPORTS_PDB";
+
+ if (!context->LG->GetMakefile()->IsOn(pdbSupportVar)) {
+ ::reportError(
+ context, content->GetOriginalExpression(),
+ "TARGET_PDB_OUTPUT_NAME is not supported by the target linker.");
+ return std::string();
+ }
+
+ cmStateEnums::TargetType targetType = target->GetType();
+
+ if (targetType != cmStateEnums::SHARED_LIBRARY &&
+ targetType != cmStateEnums::MODULE_LIBRARY &&
+ targetType != cmStateEnums::EXECUTABLE) {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_PDB_OUTPUT_NAME is allowed only for "
+ "targets with linker created artifacts.");
+ return std::string();
+ }
+
+ return target->GetPDBOutputName(context->Config);
+ }
+};
+
+template <typename ArtifactT>
+struct TargetOutputNameArtifact : public TargetArtifactBase
+{
+ TargetOutputNameArtifact() {} // NOLINT(modernize-use-equals-default)
+
+ int NumExpectedParameters() const override { return 1; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagChecker) const override
+ {
+ cmGeneratorTarget* target =
+ this->GetTarget(parameters, context, content, dagChecker);
+ if (!target) {
+ return std::string();
+ }
+
+ std::string result = TargetOutputNameArtifactResultGetter<ArtifactT>::Get(
+ target, context, content);
+ if (context->HadError) {
+ return std::string();
+ }
+ return result;
+ }
+};
+
+static const TargetOutputNameArtifact<ArtifactNameTag> targetOutputNameNode;
+
+static const TargetOutputNameArtifact<ArtifactLinkerTag>
+ targetLinkerOutputNameNode;
+
+static const TargetOutputNameArtifact<ArtifactPdbTag> targetPdbOutputNameNode;
+
static const struct ShellPathNode : public cmGeneratorExpressionNode
{
ShellPathNode() {} // NOLINT(modernize-use-equals-default)
@@ -2205,6 +2325,9 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
{ "TARGET_PDB_FILE_DIR", &targetPdbNodeGroup.FileDir },
{ "TARGET_BUNDLE_DIR", &targetBundleDirNode },
{ "TARGET_BUNDLE_CONTENT_DIR", &targetBundleContentDirNode },
+ { "TARGET_OUTPUT_NAME", &targetOutputNameNode },
+ { "TARGET_LINKER_OUTPUT_NAME", &targetLinkerOutputNameNode },
+ { "TARGET_PDB_OUTPUT_NAME", &targetPdbOutputNameNode },
{ "STREQUAL", &strEqualNode },
{ "EQUAL", &equalNode },
{ "IN_LIST", &inListNode },