From a6286e92c9be9f5b8ad8fb25b3c6e15c0ec17fa0 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 24 Mar 2013 21:18:39 +0100 Subject: [PATCH 1/2] Fix the evaluation of per-config COMPILE_DEFINITIONS (#14037) The API for retrieving per-config COMPILE_DEFINITIONS has long existed because of the COMPILE_DEFINITIONS_ style properties. Ensure that the provided configuration being generated is also used to evaluate the generator expressions in cmTarget::GetCompileDefinitions. Both the generic COMPILE_DEFINITIONS and the config-specific variant need to be evaluated with the requested configuration. This has the side-effect that the COMPILE_DEFINITIONS does not need to be additionally evaluated with no configuration, so the callers can be cleaned up a bit too. --- Source/cmExtraCodeBlocksGenerator.cxx | 6 ++--- Source/cmExtraSublimeTextGenerator.cxx | 3 +-- Source/cmGlobalXCodeGenerator.cxx | 8 ++---- Source/cmLocalUnixMakefileGenerator3.cxx | 1 - Source/cmLocalVisualStudio6Generator.cxx | 2 +- Source/cmLocalVisualStudio7Generator.cxx | 1 - Source/cmMakefileTargetGenerator.cxx | 3 --- Source/cmNinjaTargetGenerator.cxx | 5 +--- Source/cmQtAutomoc.cxx | 2 +- Source/cmTarget.cxx | 30 ++++++++++++---------- Source/cmTarget.h | 2 +- Source/cmVisualStudio10TargetGenerator.cxx | 2 -- 12 files changed, 26 insertions(+), 39 deletions(-) diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 6d5d5b5f6..f6f4ceff3 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -621,7 +621,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, ->GetGeneratorTarget(target); // the compilerdefines for this target - std::string cdefs = target->GetCompileDefinitions(); + std::string cdefs = target->GetCompileDefinitions(buildType); if(!cdefs.empty()) { @@ -640,10 +640,8 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, std::set uniqIncludeDirs; std::vector includes; - const char *config = target->GetMakefile() - ->GetDefinition("CMAKE_BUILD_TYPE"); target->GetMakefile()->GetLocalGenerator()-> - GetIncludeDirectories(includes, gtgt, "C", config); + GetIncludeDirectories(includes, gtgt, "C", buildType); for(std::vector::const_iterator dirIt=includes.begin(); dirIt != includes.end(); ++dirIt) diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx index 543140164..e4802d59e 100644 --- a/Source/cmExtraSublimeTextGenerator.cxx +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -488,12 +488,11 @@ ComputeDefines(cmSourceFile *source, cmLocalGenerator* lg, cmTarget *target, } // Add preprocessor definitions for this target and configuration. - lg->AppendDefines(defines, target->GetCompileDefinitions()); + lg->AppendDefines(defines, target->GetCompileDefinitions(config)); lg->AppendDefines(defines, source->GetProperty("COMPILE_DEFINITIONS")); { std::string defPropName = "COMPILE_DEFINITIONS_"; defPropName += cmSystemTools::UpperCase(config); - lg->AppendDefines(defines, target->GetCompileDefinitions(config)); lg->AppendDefines(defines, source->GetProperty(defPropName.c_str())); } diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 2222a0e9a..ceac56403 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1709,12 +1709,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, this->AppendDefines(ppDefs, exportMacro); } cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target); - this->AppendDefines(ppDefs, target.GetCompileDefinitions().c_str()); - if(configName) - { - this->AppendDefines(ppDefs, - target.GetCompileDefinitions(configName).c_str()); - } + this->AppendDefines(ppDefs, + target.GetCompileDefinitions(configName).c_str()); buildSettings->AddAttribute ("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList()); diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index f6ab0d051..0f680f6a1 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -1962,7 +1962,6 @@ void cmLocalUnixMakefileGenerator3 // Build a list of preprocessor definitions for the target. std::set defines; - this->AppendDefines(defines, target.GetCompileDefinitions()); this->AppendDefines(defines, target.GetCompileDefinitions( this->ConfigurationName.c_str())); if(!defines.empty()) diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index c35288c52..dc94476c8 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -1702,7 +1702,7 @@ void cmLocalVisualStudio6Generator this->AppendDefines( definesSet, - target.GetCompileDefinitions()); + target.GetCompileDefinitions(0)); this->AppendDefines( debugDefinesSet, target.GetCompileDefinitions("DEBUG")); diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index dfe828062..7d0bc67ed 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -745,7 +745,6 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, targetOptions.ParseFinish(); cmGeneratorTarget* gt = this->GlobalGenerator->GetGeneratorTarget(&target); - targetOptions.AddDefines(target.GetCompileDefinitions().c_str()); targetOptions.AddDefines(target.GetCompileDefinitions(configName).c_str()); targetOptions.SetVerboseMakefile( this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")); diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index d9aa7fed9..71926f375 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -302,9 +302,6 @@ std::string cmMakefileTargetGenerator::GetDefines(const std::string &l) } // Add preprocessor definitions for this target and configuration. - this->LocalGenerator->AppendDefines - (defines, this->Target->GetCompileDefinitions()); - this->LocalGenerator->AppendDefines (defines, this->Target->GetCompileDefinitions( this->LocalGenerator->ConfigurationName.c_str())); diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 80a1a9b94..3fb823cb0 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -228,16 +228,13 @@ ComputeDefines(cmSourceFile *source, const std::string& language) // Add preprocessor definitions for this target and configuration. this->LocalGenerator->AppendDefines (defines, - this->Target->GetCompileDefinitions()); + this->Target->GetCompileDefinitions(this->GetConfigName())); this->LocalGenerator->AppendDefines (defines, source->GetProperty("COMPILE_DEFINITIONS")); { std::string defPropName = "COMPILE_DEFINITIONS_"; defPropName += cmSystemTools::UpperCase(this->GetConfigName()); - this->LocalGenerator->AppendDefines - (defines, - this->Target->GetCompileDefinitions(this->GetConfigName())); this->LocalGenerator->AppendDefines (defines, source->GetProperty(defPropName.c_str())); diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 5730c8c9d..c7060b030 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -250,7 +250,7 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) std::string _moc_compile_defs; if (tmp) { - _moc_compile_defs = target->GetCompileDefinitions(); + _moc_compile_defs = target->GetCompileDefinitions(0); } tmp = makefile->GetProperty("COMPILE_DEFINITIONS"); if (tmp) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 56eb4ad49..732ebb20a 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2942,29 +2942,33 @@ std::vector cmTarget::GetIncludeDirectories(const char *config) //---------------------------------------------------------------------------- std::string cmTarget::GetCompileDefinitions(const char *config) { - std::string defPropName = "COMPILE_DEFINITIONS"; + const char *configProp = 0; if (config) { - defPropName += "_" + cmSystemTools::UpperCase(config); + std::string configPropName; + configPropName = "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config); + configProp = this->GetProperty(configPropName.c_str()); } - const char *prop = this->GetProperty(defPropName.c_str()); + const char *noconfigProp = this->GetProperty("COMPILE_DEFINITIONS"); cmListFileBacktrace lfbt; cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(), - defPropName, 0, 0); + "COMPILE_DEFINITIONS", 0, 0); - std::string result; - if (prop) + std::string defsString = (noconfigProp ? noconfigProp : ""); + if (configProp && noconfigProp) { - cmGeneratorExpression ge(lfbt); - - result = ge.Parse(prop)->Evaluate(this->Makefile, - config, - false, - this, - &dagChecker); + defsString += ";"; } + defsString += (configProp ? configProp : ""); + + cmGeneratorExpression ge(lfbt); + std::string result = ge.Parse(defsString.c_str())->Evaluate(this->Makefile, + config, + false, + this, + &dagChecker); std::vector libs; this->GetDirectLinkLibraries(config, libs, this); diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 0e6dd42da..e25133e58 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -430,7 +430,7 @@ public: If no macro should be defined null is returned. */ const char* GetExportMacro(); - std::string GetCompileDefinitions(const char *config = 0); + std::string GetCompileDefinitions(const char *config); // Compute the set of languages compiled by the target. This is // computed every time it is called because the languages can change diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index f4984c7ed..1cb9f2370 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1220,8 +1220,6 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( clOptions.AddFlag("PrecompiledHeader", "NotUsing"); clOptions.Parse(flags.c_str()); clOptions.Parse(defineFlags.c_str()); - clOptions.AddDefines( - this->Target->GetCompileDefinitions().c_str()); clOptions.AddDefines(this->Target->GetCompileDefinitions( configName.c_str()).c_str()); clOptions.SetVerboseMakefile( From 1703b00c7fc34f473e84f4ba29bdc73476637005 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 25 Mar 2013 09:43:22 -0400 Subject: [PATCH 2/2] Test evaluation of per-config COMPILE_DEFINITIONS (#14037) Teach the CompileDefinitions test to cover evaluation of config-specific generator expressions. --- Tests/CompileDefinitions/CMakeLists.txt | 15 ++++-- .../add_definitions_command/CMakeLists.txt | 1 + .../CMakeLists.txt | 3 ++ Tests/CompileDefinitions/compiletest.cpp | 24 ++++++++++ Tests/CompileDefinitions/runtest.c | 47 +++++++++++++++++++ .../target_prop/CMakeLists.txt | 5 ++ 6 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 Tests/CompileDefinitions/runtest.c diff --git a/Tests/CompileDefinitions/CMakeLists.txt b/Tests/CompileDefinitions/CMakeLists.txt index e7d91bf94..d3e9a3eae 100644 --- a/Tests/CompileDefinitions/CMakeLists.txt +++ b/Tests/CompileDefinitions/CMakeLists.txt @@ -7,10 +7,19 @@ if ("${CMAKE_GENERATOR}" STREQUAL "Visual Studio 6") add_definitions(-DNO_SPACES_IN_DEFINE_VALUES) endif() +# Use compile flags to tell executables which config is built +# without depending on the compile definitions functionality. +foreach(c DEBUG RELEASE RELWITHDEBINFO MINSIZEREL) + set(CMAKE_C_FLAGS_${c} "${CMAKE_C_FLAGS_${c}} -DTEST_CONFIG_${c}") + set(CMAKE_CXX_FLAGS_${c} "${CMAKE_CXX_FLAGS_${c}} -DTEST_CONFIG_${c}") +endforeach() + +set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS + "BUILD_CONFIG_NAME=\"$\"" + ) + add_subdirectory(add_definitions_command) add_subdirectory(target_prop) add_subdirectory(add_definitions_command_with_target_prop) -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/dummyexecutable.cpp" "int main(int, char **) { return 0; }\n") - -add_executable(CompileDefinitions "${CMAKE_CURRENT_BINARY_DIR}/dummyexecutable.cpp") +add_executable(CompileDefinitions runtest.c) diff --git a/Tests/CompileDefinitions/add_definitions_command/CMakeLists.txt b/Tests/CompileDefinitions/add_definitions_command/CMakeLists.txt index a6372af74..d3886a104 100644 --- a/Tests/CompileDefinitions/add_definitions_command/CMakeLists.txt +++ b/Tests/CompileDefinitions/add_definitions_command/CMakeLists.txt @@ -3,5 +3,6 @@ project(add_definitions_command) add_definitions(-DCMAKE_IS_FUN -DCMAKE_IS=Fun -DCMAKE_IS_="Fun" -DCMAKE_IS_REALLY="Very Fun") add_definitions(-DCMAKE_IS_="Fun" -DCMAKE_IS_REALLY="Very Fun" -DCMAKE_IS_FUN -DCMAKE_IS=Fun) +add_definitions(-DBUILD_IS_DEBUG=$ -DBUILD_IS_NOT_DEBUG=$>) add_executable(add_definitions_command_executable ../compiletest.cpp) diff --git a/Tests/CompileDefinitions/add_definitions_command_with_target_prop/CMakeLists.txt b/Tests/CompileDefinitions/add_definitions_command_with_target_prop/CMakeLists.txt index e415390c0..5587f7f99 100644 --- a/Tests/CompileDefinitions/add_definitions_command_with_target_prop/CMakeLists.txt +++ b/Tests/CompileDefinitions/add_definitions_command_with_target_prop/CMakeLists.txt @@ -12,3 +12,6 @@ set_property(TARGET add_definitions_command_with_target_prop_executable APPEND P add_definitions(-DCMAKE_IS_FUN) set_property(TARGET add_definitions_command_with_target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_IS=Fun CMAKE_IS_="Fun") + +add_definitions(-DBUILD_IS_DEBUG=$) +set_property(TARGET add_definitions_command_with_target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS BUILD_IS_NOT_DEBUG=$>) diff --git a/Tests/CompileDefinitions/compiletest.cpp b/Tests/CompileDefinitions/compiletest.cpp index f18e59e67..14b8eab4a 100644 --- a/Tests/CompileDefinitions/compiletest.cpp +++ b/Tests/CompileDefinitions/compiletest.cpp @@ -45,6 +45,30 @@ enum { // TEST_GENERATOR_EXPRESSIONS #endif +#ifndef BUILD_IS_DEBUG +# error "BUILD_IS_DEBUG not defined!" +#endif +#ifndef BUILD_IS_NOT_DEBUG +# error "BUILD_IS_NOT_DEBUG not defined!" +#endif + +// Check per-config definitions. +#ifdef TEST_CONFIG_DEBUG +# if !BUILD_IS_DEBUG +# error "BUILD_IS_DEBUG false with TEST_CONFIG_DEBUG!" +# endif +# if BUILD_IS_NOT_DEBUG +# error "BUILD_IS_NOT_DEBUG true with TEST_CONFIG_DEBUG!" +# endif +#else +# if BUILD_IS_DEBUG +# error "BUILD_IS_DEBUG true without TEST_CONFIG_DEBUG!" +# endif +# if !BUILD_IS_NOT_DEBUG +# error "BUILD_IS_NOT_DEBUG false without TEST_CONFIG_DEBUG!" +# endif +#endif + int main(int argc, char **argv) { return 0; diff --git a/Tests/CompileDefinitions/runtest.c b/Tests/CompileDefinitions/runtest.c new file mode 100644 index 000000000..02d2cadb0 --- /dev/null +++ b/Tests/CompileDefinitions/runtest.c @@ -0,0 +1,47 @@ +#include +#include +#include + +#ifndef BUILD_CONFIG_NAME +# error "BUILD_CONFIG_NAME not defined!" +#endif + +int main() +{ + char build_config_name[] = BUILD_CONFIG_NAME; + char* c; + for(c = build_config_name; *c; ++c) + { + *c = (char)tolower((int)*c); + } + fprintf(stderr, "build_config_name=\"%s\"\n", build_config_name); +#ifdef TEST_CONFIG_DEBUG + if(strcmp(build_config_name, "debug") != 0) + { + fprintf(stderr, "build_config_name is not \"debug\"\n"); + return 1; + } +#endif +#ifdef TEST_CONFIG_RELEASE + if(strcmp(build_config_name, "release") != 0) + { + fprintf(stderr, "build_config_name is not \"release\"\n"); + return 1; + } +#endif +#ifdef TEST_CONFIG_MINSIZEREL + if(strcmp(build_config_name, "minsizerel") != 0) + { + fprintf(stderr, "build_config_name is not \"minsizerel\"\n"); + return 1; + } +#endif +#ifdef TEST_CONFIG_RELWITHDEBINFO + if(strcmp(build_config_name, "relwithdebinfo") != 0) + { + fprintf(stderr, "build_config_name is not \"relwithdebinfo\"\n"); + return 1; + } +#endif + return 0; +} diff --git a/Tests/CompileDefinitions/target_prop/CMakeLists.txt b/Tests/CompileDefinitions/target_prop/CMakeLists.txt index abdf257ec..1ef2d6d6e 100644 --- a/Tests/CompileDefinitions/target_prop/CMakeLists.txt +++ b/Tests/CompileDefinitions/target_prop/CMakeLists.txt @@ -14,3 +14,8 @@ set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS "$<0:GE_NOT_DEFINED>" "$<1:ARGUMENT;LIST>" ) + +set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS + BUILD_IS_DEBUG=$ + BUILD_IS_NOT_DEBUG=$> + )