Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MacOSX: How to collect dependencies into a local bundle?

I am creating a plugin application (dylib) that depends on several other libraries. These other libraries are installed on my system, but are not guaranteed to be installed on any user's system. So I need to find a way bundle the dependencies along with my application.

I found that I can use otool to list or change the paths to other dylibs. This would allow to create a folder that bundles my plugin application and all needed dependencies.

However, doing this manually seems like a time-consuming and dumb task. Are there utilities available to automate it?

Or perhaps I'm doing it wrong and there is a better and more obvious approach for this problem?

Edit I created a script that automates most the task.

like image 444
StackedCrooked Avatar asked Jan 19 '10 09:01

StackedCrooked


3 Answers

Use relative paths in your dylib using install_name_tool. That way you can set them once, and install that directory anywhere without needing to modify your libraries at install time.

You should place all of your dylib dependencies into one folder, then use install_name_tool to set the relative location of the other dylibs you depend on. Suppose your library libmyfoo.dylib depends on libbar.dylib:

install_name_tool -change "/Whatever/full/path/libbar.dylib" "@loader_path/libbar.dylib" libmyfoo.dylib

This way, your library will always look for libbar.dylib in the same directory where libmyfoo.dylib is located.

You might also need to run install_name_tool on some of the other dylibs, if they depend on one another.

Beware, the documentation for install_name_tool points out that "For this tool to work when the install names or rpaths are larger the binary should be built with the ld(1) -headerpad_max_install_names option.", so be sure to include the -headerpad_max_install_names command line option when building your library.

@loader_path is relative to the binary used to load the dylib, in this case your libmyfoo.dylib. Use @executable_path if you want to find the libraries relative to executable that started the library loading sequence.

like image 75
Christopher Bruns Avatar answered Nov 19 '22 04:11

Christopher Bruns


To complete Christopher's answer, here are some links to useful resources:

  • Linking and Install Names
  • Embedding frameworks in loadable bundles
like image 24
Laurent Etiemble Avatar answered Nov 19 '22 04:11

Laurent Etiemble


Macdylibbundler is a handy little tool which does exactly what is asked for. It certainly saved my life when distributing binaries for OSX.

like image 3
BaCh Avatar answered Nov 19 '22 04:11

BaCh