Mex Link Failure: Undefined Symbols for Architecture

I am using Mac OS X 10.9, and Matlab 2013a, I'm compiling with Xcode 5.1.1 (I think, I don't know how to check). I have edited my mexopts.sh file to update all instances of 10.7 to 10.9. Now I'm getting a linker error that I see a lot of people have gotten before, however based on the answers to all the previous posts I have not gotten it to work. When I run mex -v ndfun.c this is the output I get.
>> mex -v ndfun.c
**************************************************************************
Warning: Neither -compatibleArrayDims nor -largeArrayDims is selected.
Using -compatibleArrayDims. In the future, MATLAB will require
the use of -largeArrayDims and remove the -compatibleArrayDims
option. For more information, see:
http://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html
**************************************************************************
-> mexopts.sh sourced from directory (DIR = $PREF_DIR)
FILE = /Users/artinsarraf/.matlab/R2013a/mexopts.sh
----------------------------------------------------------------
-> MATLAB = /Applications/MATLAB_R2013a.app
-> CC = xcrun -sdk macosx10.9 clang
-> CC flags:
CFLAGS = -fno-common -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -mmacosx-version-min=10.9 -fexceptions
CDEBUGFLAGS = -g
COPTIMFLAGS = -O2 -DNDEBUG
CLIBS = -L/Applications/MATLAB_R2013a.app/bin/maci64 -lmx -lmex -lmat -lstdc++
arguments = -DMX_COMPAT_32
-> CXX = xcrun -sdk macosx10.9 clang++
-> CXX flags:
CXXFLAGS = -fno-common -fexceptions -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -mmacosx-version-min=10.9
CXXDEBUGFLAGS = -g
CXXOPTIMFLAGS = -O2 -DNDEBUG
CXXLIBS = -L/Applications/MATLAB_R2013a.app/bin/maci64 -lmx -lmex -lmat -lstdc++
arguments = -DMX_COMPAT_32
-> FC = gfortran
-> FC flags:
FFLAGS = -fexceptions -m64 -fbackslash
FDEBUGFLAGS = -g
FOPTIMFLAGS = -O
FLIBS = -L/Applications/MATLAB_R2013a.app/bin/maci64 -lmx -lmex -lmat -L -lgfortran -L -lgfortranbegin
arguments = -DMX_COMPAT_32
-> LD = xcrun -sdk macosx10.9 clang
-> Link flags:
LDFLAGS = -arch x86_64 -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -mmacosx-version-min=10.9 -bundle -Wl,-exported_symbols_list,/Applications/MATLAB_R2013a.app/extern/lib/maci64/mexFunction.map
LDDEBUGFLAGS = -g
LDOPTIMFLAGS = -O
LDEXTENSION = .mexmaci64
arguments =
-> LDCXX =
-> Link flags:
LDCXXFLAGS =
LDCXXDEBUGFLAGS =
LDCXXOPTIMFLAGS =
LDCXXEXTENSION =
arguments =
----------------------------------------------------------------
-> xcrun -sdk macosx10.9 clang -c -I/Applications/MATLAB_R2013a.app/extern/include -I/Applications/MATLAB_R2013a.app/simulink/include -DMATLAB_MEX_FILE -fno-common -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -mmacosx-version-min=10.9 -fexceptions -DMX_COMPAT_32 -O2 -DNDEBUG "ndfun.c"
ndfun.c:403:7: warning: implicit declaration of function 'zgemm_' is invalid in C99
[-Wimplicit-function-declaration]
BLASCALL(zgemm)("N", "N", &m, &m, &m, &cone...
^
ndfun.c:74:21: note: expanded from macro 'BLASCALL'
#define BLASCALL(f) f ## _
^
<scratch space>:207:1: note: expanded from here
zgemm_
^
ndfun.c:614:4: warning: implicit declaration of function 'dgeev_' is invalid in C99
[-Wimplicit-function-declaration]
BLASCALL(dgeev)("N", &jobvr, &m, input + i*inputstride, &m, outeigs...
^
ndfun.c:74:21: note: expanded from macro 'BLASCALL'
#define BLASCALL(f) f ## _
^
<scratch space>:207:1: note: expanded from here
dgeev_
^
2 warnings generated.
-> xcrun -sdk macosx10.9 clang -O -arch x86_64 -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -mmacosx-version-min=10.9 -bundle -Wl,-exported_symbols_list,/Applications/MATLAB_R2013a.app/extern/lib/maci64/mexFunction.map -o "ndfun.mexmaci64" ndfun.o -L/Applications/MATLAB_R2013a.app/bin/maci64 -lmx -lmex -lmat -lstdc++
Undefined symbols for architecture x86_64:
"_dgecon_", referenced from:
_compute_lu in ndfun.o
"_dgeev_", referenced from:
_mexFunction in ndfun.o
"_dgemm_", referenced from:
_mexFunction in ndfun.o
"_dgetrf_", referenced from:
_compute_lu in ndfun.o
"_dgetri_", referenced from:
_mexFunction in ndfun.o
"_dgetrs_", referenced from:
_mexFunction in ndfun.o
"_zgemm_", referenced from:
_mexFunction in ndfun.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
mex: link of ' "ndfun.mexmaci64"' failed.
I have also tried using a different compiler. I downloaded gfortran, but I don't know how to get mex to use it. Thanks for any help anyone can give. I don't have any other files related to the undefined symbols so I'm assuming it's a compiler problem as opposed to a problem with the code (which does work for other people).

 Accepted Answer

Artin - a couple of the warnings are
ndfun.c:403:7: warning: implicit declaration of function 'zgemm_'
ndfun.c:614:4: warning: implicit declaration of function 'dgeev_'
Your code, ndfun.c, has defined or is using these (BLAS and/or LAPACK) functions in some way, so where have they been declared? When you build the MEX file from
mex -v ndfun.c
you are not including any libraries to link to these functions.
Doing a web search on ndfun.c turns up http://www.mit.edu/~pwb/matlab/ndfun/ndfun.c which has the statement (in the header)
TO COMPILE: This file makes extensive use of BLAS and LAPACK functions. "New" versions of MATLAB require the explicit linking of the library that supports those functions, on both Windows and UNIX. On Linux, my command line is: "mex ndfun.c -lmwlapack". I'm not sure if Windows is the same.
So I tried (on my Mac)
mex ndfun.c -lmwlapack
and the following errors were observed
Error using mex
Undefined symbols for architecture x86_64:
"_dgemm_", referenced from:
_mexFunction in ndfun.o
"_zgemm_", referenced from:
_mexFunction in ndfun.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
So it got a little further than running the same command without the library. Adding the BLAS library
mex ndfun.c -lmwlapack -lmwblas
allowed the MEX file (ndfun.mexmaci64) to be built successfully (though there were a couple of warnings).
There is a MATLAB link that describes how to call LAPACK and BLAS functions from MEX files. You may want to look at this as well.

3 Comments

Perfect this worked for 2 out of 3 files, thank you. When you add -lmwlapack and -lmwblas, are these already libraries that are already saved somewhere in the matlab source files? The last file as far as I can tell has no reference to either of those libraries and the linker error I get is simply:
Undefined symbols for architecture x86_64:
"_mexFunction", referenced from:
-exported_symbol[s_list] command line option
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
mex: link of ' "fort.mexmaci64"' failed.
Does there need to be a "mexFunction" in the c file because the other two files that worked both had one. If it makes a difference this c file has a header file associated with it, and it is included in the same directory. Thanks again.
The c file is fairly short so I'll add it here:
/* $Revision: 1.1 $ $Date: 2000/05/17 19:47:26 $ / /========================================================= * fort.c * auxilliary routines for conversion between MATLAB and * FORTRAN complex data structures. Copyright 1984-2000 The MathWorks, Inc. =======================================================/
//ADDED BY ME - ARTIN #include stdint.h typedef uint16_t char16_t;
#include "mex.h" //#include "fort.h"
/* * Convert MATLAB complex matrix to Fortran complex storage. * Z = mat2fort(X,ldz,ndz) converts MATLAB's mxArray X to Fortran's * complex*16 Z(ldz,ndz). The parameters ldz and ndz determine the * storage allocated for Z, while mxGetM(X) and mxGetN(X) determine % the amount of data copied. */
double* mat2fort( const mxArray *X, int ldz, int ndz ) { int i,j,m,n,incz,cmplxflag; double *Z,*xr,*xi,*zp;
Z = (double *) mxCalloc(2*ldz*ndz, sizeof(double));
xr = mxGetPr(X);
xi = mxGetPi(X);
m = mxGetM(X);
n = mxGetN(X);
zp = Z;
incz = 2*(ldz-m);
cmplxflag = (xi != NULL);
for (j = 0; j < n; j++) {
if (cmplxflag) {
for (i = 0; i < m; i++) {
*zp++ = *xr++;
*zp++ = *xi++;
}
} else {
for (i = 0; i < m; i++) {
*zp++ = *xr++;
zp++;
}
}
zp += incz;
}
return(Z);
}
/* * Convert Fortran complex storage to MATLAB real and imaginary parts. * X = fort2mat(Z,ldz,m,n) copies Z to X, producing a complex mxArray * with mxGetM(X) = m and mxGetN(X) = n. */
mxArray* fort2mat( double *Z, int ldz, int m, int n ) { int i,j,incz; double *xr,*xi,*zp; mxArray *X;
X = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
xr = mxGetPr(X);
xi = mxGetPi(X);
zp = Z;
incz = 2*(ldz-m);
for (j = 0; j < n; j++) {
for (i = 0; i < m; i++) {
*xr++ = *zp++;
*xi++ = *zp++;
}
zp += incz;
}
return(X);
}
I found the two libraries (libmwblas.dylib and libmwlapack.dylib) at /Applications/MATLAB_R2014a.app/bin/maci64.
As for building multiple C files, yes, both files should be in the build command. While I've never tried this, presumably you would do something like
mex myMexFunc.c other1.c other2.c -I/Users/geoff/otherIncludeFiles
where myMexFunc.c is the MEX function, other1.c and other2.c are the additional C files to build, and -I/Users/geoff/otherIncludeFiles is the directory to search for additional header files (presumably your myMexFunc.c includes the other1.h and other2.h header files). See MEX options for additional options to the MEX build command.
EDIT
The above assumes that all C files are in the same directory/folder.
Great, thank you again.

Sign in to comment.

More Answers (0)

Categories

Tags

Asked:

on 24 Sep 2014

Commented:

on 25 Sep 2014

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!