Consider the following directory tree:
test.F90
test/
├─ a.inc
└─ b.inc
With the following file contents:
test.F90
:#include "test/a.inc"
end
a.inc
:#if defined(__GFORTRAN__) | defined(__PGI) | defined(__NVCOMPILER)
# include "b.inc"
#else
# include "test/b.inc"
#endif
#include "b.inc"
#include "b.inc"
b.inc
:print*,'!'
The GNU (gfortran 11.1.0) and Nvidia (nvfortran 22.9) compiler preprocessors search for the file to be included in the directory relative to the current file. E.g. b.inc
should be included inside of a.inc
with #include "b.inc"
.
The Intel (ifort 2021.8.0, ifx 2023.0.0) and NAG (nagfor 7.1) compiler preprocessors search for the file to be included in the directory relative to the first file to invoke #include
. E.g. b.inc
should be included inside of a.inc
with #include "test/b.inc"
because a.inc
is included in test.F90
. However, it only applies for the first #include
command. In all consequent #include
commands, the directory is "changed" to test
and #include "b.inc"
can be used. While multiple #include "test/b.inc"
commands also work in the Intel compiler, the code doesn't compile with the NAG compiler if the consequent paths are changed to test/b.inc
.
Is this the intended behavior of the Intel and NAG compiler preprocessors? Is there a way to make the behavior of the #include
command independent of the used compiler (and avoid the first 5 lines in a.inc
)?
Intel and NAG have replied and agreed that this behavior is a bug of their preprocessors (fpp and fdfpp, respectively). This bug will be fixed in future releases. (The bug report for the Intel compiler is CMPLRLLVM-45307.)
A somewhat not very elegant solution to make this preprocessor behavior compiler-independent is to change the directory tree: distribute the files in different folders on the same level, and, in the path of #include
, always go up one level in the directory tree first and then to the desired file.
d1/
├─ test.F90
└─ b.inc
d2/
├─ a.inc
└─ b.inc
d1/test.F90
:#include "../d2/a.inc"
end
d2/a.inc
:! Even though "d2/b.inc" is in the same directory as "d2/a.inc", go up one level first
#include "../d2/b.inc"
#include "../d2/b.inc"
#include "../d1/b.inc"
d2/b.inc
:print*,'Hello from d2/b.inc'
d1/b.inc
:print*,'Hello from d1/b.inc'
All compilers will print the expected output:
Hello from d2/b.inc
Hello from d2/b.inc
Hello from d1/b.inc