Fortran_PREPROCESS + Ninja adds superfluous preprocess flag
In #18870 (closed) and !4659 (merged) we added the Fortran_PREPROCESS
property which allowed explicitly turning on/off preprocessing on a target/file level.
Unfortunately, the way it was implemented means that if Fortran_PREPROCESS
is explicitly turned ON
for a file, the preprocessor flags are added to the compilation rule for Ninja generators, even though the file will already have been preprocessed for the scan step.
This has the side effect of (possibly) causing unnecessary warnings:
mvce.F90:
! This comment shouldn't generate warnings
#define THIS_LINE_WILL_ERROR_WITHOUT_PREPROCESSING
program mvce
implicit none
print*, "Hello world"
end program mvce
CMakeLists.txt:
cmake_minimum_required(VERSION 3.22)
project(fortran_preprocess_warning LANGUAGES Fortran)
add_executable(mvce mvce.F90)
target_compile_options(mvce PRIVATE -Wall -Werror)
- Works:
cmake . -B build -GNinja && cmake --build build
- Fails:
cmake . -B build_fail -GNinja -DCMAKE_Fortran_PREPROCESS=on && cmake --build build_fail
Failure:
/usr/bin/gfortran -I/tmp/mvce -Wall -Werror -cpp -fpreprocessed -c CMakeFiles/mvce.dir/mvce.f90-pp.f90 -o CMakeFiles/mvce.dir/mvce.f90.o
/tmp/mvce/mvce.f90:1:23:
1 | ! This comment shouldn't generate warnings
| 1
Error: missing terminating ' character [-Werror]
The culprit being the -cpp
flag that gets added because CMAKE_Fortran_PREPROCESS
was explicitly set to ON
.
This is added in cmCommonTargetGenerator::AppendFortranPreprocessFlags
. A simple workaround which seems to work is to add a additional bool requires_pp = true
argument, and then around L115:
switch (preprocess) {
case cmOutputConverter::FortranPreprocess::Needed:
if (requires_pp) {
var = "CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON";
}
break;
and then in cmNinjaTargetGenerator::ComputeFlagsForObject
when we call AppendFortranPreprocessFlags
:
if (language == "Fortran") {
this->AppendFortranFormatFlags(flags, *source);
this->AppendFortranPreprocessFlags(flags, *source, false);
}
This avoids adding the preprocessing flags for Ninja, while still adding them for Makefiles, as well as always adding the no-preprocessing if requested (and able).
If this solution is acceptable, I'll make an MR