summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@sap.com>2017-11-30 14:06:21 (GMT)
committerMarc Chevrier <marc.chevrier@sap.com>2017-12-05 13:47:39 (GMT)
commit9432f686e62082045f53bd0ec8f8911966476df1 (patch)
tree9e03e1ae0c08fa693fbfb741b763d45c78b5feef
parentd06b8264212c893b5da8d7499328eb403aaaad37 (diff)
downloadCMake-9432f686e62082045f53bd0ec8f8911966476df1.zip
CMake-9432f686e62082045f53bd0ec8f8911966476df1.tar.gz
CMake-9432f686e62082045f53bd0ec8f8911966476df1.tar.bz2
Add generator expression support to per-source COMPILE_DEFINITIONS
This allows users to specify different genex-based compile definitions for each file in a target. Fixes: #17508
-rw-r--r--Help/prop_sf/COMPILE_DEFINITIONS.rst10
-rw-r--r--Help/release/dev/src-COMPILE_DEFINITIONS-genex.rst5
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx14
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx7
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx6
-rw-r--r--Source/cmMakefileTargetGenerator.cxx11
-rw-r--r--Source/cmNinjaTargetGenerator.cxx21
-rw-r--r--Source/cmServerProtocol.cxx10
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx11
-rw-r--r--Tests/GeneratorExpression/CMakeLists.txt9
-rw-r--r--Tests/GeneratorExpression/srcgenex_defs.c (renamed from Tests/GeneratorExpression/srcgenex.c)2
-rw-r--r--Tests/GeneratorExpression/srcgenex_flags.c12
-rw-r--r--Tests/RunCMake/XcodeProject/PerConfigPerSourceDefinitions-result.txt1
-rw-r--r--Tests/RunCMake/XcodeProject/PerConfigPerSourceDefinitions-stderr.txt8
-rw-r--r--Tests/RunCMake/XcodeProject/PerConfigPerSourceDefinitions.cmake3
-rw-r--r--Tests/RunCMake/XcodeProject/RunCMakeTest.cmake1
16 files changed, 103 insertions, 28 deletions
diff --git a/Help/prop_sf/COMPILE_DEFINITIONS.rst b/Help/prop_sf/COMPILE_DEFINITIONS.rst
index 1626825..8d2108c 100644
--- a/Help/prop_sf/COMPILE_DEFINITIONS.rst
+++ b/Help/prop_sf/COMPILE_DEFINITIONS.rst
@@ -17,3 +17,13 @@ by the native build tool. Xcode does not support per-configuration
definitions on source files.
.. include:: /include/COMPILE_DEFINITIONS_DISCLAIMER.txt
+
+Contents of ``COMPILE_DEFINITIONS`` 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.
+
+Generator expressions should be preferred instead of setting the alternative per-configuration
+property.
diff --git a/Help/release/dev/src-COMPILE_DEFINITIONS-genex.rst b/Help/release/dev/src-COMPILE_DEFINITIONS-genex.rst
new file mode 100644
index 0000000..892344f
--- /dev/null
+++ b/Help/release/dev/src-COMPILE_DEFINITIONS-genex.rst
@@ -0,0 +1,5 @@
+src-COMPILE_DEFINITIONS-genex
+-----------------------------
+
+* The :prop_sf:`COMPILE_DEFINITIONS` source file property learned to support
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 2443ece..bd1b6bb 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -379,6 +379,7 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines(
cmMakefile* makefile = lg->GetMakefile();
const std::string& language = source->GetLanguage();
const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ cmGeneratorExpressionInterpreter genexInterpreter(lg, target, config);
// Add the export symbol definition for shared library objects.
if (const char* exportMacro = target->GetExportMacro()) {
@@ -387,11 +388,14 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines(
// Add preprocessor definitions for this target and configuration.
lg->AddCompileDefinitions(defines, target, config, language);
- lg->AppendDefines(defines, source->GetProperty("COMPILE_DEFINITIONS"));
- {
- std::string defPropName = "COMPILE_DEFINITIONS_";
- defPropName += cmSystemTools::UpperCase(config);
- lg->AppendDefines(defines, source->GetProperty(defPropName));
+ if (const char* compile_defs = source->GetProperty("COMPILE_DEFINITIONS")) {
+ lg->AppendDefines(defines, genexInterpreter.Evaluate(compile_defs));
+ }
+
+ std::string defPropName = "COMPILE_DEFINITIONS_";
+ defPropName += cmSystemTools::UpperCase(config);
+ if (const char* config_compile_defs = source->GetProperty(defPropName)) {
+ lg->AppendDefines(defines, genexInterpreter.Evaluate(config_compile_defs));
}
std::string definesString;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 63f708b..bbf4175 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -740,8 +740,11 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
// Add per-source definitions.
BuildObjectListOrString flagsBuild(this, false);
- this->AppendDefines(flagsBuild, sf->GetProperty("COMPILE_DEFINITIONS"),
- true);
+ if (const char* compile_defs = sf->GetProperty("COMPILE_DEFINITIONS")) {
+ this->AppendDefines(
+ flagsBuild,
+ genexInterpreter.Evaluate(compile_defs, "COMPILE_DEFINITIONS"), true);
+ }
if (!flagsBuild.IsEmpty()) {
if (!flags.empty()) {
flags += ' ';
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index e5c8317..53966cd 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -1484,13 +1484,13 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
}
}
if (const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) {
- fc.CompileDefs = cdefs;
+ fc.CompileDefs = genexInterpreter.Evaluate(cdefs);
needfc = true;
}
std::string defPropName = "COMPILE_DEFINITIONS_";
defPropName += configUpper;
- if (const char* ccdefs = sf.GetProperty(defPropName.c_str())) {
- fc.CompileDefsConfig = ccdefs;
+ if (const char* ccdefs = sf.GetProperty(defPropName)) {
+ fc.CompileDefsConfig = genexInterpreter.Evaluate(ccdefs);
needfc = true;
}
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 85dc55e..5e0c582 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -447,18 +447,19 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
// Add source-sepcific preprocessor definitions.
if (const char* compile_defs = source.GetProperty("COMPILE_DEFINITIONS")) {
- this->LocalGenerator->AppendDefines(defines, compile_defs);
+ const char* evaluatedDefs = genexInterpreter.Evaluate(compile_defs);
+ this->LocalGenerator->AppendDefines(defines, evaluatedDefs);
*this->FlagFileStream << "# Custom defines: " << relativeObj
- << "_DEFINES = " << compile_defs << "\n"
+ << "_DEFINES = " << evaluatedDefs << "\n"
<< "\n";
}
std::string defPropName = "COMPILE_DEFINITIONS_";
defPropName += configUpper;
if (const char* config_compile_defs = source.GetProperty(defPropName)) {
- this->LocalGenerator->AppendDefines(defines, config_compile_defs);
+ const char* evaluatedDefs = genexInterpreter.Evaluate(config_compile_defs);
+ this->LocalGenerator->AppendDefines(defines, evaluatedDefs);
*this->FlagFileStream << "# Custom defines: " << relativeObj << "_DEFINES_"
- << configUpper << " = " << config_compile_defs
- << "\n"
+ << configUpper << " = " << evaluatedDefs << "\n"
<< "\n";
}
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index bad4112..1036977 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -177,13 +177,20 @@ std::string cmNinjaTargetGenerator::ComputeDefines(cmSourceFile const* source,
const std::string& language)
{
std::set<std::string> defines;
- this->LocalGenerator->AppendDefines(
- defines, source->GetProperty("COMPILE_DEFINITIONS"));
- {
- std::string defPropName = "COMPILE_DEFINITIONS_";
- defPropName += cmSystemTools::UpperCase(this->GetConfigName());
- this->LocalGenerator->AppendDefines(defines,
- source->GetProperty(defPropName));
+ const std::string config = this->LocalGenerator->GetConfigName();
+ cmGeneratorExpressionInterpreter genexInterpreter(
+ this->LocalGenerator, this->GeneratorTarget, config);
+
+ if (const char* compile_defs = source->GetProperty("COMPILE_DEFINITIONS")) {
+ this->LocalGenerator->AppendDefines(
+ defines, genexInterpreter.Evaluate(compile_defs));
+ }
+
+ std::string defPropName = "COMPILE_DEFINITIONS_";
+ defPropName += cmSystemTools::UpperCase(config);
+ if (const char* config_compile_defs = source->GetProperty(defPropName)) {
+ this->LocalGenerator->AppendDefines(
+ defines, genexInterpreter.Evaluate(config_compile_defs));
}
std::string definesString = this->GetDefines(language);
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index 1bb07e7..da354bd 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -712,10 +712,16 @@ static Json::Value DumpSourceFilesList(
fileData.IncludePathList = ld.IncludePathList;
std::set<std::string> defines;
- lg->AppendDefines(defines, file->GetProperty("COMPILE_DEFINITIONS"));
+ if (const char* defs = file->GetProperty("COMPILE_DEFINITIONS")) {
+ lg->AppendDefines(defines, genexInterpreter.Evaluate(defs));
+ }
+
const std::string defPropName =
"COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config);
- lg->AppendDefines(defines, file->GetProperty(defPropName));
+ if (const char* config_defs = file->GetProperty(defPropName)) {
+ lg->AppendDefines(defines, genexInterpreter.Evaluate(config_defs));
+ }
+
defines.insert(ld.Defines.begin(), ld.Defines.end());
fileData.SetDefines(defines);
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index badd24f..8589a96 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2066,12 +2066,15 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
std::string flags;
bool configDependentFlags = false;
std::string defines;
+ bool configDependentDefines = false;
if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) {
configDependentFlags =
cmGeneratorExpression::Find(cflags) != std::string::npos;
flags += cflags;
}
if (const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) {
+ configDependentDefines =
+ cmGeneratorExpression::Find(cdefs) != std::string::npos;
defines += cdefs;
}
std::string lang =
@@ -2121,6 +2124,8 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
if (!configDefines.empty()) {
configDefines += ";";
}
+ configDependentDefines |=
+ cmGeneratorExpression::Find(ccdefs) != std::string::npos;
configDefines += ccdefs;
}
// if we have flags or defines for this config then
@@ -2170,7 +2175,11 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
clOptions.AppendFlag("DisableSpecificWarnings",
"%(DisableSpecificWarnings)");
}
- clOptions.AddDefines(configDefines.c_str());
+ if (configDependentDefines) {
+ clOptions.AddDefines(genexInterpreter.Evaluate(configDefines));
+ } else {
+ clOptions.AddDefines(configDefines.c_str());
+ }
clOptions.SetConfiguration((*config).c_str());
clOptions.PrependInheritedString("AdditionalOptions");
clOptions.OutputFlagMap(*this->BuildFileStream, " ");
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index 83fd11d..5165970 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -258,8 +258,13 @@ add_custom_target(check-part4 ALL
VERBATIM
)
-add_executable(srcgenex srcgenex.c)
-set_property(SOURCE srcgenex.c PROPERTY COMPILE_FLAGS "-DNAME=$<TARGET_PROPERTY:NAME>")
+#-----------------------------------------------------------------------------
+# Cover source file properties with generator expressions.
+add_executable(srcgenex_flags srcgenex_flags.c)
+set_property(SOURCE srcgenex_flags.c PROPERTY COMPILE_FLAGS "-DNAME=$<TARGET_PROPERTY:NAME>")
+
+add_executable(srcgenex_defs srcgenex_defs.c)
+set_property(SOURCE srcgenex_defs.c PROPERTY COMPILE_DEFINITIONS NAME=$<TARGET_PROPERTY:NAME>)
#-----------------------------------------------------------------------------
# Cover test properties with generator expressions.
diff --git a/Tests/GeneratorExpression/srcgenex.c b/Tests/GeneratorExpression/srcgenex_defs.c
index 56d3c3f..883e631 100644
--- a/Tests/GeneratorExpression/srcgenex.c
+++ b/Tests/GeneratorExpression/srcgenex_defs.c
@@ -1,4 +1,4 @@
-int srcgenex(void)
+int srcgenex_defs(void)
{
return 0;
}
diff --git a/Tests/GeneratorExpression/srcgenex_flags.c b/Tests/GeneratorExpression/srcgenex_flags.c
new file mode 100644
index 0000000..3de2b12
--- /dev/null
+++ b/Tests/GeneratorExpression/srcgenex_flags.c
@@ -0,0 +1,12 @@
+int srcgenex_flags(void)
+{
+ return 0;
+}
+
+int main(int argc, char* argv[])
+{
+#ifndef NAME
+#error NAME not defined
+#endif
+ return NAME();
+}
diff --git a/Tests/RunCMake/XcodeProject/PerConfigPerSourceDefinitions-result.txt b/Tests/RunCMake/XcodeProject/PerConfigPerSourceDefinitions-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/PerConfigPerSourceDefinitions-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/XcodeProject/PerConfigPerSourceDefinitions-stderr.txt b/Tests/RunCMake/XcodeProject/PerConfigPerSourceDefinitions-stderr.txt
new file mode 100644
index 0000000..46a294d
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/PerConfigPerSourceDefinitions-stderr.txt
@@ -0,0 +1,8 @@
+^CMake Error in CMakeLists.txt:
+ Xcode does not support per-config per-source COMPILE_DEFINITIONS:
+
+ \$<\$<CONFIG:Debug>:MYDEBUG>
+
+ specified for source:
+
+ .*/Tests/RunCMake/XcodeProject/main.c$
diff --git a/Tests/RunCMake/XcodeProject/PerConfigPerSourceDefinitions.cmake b/Tests/RunCMake/XcodeProject/PerConfigPerSourceDefinitions.cmake
new file mode 100644
index 0000000..f9df55f
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/PerConfigPerSourceDefinitions.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+add_executable(main main.c)
+set_property(SOURCE main.c PROPERTY COMPILE_DEFINITIONS "$<$<CONFIG:Debug>:MYDEBUG>")
diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
index f730b83..7eb624c 100644
--- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
@@ -19,6 +19,7 @@ if (NOT XCODE_VERSION VERSION_LESS 6)
endif()
run_cmake(PerConfigPerSourceFlags)
+run_cmake(PerConfigPerSourceDefinitions)
# Use a single build tree for a few tests without cleaning.