yanhaoming的个人博客分享 http://blog.sciencenet.cn/u/yanhaoming

博文

FORTRAN静态库的生成、维护与调用

已有 15899 次阅读 2010-3-31 14:04 |个人分类:未分类|系统分类:科研笔记| 静态库

一、FORTRAN静态库的生成与维护

FORTRAN 静态库是经过编译的代码块,它与主程序相对独立,可以被主程序调用,是FORTRAN工程类型之一. 静态库包含一系列子程序,但不包括主程序. 静态库一般具有LIB扩展名并包含目标代码,且静态库存放在它们特定的目录中. FORTRAN静态库在组织大型程序和在不同程序之间共享子程序等方面具有较大的优点,其重要性不言而喻. 当将静态库与主程序联系起来时,在主程序中调用静态库中的任何子程序将编译到相应的可执行程序. 应用静态库的时候,只有所需要的子程序才在编译过程中插入到可执行文件(.EXE,这意味着这种可执行文件将比包含所有的子程序所生成的可执行文件小. 而且,不必担心哪些子程序是需要的,哪些是不需要的,编译器将替你做出选择. 同时,当更改静态库中的子程序时,相应的应用程序可以不做任何改变,而只需要对其进行重新的编译链接,即可获得新的结果,这无疑也是方便的.  

目前,常用的FORTRAN静态库有很多种,WINDOWS操作系统下的Compaq Visual FORTRAN version 6.5(简称CVF65)自带的数学统计库IMSL就是一个非常全面的静态库,可以用来解决线性代数和统计学上的很多经典问题. 此外,在NCAR互联网站有很多有用的FORTRAN子程序(网址:http://www.scd.ucar.edu/softlib/mathlib.html),其中包括地球物理科学问题、离散和快速Fourier变换、可分离的椭圆微分方程、插值、Legendre多项式、普通数学问题、本征值问题求解、线性方程求解、非线性方程求解、常微分方程求解、特殊函数、统计学等常用子程序集等. 这些FORTRAN子程序可以解决很多基础性的问题,因此有很高的利用价值.

WINDOWS操作系统下,可以用两个命令分别生成静态库. 一个是用‘nmake’命令,它一般用来编译原来应用在UNIX环境下的FORTRAN子程序集,在编译过程中要读取makefile文件中的编译命令,类似于在UNIX下安装软件. 另一个是用‘lib’命令,它可以在WINDOWS环境下编译任何需要集成为静态库的子程序集.

编译静态库在DOS命令行环境下比较方便,以后的命令行都指在此环境下运行. 在编译静态库前,首先要安装CVF65,其次要完成要编译的FORTRAN子程序(*.f90). 对于FORTRAN子程序,最好用FORTRAN90的标准来完成,应该放弃FORTRAN77标准。FORTRAN90FORTRAN语言从结构化走向面向对象化的重要一步,使FORTRAN语言更加接近C++。在FORTRAN90标准中,对数组的操作既增强了功能又简化了使用,此外自由格式、MODULE、动态数组、指针等的应用大大丰富了FORTRAN语言,使得编程更加轻松。目前,FORTRAN95FORTRAN2000标准也在应用,它们与FORTRAN90标准比较类似,主要的改进在并行运算方面,因此目前在单机上应用的主要还是FORTRAN90. DOS命令行环境下,进入到FORTRAN子程序所在的子目录,然后按下面两个步骤生成FORTRAN静态库.

1)键入“df  *.f90  /c”,回车,可以看到CVF65编译器对所有的FORTRAN子程序(*.f90)进行编译,生成*.obj文件(注意,编译时,/c中的“c”必须小写).

2)键入“lib  *.obj  /out:libname.lib”,回车,可以看到链接生成libname.lib静态库.

需要注意的是,每次加入新的子程序或对静态库中的子程序修改以后,都要按上述两个步骤重新进行编译链接. 生成静态库以后,可用“dumpbin /linkermember libname.lib”来查看静态库中可用的子程序名称. 也可执行“lib /list libname.lib”来查看静态库中的*.obj文件.

当然,也可以在CVF65集成环境下,生成静态库. 步骤如下:

a)进入到CVF65集成环境下,依次打开菜单File | New | FORTRAN Static Library. 为新的静态库命名,如:libname.lib.

b)依次打开菜单Project | Add to Project | Files,选择要编译的*.f90子程序到当前工作空间.

c)依次打开菜单Build | CompileBuild | Build进行编译链接,生成libname.lib静态库(在当前目录中的debug子目录下).

当要编译的静态库需要其它静态库支持时,在步骤(b)中将支持库(*.lib)也加入到当前工作空间,即可顺利编译新的静态库.

从上面的介绍可以看出,无论采用哪种方法,其基本步骤是一致的,即首先生成目标文件*.obj,然后再将这些文件链接成一个静态库文件*.lib. 对于简单的静态库可以按第一种方法在DOS环境下生成,对于需要其它静态库支持的子程序集则可以首先加入库的路径,再在编译时链接这些静态库,最后生成静态库文件.

静态库生成以后还要经常进行更新和维护,以便更有效的利用这些资源. 下面给出维护静态库时常用的命令.

(Ⅰ)将一个编译好的obj文件(如:ok.obj)加入到现有静态库(如:libname.lib),命令为“lib ok.obj libname.lib /out:libname.lib.

(Ⅱ)将两个或多个静态库合并成一个(all.lib),命令为“lib 1.lib 2.lib 3.lib /out:all.lib”,或“lib *.lib /out:all.lib”.

(Ⅲ)列出静态库中的成员(MEMBER),成员对大小写敏感,命令为“lib libname.lib /list:[outputfilename]”,可给出静态库中的成员,即*.obj.

(Ⅳ)从静态库中解出(extract)特定成员,命令为“lib libname.lib /extract:member.

(Ⅴ)从库中删除成员,命令为“lib libname.lib /remove:member”.

 

二、FORTRAN静态库的调用

FORTRAN静态库的调用主要有两种方式,第一种方式是在DOS环境下用命令行调用,其基本命令为“df *.f *.lib”,值得注意的是,在此种情况下,要设置合适的搜索路径(修改CVF65目录下的子目录bin中的文件dfvars.bat),也可以直接将自己的静态库拷贝到CVF65默认库目录下(CVF65根目录下的子目录lib中). 第二种方式是在CVF65环境下调用. 在此方式下有两种方法:方法一:首先对主程序进行编译,然后将静态库文件插入到当前工作空间(参考第一节步骤(b)),再进行链接,即可获得可执行文件. 方法二:对主程序编译后,依次打开菜单Project->settings…在对话框中选择Link选项卡,在Object/library models项下加入静态库文件的名字,再进行链接,同样可以获得可执行文件.

上面所述的两种方法都比较麻烦。下面介绍在FORTRAN90语言环境中应用MODULE来解决这一问题。首先建立一个F90module程序,名字为userlibmod.f90,对所有静态库中的子程序在此module程序中加入接口语句。其基本结构如下(为便于叙述,在每行都加了行号,源程序中应无此行号):

1.         MODULE userlibmod

2.         !DEC$OBJCOMMENT LIB:'LIBNAME.LIB'

3.         interface sumab

4.         subroutine int_sumab(a,b,c)

5.         integer a,b,c

6.        

7.         end subroutine int_sumab

8.         subroutine real_sumab(a,b,c)

9.         real a,b,c

10.    

11.     end subroutine real_sumab

12.     end interface sumab

13.     INTERFACE

14.     SUBROUTINE CALENDAR(IY1,IM1,ID1,IY2,IM2,ID2,IUNITS,NDAYS)

15.     INTEGER,INTENT(IN):: IY1,IM1,ID1,IY2,IM2,ID2,IUNITS

16.     INTEGER,INTENT(OUT):: NDAYS

17.    

18.     END SUBROUTINE CALENDAR

19.     END INTERFACE

20.     END MODULE

从这个module的结构可以看出,第1行要给出module的名字,最好与文件名相同。第2行告诉编译器要链接的静态库的名字(这里虽然看似注释语句,其实不是,此行可以在编译的过程中与编译器进行通讯,不能省略,不然可能造成编译错误)。312行是一个有名接口语句,这里边有两个子程序(对整数和实数分别求和)。我们可以用两个子程序名来分别调用对应的两个数求和,也可以用接口名来直接调用这两个子程序,当用接口名来调用时,如果输入的参数是整数,相当于调用int_sumab(a,b,c),如果输入的参数是实数,相当于调用real_sumab(a,b,c)。所以在F90语言中,可以简化调用函数的个数。1319行定义了另外一个无名接口,接口中也可以加入多个类似14行到18行的子程序或函数,这些子程序或函数必须已经编译到静态库“LIBNAME.LIB”中。20行是module的结束语句。

将编辑好的module程序存盘,在命令行下执行“ df userlibmod.f90 /c”,即可生成MOD文件“userlibmod.mod”。将此MOD文件放入合适的地方,如“ d:/myforlib/include/”,再将生成的静态库文件放入相应的路径,如“d:/myforlib/lib/”,则一个自己的静态库就建成了。

为了应用此静态库,首先要对CVF65设置合适的搜索路径。打开CVF65集成环境,依次打开菜单“tools | options | directories”,在show directories for下拉菜单中依次点击“include files”和“library files”,然后再下面的“directories”中在空白处依次将“ d:/myforlib/include/”和“d:/myforlib/lib/”加入,点击“ok”按钮,即完成了对搜索路径的设置。现在,就可以方便的调用静态库中的子程序或函数了,只需要在你自己的主程序中第一行加入如下语句“use userlibmod”即可(如果第一行是“program yourprogramname”,则将其加入到此行的下一行)。

 

三、其它说明

如果你应用的FORTRAN编译器是INTEL VISUAL FORTRAN 9.0 IVF)以上的版本,可以按照和上面的过程类似的方法来生成静态库,唯一的区别是编译命令不同,IVFifort命令进行编译,而lib命令是一致的;此外,对于IVF路径的设置是ifortvars.bat文件,其它的内容都是类似的。需要注意的是,由于采用了不同的编译器,CVFIVF编译的静态库一般不能共享,需要重新编译。

作者已经发布了自己编译的FORTRAN静态库软件WHIGG F90 LIB(WFL),可以从http://www.whigg.ac.cn/yanhm/wfl.htm访问。



https://wap.sciencenet.cn/blog-427151-307666.html


收藏 IP: .*| 热度|

1 黄富强

发表评论 评论 (2 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-3-28 16:13

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部