diff options
author | Kyle Edwards <kyle.edwards@kitware.com> | 2022-01-13 20:59:48 (GMT) |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2022-01-20 14:05:35 (GMT) |
commit | fce24e4f102686c5c103db301bb698e0ea82765f (patch) | |
tree | e5effdc88ea773c899b08b084aaf89dc936885dc /Source | |
parent | 1ca83ae2bbf9e474c46b6ea094c5035420bbfd45 (diff) | |
download | CMake-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.cxx | 44 | ||||
-rw-r--r-- | Source/cmPropertyDefinition.cxx | 17 | ||||
-rw-r--r-- | Source/cmPropertyDefinition.h | 22 | ||||
-rw-r--r-- | Source/cmState.cxx | 6 | ||||
-rw-r--r-- | Source/cmState.h | 8 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 11 |
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; |