Относительное включение путей различных препроцессоров Fortran
Рассмотрим следующее дерево каталогов:
test.F90
test/
├─ a.inc
└─ b.inc
Со следующим содержимым файла:
- :
#include "test/a.inc"
end
- :
#if defined(__GFORTRAN__) | defined(__PGI) | defined(__NVCOMPILER)
# include "b.inc"
#else
# include "test/b.inc"
#endif
#include "b.inc"
#include "b.inc"
- :
print*,'!'
Препроцессоры компиляторов GNU (gfortran 11.1.0) и Nvidia (nvfortran 22.9) ищут файл, который нужно включить в каталог относительно текущего файла. Например, должен быть включен внутри with .
Препроцессоры компиляторов Intel (ifort 2021.8.0, ifx 2023.0.0) и NAG (nagfor 7.1) выполняют поиск файла для включения в каталог относительно первого вызываемого файла. Напримерb.inc
должен быть включен в with, потому что включен вtest.F90
. Однако это относится только к первой команде. Во всех последующих командах каталог "изменяется" наtest
и#include "b.inc"
может быть использован. В то время как несколько#include "test/b.inc"
команды также работают в компиляторе Intel, код не компилируется компилятором NAG, если последующие пути изменены наtest/b.inc
.
Это предполагаемое поведение препроцессоров компилятора Intel и NAG? Есть ли способ сделать поведение#include
команда, независимая от используемого компилятора (и избегайте первых 5 строк вa.inc
)?
1 ответ
Intel и NAG ответили и согласились, что такое поведение является ошибкой их препроцессоров (fpp и fdfpp соответственно). Эта ошибка будет исправлена в будущих версиях. (Отчет об ошибке для компилятора Intel — CMPLRLLVM-45307.)
Несколько не очень элегантное решение сделать это поведение препроцессора независимым от компилятора состоит в том, чтобы изменить дерево каталогов: распределить файлы по разным папкам на одном уровне , а по пути#include
, всегда сначала поднимайтесь на один уровень вверх в дереве каталогов, а затем к нужному файлу.
Пример
- Дерево каталогов:
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'
Все компиляторы выведут ожидаемый результат:
Hello from d2/b.inc
Hello from d2/b.inc
Hello from d1/b.inc