Fortran For Fun 之编译工具 FoBis

Linux系统下没有一个好用的Fortran语言IDE编程工具,通常在编辑器中编辑代码,然后在命令行中使用gfortran或ifort编译,对于模块很多的工程,代码之间的依赖关系比较复杂,这时编译很麻烦,需要使用make工具来进行编译,最直接的方式就是写Makefile。但Makefile编写比较麻烦,通常使用其它工具来生成Makefile, 常用的工具包括cmake和FoBis。

FoBis是专门为fortran写的编译系统,使用非常简单方便,基本上和IDE的F5差不多。FoBis编译系统需要一个和Makefile类似的配置文件fobos,需要定义一些编译选项以及外部依赖库等,如果没有外部依赖库,所有的项目的配置基本上都是不变的,所以只用在每个项目中复制一个fobos就可以编译这个项目了。

文件结构

我通常新建一个项目的目录结构如下,src/文件中放程序源码,app/中放执行码。fobis为FoBis的配置文件,readme.md为项目介绍文档,build.sh为编译脚本,每次只需要执行./build就可以编译整个项目。

1
2
3
4
5
├── app/
├── build.sh
├── fobos
├── readme.md
└── src/

fobos

FoBis的配置文件也比较简单,很多直接使用默认情况就可以,通常需要改的地方只有preproc, mpi, include, libs, ext_libs 等基本上和IDE中需要修改的地方一样。而且可以定义不同的modes以便可以使用不同的编译器进行编译。以下是我一个项目的FoBis配置文件fobos。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[modes]
modes = tests-gnu
[common-variables]
$CSTATIC_GNU = -c -frealloc-lhs -std=f2008 -fall-intrinsics -cpp -fdefault-real-8 -Wall -ffree-line-length-none -fcoarray=lib
$DEBUG_GNU = -O0 -g3 -Warray-bounds -Wcharacter-truncation -Wline-truncation -Wimplicit-interface -Wimplicit-procedure -Wunderflow -fcheck=all -fmodule-private -ffree-line-length-132 -fimplicit-none -fbacktrace -fdump-core -finit-real=nan
$OPTIMIZE = -g
$EXDIRS =
$hdf5 = /usr/local/hdf5
$psb      = /usr/local/psblas
# main modes
[tests-gnu]
template = template-static-gnu
build_dir = app
# templates
[template-static-gnu]
compiler = gnu
exclude_dirs = $EXDIRS
src = src/
cflags = $CSTATIC_GNU $OPTIMIZE
lflags = $OPTIMIZE -fopenmp
cflags_heritage = True
colors = True
quiet = False
log = False
jobs = 10
preproc = -DDOUBLEP
mpi = True
include = $hdf5/include $psb/include $psb/modules
libs = -L$hdf5/lib -L$psb/lib/
ext_libs = hdf5_fortran hdf5hl_fortran psb_util psb_krylov psb_prec psb_base lapack blas metis caf_mpi

执行 FoBiS.py build -mode tests-gnu 就可以使用gfortran编译整个项目,可以将该命令放在buld.sh中,简化编译命令。还可以通过FoBiS.py build -m Makefile 生成Makefile,然后用make来进行编译。

FoBis的优点

不用写任何依赖关系的文件,不用写CMakelists.txt,FoBis会自动寻找项目中的所有代码,并确定其中的依赖关系,也可以定义不用编译的代码文件,使用灵活。

可以同时编译n个主程序,项目中可以有很多个program,编译的执行程序名称与代码的文件名称一致。

只会编译修改过的代码,速度挺快。在不同平台,不同编译器下只需要写一个配置文件。可以直接生成静态库,动态库。