cmGeneratorTarget: Move CheckPropertyCompatibility from cmTarget.
This commit is contained in:
parent
803a7982b4
commit
90bad039c4
|
@ -1524,6 +1524,240 @@ bool cmGeneratorTarget::IsLinkInterfaceDependentNumberMaxProperty(
|
||||||
return this->GetCompatibleInterfaces(config).PropsNumberMax.count(p) > 0;
|
return this->GetCompatibleInterfaces(config).PropsNumberMax.count(p) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename PropertyType>
|
||||||
|
PropertyType getLinkInterfaceDependentProperty(cmTarget const* tgt,
|
||||||
|
const std::string& prop,
|
||||||
|
const std::string& config,
|
||||||
|
cmTarget::CompatibleType,
|
||||||
|
PropertyType *);
|
||||||
|
|
||||||
|
template<>
|
||||||
|
bool getLinkInterfaceDependentProperty(cmTarget const* tgt,
|
||||||
|
const std::string& prop,
|
||||||
|
const std::string& config,
|
||||||
|
cmTarget::CompatibleType, bool *)
|
||||||
|
{
|
||||||
|
return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
const char * getLinkInterfaceDependentProperty(cmTarget const* tgt,
|
||||||
|
const std::string& prop,
|
||||||
|
const std::string& config,
|
||||||
|
cmTarget::CompatibleType t,
|
||||||
|
const char **)
|
||||||
|
{
|
||||||
|
switch(t)
|
||||||
|
{
|
||||||
|
case cmTarget::BoolType:
|
||||||
|
assert(0 && "String compatibility check function called for boolean");
|
||||||
|
return 0;
|
||||||
|
case cmTarget::StringType:
|
||||||
|
return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
|
||||||
|
case cmTarget::NumberMinType:
|
||||||
|
return tgt->GetLinkInterfaceDependentNumberMinProperty(prop, config);
|
||||||
|
case cmTarget::NumberMaxType:
|
||||||
|
return tgt->GetLinkInterfaceDependentNumberMaxProperty(prop, config);
|
||||||
|
}
|
||||||
|
assert(0 && "Unreachable!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
template<typename PropertyType>
|
||||||
|
void checkPropertyConsistency(cmTarget const* depender,
|
||||||
|
cmTarget const* dependee,
|
||||||
|
const std::string& propName,
|
||||||
|
std::set<std::string> &emitted,
|
||||||
|
const std::string& config,
|
||||||
|
cmTarget::CompatibleType t,
|
||||||
|
PropertyType *)
|
||||||
|
{
|
||||||
|
const char *prop = dependee->GetProperty(propName);
|
||||||
|
if (!prop)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> props;
|
||||||
|
cmSystemTools::ExpandListArgument(prop, props);
|
||||||
|
std::string pdir =
|
||||||
|
dependee->GetMakefile()->GetRequiredDefinition("CMAKE_ROOT");
|
||||||
|
pdir += "/Help/prop_tgt/";
|
||||||
|
|
||||||
|
for(std::vector<std::string>::iterator pi = props.begin();
|
||||||
|
pi != props.end(); ++pi)
|
||||||
|
{
|
||||||
|
std::string pname = cmSystemTools::HelpFileName(*pi);
|
||||||
|
std::string pfile = pdir + pname + ".rst";
|
||||||
|
if(cmSystemTools::FileExists(pfile.c_str(), true))
|
||||||
|
{
|
||||||
|
std::ostringstream e;
|
||||||
|
e << "Target \"" << dependee->GetName() << "\" has property \""
|
||||||
|
<< *pi << "\" listed in its " << propName << " property. "
|
||||||
|
"This is not allowed. Only user-defined properties may appear "
|
||||||
|
"listed in the " << propName << " property.";
|
||||||
|
depender->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(emitted.insert(*pi).second)
|
||||||
|
{
|
||||||
|
getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config,
|
||||||
|
t, 0);
|
||||||
|
if (cmSystemTools::GetErrorOccuredFlag())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string intersect(const std::set<std::string> &s1,
|
||||||
|
const std::set<std::string> &s2)
|
||||||
|
{
|
||||||
|
std::set<std::string> 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 std::string intersect(const std::set<std::string> &s1,
|
||||||
|
const std::set<std::string> &s2,
|
||||||
|
const std::set<std::string> &s3)
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
result = intersect(s1, s2);
|
||||||
|
if (!result.empty())
|
||||||
|
return result;
|
||||||
|
result = intersect(s1, s3);
|
||||||
|
if (!result.empty())
|
||||||
|
return result;
|
||||||
|
return intersect(s2, s3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string intersect(const std::set<std::string> &s1,
|
||||||
|
const std::set<std::string> &s2,
|
||||||
|
const std::set<std::string> &s3,
|
||||||
|
const std::set<std::string> &s4)
|
||||||
|
{
|
||||||
|
std::string 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 cmGeneratorTarget::CheckPropertyCompatibility(
|
||||||
|
cmComputeLinkInformation *info, const std::string& config) const
|
||||||
|
{
|
||||||
|
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
|
||||||
|
|
||||||
|
std::set<std::string> emittedBools;
|
||||||
|
static std::string strBool = "COMPATIBLE_INTERFACE_BOOL";
|
||||||
|
std::set<std::string> emittedStrings;
|
||||||
|
static std::string strString = "COMPATIBLE_INTERFACE_STRING";
|
||||||
|
std::set<std::string> emittedMinNumbers;
|
||||||
|
static std::string strNumMin = "COMPATIBLE_INTERFACE_NUMBER_MIN";
|
||||||
|
std::set<std::string> emittedMaxNumbers;
|
||||||
|
static std::string strNumMax = "COMPATIBLE_INTERFACE_NUMBER_MAX";
|
||||||
|
|
||||||
|
for(cmComputeLinkInformation::ItemVector::const_iterator li =
|
||||||
|
deps.begin(); li != deps.end(); ++li)
|
||||||
|
{
|
||||||
|
if (!li->Target)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkPropertyConsistency<bool>(this->Target, li->Target,
|
||||||
|
strBool,
|
||||||
|
emittedBools, config, cmTarget::BoolType, 0);
|
||||||
|
if (cmSystemTools::GetErrorOccuredFlag())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
checkPropertyConsistency<const char *>(this->Target, li->Target,
|
||||||
|
strString,
|
||||||
|
emittedStrings, config,
|
||||||
|
cmTarget::StringType, 0);
|
||||||
|
if (cmSystemTools::GetErrorOccuredFlag())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
checkPropertyConsistency<const char *>(this->Target, li->Target,
|
||||||
|
strNumMin,
|
||||||
|
emittedMinNumbers, config,
|
||||||
|
cmTarget::NumberMinType, 0);
|
||||||
|
if (cmSystemTools::GetErrorOccuredFlag())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
checkPropertyConsistency<const char *>(this->Target, li->Target,
|
||||||
|
strNumMax,
|
||||||
|
emittedMaxNumbers, config,
|
||||||
|
cmTarget::NumberMaxType, 0);
|
||||||
|
if (cmSystemTools::GetErrorOccuredFlag())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string prop = intersect(emittedBools,
|
||||||
|
emittedStrings,
|
||||||
|
emittedMinNumbers,
|
||||||
|
emittedMaxNumbers);
|
||||||
|
|
||||||
|
if (!prop.empty())
|
||||||
|
{
|
||||||
|
// Use a sorted std::vector to keep the error message sorted.
|
||||||
|
std::vector<std::string> props;
|
||||||
|
std::set<std::string>::const_iterator i = emittedBools.find(prop);
|
||||||
|
if (i != emittedBools.end())
|
||||||
|
{
|
||||||
|
props.push_back(strBool);
|
||||||
|
}
|
||||||
|
i = emittedStrings.find(prop);
|
||||||
|
if (i != emittedStrings.end())
|
||||||
|
{
|
||||||
|
props.push_back(strString);
|
||||||
|
}
|
||||||
|
i = emittedMinNumbers.find(prop);
|
||||||
|
if (i != emittedMinNumbers.end())
|
||||||
|
{
|
||||||
|
props.push_back(strNumMin);
|
||||||
|
}
|
||||||
|
i = emittedMaxNumbers.find(prop);
|
||||||
|
if (i != emittedMaxNumbers.end())
|
||||||
|
{
|
||||||
|
props.push_back(strNumMax);
|
||||||
|
}
|
||||||
|
std::sort(props.begin(), props.end());
|
||||||
|
|
||||||
|
std::string propsString = cmJoin(cmMakeRange(props).retreat(1), ", ");
|
||||||
|
propsString += " and the " + props.back();
|
||||||
|
|
||||||
|
std::ostringstream 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, a numeric minimum, a numeric maximum or a "
|
||||||
|
"string interpretation, but not a mixture.";
|
||||||
|
this->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
cmComputeLinkInformation*
|
cmComputeLinkInformation*
|
||||||
|
@ -1550,7 +1784,7 @@ cmGeneratorTarget::GetLinkInformation(const std::string& config) const
|
||||||
|
|
||||||
if (info)
|
if (info)
|
||||||
{
|
{
|
||||||
this->Target->CheckPropertyCompatibility(info, config);
|
this->CheckPropertyCompatibility(info, config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i->second;
|
return i->second;
|
||||||
|
|
|
@ -222,6 +222,9 @@ private:
|
||||||
cmTargetLinkInformationMap;
|
cmTargetLinkInformationMap;
|
||||||
mutable cmTargetLinkInformationMap LinkInformation;
|
mutable cmTargetLinkInformationMap LinkInformation;
|
||||||
|
|
||||||
|
void CheckPropertyCompatibility(cmComputeLinkInformation *info,
|
||||||
|
const std::string& config) const;
|
||||||
|
|
||||||
cmGeneratorTarget(cmGeneratorTarget const&);
|
cmGeneratorTarget(cmGeneratorTarget const&);
|
||||||
void operator=(cmGeneratorTarget const&);
|
void operator=(cmGeneratorTarget const&);
|
||||||
};
|
};
|
||||||
|
|
|
@ -4554,23 +4554,16 @@ const char *getTypedProperty<const char *>(cmTarget const* tgt,
|
||||||
return tgt->GetProperty(prop);
|
return tgt->GetProperty(prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CompatibleType
|
|
||||||
{
|
|
||||||
BoolType,
|
|
||||||
StringType,
|
|
||||||
NumberMinType,
|
|
||||||
NumberMaxType
|
|
||||||
};
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
template<typename PropertyType>
|
template<typename PropertyType>
|
||||||
std::pair<bool, PropertyType> consistentProperty(PropertyType lhs,
|
std::pair<bool, PropertyType> consistentProperty(PropertyType lhs,
|
||||||
PropertyType rhs,
|
PropertyType rhs,
|
||||||
CompatibleType t);
|
cmTarget::CompatibleType t);
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
template<>
|
template<>
|
||||||
std::pair<bool, bool> consistentProperty(bool lhs, bool rhs, CompatibleType)
|
std::pair<bool, bool> consistentProperty(bool lhs, bool rhs,
|
||||||
|
cmTarget::CompatibleType)
|
||||||
{
|
{
|
||||||
return std::make_pair(lhs == rhs, lhs);
|
return std::make_pair(lhs == rhs, lhs);
|
||||||
}
|
}
|
||||||
|
@ -4585,8 +4578,8 @@ std::pair<bool, const char*> consistentStringProperty(const char *lhs,
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
std::pair<bool, const char*> consistentNumberProperty(const char *lhs,
|
std::pair<bool, const char*> consistentNumberProperty(const char *lhs,
|
||||||
const char *rhs,
|
const char *rhs,
|
||||||
CompatibleType t)
|
cmTarget::CompatibleType t)
|
||||||
{
|
{
|
||||||
char *pEnd;
|
char *pEnd;
|
||||||
|
|
||||||
|
@ -4604,7 +4597,7 @@ std::pair<bool, const char*> consistentNumberProperty(const char *lhs,
|
||||||
return std::pair<bool, const char*>(false, null_ptr);
|
return std::pair<bool, const char*>(false, null_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == NumberMaxType)
|
if (t == cmTarget::NumberMaxType)
|
||||||
{
|
{
|
||||||
return std::make_pair(true, std::max(lnum, rnum) == lnum ? lhs : rhs);
|
return std::make_pair(true, std::max(lnum, rnum) == lnum ? lhs : rhs);
|
||||||
}
|
}
|
||||||
|
@ -4618,7 +4611,7 @@ std::pair<bool, const char*> consistentNumberProperty(const char *lhs,
|
||||||
template<>
|
template<>
|
||||||
std::pair<bool, const char*> consistentProperty(const char *lhs,
|
std::pair<bool, const char*> consistentProperty(const char *lhs,
|
||||||
const char *rhs,
|
const char *rhs,
|
||||||
CompatibleType t)
|
cmTarget::CompatibleType t)
|
||||||
{
|
{
|
||||||
if (!lhs && !rhs)
|
if (!lhs && !rhs)
|
||||||
{
|
{
|
||||||
|
@ -4637,13 +4630,13 @@ std::pair<bool, const char*> consistentProperty(const char *lhs,
|
||||||
|
|
||||||
switch(t)
|
switch(t)
|
||||||
{
|
{
|
||||||
case BoolType:
|
case cmTarget::BoolType:
|
||||||
assert(0 && "consistentProperty for strings called with BoolType");
|
assert(0 && "consistentProperty for strings called with BoolType");
|
||||||
return std::pair<bool, const char*>(false, null_ptr);
|
return std::pair<bool, const char*>(false, null_ptr);
|
||||||
case StringType:
|
case cmTarget::StringType:
|
||||||
return consistentStringProperty(lhs, rhs);
|
return consistentStringProperty(lhs, rhs);
|
||||||
case NumberMinType:
|
case cmTarget::NumberMinType:
|
||||||
case NumberMaxType:
|
case cmTarget::NumberMaxType:
|
||||||
return consistentNumberProperty(lhs, rhs, t);
|
return consistentNumberProperty(lhs, rhs, t);
|
||||||
}
|
}
|
||||||
assert(0 && "Unreachable!");
|
assert(0 && "Unreachable!");
|
||||||
|
@ -4718,17 +4711,17 @@ cmTarget::ReportPropertyOrigin(const std::string &p,
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
std::string compatibilityType(CompatibleType t)
|
std::string compatibilityType(cmTarget::CompatibleType t)
|
||||||
{
|
{
|
||||||
switch(t)
|
switch(t)
|
||||||
{
|
{
|
||||||
case BoolType:
|
case cmTarget::BoolType:
|
||||||
return "Boolean compatibility";
|
return "Boolean compatibility";
|
||||||
case StringType:
|
case cmTarget::StringType:
|
||||||
return "String compatibility";
|
return "String compatibility";
|
||||||
case NumberMaxType:
|
case cmTarget::NumberMaxType:
|
||||||
return "Numeric maximum compatibility";
|
return "Numeric maximum compatibility";
|
||||||
case NumberMinType:
|
case cmTarget::NumberMinType:
|
||||||
return "Numeric minimum compatibility";
|
return "Numeric minimum compatibility";
|
||||||
}
|
}
|
||||||
assert(0 && "Unreachable!");
|
assert(0 && "Unreachable!");
|
||||||
|
@ -4736,15 +4729,15 @@ std::string compatibilityType(CompatibleType t)
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
std::string compatibilityAgree(CompatibleType t, bool dominant)
|
std::string compatibilityAgree(cmTarget::CompatibleType t, bool dominant)
|
||||||
{
|
{
|
||||||
switch(t)
|
switch(t)
|
||||||
{
|
{
|
||||||
case BoolType:
|
case cmTarget::BoolType:
|
||||||
case StringType:
|
case cmTarget::StringType:
|
||||||
return dominant ? "(Disagree)\n" : "(Agree)\n";
|
return dominant ? "(Disagree)\n" : "(Agree)\n";
|
||||||
case NumberMaxType:
|
case cmTarget::NumberMaxType:
|
||||||
case NumberMinType:
|
case cmTarget::NumberMinType:
|
||||||
return dominant ? "(Dominant)\n" : "(Ignored)\n";
|
return dominant ? "(Dominant)\n" : "(Ignored)\n";
|
||||||
}
|
}
|
||||||
assert(0 && "Unreachable!");
|
assert(0 && "Unreachable!");
|
||||||
|
@ -4757,7 +4750,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
|
||||||
const std::string &p,
|
const std::string &p,
|
||||||
const std::string& config,
|
const std::string& config,
|
||||||
const char *defaultValue,
|
const char *defaultValue,
|
||||||
CompatibleType t,
|
cmTarget::CompatibleType t,
|
||||||
PropertyType *)
|
PropertyType *)
|
||||||
{
|
{
|
||||||
PropertyType propContent = getTypedProperty<PropertyType>(tgt, p);
|
PropertyType propContent = getTypedProperty<PropertyType>(tgt, p);
|
||||||
|
@ -6224,240 +6217,6 @@ std::string cmTarget::CheckCMP0004(std::string const& item) const
|
||||||
return lib;
|
return lib;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename PropertyType>
|
|
||||||
PropertyType getLinkInterfaceDependentProperty(cmTarget const* tgt,
|
|
||||||
const std::string& prop,
|
|
||||||
const std::string& config,
|
|
||||||
CompatibleType,
|
|
||||||
PropertyType *);
|
|
||||||
|
|
||||||
template<>
|
|
||||||
bool getLinkInterfaceDependentProperty(cmTarget const* tgt,
|
|
||||||
const std::string& prop,
|
|
||||||
const std::string& config,
|
|
||||||
CompatibleType, bool *)
|
|
||||||
{
|
|
||||||
return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
const char * getLinkInterfaceDependentProperty(cmTarget const* tgt,
|
|
||||||
const std::string& prop,
|
|
||||||
const std::string& config,
|
|
||||||
CompatibleType t,
|
|
||||||
const char **)
|
|
||||||
{
|
|
||||||
switch(t)
|
|
||||||
{
|
|
||||||
case BoolType:
|
|
||||||
assert(0 && "String compatibility check function called for boolean");
|
|
||||||
return 0;
|
|
||||||
case StringType:
|
|
||||||
return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
|
|
||||||
case NumberMinType:
|
|
||||||
return tgt->GetLinkInterfaceDependentNumberMinProperty(prop, config);
|
|
||||||
case NumberMaxType:
|
|
||||||
return tgt->GetLinkInterfaceDependentNumberMaxProperty(prop, config);
|
|
||||||
}
|
|
||||||
assert(0 && "Unreachable!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
template<typename PropertyType>
|
|
||||||
void checkPropertyConsistency(cmTarget const* depender,
|
|
||||||
cmTarget const* dependee,
|
|
||||||
const std::string& propName,
|
|
||||||
std::set<std::string> &emitted,
|
|
||||||
const std::string& config,
|
|
||||||
CompatibleType t,
|
|
||||||
PropertyType *)
|
|
||||||
{
|
|
||||||
const char *prop = dependee->GetProperty(propName);
|
|
||||||
if (!prop)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> props;
|
|
||||||
cmSystemTools::ExpandListArgument(prop, props);
|
|
||||||
std::string pdir =
|
|
||||||
dependee->GetMakefile()->GetRequiredDefinition("CMAKE_ROOT");
|
|
||||||
pdir += "/Help/prop_tgt/";
|
|
||||||
|
|
||||||
for(std::vector<std::string>::iterator pi = props.begin();
|
|
||||||
pi != props.end(); ++pi)
|
|
||||||
{
|
|
||||||
std::string pname = cmSystemTools::HelpFileName(*pi);
|
|
||||||
std::string pfile = pdir + pname + ".rst";
|
|
||||||
if(cmSystemTools::FileExists(pfile.c_str(), true))
|
|
||||||
{
|
|
||||||
std::ostringstream e;
|
|
||||||
e << "Target \"" << dependee->GetName() << "\" has property \""
|
|
||||||
<< *pi << "\" listed in its " << propName << " property. "
|
|
||||||
"This is not allowed. Only user-defined properties may appear "
|
|
||||||
"listed in the " << propName << " property.";
|
|
||||||
depender->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(emitted.insert(*pi).second)
|
|
||||||
{
|
|
||||||
getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config,
|
|
||||||
t, 0);
|
|
||||||
if (cmSystemTools::GetErrorOccuredFlag())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string intersect(const std::set<std::string> &s1,
|
|
||||||
const std::set<std::string> &s2)
|
|
||||||
{
|
|
||||||
std::set<std::string> 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 std::string intersect(const std::set<std::string> &s1,
|
|
||||||
const std::set<std::string> &s2,
|
|
||||||
const std::set<std::string> &s3)
|
|
||||||
{
|
|
||||||
std::string result;
|
|
||||||
result = intersect(s1, s2);
|
|
||||||
if (!result.empty())
|
|
||||||
return result;
|
|
||||||
result = intersect(s1, s3);
|
|
||||||
if (!result.empty())
|
|
||||||
return result;
|
|
||||||
return intersect(s2, s3);
|
|
||||||
}
|
|
||||||
static std::string intersect(const std::set<std::string> &s1,
|
|
||||||
const std::set<std::string> &s2,
|
|
||||||
const std::set<std::string> &s3,
|
|
||||||
const std::set<std::string> &s4)
|
|
||||||
{
|
|
||||||
std::string 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 std::string& config) const
|
|
||||||
{
|
|
||||||
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
|
|
||||||
|
|
||||||
std::set<std::string> emittedBools;
|
|
||||||
static std::string strBool = "COMPATIBLE_INTERFACE_BOOL";
|
|
||||||
std::set<std::string> emittedStrings;
|
|
||||||
static std::string strString = "COMPATIBLE_INTERFACE_STRING";
|
|
||||||
std::set<std::string> emittedMinNumbers;
|
|
||||||
static std::string strNumMin = "COMPATIBLE_INTERFACE_NUMBER_MIN";
|
|
||||||
std::set<std::string> emittedMaxNumbers;
|
|
||||||
static std::string strNumMax = "COMPATIBLE_INTERFACE_NUMBER_MAX";
|
|
||||||
|
|
||||||
for(cmComputeLinkInformation::ItemVector::const_iterator li =
|
|
||||||
deps.begin();
|
|
||||||
li != deps.end(); ++li)
|
|
||||||
{
|
|
||||||
if (!li->Target)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
checkPropertyConsistency<bool>(this, li->Target,
|
|
||||||
strBool,
|
|
||||||
emittedBools, config, BoolType, 0);
|
|
||||||
if (cmSystemTools::GetErrorOccuredFlag())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
checkPropertyConsistency<const char *>(this, li->Target,
|
|
||||||
strString,
|
|
||||||
emittedStrings, config,
|
|
||||||
StringType, 0);
|
|
||||||
if (cmSystemTools::GetErrorOccuredFlag())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
checkPropertyConsistency<const char *>(this, li->Target,
|
|
||||||
strNumMin,
|
|
||||||
emittedMinNumbers, config,
|
|
||||||
NumberMinType, 0);
|
|
||||||
if (cmSystemTools::GetErrorOccuredFlag())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
checkPropertyConsistency<const char *>(this, li->Target,
|
|
||||||
strNumMax,
|
|
||||||
emittedMaxNumbers, config,
|
|
||||||
NumberMaxType, 0);
|
|
||||||
if (cmSystemTools::GetErrorOccuredFlag())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string prop = intersect(emittedBools,
|
|
||||||
emittedStrings,
|
|
||||||
emittedMinNumbers,
|
|
||||||
emittedMaxNumbers);
|
|
||||||
|
|
||||||
if (!prop.empty())
|
|
||||||
{
|
|
||||||
// Use a sorted std::vector to keep the error message sorted.
|
|
||||||
std::vector<std::string> props;
|
|
||||||
std::set<std::string>::const_iterator i = emittedBools.find(prop);
|
|
||||||
if (i != emittedBools.end())
|
|
||||||
{
|
|
||||||
props.push_back(strBool);
|
|
||||||
}
|
|
||||||
i = emittedStrings.find(prop);
|
|
||||||
if (i != emittedStrings.end())
|
|
||||||
{
|
|
||||||
props.push_back(strString);
|
|
||||||
}
|
|
||||||
i = emittedMinNumbers.find(prop);
|
|
||||||
if (i != emittedMinNumbers.end())
|
|
||||||
{
|
|
||||||
props.push_back(strNumMin);
|
|
||||||
}
|
|
||||||
i = emittedMaxNumbers.find(prop);
|
|
||||||
if (i != emittedMaxNumbers.end())
|
|
||||||
{
|
|
||||||
props.push_back(strNumMax);
|
|
||||||
}
|
|
||||||
std::sort(props.begin(), props.end());
|
|
||||||
|
|
||||||
std::string propsString = cmJoin(cmMakeRange(props).retreat(1), ", ");
|
|
||||||
propsString += " and the " + props.back();
|
|
||||||
|
|
||||||
std::ostringstream 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, a numeric minimum, a numeric maximum or a "
|
|
||||||
"string interpretation, but not a mixture.";
|
|
||||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
std::string cmTarget::GetFrameworkDirectory(const std::string& config,
|
std::string cmTarget::GetFrameworkDirectory(const std::string& config,
|
||||||
bool rootDir) const
|
bool rootDir) const
|
||||||
|
|
|
@ -590,6 +590,14 @@ public:
|
||||||
return this->LinkLibrariesForVS6;}
|
return this->LinkLibrariesForVS6;}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum CompatibleType
|
||||||
|
{
|
||||||
|
BoolType,
|
||||||
|
StringType,
|
||||||
|
NumberMinType,
|
||||||
|
NumberMaxType
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool HandleLocationPropertyPolicy(cmMakefile* context) const;
|
bool HandleLocationPropertyPolicy(cmMakefile* context) const;
|
||||||
|
|
||||||
|
@ -754,9 +762,6 @@ private:
|
||||||
struct CompileInfo;
|
struct CompileInfo;
|
||||||
CompileInfo const* GetCompileInfo(const std::string& config) const;
|
CompileInfo const* GetCompileInfo(const std::string& config) const;
|
||||||
|
|
||||||
void CheckPropertyCompatibility(cmComputeLinkInformation *info,
|
|
||||||
const std::string& config) const;
|
|
||||||
|
|
||||||
LinkInterface const*
|
LinkInterface const*
|
||||||
GetImportLinkInterface(const std::string& config, cmTarget const* head,
|
GetImportLinkInterface(const std::string& config, cmTarget const* head,
|
||||||
bool usage_requirements_only) const;
|
bool usage_requirements_only) const;
|
||||||
|
|
Loading…
Reference in New Issue