Background: My MonoMac app uses a custom build of sqlite3.0.8.6.dylib.
I need the exact steps to have MyApp.app use this dylib.
Here are some steps I took:
Copied the dylib to MyApp.app/Contents/SharedSupport. (Related question: is this the preferred location for 3rd party dylibs or is MyApp.app/Contents/Frameworks preferred?)
Changed the installed name for the library so that it matches its new location.
MyApp.app/Contents/SharedSupport> otool -L libsqlite3.0.8.6.dylib libsqlite3.0.8.6.dylib: @executable_path/../SharedSupport/libsqlite3.0.8.6.dylib (compatibility version 9.0.0, current version 9.6.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
Problems
- MyApp.app/Contents/MacOS/MyApp does not reference the dylib directly, so I can't use install_name_tool to point to the new library location. I believe that the library is referenced by System.Data.Sqlite.dll.
- I thought of overriding DYLD_FALLBACK_LIBRARY_PATH in the launcher script but MonoMac now uses a binary launcher (MyApp.app/Contents/MacOS/MyApp), not a script, so I'm out of luck there.
Would the MonoMac gods please help with what must be a simple solution? I've spent a couple of months, on and off, trying to get this to work.
And please provide exact steps - this problem is all about the details.
You can try manually loading the
sqlite
dylib
.Of course correctly resolving the path to your
dylib
.Be careful if you're using mono. @executable_path will return the path to the mono binary, instead of the actual .EXE executable. This should work correctly with Xamarin though.
Have a look at my answer to this question: Setting path of the Native Library for DllImport on Mono for Mac
The binary launcher comes from monodevelop/main/build/MacOSX/monostub.m.
You can use either
MyApp.app/Contents/Frameworks
or some other path, the important part is not to use any path names in your[DllImport]
but instead add the<dllmap>
using@executable_path
to yourapp.config
like I explained in that other answer.There's a also a link to a test app on github in there.
Detailed Instructions
Pick a path inside the
MyApp.app
to install your native dll, for instanceContents/SharedSupport/sqlite3.0.8.6.dylib
.Compute the relative path from the directory where the managed assembly is located to the native
.dll
and prepend@executable_path
to it.For instance, if your managed assembly is in
Contents/MonoBundle/MyApp.exe
and the native dll inContents/SharedSupport/sqlite3.0.8.6.dylib
, then it's@executable_path/../SharedSupport/sqlite3.0.8.6.dylib
.Change the installed name of the library to this relative path using
install_name_tool
.Add a new
MyApp.exe.config
file to your project, containingUse the path that you computed in step 2. for the
target
field. Right-click the file in MonoDevelop, select "Quick Properties" from the context menu and enable "Copy to Output directory". This will copy the file into theContents/MonoBundle
directory, so it sits right next to yourMyApp.exe
.Use
[DllImport ("sqlite")]
to reference this in your code.When another library references it
When another library, for instance
Mono.Data.Sqlite.dll
references it, it get a little bit more complicated.Use the same steps as above, but you need to figure out which name that other library is using in its
[DllImport]
to reference the native library and put that into the<dllimport dll="..." />
. You can either look for the[DllImport]
statements in the source code or runmonodis
on the assembly and search forpinvokeimpl
, for instance:So
Mono.Data.Sqlite.dll
is using "sqlite3" to reference the native dll, so yourMyApp.exe.config
file will look like this: