Fortran 95 - 如何在编译时自动查找主程序中使用的模块

时间:2014-08-24 22:38:42

标签: module fortran build-process

我制作了我的第一个Fortran程序mainp.f95,它有两个单独的文件mfun.f95和mbisection.f95,它们是mainp.f95中使用的模块。

我在Internet上发现了2种编译方式:

第一种方式

gfortran mfun.95 mbisection.f95 mainp.f95

然后创建a.out和两个files.mod,作为可执行文件的一部分。

第二种方式

gfortran -c mfun.95 -o mfun.o
gfortran -c mbisection.f95 -o mbisection.o

然后创建两个files.o和两个files.mod。

gfortran mainp.f95 mbisection.o mfun.o

然后创建a.out文件。

我不知道他们是否是最佳,但他们有效。

问题

但是,想象一下,我没有2个模块,但有20个模块。

我应该在gfortran命令中编写每个模块,还是有办法“只编译主程序”,自动添加所需的.o和.mod文件? (假设所有文件都在同一个文件夹中,因此很容易“搜索模块”)

非常感谢!!!

2 个答案:

答案 0 :(得分:3)

当项目从“Hello World”增长到更复杂的东西时,是时候从直接命令行编译切换到build automation tool了。如何简化大型项目的构建有很多可能性,例如makefilesMicrosoft Visual Studiocmake

答案 1 :(得分:1)

我看过这些链接。但是,我注意到它们都是为C或Java设计的。通过论坛搜索,包括High Performance Mark写的帖子,我注意到"自动构建"除了编写我将在终端中编写的所有命令,但在文件中,然后运行该文件,别无他法。

我认为这是更自动的东西(例如,它会查找依赖的文件(如其他文件中的模块),并将其编译为"推荐的顺序" ,只需点击一下。)

我认为这必须存在于互联网的某个地方,但由于我还没有找到它,我决定创建自己的自动编译器。既然你帮了我,我就和你分享我的编译器(你会看到它非常基本,没有编译选项,但对我来说,高级选项(到目前为止)是无关紧要的,说实话,未知)。

我的编译器是一个fortran编写的文件,其工作方式如下:

第一阶段: 它需要一个fortran.f95文件,然后读取它的第二行。如果找到' use',则会复制使用过的模块。重复此过程,直到找到所有模块。

第二阶段: 然后它打开每个模块,以便搜索子模块。过程是相同的:它读取第二行,如果找到'使用',则复制子模块。然后第三个......直到它找不到“使用”#39;字。

第三阶段: 然后它复制一个字符数组中的所有子模块(这里假设子模块不能使用模块,这是一个坏点,在包含PI,E等的模块中思考),它搜索所有相同的模块,为了只编译一次每个模块。

第四阶段: 然后它写入要在终端写入的最终命令:gfortran(submodules.f95列表)(modules.f95列表)main.f95

文件扩展名' .f95'是在文件开头初始化的单词,因此可以轻松更改为' f90'或者其他什么。

我没有看到任何添加我的代码的按钮,因此我将其复制到此处,以防有人想要使用它。这个对我有用。 这些文件必须位于同一文件夹中。我希望回答我并发布我的编译器并不违反stackexchange的规则,我的意图是帮助而不是打扰:)

program compilador

IMPLICIT NONE
CHARACTER (LEN=18),DIMENSION(100) :: matvec
INTEGER,DIMENSION(10) :: m,proh
CHARACTER (LEN=18) :: hayuse
CHARACTER (LEN=18),DIMENSION(10) :: modulos
CHARACTER (LEN=18),DIMENSION(10,10) :: submodulos
CHARACTER (LEN=4) :: ext='.f95'
CHARACTER (LEN=2) :: for
INTEGER :: n,j,i=1,t,total,error_de_apertura,error_de_lectura,error_de_escritura 
LOGICAL :: cond OPEN(60,FILE='main.f95',STATUS='OLD',ACTION='READ',& 
IOSTAT=error_de_apertura)
IF (error_de_apertura>0) STOP 'main.f95 NO ABIERTO'
OPEN (70,FILE='comando.txt',STATUS='NEW',ACTION='WRITE',& IOSTAT=error_de_apertura)
IF (error_de_apertura>0) STOP 'comando.txt NO ABIERTO'
DO
if (i==1) then
READ(60,'(/,A3,X1A)',IOSTAT=error_de_lectura) hayuse,modulos(i)
else
READ(60,'(A3,X1A)',IOSTAT=error_de_lectura) hayuse,modulos(i)
endif
if (.not.(hayuse=='use')) exit modulos(i)
(len_trim(modulos(i))+1:len_trim(modulos(i))+4)='.f95' WRITE(*,*) hayuse,modulos(i) 
i=i+1
end do

n=i-1
IF (n>=1) THEN

!MODULOS DE MODULOS DO i=1,n

OPEN(30+i,FILE=modulos(i),STATUS='OLD',ACTION='READ',& IOSTAT=error_de_apertura)
IF (error_de_apertura>0) then
WRITE(*,*) modulos(i)//' NO ABIERTO'
STOP
endif
j=1
DO
if (j==1) then
READ(30+i,'(/,A3,X1A)',IOSTAT=error_de_lectura) hayuse,submodulos(i,j)
else
READ(30+i,'(A3,X1A)',IOSTAT=error_de_lectura) hayuse,submodulos(i,j)
endif
if (error_de_lectura>0) then WRITE (*,*) 'Error de lectura en ',modulos(i)
endif
if (.not.(hayuse=='use')) exit
submodulos(i,j)(len_trim(submodulos(i,j))+1:len_trim(submodulos(i,j))+5)='.f95'
WRITE(*,*) hayuse,submodulos(i,j)
j=j+1
end do
m(i)=j-1
end do
endif


total=1
Do i=1,n
Do j=1,m(i)
matvec(total)=submodulos(i,j)
total=total+1
end do
end do
total=total-1

!BUSQUEDA
Do i=1,total
Do j=i+1,total
if (matvec(i)==matvec(j)) then
matvec(j)=' '
endif
end do
end do

WRITE(*,*) matvec

if (n>=1) then
WRITE(70,*,IOSTAT=error_de_escritura) 'gfortran ',matvec(1:total),modulos(1:n),' main.f95'
else
WRITE(70,*,IOSTAT=error_de_escritura) 'gfortran ','main.f95'
endif
if (error_de_escritura>0) STOP 'Error de escritura final'

END PROGRAM compilador