From 8a619e8c85def632e9e7938fc5a3a36bb22f46ff Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 28 Mar 2017 12:55:14 -0400 Subject: [PATCH 1/5] cmIDEOptions: Add GetDefines method --- Source/cmIDEOptions.cxx | 5 +++++ Source/cmIDEOptions.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/Source/cmIDEOptions.cxx b/Source/cmIDEOptions.cxx index c6c0e0531c..8d07776b73 100644 --- a/Source/cmIDEOptions.cxx +++ b/Source/cmIDEOptions.cxx @@ -148,6 +148,11 @@ void cmIDEOptions::AddDefines(const std::vector& defines) this->Defines.insert(this->Defines.end(), defines.begin(), defines.end()); } +std::vector const& cmIDEOptions::GetDefines() const +{ + return this->Defines; +} + void cmIDEOptions::AddFlag(const char* flag, const char* value) { this->FlagMap[flag] = value; diff --git a/Source/cmIDEOptions.h b/Source/cmIDEOptions.h index a0696e1250..be2fd6da8c 100644 --- a/Source/cmIDEOptions.h +++ b/Source/cmIDEOptions.h @@ -24,6 +24,8 @@ public: void AddDefine(const std::string& define); void AddDefines(const char* defines); void AddDefines(const std::vector& defines); + std::vector const& GetDefines() const; + void AddFlag(const char* flag, const char* value); void AddFlag(const char* flag, std::vector const& value); void AppendFlag(std::string const& flag, std::string const& value); From 1449f6f63d09f21203b36b3485dd3eb60c73ac17 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 28 Mar 2017 12:56:29 -0400 Subject: [PATCH 2/5] cmVisualStudio10TargetGenerator: De-duplicate preprocessor defs --- Source/cmVisualStudioGeneratorOptions.cxx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index c0913e67ab..da6f9a70b2 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -1,5 +1,6 @@ #include "cmVisualStudioGeneratorOptions.h" +#include "cmAlgorithms.h" #include "cmLocalVisualStudioGenerator.h" #include "cmOutputConverter.h" #include "cmSystemTools.h" @@ -267,8 +268,10 @@ void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions( fout << prefix << "PreprocessorDefinitions=\""; } const char* sep = ""; + std::vector::const_iterator de = + cmRemoveDuplicates(this->Defines); for (std::vector::const_iterator di = this->Defines.begin(); - di != this->Defines.end(); ++di) { + di != de; ++di) { // Escape the definition for the compiler. std::string define; if (this->Version < cmGlobalVisualStudioGenerator::VS10) { From c77194ec471dd4f039c0c30e05f0b519ab44bc14 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 28 Mar 2017 13:00:59 -0400 Subject: [PATCH 3/5] VS: Honor preprocessor definitions in RC flags The VS generators use the C (or CXX) preprocessor definitions for the Windows Resource Compiler tool. This causes definitions parsed out of `CMAKE_RC_FLAGS[_]` variables to be dropped. Fix the implementation to preserve both. Issue: #16745 --- Source/cmVisualStudio10TargetGenerator.cxx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 7447821a3d..902fe0328d 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2346,6 +2346,11 @@ bool cmVisualStudio10TargetGenerator::ComputeRcOptions( std::string(this->Makefile->GetSafeDefinition(rcConfigFlagsVar)); rcOptions.Parse(flags.c_str()); + + // For historical reasons, add the C preprocessor defines to RC. + Options& clOptions = *(this->ClOptions[configName]); + rcOptions.AddDefines(clOptions.GetDefines()); + this->RcOptions[configName] = pOptions.release(); return true; } @@ -2358,12 +2363,9 @@ void cmVisualStudio10TargetGenerator::WriteRCOptions( } this->WriteString("\n", 2); - // Preprocessor definitions and includes are shared with clOptions. - Options& clOptions = *(this->ClOptions[configName]); - clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", - "\n", "RC"); - Options& rcOptions = *(this->RcOptions[configName]); + rcOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", + "\n", "RC"); rcOptions.AppendFlag("AdditionalIncludeDirectories", includes); rcOptions.AppendFlag("AdditionalIncludeDirectories", "%(AdditionalIncludeDirectories)"); From 79a915383fd0c0e55bf0ca5fe5b3cf07d1823aa7 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 28 Mar 2017 13:03:56 -0400 Subject: [PATCH 4/5] RC: Add missing CMAKE_RC_FLAGS_ entries to cache --- Modules/CMakeRCInformation.cmake | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Modules/CMakeRCInformation.cmake b/Modules/CMakeRCInformation.cmake index 10f2cfbc4f..7ddd2978b2 100644 --- a/Modules/CMakeRCInformation.cmake +++ b/Modules/CMakeRCInformation.cmake @@ -17,11 +17,26 @@ set(CMAKE_SYSTEM_AND_RC_COMPILER_INFO_FILE ${CMAKE_ROOT}/Modules/Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}.cmake) include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL) -string(STRIP "$ENV{RCFLAGS} ${CMAKE_RC_FLAGS_INIT}" CMAKE_RC_FLAGS_INIT) +set(CMAKE_RC_FLAGS_INIT "$ENV{RCFLAGS} ${CMAKE_RC_FLAGS_INIT}") + +foreach(c "" _DEBUG _RELEASE _MINSIZEREL _RELWITHDEBINFO) + string(STRIP "${CMAKE_RC_FLAGS${c}_INIT}" CMAKE_RC_FLAGS${c}_INIT) +endforeach() set (CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS_INIT}" CACHE STRING "Flags for Windows Resource Compiler.") +if(NOT CMAKE_NOT_USING_CONFIG_FLAGS) + set (CMAKE_RC_FLAGS_DEBUG "${CMAKE_RC_FLAGS_DEBUG_INIT}" CACHE STRING + "Flags for Windows Resource Compiler during debug builds.") + set (CMAKE_RC_FLAGS_MINSIZEREL "${CMAKE_RC_FLAGS_MINSIZEREL_INIT}" CACHE STRING + "Flags for Windows Resource Compiler during release builds for minimum size.") + set (CMAKE_RC_FLAGS_RELEASE "${CMAKE_RC_FLAGS_RELEASE_INIT}" CACHE STRING + "Flags for Windows Resource Compiler during release builds.") + set (CMAKE_RC_FLAGS_RELWITHDEBINFO "${CMAKE_RC_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING + "Flags for Windows Resource Compiler during release builds with debug info.") +endif() + # These are the only types of flags that should be passed to the rc # command, if COMPILE_FLAGS is used on a target this will be used # to filter out any other flags From fff34934e70da77c359e47c53ffd04701bcd7611 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 28 Mar 2017 13:04:37 -0400 Subject: [PATCH 5/5] MSVC: Restore _DEBUG preprocessor definition in RC debug builds In commit v3.8.0-rc1~304^2 (MSVC: Do not define _DEBUG explicitly when using /MDd, 2016-11-15) we removed the `_DEBUG` preprocessor definition from MSVC C and C++ flags because the `cl` compiler automatically defines it in Debug builds anyway. However, the VS generators propagate C preprocessor definitions to the RC (Windows Resource Compiler) tool. This means that we used to explicitly define `_DEBUG` for RC debug builds. Therefore existing project code may expect the definition to be there even though the `rc` compiler itself does not implicitly define `_DEBUG` in debug builds. Add the `_DEBUG` flag to the default `CMAKE_RC_FLAGS_DEBUG` instead to restore this definition for RC debug builds. This also makes it available consistently in VS, Ninja, and Makefile generators. Fixes: #16745 --- Modules/Platform/Windows-MSVC.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index 31b26b5927..e4aca6eb2b 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -310,6 +310,9 @@ macro(__windows_compiler_msvc lang) if(NOT CMAKE_RC_FLAGS_INIT) string(APPEND CMAKE_RC_FLAGS_INIT " ${_PLATFORM_DEFINES} ${_PLATFORM_DEFINES_${lang}}") endif() + if(NOT CMAKE_RC_FLAGS_DEBUG_INIT) + string(APPEND CMAKE_RC_FLAGS_DEBUG_INIT " /D_DEBUG") + endif() enable_language(RC) set(CMAKE_NINJA_CMCLDEPS_RC 1)