我有一个用 Fortran 编写的程序,旨在使用单精度 float (REAL
) 或 double float (例如使用 GNU Fortran 的 -fdefault -real-8
)。我想设计一个 makefile 来为来自相同源代码的每个类似程序构建 myprog
和 myprog-dbl
。这是我迄今为止所掌握的内容的摘要:
mymod.f
- 显示简单的浮点错误传播
MODULE mymod
REAL :: var
CONTAINS
SUBROUTINE forerror(a,j)
REAL :: a
var=0.0
DO i=0,j,1
var=var+a
END DO
WRITE(*,*) "a=",a,"j=",j,"var=",var
END SUBROUTINE
END MODULE
myprog.f
- 程序的主要部分
PROGRAM test
USE mymod
CALL ForError(0.000001,10000000)
END PROGRAM
makefile
- GNU Makefile 设计用于构建两个程序:myprog
和 myprog-dbl
# Variables
FC = gfortran
LD = $(FC)
EXECS = myprog myprog-dbl
OBJECTS = myprog.o mymod.o
# Targets
all : $(EXECS)
$(EXECS) : $(OBJECTS)
$(LD) $(LDFLAGS) -o $@ $^
# mymod must be built before prog
myprog.o : mymod.o
# Target-specific variable
myprog-dbl : FFLAGS += -fdefault-real-8
clean :
$(RM) $(OBJECTS) *.mod
.PHONY : all clean
上面的方法几乎可以工作,但并不完全有效。这是我从 shell 获得的输出,首先是创建两个程序的默认目标:
$ make all
gfortran -c -o mymod.o mymod.f
gfortran -c -o myprog.o myprog.f
gfortran -o myprog myprog.o mymod.o
gfortran -o myprog-dbl myprog.o mymod.o
$ ./myprog
a= 9.99999997E-07 j= 10000000 var= 9.59210873
$ ./myprog-dbl
a= 9.99999997E-07 j= 10000000 var= 9.59210873
但是,make myprog-dbl
结果没有使用适当的标志编译依赖对象,它与 myprog
相同。
在构建第二个程序之前需要清理对象:
$ make clean
rm -f myprog.o mymod.o *.mod
$ make myprog-dbl
gfortran -fdefault-real-8 -c -o mymod.o mymod.f
gfortran -fdefault-real-8 -c -o myprog.o myprog.f
gfortran -o myprog-dbl myprog.o mymod.o
$ ./myprog-dbl
a= 9.9999999999999995E-007 j= 10000000 var= 10.000000999267517
现在它是用 double float 构建的。如何使用单个 make all
目标构建两个相似的程序?我很高兴重建 makefile
(或两个),但不重建 Fortran 源代码。
最佳答案
我会将这两个变体编译到不同的目标子目录中。或者至少将 .mod
文件放在那里,但我更愿意将所有内容放在那里。
只需确保为模块目录使用正确的标志,该标志因编译器而异。 Gfortran 使用 -J
和 I
,Intel Fortran 使用 -module
。
顺便说一句-fdefault-real-8
很难看。在任何新代码中使用种类常量。
关于makefile - 设计 makefile 来编译不同配置的程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31650455/