Makefile告诉计算机具体如何执行目标
首先看一个简单的Makefile示例,需要有一些Linux知识
VAR1 = Hello # Defined Variables
VAR2 = World!
VAR3 = ${VAR2:World!=planet}
# merry, fun and hay are three targets of the Makefile
merry:
@echo ${VAR1}
fun1:
@echo ${VAR1}
fun2: merry
@echo ${VAR2}
fun: merry # TARGET merry is the dependency of the TARGET fun, so it has to execute the TARGET
@echo ${VAR2} is $@ and $< # $@ is the target symbol while $< is the dependency
hay:
@echo ${VAR3}
终端
输入:
Make
输出:
Hello 当只输入make时,默认执行第一个目标
输入:
Make fun1
输出:
World! 当输入 make fun1, 执行目标fun1
输入:
Make fun2
输出:
Hello
World! 执行目标fun2,具有依赖目标fun1,所以先执行fun1,再执行fun2
输入:
Make fun
输出:
Hello
World! is fun and merry
输入:
Make hay
输出:
planet
再来看一个简单的Makefile,需要对编译fortran有所了解
FC = gfortran
SRC = main.f90 add.f90 multiply.f90 #SOURCE Files
OBJ = ${SRC:.f90=.o} # substitute the .f90 to .o
FFLAG = -O3 -Wall -Wextra # Compilers flags, O3(not number 0, but character O) is the optimaztion option, Wall - Warnings,
# Wextra - Extra Warnings
%.o: %.f90 # Generic rules, .o files depends on the corresponding .f90 files
${FC} ${FFLAG} -o $@ -c $<
main: ${OBJ} # depends on files ${OBJ}, i.e the .o files
${FC} ${FFLAG} -o $@ ${OBJ} # Some common complie commands for fortran
clean: # clean all the produced files, beneficial for rebuild
rm -f *.o *.mod main
输入make,这个程序将会把main.f90 add.f90 multiply.f90 编译成 可执行程序 main
这里介绍一下Makefile里面的缩写
$@ 表示目标文件
$^ 表示所有的依赖文件
$< 表示第一个依赖文件
$? 表示比目标还要新的依赖文件列表
$% 仅当目标是函数库文件中,表示规则中的目标成员名。例如,如果一个目标是“foo.a(bar.o)”,那么,“$%”就是“bar.o”,“$@”就是“foo.a”
$+ 这个变量很像“$^”,也是所有依赖目标的集合。只是它不去除重复的依赖目标。
$* 这个变量表示目标模式中“%”及其之前的部分,例如如果目标是 Main.o,那么$*就表示main
那么我们再来看Makefile-intel-sep
OBJ = module.o sparse.o wt_aux.o math_lib.o symmetry.o readHmnR.o inverse.o proteus.o \
eigen.o ham_qlayer2qlayer.o psi.o unfolding.o rand.o \
ham_slab.o ham_bulk.o ek_slab.o ek_bulk_polar.o ek_bulk.o \
readinput.o fermisurface.o surfgreen.o surfstat.o \
mat_mul.o ham_ribbon.o ek_ribbon.o \
fermiarc.o berrycurvature.o \
wanniercenter.o dos.o orbital_momenta.o \
landau_level_sparse.o landau_level.o lanczos_sparse.o \
berry.o wanniercenter_adaptive.o \
effective_mass.o findnodes.o \
sigma_OHE.o sigma.o sigma_AHC.o \ # Target files
main.o
# compiler
F90 = ifort -fpp -DINTELMKL -fpe3
INCLUDE = -I${MKLROOT}/include
WFLAG = -nogen-interface
OFLAG = -O3 -static-intel
FFLAG = $(OFLAG) $(WFLAG)
LFLAG = $(OFLAG) # Some compilers flags
ARPACK=/Users/quan/work/workplace/ARPACK/libarpack_MAC.a
# blas and lapack libraries
# static linking
LIBS = -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_lp64.a \
${MKLROOT}/lib/intel64/libmkl_sequential.a \
${MKLROOT}/lib/intel64/libmkl_core.a -Wl,--end-group -lpthread -lm -ldl \
${ARPACK}
# dynamic linking
# LIBS = -L/${MKLROOT}/lib/intel64 -lmkl_core -lmkl_sequential -lmkl_intel_lp64 -lpthread
main : $(OBJ) # main target depends on the ${OBJ} files
$(F90) $(LFLAG) $(OBJ) -o wt.x $(LIBS) # compile to make a executable wt.x
cp -f wt.x ../bin
.SUFFIXES: .o .f90
.f90.o :
$(F90) $(FFLAG) $(INCLUDE) -c $*.f90
clean : # make clean, beneficial for rebuild
rm -f *.o *.mod *~ wt.x
参考资料:
1. Fortran 90 tutorial - Part II - Makefiles. https://www.youtube.com/watch v=yVxQ6r4dgvY&list=PLMzuj51UjsPTZjHd6XKB4PYbqYDsEBKwH&index=2&t=269s
2. Makefile中的$@, $^, $< , $?, $%, $+, $*. https://blog.csdn.net/dlf1769/article/details/78997967