summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZsolt Parragi <zsolt.parragi@cancellar.hu>2016-10-25 16:23:22 (GMT)
committerBrad King <brad.king@kitware.com>2016-10-28 15:18:03 (GMT)
commit1e4bb358946a100ea04bbc97f8195b90b44a5e9c (patch)
treeec0cebb25ef0f6fcc0d68ab8548e0d2a1f004ab3
parentee0f2d23fcf3cd7a67ad8d7bd132a475ed78405f (diff)
downloadCMake-1e4bb358946a100ea04bbc97f8195b90b44a5e9c.zip
CMake-1e4bb358946a100ea04bbc97f8195b90b44a5e9c.tar.gz
CMake-1e4bb358946a100ea04bbc97f8195b90b44a5e9c.tar.bz2
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.
-rw-r--r--Help/prop_sf/COMPILE_FLAGS.rst7
-rw-r--r--Help/release/dev/src-COMPILE_FLAGS-genex.rst5
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx6
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx19
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx4
-rw-r--r--Source/cmMakefileTargetGenerator.cxx16
-rw-r--r--Source/cmNinjaTargetGenerator.cxx10
-rw-r--r--Source/cmServerProtocol.cxx7
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx18
-rw-r--r--Tests/GeneratorExpression/CMakeLists.txt1
-rw-r--r--Tests/GeneratorExpression/echo.c3
11 files changed, 81 insertions, 15 deletions
diff --git a/Help/prop_sf/COMPILE_FLAGS.rst b/Help/prop_sf/COMPILE_FLAGS.rst
index 086a063..1012164 100644
--- a/Help/prop_sf/COMPILE_FLAGS.rst
+++ b/Help/prop_sf/COMPILE_FLAGS.rst
@@ -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
source file builds. Use :prop_sf:`COMPILE_DEFINITIONS` to pass
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.
diff --git a/Help/release/dev/src-COMPILE_FLAGS-genex.rst b/Help/release/dev/src-COMPILE_FLAGS-genex.rst
new file mode 100644
index 0000000..26cd3ef
--- /dev/null
+++ b/Help/release/dev/src-COMPILE_FLAGS-genex.rst
@@ -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)>`.
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index f46019e..0480d10 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -341,7 +341,11 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject(
}
// 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;
}
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 8424ded..84a8c5e 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -675,7 +675,24 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
default:
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.
BuildObjectListOrString flagsBuild(this, false);
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 7c32e6c..49b057b 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -1464,7 +1464,9 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
needfc = true;
}
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;
}
if (lg->FortranProject) {
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 68c166e..68aabef 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -437,8 +437,8 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
langFlags += "_FLAGS)";
this->LocalGenerator->AppendFlags(flags, langFlags);
- std::string configUpper =
- cmSystemTools::UpperCase(this->LocalGenerator->GetConfigName());
+ std::string config = this->LocalGenerator->GetConfigName();
+ std::string configUpper = cmSystemTools::UpperCase(config);
// Add Fortran format flags.
if (lang == "Fortran") {
@@ -446,12 +446,14 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
}
// Add flags from source file properties.
- if (source.GetProperty("COMPILE_FLAGS")) {
- this->LocalGenerator->AppendFlags(flags,
- source.GetProperty("COMPILE_FLAGS"));
+ if (const char* cflags = source.GetProperty("COMPILE_FLAGS")) {
+ 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);
*this->FlagFileStream << "# Custom flags: " << relativeObj
- << "_FLAGS = " << source.GetProperty("COMPILE_FLAGS")
- << "\n"
+ << "_FLAGS = " << evaluatedFlags << "\n"
<< "\n";
}
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index b48387c..cf60892 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -132,8 +132,14 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
}
// Add source file specific flags.
- this->LocalGenerator->AppendFlags(flags,
- source->GetProperty("COMPILE_FLAGS"));
+ if (const char* cflags = 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;
}
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index 857ce39..00dc0b5 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -686,7 +686,12 @@ static Json::Value DumpSourceFilesList(
cmLocalGenerator* lg = target->GetLocalGenerator();
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.IncludePathList = ld.IncludePathList;
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 22167ca..97eb3c7 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -1355,8 +1355,13 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
objectName = this->GeneratorTarget->GetObjectName(&sf);
}
std::string flags;
+ bool configDependentFlags = false;
std::string defines;
if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) {
+
+ if (cmGeneratorExpression::Find(cflags) != std::string::npos) {
+ configDependentFlags = true;
+ }
flags += cflags;
}
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
// use them
- if (!flags.empty() || !configDefines.empty() || compileAs || noWinRT) {
+ if (!flags.empty() || configDependentFlags || !configDefines.empty() ||
+ compileAs || noWinRT) {
(*this->BuildFileStream) << firstString;
firstString = ""; // only do firstString once
hasFlags = true;
@@ -1427,7 +1433,15 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
if (noWinRT) {
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")) {
clOptions.AppendFlag("AdditionalIncludeDirectories",
"%(AdditionalIncludeDirectories)");
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index 4f2f434..f0d6abf 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -257,6 +257,7 @@ add_custom_target(check-part4 ALL
# Cover test properties with generator expressions.
add_executable(echo echo.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>)
set_property(TEST echo-configuration PROPERTY
diff --git a/Tests/GeneratorExpression/echo.c b/Tests/GeneratorExpression/echo.c
index 06b0844..41596a2 100644
--- a/Tests/GeneratorExpression/echo.c
+++ b/Tests/GeneratorExpression/echo.c
@@ -3,6 +3,9 @@
int main(int argc, char* argv[])
{
+#ifndef SRC_GENEX_WORKS
+#error SRC_GENEX_WORKS not defined
+#endif
printf("%s\n", argv[1]);
return EXIT_SUCCESS;
}