summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2019-04-12 14:22:23 (GMT)
committerKitware Robot <kwrobot@kitware.com>2019-04-12 14:22:33 (GMT)
commite3ebad7def73fa656069835e916db3245ab70a62 (patch)
treeb0c620ac8fac52dbed69edc8c909fa816fe68931 /Source
parent4adc0b7c758ed98776bec63d21bb2037b0f28e2d (diff)
parentb70bac647dd2124011f8b98c7472ecfebb404d35 (diff)
downloadCMake-e3ebad7def73fa656069835e916db3245ab70a62.zip
CMake-e3ebad7def73fa656069835e916db3245ab70a62.tar.gz
CMake-e3ebad7def73fa656069835e916db3245ab70a62.tar.bz2
Merge topic 'genex-target-prefix-suffix'
b70bac647d Genex: add $<TARGET_FILE_PREFIX:...> and $<TARGET_FILE_SUFFIX:...> f65763fe9b Refactor: Add new methods to retrieve prefix and suffix Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !3207
Diffstat (limited to 'Source')
-rw-r--r--Source/cmGeneratorExpressionNode.cxx117
-rw-r--r--Source/cmGeneratorTarget.cxx163
-rw-r--r--Source/cmGeneratorTarget.h14
3 files changed, 264 insertions, 30 deletions
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index d8e1c42..af409e4 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -2297,6 +2297,119 @@ static const TargetOutputNameArtifact<ArtifactLinkerTag>
static const TargetOutputNameArtifact<ArtifactPdbTag> targetPdbOutputNameNode;
+class ArtifactFilePrefixTag;
+class ArtifactLinkerFilePrefixTag;
+class ArtifactFileSuffixTag;
+class ArtifactLinkerFileSuffixTag;
+
+template <typename ArtifactT>
+struct TargetFileArtifactResultGetter
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content);
+};
+
+template <>
+struct TargetFileArtifactResultGetter<ArtifactFilePrefixTag>
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent*)
+ {
+ return target->GetFilePrefix(context->Config);
+ }
+};
+template <>
+struct TargetFileArtifactResultGetter<ArtifactLinkerFilePrefixTag>
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content)
+ {
+ if (!target->IsLinkable()) {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_LINKER_PREFIX 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->GetFilePrefix(context->Config, artifact);
+ }
+};
+template <>
+struct TargetFileArtifactResultGetter<ArtifactFileSuffixTag>
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent*)
+ {
+ return target->GetFileSuffix(context->Config);
+ }
+};
+template <>
+struct TargetFileArtifactResultGetter<ArtifactLinkerFileSuffixTag>
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content)
+ {
+ if (!target->IsLinkable()) {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_LINKER_SUFFIX 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->GetFileSuffix(context->Config, artifact);
+ }
+};
+
+template <typename ArtifactT>
+struct TargetFileArtifact : public TargetArtifactBase
+{
+ TargetFileArtifact() {} // 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 =
+ TargetFileArtifactResultGetter<ArtifactT>::Get(target, context, content);
+ if (context->HadError) {
+ return std::string();
+ }
+ return result;
+ }
+};
+
+static const TargetFileArtifact<ArtifactFilePrefixTag> targetFilePrefixNode;
+static const TargetFileArtifact<ArtifactLinkerFilePrefixTag>
+ targetLinkerFilePrefixNode;
+static const TargetFileArtifact<ArtifactFileSuffixTag> targetFileSuffixNode;
+static const TargetFileArtifact<ArtifactLinkerFileSuffixTag>
+ targetLinkerFileSuffixNode;
+
static const struct ShellPathNode : public cmGeneratorExpressionNode
{
ShellPathNode() {} // NOLINT(modernize-use-equals-default)
@@ -2361,6 +2474,10 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
{ "TARGET_LINKER_FILE", &targetLinkerNodeGroup.File },
{ "TARGET_SONAME_FILE", &targetSoNameNodeGroup.File },
{ "TARGET_PDB_FILE", &targetPdbNodeGroup.File },
+ { "TARGET_FILE_PREFIX", &targetFilePrefixNode },
+ { "TARGET_LINKER_FILE_PREFIX", &targetLinkerFilePrefixNode },
+ { "TARGET_FILE_SUFFIX", &targetFileSuffixNode },
+ { "TARGET_LINKER_FILE_SUFFIX", &targetLinkerFileSuffixNode },
{ "TARGET_FILE_NAME", &targetNodeGroup.FileName },
{ "TARGET_LINKER_FILE_NAME", &targetLinkerNodeGroup.FileName },
{ "TARGET_SONAME_FILE_NAME", &targetSoNameNodeGroup.FileName },
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index f8c16cc..3fb95bf 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -464,6 +464,134 @@ std::string cmGeneratorTarget::GetOutputName(
return i->second;
}
+std::string cmGeneratorTarget::GetFilePrefix(
+ const std::string& config, cmStateEnums::ArtifactType artifact) const
+{
+ if (this->IsImported()) {
+ const char* prefix = this->GetFilePrefixInternal(artifact);
+
+ return prefix ? prefix : std::string();
+ }
+
+ std::string prefix, suffix, base;
+ this->GetFullNameInternal(config, artifact, prefix, base, suffix);
+ return prefix;
+}
+std::string cmGeneratorTarget::GetFileSuffix(
+ const std::string& config, cmStateEnums::ArtifactType artifact) const
+{
+ if (this->IsImported()) {
+ const char* suffix = this->GetFileSuffixInternal(artifact);
+
+ return suffix ? suffix : std::string();
+ }
+
+ std::string prefix, suffix, base;
+ this->GetFullNameInternal(config, artifact, prefix, base, suffix);
+ return suffix;
+}
+
+const char* cmGeneratorTarget::GetFilePrefixInternal(
+ cmStateEnums::ArtifactType artifact, const std::string& language) const
+{
+ // no prefix for non-main target types.
+ if (this->GetType() != cmStateEnums::STATIC_LIBRARY &&
+ this->GetType() != cmStateEnums::SHARED_LIBRARY &&
+ this->GetType() != cmStateEnums::MODULE_LIBRARY &&
+ this->GetType() != cmStateEnums::EXECUTABLE) {
+ return nullptr;
+ }
+
+ const bool isImportedLibraryArtifact =
+ (artifact == cmStateEnums::ImportLibraryArtifact);
+
+ // Return an empty prefix for the import library if this platform
+ // does not support import libraries.
+ if (isImportedLibraryArtifact &&
+ !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
+ return nullptr;
+ }
+
+ // The implib option is only allowed for shared libraries, module
+ // libraries, and executables.
+ if (this->GetType() != cmStateEnums::SHARED_LIBRARY &&
+ this->GetType() != cmStateEnums::MODULE_LIBRARY &&
+ this->GetType() != cmStateEnums::EXECUTABLE) {
+ artifact = cmStateEnums::RuntimeBinaryArtifact;
+ }
+
+ // Compute prefix value.
+ const char* targetPrefix =
+ (isImportedLibraryArtifact ? this->GetProperty("IMPORT_PREFIX")
+ : this->GetProperty("PREFIX"));
+
+ if (!targetPrefix) {
+ const char* prefixVar = this->Target->GetPrefixVariableInternal(artifact);
+ if (!language.empty() && prefixVar && *prefixVar) {
+ std::string langPrefix = prefixVar + std::string("_") + language;
+ targetPrefix = this->Makefile->GetDefinition(langPrefix);
+ }
+
+ // if there is no prefix on the target nor specific language
+ // use the cmake definition.
+ if (!targetPrefix && prefixVar) {
+ targetPrefix = this->Makefile->GetDefinition(prefixVar);
+ }
+ }
+
+ return targetPrefix;
+}
+const char* cmGeneratorTarget::GetFileSuffixInternal(
+ cmStateEnums::ArtifactType artifact, const std::string& language) const
+{
+ // no suffix for non-main target types.
+ if (this->GetType() != cmStateEnums::STATIC_LIBRARY &&
+ this->GetType() != cmStateEnums::SHARED_LIBRARY &&
+ this->GetType() != cmStateEnums::MODULE_LIBRARY &&
+ this->GetType() != cmStateEnums::EXECUTABLE) {
+ return nullptr;
+ }
+
+ const bool isImportedLibraryArtifact =
+ (artifact == cmStateEnums::ImportLibraryArtifact);
+
+ // Return an empty suffix for the import library if this platform
+ // does not support import libraries.
+ if (isImportedLibraryArtifact &&
+ !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
+ return nullptr;
+ }
+
+ // The implib option is only allowed for shared libraries, module
+ // libraries, and executables.
+ if (this->GetType() != cmStateEnums::SHARED_LIBRARY &&
+ this->GetType() != cmStateEnums::MODULE_LIBRARY &&
+ this->GetType() != cmStateEnums::EXECUTABLE) {
+ artifact = cmStateEnums::RuntimeBinaryArtifact;
+ }
+
+ // Compute suffix value.
+ const char* targetSuffix =
+ (isImportedLibraryArtifact ? this->GetProperty("IMPORT_SUFFIX")
+ : this->GetProperty("SUFFIX"));
+
+ if (!targetSuffix) {
+ const char* suffixVar = this->Target->GetSuffixVariableInternal(artifact);
+ if (!language.empty() && suffixVar && *suffixVar) {
+ std::string langSuffix = suffixVar + std::string("_") + language;
+ targetSuffix = this->Makefile->GetDefinition(langSuffix);
+ }
+
+ // if there is no suffix on the target nor specific language
+ // use the cmake definition.
+ if (!targetSuffix && suffixVar) {
+ targetSuffix = this->Makefile->GetDefinition(suffixVar);
+ }
+ }
+
+ return targetSuffix;
+}
+
void cmGeneratorTarget::ClearSourcesCache()
{
this->KindedSourcesMap.clear();
@@ -3788,6 +3916,11 @@ void cmGeneratorTarget::GetFullNameInternal(
return;
}
+ // retrieve prefix and suffix
+ std::string ll = this->GetLinkerLanguage(config);
+ const char* targetPrefix = this->GetFilePrefixInternal(artifact, ll);
+ const char* targetSuffix = this->GetFileSuffixInternal(artifact, ll);
+
// The implib option is only allowed for shared libraries, module
// libraries, and executables.
if (this->GetType() != cmStateEnums::SHARED_LIBRARY &&
@@ -3797,12 +3930,6 @@ void cmGeneratorTarget::GetFullNameInternal(
}
// Compute the full name for main target types.
- const char* targetPrefix =
- (isImportedLibraryArtifact ? this->GetProperty("IMPORT_PREFIX")
- : this->GetProperty("PREFIX"));
- const char* targetSuffix =
- (isImportedLibraryArtifact ? this->GetProperty("IMPORT_SUFFIX")
- : this->GetProperty("SUFFIX"));
const char* configPostfix = nullptr;
if (!config.empty()) {
std::string configProp = cmSystemTools::UpperCase(config);
@@ -3814,30 +3941,6 @@ void cmGeneratorTarget::GetFullNameInternal(
configPostfix = nullptr;
}
}
- const char* prefixVar = this->Target->GetPrefixVariableInternal(artifact);
- const char* suffixVar = this->Target->GetSuffixVariableInternal(artifact);
-
- // Check for language-specific default prefix and suffix.
- std::string ll = this->GetLinkerLanguage(config);
- if (!ll.empty()) {
- if (!targetSuffix && suffixVar && *suffixVar) {
- std::string langSuff = suffixVar + std::string("_") + ll;
- targetSuffix = this->Makefile->GetDefinition(langSuff);
- }
- if (!targetPrefix && prefixVar && *prefixVar) {
- std::string langPrefix = prefixVar + std::string("_") + ll;
- targetPrefix = this->Makefile->GetDefinition(langPrefix);
- }
- }
-
- // if there is no prefix on the target use the cmake definition
- if (!targetPrefix && prefixVar) {
- targetPrefix = this->Makefile->GetSafeDefinition(prefixVar).c_str();
- }
- // if there is no suffix on the target use the cmake definition
- if (!targetSuffix && suffixVar) {
- targetSuffix = this->Makefile->GetSafeDefinition(suffixVar).c_str();
- }
// frameworks have directory prefix but no suffix
std::string fw_prefix;
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 065b457..81f5255 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -534,6 +534,15 @@ public:
std::string GetOutputName(const std::string& config,
cmStateEnums::ArtifactType artifact) const;
+ /** Get target file prefix */
+ std::string GetFilePrefix(const std::string& config,
+ cmStateEnums::ArtifactType artifact =
+ cmStateEnums::RuntimeBinaryArtifact) const;
+ /** Get target file prefix */
+ std::string GetFileSuffix(const std::string& config,
+ cmStateEnums::ArtifactType artifact =
+ cmStateEnums::RuntimeBinaryArtifact) const;
+
/** Clears cached meta data for local and external source files.
* The meta data will be recomputed on demand.
*/
@@ -728,6 +737,11 @@ private:
mutable std::map<std::string, bool> DebugCompatiblePropertiesDone;
+ const char* GetFilePrefixInternal(cmStateEnums::ArtifactType artifact,
+ const std::string& language = "") const;
+ const char* GetFileSuffixInternal(cmStateEnums::ArtifactType artifact,
+ const std::string& language = "") const;
+
std::string GetFullNameInternal(const std::string& config,
cmStateEnums::ArtifactType artifact) const;
void GetFullNameInternal(const std::string& config,