diff options
author | Brad King <brad.king@kitware.com> | 2019-04-08 11:52:50 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2019-04-08 11:52:58 (GMT) |
commit | 14270eab369c3b700d89ef385af2cb94a6497b1e (patch) | |
tree | ba92e35d06e15056bd869371b9977b3c95750a95 /Source | |
parent | c756fbce9ba94e2d7f1b787d595df24dbe99c9c1 (diff) | |
parent | 1889ed923ea8c2dd204ca38b8109efdf1963c578 (diff) | |
download | CMake-14270eab369c3b700d89ef385af2cb94a6497b1e.zip CMake-14270eab369c3b700d89ef385af2cb94a6497b1e.tar.gz CMake-14270eab369c3b700d89ef385af2cb94a6497b1e.tar.bz2 |
Merge topic 'genex-output_name'
1889ed923e Genex: Add capability to retrieve base name for various target artifacts
26b6d2aff0 Refactor struct TargetFileSystemArtifact
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !3190
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmGeneratorExpressionNode.cxx | 164 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 25 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.h | 3 |
3 files changed, 182 insertions, 10 deletions
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 19d2b3a..cef36fc 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -2023,18 +2023,16 @@ struct TargetFilesystemArtifactResultGetter<ArtifactPathTag> static std::string Get(const std::string& result) { return result; } }; -template <typename ArtifactT, typename ComponentT> -struct TargetFilesystemArtifact : public cmGeneratorExpressionNode +struct TargetArtifactBase : public cmGeneratorExpressionNode { - TargetFilesystemArtifact() {} // NOLINT(modernize-use-equals-default) - - int NumExpectedParameters() const override { return 1; } + TargetArtifactBase() {} // NOLINT(modernize-use-equals-default) - std::string Evaluate( +protected: + cmGeneratorTarget* GetTarget( const std::vector<std::string>& parameters, cmGeneratorExpressionContext* context, const GeneratorExpressionContent* content, - cmGeneratorExpressionDAGChecker* dagChecker) const override + cmGeneratorExpressionDAGChecker* dagChecker) const { // Lookup the referenced target. std::string name = parameters.front(); @@ -2042,20 +2040,20 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode if (!cmGeneratorExpression::IsValidTargetName(name)) { ::reportError(context, content->GetOriginalExpression(), "Expression syntax not recognized."); - return std::string(); + return nullptr; } cmGeneratorTarget* target = context->LG->FindGeneratorTargetToUse(name); if (!target) { ::reportError(context, content->GetOriginalExpression(), "No target \"" + name + "\""); - return std::string(); + return nullptr; } if (target->GetType() >= cmStateEnums::OBJECT_LIBRARY && target->GetType() != cmStateEnums::UNKNOWN_LIBRARY) { ::reportError(context, content->GetOriginalExpression(), "Target \"" + name + "\" is not an executable or library."); - return std::string(); + return nullptr; } if (dagChecker && (dagChecker->EvaluatingLinkLibraries(target) || @@ -2064,6 +2062,29 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode ::reportError(context, content->GetOriginalExpression(), "Expressions which require the linker language may not " "be used while evaluating link libraries"); + return nullptr; + } + + return target; + } +}; + +template <typename ArtifactT, typename ComponentT> +struct TargetFilesystemArtifact : public TargetArtifactBase +{ + TargetFilesystemArtifact() {} // 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(); } context->DependTargets.insert(target); @@ -2110,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) @@ -2184,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 }, diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 23b5bcb..f8c16cc 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -3884,6 +3884,31 @@ std::string cmGeneratorTarget::GetLinkerLanguage( return this->GetLinkClosure(config)->LinkerLanguage; } +std::string cmGeneratorTarget::GetPDBOutputName( + const std::string& config) const +{ + std::string base = + this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact); + + std::vector<std::string> props; + std::string configUpper = cmSystemTools::UpperCase(config); + if (!configUpper.empty()) { + // PDB_NAME_<CONFIG> + props.push_back("PDB_NAME_" + configUpper); + } + + // PDB_NAME + props.emplace_back("PDB_NAME"); + + for (std::string const& p : props) { + if (const char* outName = this->GetProperty(p)) { + base = outName; + break; + } + } + return base; +} + std::string cmGeneratorTarget::GetPDBName(const std::string& config) const { std::string prefix; diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 3f2025e..065b457 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -503,6 +503,9 @@ public: OutputInfo const* GetOutputInfo(const std::string& config) const; + // Get the target PDB base name. + std::string GetPDBOutputName(const std::string& config) const; + /** Get the name of the pdb file for the target. */ std::string GetPDBName(const std::string& config = "") const; |