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
This commit is contained in:
Brad King
2023-04-04 14:08:11 -04:00
parent 87b97464f7
commit 6b58cdd4cf
2 changed files with 24 additions and 2 deletions

View File

@@ -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-]+( |$)")

View File

@@ -21,6 +21,8 @@
#include <cm3p/json/value.h>
#include <cm3p/json/writer.h>
#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