diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmExportFileGenerator.cxx | 14 | ||||
-rw-r--r-- | Source/cmGeneratorExpressionEvaluator.cxx | 44 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 209 | ||||
-rw-r--r-- | Source/cmTarget.h | 8 |
4 files changed, 262 insertions, 13 deletions
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index b01e499..65f1cc6 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -411,6 +411,12 @@ void getCompatibleInterfaceProperties(cmTarget *target, getPropertyContents(li->Target, "COMPATIBLE_INTERFACE_STRING", ifaceProperties); + getPropertyContents(li->Target, + "COMPATIBLE_INTERFACE_NUMBER_MIN", + ifaceProperties); + getPropertyContents(li->Target, + "COMPATIBLE_INTERFACE_NUMBER_MAX", + ifaceProperties); } } @@ -423,11 +429,19 @@ void cmExportFileGenerator::PopulateCompatibleInterfaceProperties( target, properties); this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_STRING", target, properties); + this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_NUMBER_MIN", + target, properties); + this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_NUMBER_MAX", + target, properties); std::set<std::string> ifaceProperties; getPropertyContents(target, "COMPATIBLE_INTERFACE_BOOL", ifaceProperties); getPropertyContents(target, "COMPATIBLE_INTERFACE_STRING", ifaceProperties); + getPropertyContents(target, "COMPATIBLE_INTERFACE_NUMBER_MIN", + ifaceProperties); + getPropertyContents(target, "COMPATIBLE_INTERFACE_NUMBER_MAX", + ifaceProperties); getCompatibleInterfaceProperties(target, ifaceProperties, 0); diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 33863f4..f92c18e 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -980,10 +980,54 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode context->Config); return propContent ? propContent : ""; } + if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName, + context->Config)) + { + context->HadContextSensitiveCondition = true; + const char *propContent = + target->GetLinkInterfaceDependentNumberMinProperty( + propertyName, + context->Config); + return propContent ? propContent : ""; + } + if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName, + context->Config)) + { + context->HadContextSensitiveCondition = true; + const char *propContent = + target->GetLinkInterfaceDependentNumberMaxProperty( + propertyName, + context->Config); + return propContent ? propContent : ""; + } return linkedTargetsContent; } + if (!target->IsImported() + && dagCheckerParent && !dagCheckerParent->EvaluatingLinkLibraries()) + { + if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName, + context->Config)) + { + context->HadContextSensitiveCondition = true; + const char *propContent = + target->GetLinkInterfaceDependentNumberMinProperty( + propertyName, + context->Config); + return propContent ? propContent : ""; + } + if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName, + context->Config)) + { + context->HadContextSensitiveCondition = true; + const char *propContent = + target->GetLinkInterfaceDependentNumberMaxProperty( + propertyName, + context->Config); + return propContent ? propContent : ""; + } + } for (size_t i = 1; i < cmArraySize(targetPropertyTransitiveWhitelist); ++i) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 91a7be8..c42ba95 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -4453,7 +4453,9 @@ const char *getTypedProperty<const char *>(cmTarget *tgt, const char *prop, enum CompatibleType { BoolType, - StringType + StringType, + NumberMinType, + NumberMaxType }; //---------------------------------------------------------------------------- @@ -4474,6 +4476,38 @@ const char * consistentStringProperty(const char *lhs, const char *rhs) return strcmp(lhs, rhs) == 0 ? lhs : 0; } +#if defined(_MSC_VER) && _MSC_VER <= 1200 +template<typename T> const T& +cmMaximum(const T& l, const T& r) {return l > r ? l : r;} +template<typename T> const T& +cmMinimum(const T& l, const T& r) {return l < r ? l : r;} +#else +#define cmMinimum std::min +#define cmMaximum std::max +#endif + +//---------------------------------------------------------------------------- +const char * consistentNumberProperty(const char *lhs, const char *rhs, + CompatibleType t) +{ + double lnum; + double rnum; + if(sscanf(lhs, "%lg", &lnum) != 1 || + sscanf(rhs, "%lg", &rnum) != 1) + { + return 0; + } + + if (t == NumberMaxType) + { + return cmMaximum(lnum, rnum) == lnum ? lhs : rhs; + } + else + { + return cmMinimum(lnum, rnum) == lnum ? lhs : rhs; + } +} + //---------------------------------------------------------------------------- template<> const char* consistentProperty(const char *lhs, const char *rhs, @@ -4498,6 +4532,9 @@ const char* consistentProperty(const char *lhs, const char *rhs, return 0; case StringType: return consistentStringProperty(lhs, rhs); + case NumberMinType: + case NumberMaxType: + return consistentNumberProperty(lhs, rhs, t); } assert(!"Unreachable!"); return 0; @@ -4686,6 +4723,30 @@ const char * cmTarget::GetLinkInterfaceDependentStringProperty( } //---------------------------------------------------------------------------- +const char * cmTarget::GetLinkInterfaceDependentNumberMinProperty( + const std::string &p, + const char *config) +{ + return checkInterfacePropertyCompatibility<const char *>(this, + p, + config, + "empty", + NumberMinType, 0); +} + +//---------------------------------------------------------------------------- +const char * cmTarget::GetLinkInterfaceDependentNumberMaxProperty( + const std::string &p, + const char *config) +{ + return checkInterfacePropertyCompatibility<const char *>(this, + p, + config, + "empty", + NumberMaxType, 0); +} + +//---------------------------------------------------------------------------- bool isLinkDependentProperty(cmTarget *tgt, const std::string &p, const char *interfaceProperty, const char *config) @@ -4754,6 +4815,30 @@ bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p, } //---------------------------------------------------------------------------- +bool cmTarget::IsLinkInterfaceDependentNumberMinProperty(const std::string &p, + const char *config) +{ + if (this->TargetTypeValue == OBJECT_LIBRARY) + { + return false; + } + return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_NUMBER_MIN", + config); +} + +//---------------------------------------------------------------------------- +bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p, + const char *config) +{ + if (this->TargetTypeValue == OBJECT_LIBRARY) + { + return false; + } + return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_NUMBER_MAX", + config); +} + +//---------------------------------------------------------------------------- void cmTarget::GetLanguages(std::set<cmStdString>& languages) const { for(std::vector<cmSourceFile*>::const_iterator @@ -5759,6 +5844,10 @@ const char * getLinkInterfaceDependentProperty(cmTarget *tgt, return 0; case StringType: return tgt->GetLinkInterfaceDependentStringProperty(prop, config); + case NumberMinType: + return tgt->GetLinkInterfaceDependentNumberMinProperty(prop, config); + case NumberMaxType: + return tgt->GetLinkInterfaceDependentNumberMaxProperty(prop, config); } assert(!"Unreachable!"); return 0; @@ -5812,6 +5901,50 @@ void checkPropertyConsistency(cmTarget *depender, cmTarget *dependee, } } +static cmStdString intersect(const std::set<cmStdString> &s1, + const std::set<cmStdString> &s2) +{ + std::set<cmStdString> intersect; + std::set_intersection(s1.begin(),s1.end(), + s2.begin(),s2.end(), + std::inserter(intersect,intersect.begin())); + if (!intersect.empty()) + { + return *intersect.begin(); + } + return ""; +} +static cmStdString intersect(const std::set<cmStdString> &s1, + const std::set<cmStdString> &s2, + const std::set<cmStdString> &s3) +{ + cmStdString result; + result = intersect(s1, s2); + if (!result.empty()) + return result; + result = intersect(s1, s3); + if (!result.empty()) + return result; + return intersect(s2, s3); +} +static cmStdString intersect(const std::set<cmStdString> &s1, + const std::set<cmStdString> &s2, + const std::set<cmStdString> &s3, + const std::set<cmStdString> &s4) +{ + cmStdString result; + result = intersect(s1, s2); + if (!result.empty()) + return result; + result = intersect(s1, s3); + if (!result.empty()) + return result; + result = intersect(s1, s4); + if (!result.empty()) + return result; + return intersect(s2, s3, s4); +} + //---------------------------------------------------------------------------- void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, const char* config) @@ -5820,6 +5953,8 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, std::set<cmStdString> emittedBools; std::set<cmStdString> emittedStrings; + std::set<cmStdString> emittedMinNumbers; + std::set<cmStdString> emittedMaxNumbers; for(cmComputeLinkInformation::ItemVector::const_iterator li = deps.begin(); @@ -5845,23 +5980,71 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, { return; } + checkPropertyConsistency<const char *>(this, li->Target, + "COMPATIBLE_INTERFACE_NUMBER_MIN", + emittedMinNumbers, config, + NumberMinType, 0); + if (cmSystemTools::GetErrorOccuredFlag()) + { + return; + } + checkPropertyConsistency<const char *>(this, li->Target, + "COMPATIBLE_INTERFACE_NUMBER_MAX", + emittedMaxNumbers, config, + NumberMaxType, 0); + if (cmSystemTools::GetErrorOccuredFlag()) + { + return; + } } - for(std::set<cmStdString>::const_iterator li = emittedBools.begin(); - li != emittedBools.end(); ++li) + std::string prop = intersect(emittedBools, + emittedStrings, + emittedMinNumbers, + emittedMaxNumbers); + + if (!prop.empty()) { - const std::set<cmStdString>::const_iterator si = emittedStrings.find(*li); - if (si != emittedStrings.end()) + std::set<std::string> props; + std::set<cmStdString>::const_iterator i = emittedBools.find(prop); + if (i != emittedBools.end()) { - cmOStringStream e; - e << "Property \"" << *li << "\" appears in both the " - "COMPATIBLE_INTERFACE_BOOL and the COMPATIBLE_INTERFACE_STRING " - "property in the dependencies of target \"" << this->GetName() << - "\". This is not allowed. A property may only require compatibility " - "in a boolean interpretation or a string interpretation, but not both."; - this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); - break; + props.insert("COMPATIBLE_INTERFACE_BOOL"); + } + i = emittedStrings.find(prop); + if (i != emittedStrings.end()) + { + props.insert("COMPATIBLE_INTERFACE_STRING"); } + i = emittedMinNumbers.find(prop); + if (i != emittedMinNumbers.end()) + { + props.insert("COMPATIBLE_INTERFACE_NUMBER_MIN"); + } + i = emittedMaxNumbers.find(prop); + if (i != emittedMaxNumbers.end()) + { + props.insert("COMPATIBLE_INTERFACE_NUMBER_MAX"); + } + + std::string propsString = *props.begin(); + props.erase(props.begin()); + while (props.size() > 1) + { + propsString += ", " + *props.begin(); + props.erase(props.begin()); + } + if (props.size() == 1) + { + propsString += " and the " + *props.begin(); + } + cmOStringStream e; + e << "Property \"" << prop << "\" appears in both the " + << propsString << + " property in the dependencies of target \"" << this->GetName() << + "\". This is not allowed. A property may only require compatibility " + "in a boolean interpretation or a string interpretation, but not both."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); } } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index e8f4e08..9d62f5f 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -536,12 +536,20 @@ public: const char *config); bool IsLinkInterfaceDependentStringProperty(const std::string &p, const char *config); + bool IsLinkInterfaceDependentNumberMinProperty(const std::string &p, + const char *config); + bool IsLinkInterfaceDependentNumberMaxProperty(const std::string &p, + const char *config); bool GetLinkInterfaceDependentBoolProperty(const std::string &p, const char *config); const char *GetLinkInterfaceDependentStringProperty(const std::string &p, const char *config); + const char *GetLinkInterfaceDependentNumberMinProperty(const std::string &p, + const char *config); + const char *GetLinkInterfaceDependentNumberMaxProperty(const std::string &p, + const char *config); std::string GetDebugGeneratorExpressions(const std::string &value, cmTarget::LinkLibraryType llt); |