Bundling .dylib files with mono executable
Asked Answered
V

2

0

I have an application and I'd like to bundle a specific dylib along with it. I'm using "dylibbundler" to copy the dylib along with dependencies to the executable folder. Here's the command I'm using:

dylibbundler -od -b -x /opt/local/lib/libil.dylib -d ./libs/ -p @executable_path/libs/

dylibbundler is located in the same directory with the executable. The tool recursively runs "install_name_tool" on the library and all of its dependencies (and copies them to a specified directory). Running otool -L on the ./libs/libil.1.dylib returns:

@executable_path/libs/libIL.1.dylib (compatibility version 3.0.0, current version 3.0.0)
@executable_path/libs/libtiff.5.dylib (compatibility version 8.0.0, current version 8.0.0)
@executable_path/libs/liblzma.5.dylib (compatibility version 6.0.0, current version 6.4.0)
@executable_path/libs/libpng15.15.dylib (compatibility version 30.0.0, current version 30.0.0)
@executable_path/libs/libmng.1.dylib (compatibility version 2.0.0, current version 2.0.0)
@executable_path/libs/liblcms.1.dylib (compatibility version 2.0.0, current version 2.19.0)
@executable_path/libs/libjasper.1.dylib (compatibility version 2.0.0, current version 2.0.0)
@executable_path/libs/libjpeg.9.dylib (compatibility version 10.0.0, current version 10.0.0)
@executable_path/libs/libIlmImf.6.dylib (compatibility version 7.0.0, current version 7.0.0)
@executable_path/libs/libImath.6.dylib (compatibility version 7.0.0, current version 7.0.0)
@executable_path/libs/libHalf.6.dylib (compatibility version 7.0.0, current version 7.0.0)
@executable_path/libs/libIlmThread.6.dylib (compatibility version 7.0.0, current version 7.0.0)
@executable_path/libs/libIex.6.dylib (compatibility version 7.0.0, current version 7.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
@executable_path/libs/libz.1.dylib (compatibility version 1.0.0, current version 1.2.7)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)

It seems to me that it has copied everything over correctly. But when I run my application, I keep getting the same exception:

Unhandled Exception: System.DllNotFoundException: ./libs/libIL.1.dylib
Unhandled Exception: System.DllNotFoundException: @executable_path/libs/libIL.1.dylib
Unhandled Exception: System.DllNotFoundException: libs/libIL.1.dylib

As you can see, I've tried 3 different ways of referencing to the library, but it always fails to find it.

Any help would be greatly appreciated, I've been trying to solve this issue for months now.

UPDATE: If I specify an absolute path to the dylib, it finds it, but then complains about the dependencies:

Mono: DllImport error loading library 'dlopen(/Users/me/myapp/libs/libil.1.dylib, 9): Library not loaded: @executable_path/libs/libtiff.5.dylib
  Referenced from: /Users/me/myapp/libs/libil.1.dylib
  Reason: image not found'.

It seems to me that @executable_path isn't being substituted with the actual absolute executable path.

Villatoro answered 22/10, 2013 at 15:34 Comment(0)
M
2

Have in mind that the native executable is not myapp.exe, it's the mono binary.

Try setting DYLD_LIBRARY_PATH as mentioned in a different answer (note that you have to set it before executing your app, since the dynamic library loader reads this value when the application is loaded into memory, way before your Main method is executed).

Masjid answered 23/10, 2013 at 10:14 Comment(2)
I also had a thought that @executable_path points to the mono binary. However the following question says that executable_path works perfectly with mono apps: #14537343 any ideas?Villatoro
I depends on how you built and executed your application. If you're using a MonoMac/Xamarin.Mac project, then that answer is correct (because the build process will build a custom launcher and link libmono into it, as opposed to using the mono binary itself), otherwise it isn't.Masjid
N
1

Since I am actually a Linux guy and don't know what are the exact results considering OSX dynamic libraries as well as the dylibbundler tool, I can't really tell something for sure. On Linux, however, the libraries are searched (among others) in paths enlisted in the LD_LIBRARY_PATH variable. The OSX equivalent is DYLD_LIBRARY_PATH. You can try setting this variable to the directory containing the library.

Narvaez answered 22/10, 2013 at 15:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.