第一, 函数库安装后包含什么内容?都有什么作用?
通常来说,函数库的主要内容是两部分:include 和 lib ,使用函数库的所有问题,都是让编译器正确的识别 include 和 lib。
在使用函数库以前,到安装目录下了解一下函数库的组成是很有必要的。(各函数库的版本可能有差异,切记不可完全照这教科书来做,包括本文)
1. include 它告诉编译器,我们使用到的这些函数是什么,需要多少个参数,每个参数是什么类型,返回什么值。它的作用就像 Interface 接口一样。它没有函数内部如何实现的说明,只有接口!
对于 Fortran 函数库,通常 include 里包含的都是 *.mod 文件,有些也包含 *.f90 文件(源代码方式声明接口)。
2. lib 链接器在链接成最终可执行文件时,需要把 lib 中的函数库一起链接。它是函数内部的实现,是函数的实际作用体,也是可执行代码。
举一个生活中的 include 和 lib 的例子:
比如你买了一个工具箱(函数库),你需要翻阅它的目录(include )来了解这里面哪个工具可以做什么,哪些工具需要电源,电源是否是220V?哪些工具需要加水?这些工具各自的作用是什么?(函数的输入输出)。
当你需要实际使用到某个工具时,你才会去寻找真正的它(lib),并把它拿到自己身边来(链接)。
除了这两个重要的组成部分之外,一些函数库还会有:
3. examples 或 test / code / demo 一类的,用于示范函数库的使用(但是它没法示范如何操作,如何设置编译环境)
4. document 或 doc / help ,这是函数库的说明书。里面的 how to us 章节也对它的使用有指导作用。
5. bin ,个别函数库具有一些可执行的工具,通常存放在这里。
6. src ,开源函数库通常会有源代码,存放在这里。(IMSL 和 MKL 均不开源)
第二. 如何设置编译环境,让编译器正确使用 include 和 lib ?
这里仅以 Visual Studio 为例进行说明,其他编译环境请类比类推。
所有的 VS 使用函数库,都可以用以下 4 个操作完成:
大图
下面分别介绍
1. 设置路径(一次性操作)
函数库的安装目录一般并不在编译环境一起,编译器不可能每次都全盘去搜索函数库。所以,我们必须告诉编译环境,函数库在哪儿?(即:它的路径是什么?)
首先,要告诉编译环境什么路径:
某些函数库安装后,可能有多个 include 和 lib,比如 IA32 和 EMT64 / x64 等。它们对应于32位和64位。我建议在其中选择某一个使用,不熟悉的时候,不要两个一起使用。
某些编译器安装后,还可能有 static 和 dll 不同两种。它们分别是设置静态链接和动态链接(他们的区别可参考这篇文章>>>),这个可以两个一起添加,不会引起太大的问题。
比如我的计算机上,IMSL的两个路径分别为(仅举例):
F:\Developer\IntelVisualFortran\IMSL\CTT6.0\include\IA32
F:\Developer\IntelVisualFortran\IMSL\CTT6.0\lib\IA32
如何告诉路径让编译环境知道:
Visual studio,通过自身的路径设置来寻找函数库。在 Visual Studio 下,通过工具(Tools)菜单,选项(Option)打开设置。
大图
分别点击 Includes 和 Libraries 后面的按钮,对应的添加 Include 和 Lib 的路径(注意路径每行一个,不可删除或更改原有的内容):
大图
确定以后既可。
CVF 设置方法类似,也是 Tools ,Option
大图
另有些编译环境,是通过 include 和 lib 的环境变量来寻找的。(Visual Studio 不需要这一步骤)
windows 下设置环境变量的方法是:在“我的电脑”上右键,选择属性,然后选择高级系统设置,高级选项卡,环境变量。
大图
通常我们在系统变量里找到 Include 和 Lib,把函数库的 include 和 lib 文件夹对应的添加进去。
添加方法是:在当前的内容后面加一个分号 ;(如果原来有内容的话),然后粘贴路径。
大图
注意 include 和 lib 都要分别添加路径。添加完毕后要点确定(一些计算机上可能需要注销或重启才能生效)
2. 使用函数库(每个工程都需操作)
设置好路径后,编译器就会自动去这些路径寻找 include 和 lib 了。但是,我们的工程里还得需要一些操作,以便让编译器知道,这个代码需要上述路径的哪些函数?
使用 include(编译阶段)
通常 Fortran 的代码使用 include 的方式是在源代码中添加 use 语句。
比如 use IMSL,高版本的可能是 use numerical_libraries,也可能需要 use 其他模块。
此处的 use 必须能够在上述的 include 路径里有对应的 *.mod 文件存在。
比如存在 numerical_libraries.mod 文件,才可以 use numerical_libraries
(具体你的代码使用了什么函数,需要 use 哪些模块,请参考函数库的帮助文档)
使用 lib(链接阶段)
使用 lib 的方法各编译环境可能不同。这里提供两种方法,选一种既可:
在 Visual Studio 中,打开工程属性(在工程上右键,属性),然后展开 链接器(Linker) 设置,输入(Input),在 Additional Dependencies 中输入需要添加的 lib 文件名(多个文件用空格隔开)。
大图
(如果在 VS+IVF 上使用MKL,有一个更简单的方法:展开上图的 Fortran ,Libraries,选择 Use Intel math Kernel Library。注意有常规串行,并行,集群三个版本。)
CVF 下与之类似,Project 菜单,选择 Setting,在其中填入 lib 文件既可。
大图
使用 lib,对于 Intel Fortran 来说,还有一个方法可以选择。那就是使用 !dec$objcomment 这个预处理语句(这不是 Fortran 语法标准)。
这个语句会告诉 Intel Fortran,链接时,链接哪个(或哪些)函数库。
比如:
!dec$objcomment lib:'imsl.lib'
!dec$objcomment lib:'imslscalar.lib'
!dec$objcomment lib:'imslblas.lib'
编译器就会链接上述的三个 lib 文件,这与之前的添加设置里输入这三个 lib 文件是等效的。
部分函数库,可能在 include 文件夹里有已经书写好的 *.f90 文件,包含这些语句,咱们可以直接 include 它。
比如,在我的电脑上 F:\Developer\IntelVisualFortran\IMSL\CTT6.0\include\IA32 这里有一个叫 link_f90_static.h 的文件。我可以在源代码里添加一句代码 include "link_f90_static.h" 来完成对 lib 文件的使用。
Program www_fcode_cn include "link_f90_static.h" use Numerical_Libraries use lin_sol_svd_int !// 举例 use rand_int !// 举例 Implicit None !// 正文代码 End Program www_fcode_cn
这种方法在理解上有点困难,使用了 include 语句,目的却是使编译器正确的找到 lib 文件。 需要注意的是,这里介绍了两种使用 lib 的方法,选择一种既可。不要两种都用。
第三. 还是有错误?
有错误不要急,冷静的查看错误提示,根据错误来判断是什么地方的问题。
error #7002: Error in opening the compiled module file. Check INCLUDE paths. [NUMERICAL_LIBRARIES]
这个错误在于,include 设置不正确,编译器找不到 Numerical_libraries.mod 文件。
首先确认自己安装了 IMSL,然后确定自己设置好了 Include 的路径。一定要在设置好的路径里找到提示中指明的那个 *.mod 文件。
error #7881: This module file was generated for a different platform or by an incompatible compiler or compiler release. It cannot be read. [SGL]
这说明 *.mod 文件是由不同的编译器生成的,无法直接在您的编译器上使用。(彭国伦书中的 SGL 提供的 mod 文件就会这样)
遇到这个问题,您只能问作者要适合你的编译器的 mod 文件了。如果作者发布了接口文件(*.f90),您可以编译它,而获得适合自己使用的 mod 文件,然后替换原有的既可。
error LNK2019: 无法解析的外部符号 _RAND_INT_mp_DMR,该符号在函数 __MAIN_ 中被引用
或者
error LINK2019: unresolved external symbol _RAND_INT_mp_DMR
这通常是 lib 的路径设置,或使用不正确。检查函数库安装,路径设置,使用等。
结束语:
本文仅说明了函数库使用中的通用方法,由于函数库和编译器的品牌,版本各不相同,请不要完全照搬本文内容。
一定要根据自己的实际情况来设置。(浏览一下函数库的安装目录,看看 EXAMPLE 代码和帮助文档,都会对你有帮助)
祝大家码到成功!