summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2022-01-13 20:59:48 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2022-01-20 14:05:35 (GMT)
commitfce24e4f102686c5c103db301bb698e0ea82765f (patch)
treee5effdc88ea773c899b08b084aaf89dc936885dc /Source
parent1ca83ae2bbf9e474c46b6ea094c5035420bbfd45 (diff)
downloadCMake-fce24e4f102686c5c103db301bb698e0ea82765f.zip
CMake-fce24e4f102686c5c103db301bb698e0ea82765f.tar.gz
CMake-fce24e4f102686c5c103db301bb698e0ea82765f.tar.bz2
define_property(): Add INITIALIZE_FROM_VARIABLE argument
Fixes: #20698
Diffstat (limited to 'Source')
-rw-r--r--Source/cmDefinePropertyCommand.cxx44
-rw-r--r--Source/cmPropertyDefinition.cxx17
-rw-r--r--Source/cmPropertyDefinition.h22
-rw-r--r--Source/cmState.cxx6
-rw-r--r--Source/cmState.h8
-rw-r--r--Source/cmTarget.cxx11
6 files changed, 93 insertions, 15 deletions
diff --git a/Source/cmDefinePropertyCommand.cxx b/Source/cmDefinePropertyCommand.cxx
index 10c36cd..7a2f34f 100644
--- a/Source/cmDefinePropertyCommand.cxx
+++ b/Source/cmDefinePropertyCommand.cxx
@@ -2,6 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmDefinePropertyCommand.h"
+#include <algorithm>
+#include <iterator>
+
#include <cmext/string_view>
#include "cmArgumentParser.h"
@@ -50,12 +53,14 @@ bool cmDefinePropertyCommand(std::vector<std::string> const& args,
std::string PropertyName;
std::vector<std::string> BriefDocs;
std::vector<std::string> FullDocs;
+ std::string initializeFromVariable;
cmArgumentParser<void> parser;
parser.Bind("PROPERTY"_s, PropertyName);
parser.Bind("BRIEF_DOCS"_s, BriefDocs);
parser.Bind("FULL_DOCS"_s, FullDocs);
parser.Bind("INHERITED"_s, inherited);
+ parser.Bind("INITIALIZE_FROM_VARIABLE"_s, initializeFromVariable);
std::vector<std::string> invalidArgs;
parser.Parse(cmMakeRange(args).advance(1), &invalidArgs);
@@ -71,10 +76,47 @@ bool cmDefinePropertyCommand(std::vector<std::string> const& args,
return false;
}
+ if (!initializeFromVariable.empty()) {
+ // Make sure property scope is TARGET.
+ if (scope != cmProperty::TARGET) {
+ status.SetError(
+ "Scope must be TARGET if INITIALIZE_FROM_VARIABLE is specified");
+ return false;
+ }
+
+ // Make sure the variable has the property name as a suffix.
+ if (!cmHasSuffix(initializeFromVariable, PropertyName)) {
+ status.SetError(cmStrCat("Variable name \"", initializeFromVariable,
+ "\" does not end with property name \"",
+ PropertyName, "\""));
+ return false;
+ }
+ if (initializeFromVariable == PropertyName) {
+ status.SetError(cmStrCat(
+ "Variable name must have a non-empty prefix before property name \"",
+ PropertyName, "\""));
+ return false;
+ }
+ }
+
+ // Make sure the variable is not reserved.
+ static constexpr const char* reservedPrefixes[] = {
+ "CMAKE_",
+ "_CMAKE_",
+ };
+ if (std::any_of(std::begin(reservedPrefixes), std::end(reservedPrefixes),
+ [&initializeFromVariable](const char* prefix) {
+ return cmHasPrefix(initializeFromVariable, prefix);
+ })) {
+ status.SetError(
+ cmStrCat("variable name \"", initializeFromVariable, "\" is reserved"));
+ return false;
+ }
+
// Actually define the property.
status.GetMakefile().GetState()->DefineProperty(
PropertyName, scope, cmJoin(BriefDocs, ""), cmJoin(FullDocs, ""),
- inherited);
+ inherited, initializeFromVariable);
return true;
}
diff --git a/Source/cmPropertyDefinition.cxx b/Source/cmPropertyDefinition.cxx
index 1796bb8..22723b9 100644
--- a/Source/cmPropertyDefinition.cxx
+++ b/Source/cmPropertyDefinition.cxx
@@ -6,31 +6,34 @@
cmPropertyDefinition::cmPropertyDefinition(std::string shortDescription,
std::string fullDescription,
- bool chained)
+ bool chained,
+ std::string initializeFromVariable)
: ShortDescription(std::move(shortDescription))
, FullDescription(std::move(fullDescription))
, Chained(chained)
+ , InitializeFromVariable(std::move(initializeFromVariable))
{
}
void cmPropertyDefinitionMap::DefineProperty(
const std::string& name, cmProperty::ScopeType scope,
const std::string& ShortDescription, const std::string& FullDescription,
- bool chain)
+ bool chain, const std::string& initializeFromVariable)
{
- auto it = this->Map_.find(key_type(name, scope));
+ auto it = this->Map_.find(KeyType(name, scope));
if (it == this->Map_.end()) {
// try_emplace() since C++17
- this->Map_.emplace(
- std::piecewise_construct, std::forward_as_tuple(name, scope),
- std::forward_as_tuple(ShortDescription, FullDescription, chain));
+ this->Map_.emplace(std::piecewise_construct,
+ std::forward_as_tuple(name, scope),
+ std::forward_as_tuple(ShortDescription, FullDescription,
+ chain, initializeFromVariable));
}
}
cmPropertyDefinition const* cmPropertyDefinitionMap::GetPropertyDefinition(
const std::string& name, cmProperty::ScopeType scope) const
{
- auto it = this->Map_.find(key_type(name, scope));
+ auto it = this->Map_.find(KeyType(name, scope));
if (it != this->Map_.end()) {
return &it->second;
}
diff --git a/Source/cmPropertyDefinition.h b/Source/cmPropertyDefinition.h
index fca936e..9dd2cfe 100644
--- a/Source/cmPropertyDefinition.h
+++ b/Source/cmPropertyDefinition.h
@@ -22,7 +22,8 @@ class cmPropertyDefinition
public:
/// Constructor
cmPropertyDefinition(std::string shortDescription,
- std::string fullDescription, bool chained);
+ std::string fullDescription, bool chained,
+ std::string initializeFromVariable);
/// Is the property chained?
bool IsChained() const { return this->Chained; }
@@ -39,10 +40,17 @@ public:
return this->FullDescription;
}
+ /// Get the variable the property is initialized from
+ const std::string& GetInitializeFromVariable() const
+ {
+ return this->InitializeFromVariable;
+ }
+
private:
std::string ShortDescription;
std::string FullDescription;
bool Chained;
+ std::string InitializeFromVariable;
};
/** \class cmPropertyDefinitionMap
@@ -54,13 +62,19 @@ public:
// define the property
void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
const std::string& ShortDescription,
- const std::string& FullDescription, bool chain);
+ const std::string& FullDescription, bool chain,
+ const std::string& initializeFromVariable);
// get the property definition if present, otherwise nullptr
cmPropertyDefinition const* GetPropertyDefinition(
const std::string& name, cmProperty::ScopeType scope) const;
+ using KeyType = std::pair<std::string, cmProperty::ScopeType>;
+ const std::map<KeyType, cmPropertyDefinition>& GetMap() const
+ {
+ return this->Map_;
+ }
+
private:
- using key_type = std::pair<std::string, cmProperty::ScopeType>;
- std::map<key_type, cmPropertyDefinition> Map_;
+ std::map<KeyType, cmPropertyDefinition> Map_;
};
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 07b4759..f1144e1 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -327,10 +327,12 @@ cmStateSnapshot cmState::Reset()
void cmState::DefineProperty(const std::string& name,
cmProperty::ScopeType scope,
const std::string& ShortDescription,
- const std::string& FullDescription, bool chained)
+ const std::string& FullDescription, bool chained,
+ const std::string& initializeFromVariable)
{
this->PropertyDefinitions.DefineProperty(name, scope, ShortDescription,
- FullDescription, chained);
+ FullDescription, chained,
+ initializeFromVariable);
}
cmPropertyDefinition const* cmState::GetPropertyDefinition(
diff --git a/Source/cmState.h b/Source/cmState.h
index b834bba..4f2b7df 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -133,12 +133,18 @@ public:
// Define a property
void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
const std::string& ShortDescription,
- const std::string& FullDescription, bool chain = false);
+ const std::string& FullDescription, bool chain = false,
+ const std::string& initializeFromVariable = "");
// get property definition
cmPropertyDefinition const* GetPropertyDefinition(
const std::string& name, cmProperty::ScopeType scope) const;
+ const cmPropertyDefinitionMap& GetPropertyDefinitions() const
+ {
+ return this->PropertyDefinitions;
+ }
+
bool IsPropertyChained(const std::string& name,
cmProperty::ScopeType scope) const;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index c5703a1..ad19e03 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -28,6 +28,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmProperty.h"
+#include "cmPropertyDefinition.h"
#include "cmPropertyMap.h"
#include "cmRange.h"
#include "cmSourceFile.h"
@@ -557,6 +558,16 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
}
}
}
+
+ for (auto const& prop : mf->GetState()->GetPropertyDefinitions().GetMap()) {
+ if (prop.first.second == cmProperty::TARGET &&
+ !prop.second.GetInitializeFromVariable().empty()) {
+ if (auto value =
+ mf->GetDefinition(prop.second.GetInitializeFromVariable())) {
+ this->SetProperty(prop.first.first, value);
+ }
+ }
+ }
}
cmTarget::cmTarget(cmTarget&&) noexcept = default;