Fortran INCLUDE not pre-processed when using ninja generator
We are switching from cmake + nmake to cmake + ninja (on windows) to compile a rather large codebase.
One of the constructions used in our fortran (77) code is to INCLUDE a header with a shared common block. The included file contains a conditional CDEC$ block to set the DLLIMPORT attribute depending on the presence of a define.
Header with shared common block, inside library 'mylib' (the common block is exported using a windows .def file):
CDEC$ IF .NOT. DEFINED(mylib_EXPORTS) CDEC$ ATTRIBUTES DLLIMPORT :: /SHCOMM/ CDEC$ END IF INTEGER IFAC COMMON /SHCOMM/ IFAC
Usage of the common block from outside 'mylib':
SUBROUTINE S1( D ) DOUBLE PRECISION D INCLUDE 'shcomm.h' C D = IFAC * D C END
A small example project is attached containing the full source code.
When building the project on windows with the NMake generator (and the intel fortran compiler), the headers are correctly processed. However, when using the ninja generator, the export of SHCOMM seems to fail:
xilink /nologo CMakeFiles\mylib.dir\mylib\ini.f.obj /out:mylib.dll /implib:mylib.lib /pdb:mylib.pdb /dll /version:0.0 /machine:x64 /debug /INCREMENTAL /DEF:Z:\cmake_fortran_issue\frtinc\src\mylib\exports.def /DEF:Z:\cmake_fortran_issue\frtinc\src\mylib\exports.def user32.lib /MANIFEST /MANIFESTFILE:CMakeFiles\mylib.dir/intermediate.manifest CMakeFiles\mylib.dir/manifest.res Creating library mylib.lib and object mylib.exp ini.f.obj : warning LNK4217: locally defined symbol SHCOMM imported in function INI
It looks like in the generated rules.ninja, the
Fortran_COMPILER__mylib rule does not pass
$DEFINES to ifort.exe. The fortran file 'INCLUDE'-ing the header with the exported common block will not have it's macros expanded, which in turn causes the missing 'DLLIMPORT', which leads to the linker warning.
It would be very helpful for us to get this working, as the cmake + ninja combination compiles an order of magnitude faster than the cmake + nmake combination. I have included a cmake patch I used that seems to work for our scenario. I don't know the cmake code well enough to judge whether this has any other unwanted side-effects.
Sample project (run again.bat): cmake_fortran_issue.zip
Build log: log.txt
CMake patch: cmake-fortran.patch