Make MATLAB Mex search for a library in a particul

2019-07-29 10:01发布

问题:

I have created a mex function which relies on a library that relies on another library. When I execute the function, it outputs this error at runtime:

Invalid MEX-file
...
Library not loaded: /usr/local/lib/libgomp.1.dylib

I do have this library on my computer but it is located in usr/local/gfortran/lib

So I tried this:

setenv('DYLD_LIBRARY_PATH', '/usr/local/gfortran/lib');

But this doesn't fix the issue at all. I'm using MacOS Sierra 10.12.6. How can I make MATLAB search for that specific folder?

回答1:

MacOS works differently than other OSes with regard to how it searches for dynamic libraries (== shared objects). A few things to know:

  1. Each .dylib file has an "install name". This is a string embedded in the file that tells the linker where it is to be found. When you link your library/executable/MEX-file to the .dylib, the "install name" is stored and used at run time to locate the library. That is, it's not the current location of the file that is stored, but the location that it reports it should be found at.

  2. The "install name" can start with "@rpath", this indicates a relative path.

  3. An executable/library/MEX-file that links to a .dylib can specify alternative directories where to search for dependencies. This is equivalent to the rpath under Linux. These directories can be absolute, or start with "@executable_path" or "@loader_path", indicating a relative path. "@executable_path" is the directory of the executable (the MATLAB binary in case of a MEX-file), and "@loader_path" is the path of the binary that is trying to load the library (e.g. the MEX-file).

Here is more information on these topics: https://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html

There are linker flags that you can use to set correct install names and rpaths and so forth, but you can also use the install_name_tool program to change these things after linking. This might be easiest in your case.

In your case, you can use something like this to change where your MEX-file looks for the dependent library:

install_name_tool -change /usr/local/lib/libgomp.1.dylib usr/local/gfortran/lib/libgomp.1.dylib mexfile.mexmaci64

(replace mexfile.mexmaci64 with the name of your MEX file).

If you want to use relative paths, for example if you move the dependent libgomp.1.dylib to a path that depends on the location of the MEX file, you'd instead do:

install_name_tool -change /usr/local/lib/libgomp.1.dylib @rpath/libgomp.1.dylib mexfile.mexmaci64
install_name_tool -add_rpath @loader_path/../lib mexfile.mexmaci64

or

install_name_tool -change /usr/local/lib/libgomp.1.dylib @loader_path/../lib/libgomp.1.dylib mexfile.mexmaci64