不同Fortran预处理器相对包含路径差异及跨编译器兼容问询
Fortran预处理器#include路径兼容性问题解答
目录结构
test.F90 test/ ├─ a.inc └─ b.inc
文件内容
test.F90
#include "test/a.inc" end
test/a.inc
#if defined(__GFORTRAN__) | defined(__PGI) | defined(__NVCOMPILER) # include "b.inc" #else # include "test/b.inc" #endif #include "b.inc" #include "b.inc"
test/b.inc
print*,'!'
不同编译器的#include路径行为
- GNU(gfortran 11.1.0)、Nvidia(nvfortran 22.9):预处理器始终在当前被包含文件的相对目录中查找依赖文件。比如在
a.inc中用#include "b.inc"就能找到同目录下的b.inc。 - Intel(ifort 2021.8.0、ifx 2023.0.0)、NAG(nagfor 7.1):首次处理嵌套
#include时,会基于发起首次包含的主文件(test.F90)的相对目录查找;后续在同一个被包含文件中再次使用#include时,目录会切换到当前被包含文件的所在目录。其中Intel允许重复使用主文件相对路径(如多次#include "test/b.inc"),但NAG会因此编译失败。
问题
- Intel和NAG编译器预处理器的该行为是否为预期设计?
- 是否存在方法可使
#include命令的行为独立于编译器(即无需a.inc中前5行的条件编译代码)?
解答
1. 行为是否为预期设计
Intel和NAG的这种路径查找行为是符合各自官方文档的预期设计。
Fortran标准并未对预处理器的文件查找规则做强制统一规定,各编译器厂商可根据自身实现逻辑制定规则:
- Intel编译器的预处理器(fpp/cpp)设计为:首次嵌套包含时继承主源文件的查找路径,后续包含操作则切换到当前被包含文件的目录;
- NAG编译器的预处理器则严格遵循“首次依赖基于主文件目录,后续切换到当前包含文件目录”的规则,且不允许重复使用主文件相对路径解析同一文件,避免路径冲突。
2. 跨编译器兼容的解决方案
无需条件编译的兼容方法主要有以下几种:
方法1:编译时指定统一的包含目录
通过编译器的-I参数指定test/目录为包含目录,这样所有编译器都会优先从指定目录中查找.inc文件,此时a.inc中直接写#include "b.inc"即可适配所有编译器。
编译命令示例:
# Intel ifort/ifx ifort -I./test test.F90 # NAG nagfor nagfor -I./test test.F90 # GNU gfortran/Nvidia nvfortran gfortran -I./test test.F90
方法2:统一使用基于项目根目录的绝对路径
如果项目目录结构固定,可在#include中使用绝对路径(如#include "/path/to/project/test/b.inc"),但这种方法灵活性差,不适合多环境部署。
方法3:编译时定义路径宏统一前缀
编译时通过-D参数定义路径宏,例如:
# 所有编译器通用 gfortran -DINCDIR="./test" test.F90
然后在a.inc中写:
#include INCDIR"/b.inc"
注:部分编译器可能需要调整为#include INCDIR"b.inc",需根据实际情况适配。
内容的提问来源于stack exchange,提问作者V T
相关产品推荐
相关产品推荐

