Features: Extend concept to C language.

Add properties and variables corresponding to CXX equivalents.

Add features for c_function_prototypes (C90), c_restrict (C99),
c_variadic_macros (C99) and c_static_assert (C11). This feature
set can be extended later.

Add a <PREFIX>_RESTRICT symbol define to WriteCompilerDetectionHeader
to conditionally represent the c_restrict feature.
This commit is contained in:
Stephen Kelly
2013-11-04 01:15:43 +01:00
parent 775458dede
commit e0890d03a4
57 changed files with 630 additions and 27 deletions
+4
View File
@@ -2201,6 +2201,10 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget* target,
// Maintain sorted order, most recent first.
langStdMap["CXX"].push_back("11");
langStdMap["CXX"].push_back("98");
langStdMap["C"].push_back("11");
langStdMap["C"].push_back("99");
langStdMap["C"].push_back("90");
}
std::string standard(standardProp);
+114 -2
View File
@@ -4973,6 +4973,10 @@ void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm)
}
#define FEATURE_STRING(F) , #F
static const char * const C_FEATURES[] = {
0
FOR_EACH_C_FEATURE(FEATURE_STRING)
};
static const char * const CXX_FEATURES[] = {
0
@@ -4980,6 +4984,11 @@ static const char * const CXX_FEATURES[] = {
};
#undef FEATURE_STRING
static const char * const C_STANDARDS[] = {
"90"
, "99"
, "11"
};
static const char * const CXX_STANDARDS[] = {
"98"
, "11"
@@ -4995,10 +5004,13 @@ AddRequiredTargetFeature(cmTarget *target, const std::string& feature,
target->AppendProperty("COMPILE_FEATURES", feature.c_str());
return true;
}
bool isCFeature = std::find_if(cmArrayBegin(C_FEATURES) + 1,
cmArrayEnd(C_FEATURES), cmStrCmp(feature))
!= cmArrayEnd(C_FEATURES);
bool isCxxFeature = std::find_if(cmArrayBegin(CXX_FEATURES) + 1,
cmArrayEnd(CXX_FEATURES), cmStrCmp(feature))
!= cmArrayEnd(CXX_FEATURES);
if (!isCxxFeature)
if (!isCFeature && !isCxxFeature)
{
cmOStringStream e;
if (error)
@@ -5022,7 +5034,7 @@ AddRequiredTargetFeature(cmTarget *target, const std::string& feature,
return false;
}
std::string lang = "CXX";
std::string lang = isCFeature ? "C" : "CXX";
const char* featuresKnown =
this->GetDefinition("CMAKE_" + lang + "_COMPILE_FEATURES");
@@ -5071,6 +5083,16 @@ AddRequiredTargetFeature(cmTarget *target, const std::string& feature,
target->AppendProperty("COMPILE_FEATURES", feature.c_str());
return isCFeature
? this->AddRequiredTargetCFeature(target, feature)
: this->AddRequiredTargetCxxFeature(target, feature);
}
//----------------------------------------------------------------------------
bool cmMakefile::
AddRequiredTargetCxxFeature(cmTarget *target,
const std::string& feature) const
{
bool needCxx98 = false;
bool needCxx11 = false;
@@ -5136,3 +5158,93 @@ AddRequiredTargetFeature(cmTarget *target, const std::string& feature,
}
return true;
}
//----------------------------------------------------------------------------
bool cmMakefile::
AddRequiredTargetCFeature(cmTarget *target, const std::string& feature) const
{
bool needC90 = false;
bool needC99 = false;
bool needC11 = false;
if (const char *propC90 =
this->GetDefinition("CMAKE_C90_COMPILE_FEATURES"))
{
std::vector<std::string> props;
cmSystemTools::ExpandListArgument(propC90, props);
needC90 = std::find(props.begin(), props.end(), feature) != props.end();
}
if (const char *propC99 =
this->GetDefinition("CMAKE_C99_COMPILE_FEATURES"))
{
std::vector<std::string> props;
cmSystemTools::ExpandListArgument(propC99, props);
needC99 = std::find(props.begin(), props.end(), feature) != props.end();
}
if (const char *propC11 =
this->GetDefinition("CMAKE_C11_COMPILE_FEATURES"))
{
std::vector<std::string> props;
cmSystemTools::ExpandListArgument(propC11, props);
needC11 = std::find(props.begin(), props.end(), feature) != props.end();
}
const char *existingCStandard = target->GetProperty("C_STANDARD");
if (existingCStandard)
{
if (std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS),
cmStrCmp(existingCStandard)) == cmArrayEnd(C_STANDARDS))
{
cmOStringStream e;
e << "The C_STANDARD property on target \"" << target->GetName()
<< "\" contained an invalid value: \"" << existingCStandard << "\".";
this->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
return false;
}
}
const char * const *existingCIt = existingCStandard
? std::find_if(cmArrayBegin(C_STANDARDS),
cmArrayEnd(C_STANDARDS),
cmStrCmp(existingCStandard))
: cmArrayEnd(C_STANDARDS);
bool setC90 = needC90 && !existingCStandard;
bool setC99 = needC99 && !existingCStandard;
bool setC11 = needC11 && !existingCStandard;
if (needC11 && existingCStandard && existingCIt <
std::find_if(cmArrayBegin(C_STANDARDS),
cmArrayEnd(C_STANDARDS),
cmStrCmp("11")))
{
setC11 = true;
}
else if(needC99 && existingCStandard && existingCIt <
std::find_if(cmArrayBegin(C_STANDARDS),
cmArrayEnd(C_STANDARDS),
cmStrCmp("99")))
{
setC99 = true;
}
else if(needC90 && existingCStandard && existingCIt <
std::find_if(cmArrayBegin(C_STANDARDS),
cmArrayEnd(C_STANDARDS),
cmStrCmp("90")))
{
setC90 = true;
}
if (setC11)
{
target->SetProperty("C_STANDARD", "11");
}
else if (setC99)
{
target->SetProperty("C_STANDARD", "99");
}
else if (setC90)
{
target->SetProperty("C_STANDARD", "90");
}
return true;
}
+6
View File
@@ -1098,6 +1098,12 @@ private:
std::vector<cmSourceFile*> QtUiFilesWithOptions;
unsigned int NumLastMatches;
bool AddRequiredTargetCFeature(cmTarget *target,
const std::string& feature) const;
bool AddRequiredTargetCxxFeature(cmTarget *target,
const std::string& feature) const;
};
//----------------------------------------------------------------------------
+3
View File
@@ -314,6 +314,9 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->SetPropertyDefault("MACOSX_BUNDLE", 0);
this->SetPropertyDefault("MACOSX_RPATH", 0);
this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0);
this->SetPropertyDefault("C_STANDARD", 0);
this->SetPropertyDefault("C_STANDARD_REQUIRED", 0);
this->SetPropertyDefault("C_EXTENSIONS", 0);
this->SetPropertyDefault("CXX_STANDARD", 0);
this->SetPropertyDefault("CXX_STANDARD_REQUIRED", 0);
this->SetPropertyDefault("CXX_EXTENSIONS", 0);
+6 -2
View File
@@ -2273,12 +2273,16 @@ const char *cmake::GetProperty(const std::string& prop,
}
this->SetProperty("ENABLED_LANGUAGES", lang.c_str());
}
#define STRING_LIST_ELEMENT(F) ";" #F
if (prop == "CMAKE_C_KNOWN_FEATURES")
{
return FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT) + 1;
}
if (prop == "CMAKE_CXX_KNOWN_FEATURES")
{
#define STRING_LIST_ELEMENT(F) ";" #F
return FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT) + 1;
#undef STRING_LIST_ELEMENT
}
#undef STRING_LIST_ELEMENT
return this->Properties.GetPropertyValue(prop, scope, chain);
}
+6
View File
@@ -458,6 +458,12 @@ private:
{"-Wno-dev", "Suppress developer warnings."},\
{"-Wdev", "Enable developer warnings."}
#define FOR_EACH_C_FEATURE(F) \
F(c_function_prototypes) \
F(c_restrict) \
F(c_static_assert) \
F(c_variadic_macros)
#define FOR_EACH_CXX_FEATURE(F) \
F(cxx_alias_templates) \
F(cxx_alignas) \