1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-15 20:46:37 +08:00

Add generator expression support to per-source COMPILE_FLAGS

This allows users to specify different genex-based compile flags for
each file in a target, e.g. compiling just a single file with `Od/Ox` in
release builds on Visual Studio.
This commit is contained in:
Zsolt Parragi
2016-10-25 18:23:22 +02:00
committed by Brad King
parent ee0f2d23fc
commit 1e4bb35894
11 changed files with 81 additions and 15 deletions

View File

@@ -6,3 +6,10 @@ Additional flags to be added when compiling this source file.
These flags will be added to the list of compile flags when this These flags will be added to the list of compile flags when this
source file builds. Use :prop_sf:`COMPILE_DEFINITIONS` to pass source file builds. Use :prop_sf:`COMPILE_DEFINITIONS` to pass
additional preprocessor definitions. additional preprocessor definitions.
Contents of ``COMPILE_FLAGS`` may use "generator expressions"
with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
manual for available expressions. However, :generator:`Xcode`
does not support per-config per-source settings, so expressions
that depend on the build configuration are not allowed with that
generator.

View File

@@ -0,0 +1,5 @@
src-COMPILE_FLAGS-genex
-----------------------
* The :prop_sf:`COMPILE_FLAGS` source file property learned to support
:manual:`generator expressions <cmake-generator-expressions(7)>`.

View File

@@ -341,7 +341,11 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject(
} }
// Add source file specific flags. // Add source file specific flags.
lg->AppendFlags(flags, source->GetProperty("COMPILE_FLAGS")); if (const char* cflags = source->GetProperty("COMPILE_FLAGS")) {
cmGeneratorExpression ge;
const char* processed = ge.Parse(cflags)->Evaluate(lg, config);
lg->AppendFlags(flags, processed);
}
return flags; return flags;
} }

View File

@@ -675,7 +675,24 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
default: default:
break; break;
} }
lg->AppendFlags(flags, sf->GetProperty("COMPILE_FLAGS")); if (const char* cflags = sf->GetProperty("COMPILE_FLAGS")) {
cmGeneratorExpression ge;
std::string configName = "NO-PER-CONFIG-SUPPORT-IN-XCODE";
CM_AUTO_PTR<cmCompiledGeneratorExpression> compiledExpr = ge.Parse(cflags);
const char* processed = compiledExpr->Evaluate(lg, configName);
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);
}
// Add per-source definitions. // Add per-source definitions.
BuildObjectListOrString flagsBuild(this, false); BuildObjectListOrString flagsBuild(this, false);

View File

@@ -1464,7 +1464,9 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
needfc = true; needfc = true;
} }
if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) { if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) {
fc.CompileFlags = cflags; cmGeneratorExpression ge;
CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = ge.Parse(cflags);
fc.CompileFlags = cge->Evaluate(lg, *i);
needfc = true; needfc = true;
} }
if (lg->FortranProject) { if (lg->FortranProject) {

View File

@@ -437,8 +437,8 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
langFlags += "_FLAGS)"; langFlags += "_FLAGS)";
this->LocalGenerator->AppendFlags(flags, langFlags); this->LocalGenerator->AppendFlags(flags, langFlags);
std::string configUpper = std::string config = this->LocalGenerator->GetConfigName();
cmSystemTools::UpperCase(this->LocalGenerator->GetConfigName()); std::string configUpper = cmSystemTools::UpperCase(config);
// Add Fortran format flags. // Add Fortran format flags.
if (lang == "Fortran") { if (lang == "Fortran") {
@@ -446,12 +446,14 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
} }
// Add flags from source file properties. // Add flags from source file properties.
if (source.GetProperty("COMPILE_FLAGS")) { if (const char* cflags = source.GetProperty("COMPILE_FLAGS")) {
this->LocalGenerator->AppendFlags(flags, cmGeneratorExpression ge;
source.GetProperty("COMPILE_FLAGS")); CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = ge.Parse(cflags);
const char* evaluatedFlags = cge->Evaluate(this->LocalGenerator, config,
false, this->GeneratorTarget);
this->LocalGenerator->AppendFlags(flags, evaluatedFlags);
*this->FlagFileStream << "# Custom flags: " << relativeObj *this->FlagFileStream << "# Custom flags: " << relativeObj
<< "_FLAGS = " << source.GetProperty("COMPILE_FLAGS") << "_FLAGS = " << evaluatedFlags << "\n"
<< "\n"
<< "\n"; << "\n";
} }

View File

@@ -132,8 +132,14 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
} }
// Add source file specific flags. // Add source file specific flags.
this->LocalGenerator->AppendFlags(flags, if (const char* cflags = source->GetProperty("COMPILE_FLAGS")) {
source->GetProperty("COMPILE_FLAGS")); std::string config = this->LocalGenerator->GetConfigName();
cmGeneratorExpression ge;
CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = ge.Parse(cflags);
const char* evaluatedFlags = cge->Evaluate(this->LocalGenerator, config,
false, this->GeneratorTarget);
this->LocalGenerator->AppendFlags(flags, evaluatedFlags);
}
return flags; return flags;
} }

View File

@@ -686,7 +686,12 @@ static Json::Value DumpSourceFilesList(
cmLocalGenerator* lg = target->GetLocalGenerator(); cmLocalGenerator* lg = target->GetLocalGenerator();
std::string compileFlags = ld.Flags; std::string compileFlags = ld.Flags;
lg->AppendFlags(compileFlags, file->GetProperty("COMPILE_FLAGS")); if (const char* cflags = file->GetProperty("COMPILE_FLAGS")) {
cmGeneratorExpression ge;
const char* processed =
ge.Parse(cflags)->Evaluate(target->GetLocalGenerator(), config);
lg->AppendFlags(compileFlags, processed);
}
fileData.Flags = compileFlags; fileData.Flags = compileFlags;
fileData.IncludePathList = ld.IncludePathList; fileData.IncludePathList = ld.IncludePathList;

View File

@@ -1355,8 +1355,13 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
objectName = this->GeneratorTarget->GetObjectName(&sf); objectName = this->GeneratorTarget->GetObjectName(&sf);
} }
std::string flags; std::string flags;
bool configDependentFlags = false;
std::string defines; std::string defines;
if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) { if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) {
if (cmGeneratorExpression::Find(cflags) != std::string::npos) {
configDependentFlags = true;
}
flags += cflags; flags += cflags;
} }
if (const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) { if (const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) {
@@ -1412,7 +1417,8 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
} }
// if we have flags or defines for this config then // if we have flags or defines for this config then
// use them // use them
if (!flags.empty() || !configDefines.empty() || compileAs || noWinRT) { if (!flags.empty() || configDependentFlags || !configDefines.empty() ||
compileAs || noWinRT) {
(*this->BuildFileStream) << firstString; (*this->BuildFileStream) << firstString;
firstString = ""; // only do firstString once firstString = ""; // only do firstString once
hasFlags = true; hasFlags = true;
@@ -1427,7 +1433,15 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
if (noWinRT) { if (noWinRT) {
clOptions.AddFlag("CompileAsWinRT", "false"); clOptions.AddFlag("CompileAsWinRT", "false");
} }
clOptions.Parse(flags.c_str()); if (configDependentFlags) {
cmGeneratorExpression ge;
CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = ge.Parse(flags);
std::string evaluatedFlags =
cge->Evaluate(this->LocalGenerator, *config);
clOptions.Parse(evaluatedFlags.c_str());
} else {
clOptions.Parse(flags.c_str());
}
if (clOptions.HasFlag("AdditionalIncludeDirectories")) { if (clOptions.HasFlag("AdditionalIncludeDirectories")) {
clOptions.AppendFlag("AdditionalIncludeDirectories", clOptions.AppendFlag("AdditionalIncludeDirectories",
"%(AdditionalIncludeDirectories)"); "%(AdditionalIncludeDirectories)");

View File

@@ -257,6 +257,7 @@ add_custom_target(check-part4 ALL
# Cover test properties with generator expressions. # Cover test properties with generator expressions.
add_executable(echo echo.c) add_executable(echo echo.c)
add_executable(pwd pwd.c) add_executable(pwd pwd.c)
set_property(SOURCE echo.c PROPERTY COMPILE_FLAGS $<1:-DSRC_GENEX_WORKS>)
add_test(NAME echo-configuration COMMAND echo $<CONFIGURATION>) add_test(NAME echo-configuration COMMAND echo $<CONFIGURATION>)
set_property(TEST echo-configuration PROPERTY set_property(TEST echo-configuration PROPERTY

View File

@@ -3,6 +3,9 @@
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
#ifndef SRC_GENEX_WORKS
#error SRC_GENEX_WORKS not defined
#endif
printf("%s\n", argv[1]); printf("%s\n", argv[1]);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }