MATLAB Answers

Mick
0

Best way to locate shared (.dylib) libraries used by MATLAB mex files on MacOS X

Asked by Mick
on 3 Oct 2017
Latest activity Commented on by Jim Hokanson on 2 Sep 2018
I'm using MATLAB on a MacOS X system, and building mex files. These mex files depend on various shared (.dylib) libraries, which I keep in the same directory as the mex files.
On older versions of MacOS X, in order to find those shared libraries at MATLAB run time, it was sufficient to have the environment variable DYLD_LIBRARY_PATH set to include that directory name. The variable could be set before starting MATLAB, or by setting it in a copy of the matlab script. Either way, so long as DYLD_LIBRARY_PATH was set to include the location before starting MATLAB or by making a copy of the matlab script which included a line to set DYLD_LIBRARY_PATH correctly, the mex files would work properly. If the environment variable was not set correctly, MATLAB would just issue an error message saying that dylibs couldn't be found.
But, on recent versions of MacOS X (or, perhaps, it's recent MacOS X combined with recent MATLAB - I'm not sure) this no longer works - DYLD_LIBRARY_PATH gets ignored, and the mex files fail, I guess because of Apple's tightened security policies.
What does work is to make sure that MATLAB's current working directory is the directory containing the mex files and dylibs when using the mex files for the first time. After that you can change directories and the mex files still work. When you do this there's no need to worry about DYLD_LIBRARY_PATH. Presumably once the dylibs have been loaded in this way, they stay loaded and no longer need to be in your path. As far as I can tell this works with all versions of MATLAB from at least R2015b up to R2017b and with all versions of MacOS up to the latest I've got access to, which is MacOS X 10.12 (sierra).
So - when I distribute my mex files to other people, I just need to tell them that they need to be in the right directory before they first use one of them (or add code to their startup.m file to do it for them). In fact, I've not found any other way of getting it to work.
My question is - is this a sensible way of ensuring that dylibs needed by mex files on MacOS are located? If not, what is the recommended way?

  4 Comments

Show 1 older comment
Yes - that's an interesting idea that I guess would work. I'm not hugely keen on cluttering up /usr/local/lib with symlinks, though, partly because as new versions of my mex files come along the symlinks will need to change, and also because there's a good chance some of the run-time dylibs will clash with other people's applications and eventually break them. But - good idea that I think may be usable in extremis
On the other hand, I am not certain I have identified the correct problem. System Integrity Protection seems to be limited as to which files it affects, and user-installed /Applications are not affected; https://support.apple.com/en-ca/ht204899
You're right that user installed /Applications are not supposed to be affected, so it's not clear what's going on here; nevertheless, I tried putting symlinks into /usr/local/lib and it did indeed work. I'm not going to use the method for the reasons I gave before, but if this method was given as an answer then it might be helpful for others

Sign in to comment.

Tags

1 Answer

Answer by Jim Hokanson on 7 Mar 2018

I've had some luck with the following command in the same directory as my mex file.
install_name_tool -change /Users/jim/Documents/repos/matlab_git/mex_lib_code/zip/libzip.dylib @loader_path/libzip.dylib kzip_mex.mexmaci64
or more generally:
install_name_tool -change <old_dylib_path> @loader_path/<dylib_file_name> <mex_file_name>
To get the first value, run:
otool -L kzip_mex.mexmaci64
This should report where the dylibs are being loaded from. Use these values as the first input.
The second input, in my case @loader_path/libzip.dylib, should be replaced with your dylib name, keeping the @loader_path part.
Finally, the third input specifies what file should be targeted for this change. Give it the name of your mex file.
Rerun the otool command and now you should see the path to the dylib has changed ...

  2 Comments

Do you have tips for Dylib to use with Load Library?
I would think it would be pretty much the same process, just replace the mexmaci64 with the library that you are loading => my_library.dylib (instead of my_library.mexmaci64). Note in this case your goal is still to find dependencies of the dynamic library you are working with (either mex or dylib) and point those to a local copy.

Sign in to comment.