Написание Makefile для компиляции программы .f и кодов, написанных для компилятора gfortan с использованием кода .f90, написанного для Ifort

У меня есть набор кодов .f, написанных для компиляции в gfortran, и Makefile, который создает программу.

Я хотел бы использовать в качестве дополнительного кода NewCode.f90 в этой программе, но это .f90, и он написан для компиляции с использованием Ifort. Я написал файл make, чтобы он компилировал все коды в ifort, поскольку это необходимо для NewCode.f90:

FC=ifort

ARCH = linux

include SYS.$(ARCH)

MYFLGS = -O0 -pg -g -fbounds-check -Wall -fbacktrace -finit-real=nan
LINKFLAGS = -L$(MKLROOT)
FFLAGS = $(MYFLGS) -I$(INCDIR) -static

.SUFFIXES: .o .f .c .f90

.f.o:
    $(FC) $(FFLAGS) -c $*.f
NewCode.o NewCode.f90:
    $(FC) $(FFLAGS) -ffree-form NewCode.f90 -c
.c.o:
    $(CC) $(CFLAGS) -c $*.c

OBJ =   code1.o code2.o code3.o NewCode.o

default:    nonlinear

nonlinear:  setnl Program

setnl:
/bin/rm -f *.o *.bak core par.h
/bin/ln -sf INCLUDE/nonlinear.par par.h

clean:
/bin/rm -f *.o *.bak core par.h
/bin/rm -rf ../bin/*

cleanarch:
/bin/rm -f *.o *.bak core par.h
/bin/rm -f $(INSTDIR)/program


program:    program.f program.o $(OBJ) par.h
            $(FC) $(FFLAGS) $(LINKFLAGS) -o $@ program.o $(OBJ) $(LIBS)  -Wl,--start-group -L$(MKLROOT)/lib/intel64 -lmkl_gf_ilp64 -lmkl_core -lmkl_sequential -Wl,--end-group -lpthread

Когда я создаю этот файл, он сталкивается с проблемами компиляции файлов, написанных (я думаю) на fortran 70, с использованием компилятора ifort. Например, программа вызывает функцию IPARITY:

FUNCTION IPARITY(l)
IMPLICIT REAL*4 (A-H, O-Z)

k = l/2
kk = 2*k - l
IF ( kk.EQ.0 ) THEN
  IPARITY = 1
ELSE
  IPARITY = -1
END IF
RETURN
END

Называя это, например:

PRINT *,IPARITY(1)

Когда я компилирую эту программу с помощью gfortran, эта функция компилируется и вызывается без каких-либо проблем, однако, когда я компилирую ее с помощью ifort, возникают проблемы. Похоже, компилятор ожидает, что IPARITY будет массивом:

An array-valued argument is required in this context. 

Я попытался скомпилировать файлы, написанные на fortran 70, используя gfortran, и файлы в fortran 90, используя ifort, но мне не удалось получить это правильно:

COMP=ifort
ARCH=linux 
...
...
.f.o:
    $(FC) $(FFLAGS) -c $*.f
NewCode.o NewCode.f90:
    $(COMP) $(FFLAGS) -ffree-form NewCode.f90 -c
.c.o:
    $(CC) $(CFLAGS) -c $*.c
...
...
...
program: program.f program.o $(OBJ) par.h
            $(FC) $(FFLAGS) $(LINKFLAGS) -o $@ program.o $(OBJ) $(LIBS)  -Wl,--start-group -L$(MKLROOT)/lib/intel64 -lmkl_gf_ilp64 -lmkl_core -lmkl_sequential -Wl,--end-group -lpthread

Как бы то ни было, сумматор я поставил так:

program:    program.f program.o $(OBJ) par.h
            $(FC) ...

Or

program:    program.f program.o $(OBJ) par.h
            $(COMP) ...

Я получаю ошибки в кодах .f90 и .f соответственно.

Я думаю, что нужен либо тег в make-файле:

  .f.o:
  $(FC) $(FFLAGS) -c $*.f

Это сообщит компилятору, что он читает код fortran 70, но при этом компилируется правильно. Или флаг в строке комбайнера, который позволит разным кодам, скомпилированным с использованием разных компиляторов, составлять программу вместе.

Любой совет будет очень кстати.

Большое Вам спасибо

Джеймс


person James    schedule 25.07.2014    source источник
comment
То, что должно быть написано в .f90 и написано для компиляции с использованием Ifort. именно значит?   -  person Vladimir F    schedule 25.07.2014
comment
Make-файлы, вероятно, неактуальны, опубликуйте исходный код.   -  person Vladimir F    schedule 25.07.2014
comment
Когда я говорю, что написаны ... Я имею в виду, что когда файл .f90 компилируется с использованием ifort, он работает без проблем, однако, когда он компилируется с использованием gfortran, он содержит ошибки в некоторых основных строках кода. Вот пример, который я привел в своем вопросе. Точно так же файлы .f запускаются без проблем, когда я компилирую их с помощью gfortran, но разбиваются на простые строки, читающие массивы и т. Д., Когда они скомпилированы с помощью IFORT. Первоначально я думал, что команда -ffree-form означает, что файл .f90 можно скомпилировать с помощью gfortran, но, похоже, это не помогло.   -  person James    schedule 25.07.2014
comment
Это проблема, которая наблюдалась раньше, или более вероятно, что я неправильно построил свой Makefile и коды. Я пытаюсь написать игрушечную программу, чтобы продемонстрировать мою проблему, но она оказывается немного неудобной, поэтому, возможно, вам придется терпеть меня, я боюсь.   -  person James    schedule 25.07.2014
comment
Без кода мы не сможем вам помочь, файлы Makefile, вероятно, неуместны.   -  person Vladimir F    schedule 25.07.2014
comment
Например, программа вызывает функцию четности: FUNCTION IPARITY (l) IMPLICIT REAL * 4 (AH, OZ) k = l / 2 kk = 2 * k - l IF (kk.EQ.0) THEN IPARITY = 1 ELSE IPARITY = -1 END IF RETURN END И эта функция вызывается в программе, например: print *, IPARITY (4). Когда программа скомпилирована с использованием gfortran, функция работает правильно, однако, когда программа скомпилирована с использованием ifort, она думает, что IPARITY является массивом, давая сообщение: в этом контексте требуется аргумент, возвращающий значение массива.   -  person James    schedule 25.07.2014
comment
Отредактируйте вопрос, не пишите в комментариях. Вы читали какой-нибудь учебник, как пользоваться этим сайтом?   -  person Vladimir F    schedule 25.07.2014
comment
Я понимаю (по крайней мере, я думаю, что это правильно), что если бы я писал функцию в fortran 90 для использования в fortran 90, я бы написал эту функцию по-другому. Но мой вопрос в том, действительно ли есть теги, которые можно поместить в файлы Makefile, чтобы компилятор, в данном случае ifort, знал, что он читает более старый fortran (я думаю, fortran 70) и обрабатывает его должным образом, то есть не ломается.   -  person James    schedule 25.07.2014
comment
Мы должны увидеть код, я голосую за его закрытие. Код, соответствующий стандарту, не требует дополнительных настроек.   -  person Vladimir F    schedule 25.07.2014
comment
Кстати, iparity - это внутренняя функция, которая принимает массив в обоих компиляторах. Я понятия не имею, что должно означать iparity (4). Возможно, это внешняя функция в вашем коде, но вы ее не показываете.   -  person Vladimir F    schedule 25.07.2014
comment
IPARITY (4) относится к простой функции, данной в этом комментарии, а теперь в моем вопросе.   -  person James    schedule 25.07.2014
comment
НАПИШИТЕ БОЛЬШЕ ПОЛНОГО КОДА !!! Возможно, вам где-то не хватает ВНЕШНЕГО КОДА.   -  person Vladimir F    schedule 25.07.2014
comment
Все ли процедуры в модулях и используются ли основной программой? Вероятно, компилятор сбивает с толку пользовательская функция и встроенная функция. Также лучше не использовать неявную типизацию. implicit none и объявите все переменные.   -  person M. S. B.    schedule 25.07.2014
comment
Я готов поспорить, что это код FORTRAN77, следовательно, implicit none не доступен в стандарте.   -  person Vladimir F    schedule 25.07.2014


Ответы (1)


Ваш код все еще очень неполный, но я, по крайней мере, попытаюсь угадать из вашего фрагмента, что находится в совершенно секретном остатке.

Вероятно, вы не можете объявить IPARITY как EXTERNAL, хотя вы всегда должны делать это для внешних функций. В Fortran 2008 есть другая функция, называемая IPARITY, поэтому компилятор считает, что вам нужна именно эта . Чтобы сообщить об этом, вы хотите, чтобы ваша собственная внешняя процедура объявила его как EXTERNAL.

     EXTERNAL IPARITY
     integer iparity
     ...
     print *,IPARITY(4)

или используйте блок интерфейса, если вы используете Fortran 90 или новее

     interface
       integer function iparity(i)
         integer i
       end function
     end interface
     ...
     print *,IPARITY(4)

Для всех ваших будущих программ я настоятельно рекомендую использовать как минимум Fortran 90 и использовать implicit none во всех областях. Кроме того, используя модули, вы избегаете этих проблем и получаете много других преимуществ.

person Vladimir F    schedule 25.07.2014