Refactor per-source generator expression evaluation
Prepare to add generator expression support to more source properties. Factor out some duplicated code into a helper to avoid further duplication.
This commit is contained in:
parent
a4faf86387
commit
6bffc13ef1
@ -362,9 +362,8 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject(
|
||||
|
||||
// Add source file specific flags.
|
||||
if (const char* cflags = source->GetProperty("COMPILE_FLAGS")) {
|
||||
cmGeneratorExpression ge;
|
||||
const char* processed = ge.Parse(cflags)->Evaluate(lg, config);
|
||||
lg->AppendFlags(flags, processed);
|
||||
cmGeneratorExpressionInterpreter genexInterpreter(lg, gtgt, config);
|
||||
lg->AppendFlags(flags, genexInterpreter.Evaluate(cflags));
|
||||
}
|
||||
|
||||
return flags;
|
||||
|
@ -153,4 +153,54 @@ private:
|
||||
bool EvaluateForBuildsystem;
|
||||
};
|
||||
|
||||
class cmGeneratorExpressionInterpreter
|
||||
{
|
||||
CM_DISABLE_COPY(cmGeneratorExpressionInterpreter)
|
||||
|
||||
public:
|
||||
cmGeneratorExpressionInterpreter(cmLocalGenerator* localGenerator,
|
||||
cmGeneratorTarget* generatorTarget,
|
||||
const std::string& config)
|
||||
: LocalGenerator(localGenerator)
|
||||
, GeneratorTarget(generatorTarget)
|
||||
, Config(config)
|
||||
{
|
||||
}
|
||||
|
||||
const char* Evaluate(const char* expression)
|
||||
{
|
||||
this->CompiledGeneratorExpression =
|
||||
this->GeneratorExpression.Parse(expression);
|
||||
|
||||
return this->CompiledGeneratorExpression->Evaluate(
|
||||
this->LocalGenerator, this->Config, false, this->GeneratorTarget);
|
||||
}
|
||||
const char* Evaluate(const std::string& expression)
|
||||
{
|
||||
return this->Evaluate(expression.c_str());
|
||||
}
|
||||
|
||||
protected:
|
||||
cmGeneratorExpression& GetGeneratorExpression()
|
||||
{
|
||||
return this->GeneratorExpression;
|
||||
}
|
||||
|
||||
cmCompiledGeneratorExpression& GetCompiledGeneratorExpression()
|
||||
{
|
||||
return *(this->CompiledGeneratorExpression);
|
||||
}
|
||||
|
||||
cmLocalGenerator* GetLocalGenerator() { return this->LocalGenerator; }
|
||||
|
||||
cmGeneratorTarget* GetGeneratorTarget() { return this->GeneratorTarget; }
|
||||
|
||||
private:
|
||||
cmGeneratorExpression GeneratorExpression;
|
||||
std::unique_ptr<cmCompiledGeneratorExpression> CompiledGeneratorExpression;
|
||||
cmLocalGenerator* LocalGenerator = nullptr;
|
||||
cmGeneratorTarget* GeneratorTarget = nullptr;
|
||||
std::string Config;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -676,9 +676,51 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFileFromPath(
|
||||
return buildFile;
|
||||
}
|
||||
|
||||
class XCodeGeneratorExpressionInterpreter
|
||||
: public cmGeneratorExpressionInterpreter
|
||||
{
|
||||
CM_DISABLE_COPY(XCodeGeneratorExpressionInterpreter)
|
||||
|
||||
public:
|
||||
XCodeGeneratorExpressionInterpreter(cmSourceFile* sourceFile,
|
||||
cmLocalGenerator* localGenerator,
|
||||
cmGeneratorTarget* generatorTarget)
|
||||
: cmGeneratorExpressionInterpreter(localGenerator, generatorTarget,
|
||||
"NO-PER-CONFIG-SUPPORT-IN-XCODE")
|
||||
, SourceFile(sourceFile)
|
||||
{
|
||||
}
|
||||
|
||||
using cmGeneratorExpressionInterpreter::Evaluate;
|
||||
|
||||
const char* Evaluate(const char* expression, const char* property)
|
||||
{
|
||||
const char* processed = this->Evaluate(expression);
|
||||
if (this->GetCompiledGeneratorExpression()
|
||||
.GetHadContextSensitiveCondition()) {
|
||||
std::ostringstream e;
|
||||
/* clang-format off */
|
||||
e <<
|
||||
"Xcode does not support per-config per-source " << property << ":\n"
|
||||
" " << expression << "\n"
|
||||
"specified for source:\n"
|
||||
" " << this->SourceFile->GetFullPath() << "\n";
|
||||
/* clang-format on */
|
||||
this->GetLocalGenerator()->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
}
|
||||
|
||||
return processed;
|
||||
}
|
||||
|
||||
private:
|
||||
cmSourceFile* SourceFile = nullptr;
|
||||
};
|
||||
|
||||
cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
|
||||
cmLocalGenerator* lg, cmSourceFile* sf, cmGeneratorTarget* gtgt)
|
||||
{
|
||||
XCodeGeneratorExpressionInterpreter genexInterpreter(sf, lg, gtgt);
|
||||
|
||||
// Add flags from target and source file properties.
|
||||
std::string flags;
|
||||
const char* srcfmt = sf->GetProperty("Fortran_FORMAT");
|
||||
@ -693,24 +735,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
|
||||
break;
|
||||
}
|
||||
if (const char* cflags = sf->GetProperty("COMPILE_FLAGS")) {
|
||||
cmGeneratorExpression ge;
|
||||
std::string configName = "NO-PER-CONFIG-SUPPORT-IN-XCODE";
|
||||
std::unique_ptr<cmCompiledGeneratorExpression> compiledExpr =
|
||||
ge.Parse(cflags);
|
||||
const char* processed =
|
||||
compiledExpr->Evaluate(lg, configName, false, gtgt);
|
||||
if (compiledExpr->GetHadContextSensitiveCondition()) {
|
||||
std::ostringstream e;
|
||||
/* clang-format off */
|
||||
e <<
|
||||
"Xcode does not support per-config per-source COMPILE_FLAGS:\n"
|
||||
" " << cflags << "\n"
|
||||
"specified for source:\n"
|
||||
" " << sf->GetFullPath() << "\n";
|
||||
/* clang-format on */
|
||||
lg->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
}
|
||||
lg->AppendFlags(flags, processed);
|
||||
lg->AppendFlags(flags, genexInterpreter.Evaluate(cflags, "COMPILE_FLAGS"));
|
||||
}
|
||||
|
||||
// Add per-source definitions.
|
||||
|
@ -1456,15 +1456,14 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
|
||||
i != configs.end(); ++i, ++ci) {
|
||||
std::string configUpper = cmSystemTools::UpperCase(*i);
|
||||
cmLVS7GFileConfig fc;
|
||||
cmGeneratorExpressionInterpreter genexInterpreter(lg, gt, *i);
|
||||
bool needfc = false;
|
||||
if (!objectName.empty()) {
|
||||
fc.ObjectName = objectName;
|
||||
needfc = true;
|
||||
}
|
||||
if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) {
|
||||
cmGeneratorExpression ge;
|
||||
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(cflags);
|
||||
fc.CompileFlags = cge->Evaluate(lg, *i, false, gt);
|
||||
fc.CompileFlags = genexInterpreter.Evaluate(cflags);
|
||||
needfc = true;
|
||||
}
|
||||
if (lg->FortranProject) {
|
||||
|
@ -425,6 +425,8 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
|
||||
|
||||
std::string config = this->LocalGenerator->GetConfigName();
|
||||
std::string configUpper = cmSystemTools::UpperCase(config);
|
||||
cmGeneratorExpressionInterpreter genexInterpreter(
|
||||
this->LocalGenerator, this->GeneratorTarget, config);
|
||||
|
||||
// Add Fortran format flags.
|
||||
if (lang == "Fortran") {
|
||||
@ -433,10 +435,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
|
||||
|
||||
// Add flags from source file properties.
|
||||
if (const char* cflags = source.GetProperty("COMPILE_FLAGS")) {
|
||||
cmGeneratorExpression ge;
|
||||
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(cflags);
|
||||
const char* evaluatedFlags = cge->Evaluate(this->LocalGenerator, config,
|
||||
false, this->GeneratorTarget);
|
||||
const char* evaluatedFlags = genexInterpreter.Evaluate(cflags);
|
||||
this->LocalGenerator->AppendFlags(flags, evaluatedFlags);
|
||||
*this->FlagFileStream << "# Custom flags: " << relativeObj
|
||||
<< "_FLAGS = " << evaluatedFlags << "\n"
|
||||
|
@ -136,12 +136,11 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
|
||||
|
||||
// Add source file specific flags.
|
||||
if (const char* cflags = source->GetProperty("COMPILE_FLAGS")) {
|
||||
std::string config = this->LocalGenerator->GetConfigName();
|
||||
cmGeneratorExpression ge;
|
||||
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(cflags);
|
||||
const char* evaluatedFlags = cge->Evaluate(this->LocalGenerator, config,
|
||||
false, this->GeneratorTarget);
|
||||
this->LocalGenerator->AppendFlags(flags, evaluatedFlags);
|
||||
cmGeneratorExpressionInterpreter genexInterpreter(
|
||||
this->LocalGenerator, this->GeneratorTarget,
|
||||
this->LocalGenerator->GetConfigName());
|
||||
this->LocalGenerator->AppendFlags(flags,
|
||||
genexInterpreter.Evaluate(cflags));
|
||||
}
|
||||
|
||||
return flags;
|
||||
|
@ -692,6 +692,8 @@ static Json::Value DumpSourceFilesList(
|
||||
|
||||
std::vector<cmSourceFile*> files;
|
||||
target->GetSourceFiles(files, config);
|
||||
cmGeneratorExpressionInterpreter genexInterpreter(
|
||||
target->GetLocalGenerator(), target, config);
|
||||
|
||||
std::unordered_map<LanguageData, std::vector<std::string>> fileGroups;
|
||||
for (cmSourceFile* file : files) {
|
||||
@ -703,11 +705,7 @@ static Json::Value DumpSourceFilesList(
|
||||
|
||||
std::string compileFlags = ld.Flags;
|
||||
if (const char* cflags = file->GetProperty("COMPILE_FLAGS")) {
|
||||
cmGeneratorExpression ge;
|
||||
auto cge = ge.Parse(cflags);
|
||||
const char* processed =
|
||||
cge->Evaluate(target->GetLocalGenerator(), config);
|
||||
lg->AppendFlags(compileFlags, processed);
|
||||
lg->AppendFlags(compileFlags, genexInterpreter.Evaluate(cflags));
|
||||
}
|
||||
fileData.Flags = compileFlags;
|
||||
|
||||
|
@ -2062,10 +2062,8 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
|
||||
bool configDependentFlags = false;
|
||||
std::string defines;
|
||||
if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) {
|
||||
|
||||
if (cmGeneratorExpression::Find(cflags) != std::string::npos) {
|
||||
configDependentFlags = true;
|
||||
}
|
||||
configDependentFlags =
|
||||
cmGeneratorExpression::Find(cflags) != std::string::npos;
|
||||
flags += cflags;
|
||||
}
|
||||
if (const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) {
|
||||
@ -2122,8 +2120,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
|
||||
}
|
||||
// if we have flags or defines for this config then
|
||||
// use them
|
||||
if (!flags.empty() || configDependentFlags || !configDefines.empty() ||
|
||||
compileAs || noWinRT) {
|
||||
if (!flags.empty() || !configDefines.empty() || compileAs || noWinRT) {
|
||||
(*this->BuildFileStream) << firstString;
|
||||
firstString = ""; // only do firstString once
|
||||
hasFlags = true;
|
||||
@ -2144,6 +2141,8 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
|
||||
} else if (srclang == "CSharp") {
|
||||
flagtable = gg->GetCSharpFlagTable();
|
||||
}
|
||||
cmGeneratorExpressionInterpreter genexInterpreter(
|
||||
this->LocalGenerator, this->GeneratorTarget, *config);
|
||||
cmVisualStudioGeneratorOptions clOptions(
|
||||
this->LocalGenerator, cmVisualStudioGeneratorOptions::Compiler,
|
||||
flagtable, 0, this);
|
||||
@ -2154,11 +2153,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
|
||||
clOptions.AddFlag("CompileAsWinRT", "false");
|
||||
}
|
||||
if (configDependentFlags) {
|
||||
cmGeneratorExpression ge;
|
||||
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(flags);
|
||||
std::string evaluatedFlags = cge->Evaluate(
|
||||
this->LocalGenerator, *config, false, this->GeneratorTarget);
|
||||
clOptions.Parse(evaluatedFlags.c_str());
|
||||
clOptions.Parse(genexInterpreter.Evaluate(flags));
|
||||
} else {
|
||||
clOptions.Parse(flags.c_str());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user