Let me describe a way which works through all systems and simplifies the distribution of library code within a package a lot.
First I want to point out that there are two major scenarios here:
You are currently developing a package containing
When you are actively working on such a package, it is most likely not installed in your
$UserAddOnsDirectory but instead in your development path.
Nevertheless, you want to test, debug or run your library functions within Mathematica. On those development machines I find it quite convenient to either set the Mathematica
$LibraryPath variable or provide the appropriate environment variables to Mathematica. The latter can be annoying sometimes, especially on OSX because they change the way of sending env-variables to applications every five minutes.
The second scenario is when you have finished your package development and it is ready to be installed (or distributed to other machines). Here, there is a much easier way to solve the dependency problem which I will describe in the following
Set up your package structure correctly
Your package should have the library functions and dependency libraries in the appropriate folder under
Package/LibraryResources/$SystemID. As example, here the directory structure of one of my projects
│ └── English
│ └── ReferencePages
│ └── Symbols
The overall advantage of putting a package structured like above into a place where Mathematica can find it is that it will automatically add the correct library path to its
$LibraryPath variable and all
.so|.dylib|.dll will be found.
Loading the dependencies before your
Now you can first check that all your libraries can be found even if you haven't set any environment variable explicitly or hard-coded the library position like in Szabolcs answer. To give an example for my package:
(* on Linux *)
(* /home/patrick/.Mathematica/Applications/IPCU/LibraryResources/Linux-x86-64/libtbb.so *)
(* on OSX *)
Now, what you have to do is to load all dependency libraries before you load you actual
LibraryLink functions. Please be careful, because order might be important. If you get an error, please check the content of
LibraryLink`$LibraryError, which gives a more detailed reason for failure.
To grab an example, the underlying parallel LibraryLink function from my answer here uses the above mentioned Intel TBB library.
If I just try to load the
calculateNewtonFractal LibraryLink function, I get the following error
LibraryFunction::libload: The function calculateNewtonFractal was not loaded from the file /home/patrick/.Mathematica/Applications/IPCU/LibraryResources/Linux-x86-64/ipcu_library.so.
and the content of
"libtbb.so.2: cannot open shared object file: No such file or directory"
If I instead preload the tbb, it works excellent:
Therefore, the condensed required steps are:
- Make sure your dependency libraries can be found with
FindLibrary by (i) using above package structure, (ii) setting
$LibraryPath manually or (iii) setting system environment variables and providing them to Mathematica.
- Load the dependency libraries in the correct order (they might depend on each other) using
LibraryLink`$LibraryError if you get errors.
- Load your LibraryLink function using