Merge topic 'src-COMPILE_DEFINITIONS-genex'

9432f686 Add generator expression support to per-source COMPILE_DEFINITIONS

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !1546
This commit is contained in:
Brad King 2017-12-06 13:05:25 +00:00 committed by Kitware Robot
commit 060cf73ec8
16 changed files with 103 additions and 28 deletions

View File

@ -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.

View File

@ -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)>`.

View File

@ -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;

View File

@ -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 += ' ';

View File

@ -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;
}

View File

@ -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";
}

View File

@ -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);

View File

@ -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);

View File

@ -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, " ");

View File

@ -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.

View File

@ -1,4 +1,4 @@
int srcgenex(void)
int srcgenex_defs(void)
{
return 0;
}

View File

@ -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();
}

View File

@ -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$

View File

@ -0,0 +1,3 @@
enable_language(C)
add_executable(main main.c)
set_property(SOURCE main.c PROPERTY COMPILE_DEFINITIONS "$<$<CONFIG:Debug>:MYDEBUG>")

View File

@ -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.