Compiler errors Fortran&;Matlab链接——未定义符号
我继承了这段用fortran 90编写的mex代码,我无法正确构建它。所有对象文件都编译得很好,但链接失败。 幸运的是,我有好几条线索来解决这个问题 链接器的唯一抱怨是Compiler errors Fortran&;Matlab链接——未定义符号,compiler-errors,linker,fortran,mex,gfortran,Compiler Errors,Linker,Fortran,Mex,Gfortran,我继承了这段用fortran 90编写的mex代码,我无法正确构建它。所有对象文件都编译得很好,但链接失败。 幸运的是,我有好几条线索来解决这个问题 链接器的唯一抱怨是 Undefined symbols for architecture x86_64: "_mxgetstring_", referenced from: _mexfunction_ in qgstep_mex.o ld: symbol(s) not found for architecture x86_64 现
Undefined symbols for architecture x86_64:
"_mxgetstring_", referenced from:
_mexfunction_ in qgstep_mex.o
ld: symbol(s) not found for architecture x86_64
现在,mxGetString
只在中的一个位置调用
所以如果我把这个改成
status = 0
和hardcodeprmfname
,软件包构建得很好。但我当然不想硬编码
但是,我已经成功地构建了另一个使用mxGetString()
的程序,即Matlab提供的示例文件
这两个程序都由mex发出的相同命令链接
gcc -O -Wl,-twolevel_namespace -undefined error -arch x86_64 -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/ -mmacosx-version-min=10.5 -bundle -Wl,-exported_symbols_list,/Applications/MATLAB_R2012a.app/extern/lib/maci64/fexport.map -o "revord.mexmaci64" revord.o -L/Applications/MATLAB_R2012a.app/bin/maci64 -lmx -lmex -lmat -L/opt/local/lib/gcc47/gcc/x86_64-apple-darwin12/4.7.3/../../.. -lgfortran -L/opt/local/lib/gcc47/gcc/x86_64-apple-darwin12/4.7.3 -lgfortranbegin
除了将revord.F
替换为qgstep_mex.f90
以及类似的输出名称
revord.F
#include "fintrf.h"
在编译过程中由标志指向
-I/Applications/MATLAB_R2012a.app/extern/include
但是,如果我尝试将其放入qgstep\u mex.f90
,链接器只会抱怨
Warning: qgstep_mex.f90:1: Illegal preprocessor directive.
那么,有人知道如何让它工作吗
更新(回应M.S.B.的回答)
将扩展名的大小写更改为.F90没有效果,但是-cpp
标志似乎已经成功了。然而,现在它给出了一个我不太理解的错误(在编译期间,不是链接期间)(我不太擅长Fortran)
include文件中的相关行似乎是
#if defined(MX_COMPAT_32)
.
.
.
#define mxGetString mxGetString700
根据M.S.B.的更新进行更新
啊哈。看来我毕竟不应该包括fintrf.h
。项目目录中还有另一个文件,包含
module mexf90_mod
interface
function mxGetString(p, string, STRLEN)
integer(8) :: mxGetString
integer(8) :: p
character*(*) :: string
integer(4) :: STRLEN
end function mxGetString
function mxGetPr(pm)
integer(8), pointer :: mxGetPr
integer(8) :: pm
end function mxGetPr
.
.
奇怪的是,mxGetPr在mxGetString之前的qgstep_mex.f90
中调用得很好,但是调用mxGetString失败,错误消息如上所述。以下是我使用的链接命令(为清晰起见插入了换行符)
可以看出,对象文件的顺序似乎也是正确的
更新
该软件包在linux系统上构建得很好。因此,我想这两个编译器之间一定有一些不同。以下是linux系统上使用的链接代码:
gfortran -O -pthread -shared -Wl,--version-script,/ufs/local/matlab-2012a/extern/lib/glnxa64/fexport.map -Wl,--no-undefined
-o "QG_step_f.mexa64" utils.o parameters.o helmholtz.o calc.o qgflux.o qgstep.o mexf90.o qgstep_mex.o
-Wl,-rpath-link,/ufs/local/matlab-2012a/bin/glnxa64 -L/ufs/local/matlab-2012a/bin/glnxa64 -lmx -lmex -lmat -lm
fortran中的include语句没有#
在构建时,为什么不使用gfortran而不是gcc呢。使编译器不必知道您在编译什么。尝试将文件名qgstep\u mex.f90更改为qgstep\u mex.f90。这将导致gfortran运行C预处理器。还有一个编译器选项会导致这种情况 编辑以响应问题更新:
编译器希望键入函数
mxGetString7001
。有几种方法可以做到这一点。理想的方法是将函数的源代码放在模块中。然后,当调用方使用该模块时,编译器知道函数的返回类型及其参数的类型。也许这是存在的,您需要将源代码文件添加到compile语句中。。。在使用此函数的文件之前。如果没有,您可以编写一个接口
块来提供此信息。或者您可以声明函数并使用外部
语句,但这实际上是一种解决方法,使用FORTRAN 77方法。我相信include语句是用于预处理器的,这就是它的语法不同的原因。
module mexf90_mod
interface
function mxGetString(p, string, STRLEN)
integer(8) :: mxGetString
integer(8) :: p
character*(*) :: string
integer(4) :: STRLEN
end function mxGetString
function mxGetPr(pm)
integer(8), pointer :: mxGetPr
integer(8) :: pm
end function mxGetPr
.
.
gfortran-mp-4.7 -O -Wl,-twolevel_namespace -undefined error -arch x86_64
-Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/
-mmacosx-version-min=10.5 -bundle -Wl,-exported_symbols_list,/Applications/MATLAB_R2012a.app/extern/lib/maci64/fexport.map
-o "QG_step_f.mexmaci64" utils.o parameters.o helmholtz.o calc.o qgflux.o qgstep.o mexf90.o qgstep_mex.o
-L/Applications/MATLAB_R2012a.app/bin/maci64 -lmx -lmex -lmat -L/opt/local/lib/gcc47/gcc/x86_64-apple-darwin12/4.7.3/../../..
-lgfortran -L/opt/local/lib/gcc47/gcc/x86_64-apple-darwin12/4.7.3 -lgfortranbegin
gfortran -O -pthread -shared -Wl,--version-script,/ufs/local/matlab-2012a/extern/lib/glnxa64/fexport.map -Wl,--no-undefined
-o "QG_step_f.mexa64" utils.o parameters.o helmholtz.o calc.o qgflux.o qgstep.o mexf90.o qgstep_mex.o
-Wl,-rpath-link,/ufs/local/matlab-2012a/bin/glnxa64 -L/ufs/local/matlab-2012a/bin/glnxa64 -lmx -lmex -lmat -lm
include "fintrf.h"