From 957c2aac7fb4833b333cf3362cb8c6918a8e8a82 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 7 May 2015 11:43:02 -0400 Subject: [PATCH 1/4] RC: Simplify selection of resource compiler based on C/C++ toolchain Revert the refactoring by commit v2.8.11~105^2~1 (Ninja: use MinGW generator code in EnableLanguage, 2013-03-09) and move the MinGW- specific logic back to the "MinGW Makefiles" generator. Instead teach the platform information modules for GNU and MSVC on Windows to set the preferred RC compiler just before enabling the RC language. This way we choose the RC compiler based on the C/C++ toolchain that is actually enabled. --- Modules/Platform/CYGWIN-GNU.cmake | 4 +++ Modules/Platform/Windows-GNU.cmake | 4 +++ Modules/Platform/Windows-MSVC.cmake | 3 +++ Source/cmGlobalGenerator.cxx | 32 ----------------------- Source/cmGlobalGenerator.h | 1 - Source/cmGlobalMinGWMakefileGenerator.cxx | 28 +++++++++++++++++++- Source/cmGlobalNinjaGenerator.cxx | 1 - 7 files changed, 38 insertions(+), 35 deletions(-) diff --git a/Modules/Platform/CYGWIN-GNU.cmake b/Modules/Platform/CYGWIN-GNU.cmake index 3144ac483..1a46c1031 100644 --- a/Modules/Platform/CYGWIN-GNU.cmake +++ b/Modules/Platform/CYGWIN-GNU.cmake @@ -53,5 +53,9 @@ macro(__cygwin_compiler_gnu lang) set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS} -Wl,--enable-auto-import") set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS}") + if(NOT CMAKE_RC_COMPILER_INIT) + set(CMAKE_RC_COMPILER_INIT windres) + endif() + enable_language(RC) endmacro() diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake index c827c325e..c0d7d8cd8 100644 --- a/Modules/Platform/Windows-GNU.cmake +++ b/Modules/Platform/Windows-GNU.cmake @@ -138,6 +138,10 @@ macro(__windows_compiler_gnu lang) endforeach() endif() + if(NOT CMAKE_RC_COMPILER_INIT) + set(CMAKE_RC_COMPILER_INIT windres) + endif() + enable_language(RC) endmacro() diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index 2905ceeac..13fe8bc9c 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -298,6 +298,9 @@ macro(__windows_compiler_msvc lang) set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "/MD /O1 /Ob1 /D NDEBUG") set(CMAKE_${lang}_LINKER_SUPPORTS_PDB ON) + if(NOT CMAKE_RC_COMPILER_INIT) + set(CMAKE_RC_COMPILER_INIT rc) + endif() if(NOT CMAKE_RC_FLAGS_INIT) set(CMAKE_RC_FLAGS_INIT "${_PLATFORM_DEFINES} ${_PLATFORM_DEFINES_${lang}}") endif() diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 1c905377c..746be4d9a 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -2420,38 +2420,6 @@ bool cmGlobalGenerator::UseFolderProperty() return false; } -//---------------------------------------------------------------------------- -void cmGlobalGenerator::EnableMinGWLanguage(cmMakefile *mf) -{ - this->FindMakeProgram(mf); - std::string makeProgram = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"); - std::vector locations; - locations.push_back(cmSystemTools::GetProgramPath(makeProgram)); - locations.push_back("/mingw/bin"); - locations.push_back("c:/mingw/bin"); - std::string tgcc = cmSystemTools::FindProgram("gcc", locations); - std::string gcc = "gcc.exe"; - if(!tgcc.empty()) - { - gcc = tgcc; - } - std::string tgxx = cmSystemTools::FindProgram("g++", locations); - std::string gxx = "g++.exe"; - if(!tgxx.empty()) - { - gxx = tgxx; - } - std::string trc = cmSystemTools::FindProgram("windres", locations); - std::string rc = "windres.exe"; - if(!trc.empty()) - { - rc = trc; - } - mf->AddDefinition("CMAKE_GENERATOR_CC", gcc.c_str()); - mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx.c_str()); - mf->AddDefinition("CMAKE_GENERATOR_RC", rc.c_str()); -} - //---------------------------------------------------------------------------- cmTarget cmGlobalGenerator::CreateGlobalTarget( const std::string& name, const char* message, diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 710719894..22ba2889c 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -433,7 +433,6 @@ protected: virtual const char* GetPredefinedTargetsFolder(); virtual bool UseFolderProperty(); - void EnableMinGWLanguage(cmMakefile *mf); private: cmMakefile* TryCompileOuterMakefile; diff --git a/Source/cmGlobalMinGWMakefileGenerator.cxx b/Source/cmGlobalMinGWMakefileGenerator.cxx index c9389aac4..b1288709f 100644 --- a/Source/cmGlobalMinGWMakefileGenerator.cxx +++ b/Source/cmGlobalMinGWMakefileGenerator.cxx @@ -26,7 +26,33 @@ void cmGlobalMinGWMakefileGenerator cmMakefile *mf, bool optional) { - this->EnableMinGWLanguage(mf); + this->FindMakeProgram(mf); + std::string makeProgram = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"); + std::vector locations; + locations.push_back(cmSystemTools::GetProgramPath(makeProgram)); + locations.push_back("/mingw/bin"); + locations.push_back("c:/mingw/bin"); + std::string tgcc = cmSystemTools::FindProgram("gcc", locations); + std::string gcc = "gcc.exe"; + if(!tgcc.empty()) + { + gcc = tgcc; + } + std::string tgxx = cmSystemTools::FindProgram("g++", locations); + std::string gxx = "g++.exe"; + if(!tgxx.empty()) + { + gxx = tgxx; + } + std::string trc = cmSystemTools::FindProgram("windres", locations); + std::string rc = "windres.exe"; + if(!trc.empty()) + { + rc = trc; + } + mf->AddDefinition("CMAKE_GENERATOR_CC", gcc.c_str()); + mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx.c_str()); + mf->AddDefinition("CMAKE_GENERATOR_RC", rc.c_str()); this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional); } diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 678d60b21..9a017e57d 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -555,7 +555,6 @@ void cmGlobalNinjaGenerator if (makefile->IsOn("CMAKE_COMPILER_IS_MINGW")) { UsingMinGW = true; - this->EnableMinGWLanguage(makefile); } if (std::find(langs.begin(), langs.end(), "Fortran") != langs.end()) { From 378c2a0e860f32e0435844d7d6af79a4fdc2b455 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 7 May 2015 14:01:58 -0400 Subject: [PATCH 2/4] Ninja: Refactor detection of MinGW tools on Windows Check for CMAKE_COMPILER_IS_MINGW only after enabling a language when it might actually be set. Previously this worked by accident because the check for working compiler or a second language enabled would cause the code path to be taken. Store UsingMinGW as an instance member of cmGlobalNinjaGenerator so that it is reset on each reconfigure. Otherwise cmake-gui cannot switch between build trees for MinGW or non-MinGW tools. --- Source/cmGlobalNinjaGenerator.cxx | 24 +++++++++++------------- Source/cmGlobalNinjaGenerator.h | 11 ++++------- Source/cmNinjaTargetGenerator.cxx | 2 +- 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 9a017e57d..9894aa822 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -96,7 +96,7 @@ std::string cmGlobalNinjaGenerator::EncodePath(const std::string &path) { std::string result = path; #ifdef _WIN32 - if(UsingMinGW) + if (this->IsMinGW()) cmSystemTools::ReplaceString(result, "\\", "/"); else cmSystemTools::ReplaceString(result, "/", "\\"); @@ -484,6 +484,7 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator() , CompileCommandsStream(0) , Rules() , AllDependencies() + , UsingMinGW(false) , ComputingUnknownDependencies(false) , PolicyCMP0058(cmPolicies::WARN) { @@ -544,23 +545,16 @@ void cmGlobalNinjaGenerator::Generate() this->CloseBuildFileStream(); } -// Implemented in all cmGlobaleGenerator sub-classes. -// Used in: -// Source/cmMakefile.cxx: void cmGlobalNinjaGenerator ::EnableLanguage(std::vectorconst& langs, - cmMakefile* makefile, + cmMakefile* mf, bool optional) { - if (makefile->IsOn("CMAKE_COMPILER_IS_MINGW")) - { - UsingMinGW = true; - } if (std::find(langs.begin(), langs.end(), "Fortran") != langs.end()) { cmSystemTools::Error("The Ninja generator does not support Fortran yet."); } - this->cmGlobalGenerator::EnableLanguage(langs, makefile, optional); + this->cmGlobalGenerator::EnableLanguage(langs, mf, optional); for(std::vector::const_iterator l = langs.begin(); l != langs.end(); ++l) { @@ -568,12 +562,16 @@ void cmGlobalNinjaGenerator { continue; } - this->ResolveLanguageCompiler(*l, makefile, optional); + this->ResolveLanguageCompiler(*l, mf, optional); } +#ifdef _WIN32 + if (mf->IsOn("CMAKE_COMPILER_IS_MINGW")) + { + this->UsingMinGW = true; + } +#endif } -bool cmGlobalNinjaGenerator::UsingMinGW = false; - // Implemented by: // cmGlobalUnixMakefileGenerator3 // cmGlobalGhsMultiGenerator diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index d7b3adddc..9b6717a71 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -63,7 +63,7 @@ public: static std::string EncodeIdent(const std::string &ident, std::ostream &vars); static std::string EncodeLiteral(const std::string &lit); - static std::string EncodePath(const std::string &path); + std::string EncodePath(const std::string &path); static std::string EncodeDepfileSpace(const std::string &path); /** @@ -155,9 +155,7 @@ public: const cmNinjaDeps& targets, const std::string& comment = ""); - - static bool IsMinGW() { return UsingMinGW; } - + bool IsMinGW() const { return this->UsingMinGW; } public: /// Default constructor. @@ -362,6 +360,8 @@ private: /// The set of dependencies to add to the "all" target. cmNinjaDeps AllDependencies; + bool UsingMinGW; + /// The set of custom commands we have seen. std::set CustomCommands; @@ -385,9 +385,6 @@ private: typedef std::map TargetAliasMap; TargetAliasMap TargetAliases; - - static bool UsingMinGW; - }; #endif // ! cmGlobalNinjaGenerator_h diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index dfd3c04e4..a3c9be659 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -175,7 +175,7 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile const* source, // needed by cmcldeps false, this->GetConfigName()); - if(cmGlobalNinjaGenerator::IsMinGW()) + if (this->GetGlobalGenerator()->IsMinGW()) cmSystemTools::ReplaceString(includeFlags, "\\", "/"); this->LocalGenerator->AppendFlags(languageFlags, includeFlags); From b3de0dfe93af769ee7420cd1380395d656b4dac9 Mon Sep 17 00:00:00 2001 From: Thomas Herz Date: Thu, 7 May 2015 00:45:01 +0200 Subject: [PATCH 3/4] Ninja: Use forward slashes for any GCC on Windows (#15439) Any GCC compiler on a Windows host needs forward slashes, not just those built for MinGW. --- Source/cmGlobalNinjaGenerator.cxx | 12 ++++++++---- Source/cmGlobalNinjaGenerator.h | 4 ++-- Source/cmNinjaTargetGenerator.cxx | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 9894aa822..65e80e41a 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -96,7 +96,7 @@ std::string cmGlobalNinjaGenerator::EncodePath(const std::string &path) { std::string result = path; #ifdef _WIN32 - if (this->IsMinGW()) + if (this->IsGCCOnWindows()) cmSystemTools::ReplaceString(result, "\\", "/"); else cmSystemTools::ReplaceString(result, "/", "\\"); @@ -484,7 +484,7 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator() , CompileCommandsStream(0) , Rules() , AllDependencies() - , UsingMinGW(false) + , UsingGCCOnWindows(false) , ComputingUnknownDependencies(false) , PolicyCMP0058(cmPolicies::WARN) { @@ -565,9 +565,13 @@ void cmGlobalNinjaGenerator this->ResolveLanguageCompiler(*l, mf, optional); } #ifdef _WIN32 - if (mf->IsOn("CMAKE_COMPILER_IS_MINGW")) + if (mf->IsOn("CMAKE_COMPILER_IS_MINGW") || + strcmp(mf->GetSafeDefinition("CMAKE_C_COMPILER_ID"), "GNU") == 0 || + strcmp(mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID"), "GNU") == 0 || + strcmp(mf->GetSafeDefinition("CMAKE_C_SIMULATE_ID"), "GNU") == 0 || + strcmp(mf->GetSafeDefinition("CMAKE_CXX_SIMULATE_ID"), "GNU") == 0) { - this->UsingMinGW = true; + this->UsingGCCOnWindows = true; } #endif } diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 9b6717a71..00dc237bd 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -155,7 +155,7 @@ public: const cmNinjaDeps& targets, const std::string& comment = ""); - bool IsMinGW() const { return this->UsingMinGW; } + bool IsGCCOnWindows() const { return UsingGCCOnWindows; } public: /// Default constructor. @@ -360,7 +360,7 @@ private: /// The set of dependencies to add to the "all" target. cmNinjaDeps AllDependencies; - bool UsingMinGW; + bool UsingGCCOnWindows; /// The set of custom commands we have seen. std::set CustomCommands; diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index a3c9be659..128a35be9 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -175,7 +175,7 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile const* source, // needed by cmcldeps false, this->GetConfigName()); - if (this->GetGlobalGenerator()->IsMinGW()) + if (this->GetGlobalGenerator()->IsGCCOnWindows()) cmSystemTools::ReplaceString(includeFlags, "\\", "/"); this->LocalGenerator->AppendFlags(languageFlags, includeFlags); From 20560e8dca47d7ff80d1a2d9b4e0cf952fa1a790 Mon Sep 17 00:00:00 2001 From: Thomas Herz Date: Thu, 7 May 2015 00:48:03 +0200 Subject: [PATCH 4/4] Ninja: Do not use newlines in response files with Windows GNU tools (#15439) Since commit v2.8.11~213^2 (Ninja: Avoid LNK1170 linker error, 2013-02-01) we generate linker response files with "$in_newline" to support a large number of object files with the MS link.exe tool. However, the GNU linker on Windows does not understand the newline endings that Ninja puts in the response files. Switch back to "$in" for that case. --- Source/cmNinjaNormalTargetGenerator.cxx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 155a30e44..4c51d2333 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -202,7 +202,12 @@ cmNinjaNormalTargetGenerator responseFlag += rspfile; // build response file content - rspcontent = "$in_newline $LINK_PATH $LINK_LIBRARIES"; + if (this->GetGlobalGenerator()->IsGCCOnWindows()) { + rspcontent = "$in"; + } else { + rspcontent = "$in_newline"; + } + rspcontent += " $LINK_PATH $LINK_LIBRARIES"; vars.Objects = responseFlag.c_str(); vars.LinkLibraries = ""; }