在Linux环境下,使用ifortran编译 带有结构的和.inc头文件 的fortran项目生成.so文件

1 致谢

Godzilla_BB

DOSKEY_jason

2 参考文章和手册

在linux下安装fortran编译器详细教程

linux下gfortran 生成so文件

Intel® Fortran Compiler User and Reference Guides.pdf

3 需求描述

一个复杂的fortran项目 编译成一个对外暴露函数 接口的 .so文件 供外部调用。

3.1 文件结构

该项目共15个文件,包含13个.f90源文件和2个定义常量声明的.inc文件。

3.2 文件调用关系

其中13个源文件中1个是主程序(带有program关键字),其他12个为模块化调用的函数function和子程序subroutine。
并且主程序和子模块或函数间有一定的调用关系,且这13个.f90源文件中某些引用了.inc文件,以加载常量声明(即:出现了include 'xxx.inc’的加载外部文件的语句)

示例调用关系如下:
在这里插入图片描述

4 主程序改造为函数

由于主程序是program关键字编写的,进行部分改造,使主程序源文件 变成一个函数function的f90源文件。

源主程序代码示例

program TPKx1
	! ...
	end program

改造成函数后代码示例

integer function TPKx1()

	!program TPKx1
	! ...
	!end program
	
	TPKx1 = 9999
    return 
    end function

5 项目编译方法

5.1 方案一 直接对所有.f90源文件进行编译

借助 ifortran编译器 编译时 将当前路径作为默认搜索路径的特点

5.1.1 具体实现

文件路径结构

将所有.f90文件和所有.inc文件放置于同一个文件夹下。

在Linux环境下,在该文件夹中打开shell终端,

输入命令(此时终端的路径为放置所有文件的文件夹路径)

ifort -fPIC -shared -o 目标文件名.so ./*.f90

释义

ifort 使用ifort编译器进行编译

-fPIC 编译器产生与位置无关代码(Position-Independent Code)

-shared -o 生成共享文件(shared object)

目标文件名.so 指定需要生成的.so文件的名称

./*.f90 指定需要参与编译的源文件为: 当前路径下所有以.f90后缀结尾的文件

5.1.2 注意事项

① 带有include ‘xxx.inc’ 代码的 f90源文件,在编译时,虽然没有指定参与编译的’xxx.inc’文件,但是由于编译器默认会在当前目录下寻找所需的 'xxx.inc’文件,然在f90源文件中相应的地方展开,所以最终可以成功编译出需要的.so文件。

② 虽然将所有的f90文件和inc文件置于同一文件夹下,但是编译时,选择 参与编译的文件只能是所有的.f90文件因为.inc文件 ifortran编译器无法辨识。即:发生 file format not recognized for xxx .inc警告,导致编译.so文件失败。
若使用如下命令,

ifort -fPIC -shared -o 目标文件名.so ./*

警告示例
在这里插入图片描述

5.2 方案二 编译时使用 -I 参数指定头文件路径进行编译

5.2.1 具体实现

文件路径结构

将所有.f90文件放入 A 文件夹下, 在A文件夹下新建include文件夹,将所有.inc文件放入A文件夹下的include文件夹

输入命令(此时终端的路径显示为A文件夹路径)

ifort -I ./include -fPIC -shared -o 目标文件名.so ./*.f90

释义

-I ./include 指定编译所需头文件的路径为 ./include 文件夹,即当前文件夹下的include文件夹

5.2.2 注意事项

输入编译命令时,打开的终端的路径为A文件夹时(此时A文件夹下有include文件夹), 告诉编译器

所需参与编译的文件应该为 ./*.f90 而不能是 ./*  (./* 表示当前文件夹下所有内容)

这样会导致编译器将 include文件夹这一对象也作为需要参与编译的文件,而导致无法识别文件夹发生错误。

警告示例
在这里插入图片描述

6 生成.so文件后的注意事项

将原主程序program, 改造成function函数后。在外部调用,

最终输出的.so文件中的TPKx1()函数, 函数名会发生改变,变成小写并添加下划线_ ,即:tpkx1_ 

具体检测方法
输入命令

nm 目标文件名.so

查看该.so文件对外暴露的函数接口 为 tpkx1_ , 在使用JNA进行调用时需要注意这一点,否则无法调用该函数成功。
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值