注意事项:
module 文件的编译顺序一定要放在最前面
下一篇将使用变量对Makefile文件进行简化
Makefile 文件
#next step: add variable on 2021.4.16
OBJS= main.o sub_add.o sub_minus.o
main.out: $(OBJS)
# mpif90 -o main.out $(OBJS)
mpif90 -o main.out commonData.f90 main.f90 -I ./sub/ \
sub/sub_add.f90 sub/sub_minus.f90
clean:
rm *.o *.out *.mod
#successfully, all the below are very important, shouldn't be deleted.
main.o: commonData.f90 sub_add.o sub_minus.o
sub_add.o: sub/sub_add.f90
sub_minus.o: sub/sub_minus.f90
commonData.f90
MODULE share_data
IMPLICIT NONE
SAVE
INTEGER , PARAMETER :: num_vals = 5 , PI = 3.141592
REAL , DIMENSION(num_vals) :: values
END MODULE share_data
main.f90
program main
use share_data
!INTEGER , PARAMETER :: num_vals = 5 , PI = 3.141592
integer a,b, c
a=1
b=2
write(*, *)"hello world"
write(*, *) "num_vals=", num_vals
call add(a,b,c)
write(*,*) "a+b=3?",c
call minus(a,b,c)
write(*,*) "a-b=-1?",c
end
sub/sub_add.f90
subroutine add(a,b,c)
integer a,b,c
c=a+b
end
sub/sub_minus.f90
subroutine minus(a,b,c)
integer a,b,c
c=a-b
end
Makefile version 2:多个目录下程序的编译,需要注意 -I ./add/ -I ./minus/ 每一个文件夹前面必须对应一个-I,否则报错。
OBJS= main.o sub_add.o sub_minus.o
main.out: $(OBJS)
# mpif90 -o main.out $(OBJS)
mpif90 -o main.out commonData.f90 main.f90 \
-I ./add/ -I ./minus/ \
add/sub_add.f90 minus/sub_minus.f90
clean:
rm *.o *.out *.mod
#successfully, all the below are very important, shouldn't be deleted.
main.o: commonData.f90 #main.f90 #sub_add.o #sub_minus.o
sub_add.o: add/sub_add.f90 #sub_add.f90 #
sub_minus.o: minus/sub_minus.f90
Makefile version 3
main.out: $(OBJS)
mpif90 -o main.out \
commonData.f90 Main/main.f90 \
-I ./add/ -I ./minus/ \
add/*.f90 minus/*.f90
clean:
rm *.o *.out *.mod
main.o: commonData.f90 Main/main.f90 #sub_add.o #sub_minus.o
sub_add.o: add/sub_add.f90 #sub_add.f90 #
sub_minus.o: minus/sub_minus.f90 #minus/sub_minus.f90
OBJS= main.o #sub_add.o #sub_minus.o
Makefile version 4
main.out: $(OBJS)
mpif90 -o main.out \
CommonData/commonData.f90 Main/main.f90 \
-I ./add/ -I ./minus/ \
add/*.f90 minus/*.f90
clean:
rm *.o *.out *.mod
main.o: CommonData/commonData.f90 Main/main.f90 #sub_add.o #sub_minus.o
sub_add.o: add/sub_add.f90 #sub_add.f90 #
sub_minus.o: minus/sub_minus.f90 #minus/sub_minus.f90
OBJS= main.o #sub_add.o #sub_minus.o
Makefile version 5
main.out: $(OBJS)
mpif90 -o main.out \
CommonData/commonData.f90 \
-I ./Main/ Main/*.f90 \
-I ./add/ add/*.f90 \
-I ./minus/ minus/*.f90
clean:
rm *.o *.out *.mod
main.o: CommonData/commonData.f90 Main/main.f90 #sub_add.o #sub_minus.o
sub_multiply.o: Main/sub_multiply.f90
sub_add.o: add/sub_add.f90 #sub_add.f90 #
sub_minus.o: minus/sub_minus.f90 #minus/sub_minus.f90
OBJS= main.o #sub_add.o #sub_minus.o
Makefile version 6: finally, all files are compiled using the same pattern, -I , it seems to be the most elegant method to write each dependency explicitly.
Nest step: maybe Mo Huang Rui’s implicit method would be more succent?
main.out: $(OBJS)
mpif90 -o main.out \
-I ./CommonData/ CommonData/*.f90 \
-I ./Main/ Main/*.f90 \
-I ./add/ add/*.f90 \
-I ./minus/ minus/*.f90
clean:
rm *.o *.out *.mod
main.o: CommonData/*.f90 Main/main.f90 #sub_add.o #sub_minus.o
sub_multiply.o: Main/sub_multiply.f90
sub_add.o: add/sub_add.f90 #sub_add.f90 #
sub_minus.o: minus/sub_minus.f90 #minus/sub_minus.f90
OBJS= main.o #sub_add.o #sub_minus.o
If I comment line 3-6, add all .o file in the OBJS variable, when execute make, it shows the error:
mpif90 -o main.out
/usr/lib/gcc/x86_64-linux-gnu/5/…/…/…/x86_64-linux-gnu/crt1.o: In function _start': (.text+0x20): undefined reference to
main’
collect2: error: ld returned 1 exit status
Makefile:2: recipe for target ‘main.out’ failed
make: *** [main.out] Error 1
main.out: $(OBJS)
mpif90 -o main.out \
-I ./CommonData/ CommonData/*.f90 \
-I ./Main/ Main/*.f90 \
-I ./add/ add/*.f90 \
-I ./minus/ minus/*.f90
clean:
rm *.o *.out *.mod
main.o: CommonData/*.f90 Main/main.f90 #sub_add.o #sub_minus.o
sub_multiply.o: Main/sub_multiply.f90
sub_add.o: add/sub_add.f90 #sub_add.f90 #
sub_minus.o: minus/sub_minus.f90 #minus/sub_minus.f90
OBJS= main.o sub_add.o sub_minus.o
The following Makefile works, however, there is no output .o file. Only execution file: main created.
HOME = .
F90=/usr/bin/mpif90
VPATH = ../src
EXE = ../main
opt = -O3
$(EXE): $(OBJS)
$(F90) -o $(EXE) \
-I $(VPATH)/CommonData/ $(VPATH)/CommonData/*.f90 \
-I $(VPATH)/Main/ $(VPATH)/Main/*.f90 \
-I $(VPATH)/add/ $(VPATH)/add/*.f90 \
-I ./minus/ $(VPATH)/minus/*.f90
clean:
rm *.o *.out *.mod
main.o: CommonData/*.f90 Main/main.f90 #sub_add.o #sub_minus.o
sub_multiply.o: Main/sub_multiply.f90
sub_add.o: add/sub_add.f90 #sub_add.f90 #
sub_minus.o: minus/sub_minus.f90 #minus/sub_minus.f90
OBJS= main.o sub_add.o sub_minus.o