【轮子DIY】一个比较通用的fortran90程序make系统 - 悲催的科学匠人 - 冷水's blog
【轮子DIY】一个比较通用的fortran90程序make系统
冷水
posted @ 2013年4月17日 14:55
in fortran
, 3266 阅读
一个项目中的副产品,目的是为fotran90项目构造简单的make系统
目录结构是主目录下必须包含bin,src和make目录。make目录下是一些makefile,而src就是源代码了。由于fortran的module特殊性,如果有module,src必须包含一个mod目录。如果包含fortran77代码,我也专门开辟一个f77目录包含这些文件,当然叶可以采用其它办法。此外,如果包含混编的c代码,我放入anisc目录。其它代码那找类别分别创建src的子目录即可。一个例子如下
poject +---bin +---make +---src +---mod +---f77 +---anisc +---main
make目录中关键的文件有
- make.inc,定义所有编译参数
- make_mod,专用于编译module
- make_f77,专用于编译fortran77代码
- make_clib,专用于编译c文件
- make_sub,用于编译其它src下子目录中fortran90代码
- Makefile,主make文件
make.inc
# CMODE # options: # gnu, # pgi, # intel COMPILER=gnu # path PROJECT_HOME=.. SRCDIR=$(PROJECT_HOME)/src OBJDIR=$(PROJECT_HOME)/obj_$(COMPILER)/$(CMODE) MODDIR=$(PROJECT_HOME)/mod BINDIR=$(PROJECT_HOME)/bin # PGI fortran and C ifeq ($(COMPILER),pgi) FC=mpif90 LINK=mpif90 CC=pgcc ifeq ($(CMODE),debug) FFLAGS0 = -module $(OBJDIR) -g -r8 -Kieee -C else CMODE = release FFLAGS0 = -module $(OBJDIR) -O2 -r8 -Kieee endif ARCH = ar ARCHFLAG = cr endif # Intel fortran and C ifeq ($(COMPILER),intel) FC=mpif90 LINK=mpif90 CC=icc ifeq ($(CMODE),debug) FFLAGS0 = -module $(OBJDIR) -g -r8 -check all else CMODE = release FFLAGS0 = -module $(OBJDIR) -O2 -r8 endif ARCH = ar ARCHFLAG = cr endif # GNU fortran and C ifeq ($(COMPILER),gnu) FC=mpif90 LINK=mpif90 CC=gcc ifeq ($(CMODE),debug) FFLAGS0 = -J$(OBJDIR) -fdefault-real-8 -frecord-marker=4 -g -fcheck=all -fbacktrace else CMODE = release FFLAGS0 = -J$(OBJDIR) -O2 -fdefault-real-8 -frecord-marker=4 endif ARCH = ar ARCHFLAG = cr endif FFLAGS = $(FFLAGS0) # LIB dir 这里加入必要的库和路径 LIBDIR= #-L$(BLASDIR) -L$(LAPACKDIR) LIBS = # # output exe file, 你可以修改run为其它名称 EXE=$(BINDIR)/run_$(COMPILER)_$(CMODE)
make_f77
include make.inc MYSRC= $(wildcard $(SRCDIR)/$(SUB)/*.f) MYTMP= $(patsubst %.f,%.o, $(MYSRC)) MYOBJ= $(patsubst $(SRCDIR)/$(SUB)%,$(OBJDIR)%, $(MYTMP)) all: $(MYOBJ) $(MYOBJ): $(OBJDIR)/%.o: $(SRCDIR)/$(SUB)/%.f $(FC) -c $(FFLAGS) $< -o $@ clean: rm -f $(MYOBJ) submit:
make_clib
include make.inc MYSRC= $(wildcard $(SRCDIR)/$(SUB)/*.c) MYTMP= $(patsubst %.c,%.o, $(MYSRC)) MYOBJ= $(patsubst $(SRCDIR)/$(SUB)%,$(OBJDIR)%, $(MYTMP)) all: $(MYOBJ) $(MYOBJ): $(OBJDIR)/%.o: $(SRCDIR)/$(SUB)/%.c $(CC) -c $< -o $@ clean: rm -f $(MYOBJ) submit:
make_sub
include make.inc MYSRC= $(wildcard $(SRCDIR)/$(SUB)/*.f90) MYTMP= $(patsubst %.f90,%.o, $(MYSRC)) MYOBJ= $(patsubst $(SRCDIR)/$(SUB)/%,$(OBJDIR)/$(DEST)/%, $(MYTMP)) all: $(MYOBJ) $(MYOBJ): $(OBJDIR)/$(DEST)/%.o: $(SRCDIR)/$(SUB)/%.f90 $(FC) -c $(FFLAGS) $< -o $@ clean: rm -f $(MYOBJ) submit:
make_mod
include make.inc SUB=mod # 这里必须按照一定顺序填写module源代码文件 MYSRC = $(SRCDIR)/$(SUB)/mod1.f90 \ $(SRCDIR)/$(SUB)/mod2.f90 \ $(SRCDIR)/$(SUB)/mod3.f90 MYTMP= $(patsubst %.f90,%.o, $(MYSRC)) MYOBJ= $(patsubst $(SRCDIR)/$(SUB)%,$(OBJDIR)%, $(MYTMP)) all: $(MYOBJ) $(MYOBJ): $(OBJDIR)/%.o: $(SRCDIR)/$(SUB)/%.f90 $(FC) -c $(FFLAGS) $< -o $@ clean: rm -f $(MYOBJ)
Makefile
include make.inc TMPLIB = $(OBJDIR)/../libmytmp_$(CMODE).a all: objs main main: $(TMPLIB) $(LINK) $(TMPLIB) $(LIBDIR) $(LIBS) $(FFLAGS) -o $(EXE) #编译所有obj文件并构造库,在make_mod后列出所有src子目录的编译命令 make -f make_sub "SUB=子目录名称" objs: make -f make_mod make -f make_sub "SUB=main" make -f make_f77 "SUB=f77" make -f make_clib "SUB=anis_c" $(ARCH) $(ARCHFLAG) $(OBJDIR)/../libmytmp_$(CMODE).a $(OBJDIR)/*.o #删除所有obj文件、mod文件和库,在make_mod后列出所有src子目录的编译命令 make -f make_sub "SUB=子目录名称" clean 来清理给定类别的obj文件 #这里只是举例说明可以指定clean一部分文件,在某些场合下可以采用这个方法进行较为精确的clean控制 cleanall: make -f make_mod clean make -f make_sub "SUB=main" clean make -f make_f77 "SUB=f77" clean make -f make_clib "SUB=anis_c" clean rm -f $(OBJDIR)/../libmytmp_$(CMODE).a rm -f $(OBJDIR)/*.mod #粗暴的删除所有编译生成的文件, clean: rm -f $(OBJDIR)/../libmytmp_$(CMODE).a rm -f $(OBJDIR)/*.mod rm -f $(OBJDIR)/*.o #创建obj文件目录 dir: mkdir ../obj_$(COMPILER) mkdir ../obj_$(COMPILER)/debug mkdir ../obj_$(COMPILER)/release
具体使用时,只需要为module手工填写文件名,其它非module的代码一律自动寻找。第一次编译,需要先 make dir创建目录,而后再make。默认编译优化版本,使用make CMODE=debug会编译调试版本。