mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-02 20:29:49 -05:00
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:
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) \
|
||||
|
||||
Reference in New Issue
Block a user