链接导入垫子文件的FORTRAN代码的错误



我必须在fortran程序中导入垫子文件。我遵循了示例文件,但链接时我面临一些问题。汇编正常发生。

最小代码:

#include "fintrf.h"
PROGRAM main 
USE ssa
USE dmotifs
USE param
IMPLICIT NONE
! MAT-FILE Declarations !
INTEGER matOpen, matGetDir 
INTEGER matGetVariableInfo
INTEGER mp, dir, adir(100), pa
INTEGER mxGetM, mxGetN, matClose
INTEGER ndir, i, clstat
CHARACTER*32 names(100) 
!===========================!
if(all(fnames(:)%fn .NE. argfun)) then
    write(*,*) "No such motif: ",argfun
    write(*,*) "Input format-> main <motifname>"
    stop
else
    fin=fchton(argfun)  
    y0=nM2m*analys(p,argfun)
    ! ==> OPEN MAT-file <== !
    mp=matOpen('./PRMS_lxr_29Apr15.mat','r')
    if (mp .eq. 0) then
         write(6,*) "Can't open MAT-file"
         stop
    end if
    dir = matgetdir(mp, ndir)
      if (dir .eq. 0) then
         write(6,*) "Can't read MAT-file-directory."
         stop
    endif
    call mxCopyPtrToPtrArray(dir, adir, ndir)
    do 20 i=1,ndir
         call mxCopyPtrToCharacter(adir(i), names(i), 32)
 20 continue
    write(6,*) 'Directory of Mat-file:'
    do 30 i=1,ndir
        write(6,*) names(i)
 30 continue
    write(6,*) 'Getting Header info from first array.'
    pa = matGetVariableInfo(mp, names(1))
    write(6,*) 'Retrieved ', names(1)
    write(6,*) '  With size ', mxGetM(pa), '-by-', mxGetN(pa)
    call mxDestroyArray(pa)
    clstat=matClose(mp)
end if
END PROGRAM main

我正在使用gfortran 4.8.3用于使用默认命令编译 链接:

gfortran main.f90 dmotifs.o param.o ssa.o -o main

当我不包括: #include "finitrf.h"时,此代码对罚款(无链接)进行编译(无链接),否则编译器说

Warning: main.f90:1: Illegal preprocessor directive

我尝试将finitrf.h重命名为finitrf.f90,但没有任何区别。但是,在链接期间,我遇到了这些错误:

main.f90:(.text+0x3ea): undefined reference to `matopen_'
main.f90:(.text+0x487): undefined reference to `matgetdir_'
main.f90:(.text+0x52b): undefined reference to `mxcopyptrtoptrarray_'
main.f90:(.text+0x583): undefined reference to `mxcopyptrtocharacter_'
main.f90:(.text+0x71b): undefined reference to `matgetvariableinfo_'
main.f90:(.text+0x804): undefined reference to `mxgetm_'
main.f90:(.text+0x855): undefined reference to `mxgetn_'
main.f90:(.text+0x89c): undefined reference to `mxdestroyarray_'
main.f90:(.text+0x8b0): undefined reference to `matclose_'
collect2: error: ld returned 1 exit status

我需要一个makefile还是在编译命令中添加其他参数?

编辑:

我添加了-cpp选项,这消除了Illegal preprocessor directive

的问题

现在,当我使用MATLAB外部组件的路径(finitf.h)时,我仍然会遇到相同的错误。

gfortran main.f90 dmotifs.o param.o ssa.o -I/usr/local/matlab2008a/extern/include -L/usr/local/matlab2008a/extern/lib -cpp -o main

如果我提供了包含其他MATLAB库在内的/usr/local/matlab2008a/bin/glnxa64的库路径,包括libmat.so,我仍然会遇到相同的错误。

对于较低的案例文件扩展*.f90*.f通常会停用预处理器。为了使其重命名(主)文件具有C*.F90*.F的资本扩展名,或者提供相应的命令行选项(-cpp用于gfortran-fppifort)。

假设丢失的子例程/函数实际上在fintrf.h中声明了,这应该解决您的问题。

您还应告诉编译器与包含MATLAB函数的库链接。

正如亚历山大·沃格特(Alexander Vogt)指出的那样,编译器需要 -cpp选项才能使预处理器识别标头文件,而不是将其视为非法。

链接需要通常位于<matlabroot>/extern/include中的finitrf.h,并且基本库中存在于<matlabroot>/bin/<arch>/中。

但仅指定这一点不起作用,并且确切的MATLAB库的规范似乎是必不可少的。这些是libmat.solibmx.so

这些库依次取决于其他库,因此需要另一个标志来设置rpath

最后,它可与以下命令一起使用:

gfortran main.f90 dmotifs.o param.o ssa.o -I/usr/local/matlab2008a/extern/include -L/usr/local/matlab2008a/bin/glnxa64 -cpp -o main -lmat -lmx -Wl,-rpath /usr/local/matlab2008a/bin/glnxa64/

或一般

gfortran program.f90 -I<matlabroot>/extern/include -L<matlabroot>/bin/<arch> -cpp -lmat -lmx -Wl, -rpath <matlabroot>/bin/<arch> -o program.out

还请参见C中有关相同问题的这篇文章。