From 6b58cdd4cf59d6d5c66c66daf81112f911e84238 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 4 Apr 2023 14:08:11 -0400 Subject: Ninja: Exclude NVHPC -Werror flags during Fortran preprocessing The Ninja generator preprocesses Fortran separately in order to scan for module dependencies. NVHPC's `nvfortran` does not support its `-Werror` flag while preprocessing with `-E`, so filter it out. Fixes: #24665 --- Modules/Compiler/NVHPC-Fortran.cmake | 1 + Source/cmNinjaTargetGenerator.cxx | 25 +++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Modules/Compiler/NVHPC-Fortran.cmake b/Modules/Compiler/NVHPC-Fortran.cmake index 59755b3..5c06457 100644 --- a/Modules/Compiler/NVHPC-Fortran.cmake +++ b/Modules/Compiler/NVHPC-Fortran.cmake @@ -1,3 +1,4 @@ include(Compiler/PGI-Fortran) include(Compiler/NVHPC) __compiler_nvhpc(Fortran) +set(CMAKE_Fortran_PREPROCESS_SOURCE_EXCLUDE_FLAGS_REGEX "(^| )-Werror +[a-z][a-z-]+( |$)") diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index e163edb..5dbc283 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -21,6 +21,8 @@ #include #include +#include "cmsys/RegularExpression.hxx" + #include "cmComputeLinkInformation.h" #include "cmCustomCommandGenerator.h" #include "cmDyndepCollation.h" @@ -1259,6 +1261,7 @@ namespace { cmNinjaBuild GetScanBuildStatement(const std::string& ruleName, const std::string& ppFileName, bool compilePP, bool compilePPWithDefines, + cmValue ppExcludeFlagsRegex, cmNinjaBuild& objBuild, cmNinjaVars& vars, const std::string& objectFileName, cmLocalGenerator* lg) @@ -1287,6 +1290,20 @@ cmNinjaBuild GetScanBuildStatement(const std::string& ruleName, // Scanning and compilation generally use the same flags. scanBuild.Variables["FLAGS"] = vars["FLAGS"]; + // Exclude flags not valid during preprocessing. + if (compilePP && !ppExcludeFlagsRegex.IsEmpty()) { + std::string in = std::move(scanBuild.Variables["FLAGS"]); + std::string out; + cmsys::RegularExpression regex(*ppExcludeFlagsRegex); + std::string::size_type pos = 0; + while (regex.find(in.c_str() + pos)) { + out = cmStrCat(out, in.substr(pos, regex.start()), ' '); + pos += regex.end(); + } + out = cmStrCat(out, in.substr(pos)); + scanBuild.Variables["FLAGS"] = std::move(out); + } + if (compilePP && !compilePPWithDefines) { // Move preprocessor definitions to the scan/preprocessor build statement. std::swap(scanBuild.Variables["DEFINES"], vars["DEFINES"]); @@ -1511,18 +1528,22 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( std::string scanRuleName; std::string ppFileName; + cmValue ppExcludeFlagsRegex; if (compilePP) { scanRuleName = this->LanguagePreprocessAndScanRule(language, config); ppFileName = this->ConvertToNinjaPath( this->GetPreprocessedFilePath(source, config)); + ppExcludeFlagsRegex = this->Makefile->GetDefinition(cmStrCat( + "CMAKE_", language, "_PREPROCESS_SOURCE_EXCLUDE_FLAGS_REGEX")); } else { scanRuleName = this->LanguageScanRule(language, config); ppFileName = cmStrCat(objectFileName, ".ddi.i"); } cmNinjaBuild ppBuild = GetScanBuildStatement( - scanRuleName, ppFileName, compilePP, compilePPWithDefines, objBuild, - vars, objectFileName, this->LocalGenerator); + scanRuleName, ppFileName, compilePP, compilePPWithDefines, + ppExcludeFlagsRegex, objBuild, vars, objectFileName, + this->LocalGenerator); if (compilePP) { // In case compilation requires flags that are incompatible with -- cgit v0.12