diff options
author | Marc Chevrier <marc.chevrier@gmail.com> | 2019-04-03 15:27:39 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2019-04-08 11:49:08 (GMT) |
commit | 1889ed923ea8c2dd204ca38b8109efdf1963c578 (patch) | |
tree | 85921aa33294bc3b2d488a5ba4ad84882128782b /Source/cmGeneratorExpressionNode.cxx | |
parent | 26b6d2aff0076b44fac605de0d3dbfc3f55e64fb (diff) | |
download | CMake-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.cxx | 123 |
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 }, |