OS X native plugin difficulty

I have a native OS X plugin with a dylibs inside. It just does not work, despite its seeming identical configuration to one that DOES work.

My plugin is Plugin.bundle and contains (for now) a single .dylib, libFOO_Platform.dylib

I have followed the instructions on this page, and the FOO_Platform.dylib within Plugin.bundle is set up as follows:

otool -L *.dylib
libFOO_Platform.dylib:
    @loader_path/libFOO_Platform.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 104.1.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)

I call a single test function within via this C# method:

        [DllImport("FOO_Platform", CallingConvention = CallingConvention.Cdecl)]
        internal static extern void initPlatform ();

This results in “DLLNotFoundException: FOO_Platform”

If I go and alter the DLLImport to reference the name of the bundle (rather than the dylib), ala

        [DllImport("Plugin", CallingConvention = CallingConvention.Cdecl)]
        internal static extern void initPlatform ();

it produces

Couldn't open Demo.app/Contents/Plugins/Plugin.bundle/Contents/MacOS/Plugin,
error: dlopen(, 2): Library not loaded: @rpath/libFOO_Platform.dylib
Referenced from Demo.app/Contents/Plugins/Plugin.bundle/Contents/MacOS/Plugin
Reason: image not found

Couldn't open Demo.app/Contents/Plugins/Plugin.bundle/Contents/MacOS/Plugin,
error: dlopen(, 2): Library not loaded: @rpath/libFOO_Platform.dylib
Referenced from Demo.app/Contents/Plugins/Plugin.bundle/Contents/MacOS/Plugin
Reason: image not found

DllNotFoundException: Demo.app/Contents/Plugins/Plugin.bundle/Contents/MacOS/Plugin

Notice that in the above, the @loader_path has been replaced by @rpath.

I’m thoroughly confused now. The second DllImport() use seems to be more successful, but screams of terrible design, as when there are multiple libraries (as there WILL BE – this is a simplified failure case), the same DllImport() statement that works on OS X (where the plugin name is used) will not work on Windows (where the library name, minus “lib” and the file extension are used).

What am I doing wrong here?

edit: the following also did not help

otool -L *.dylib
libFOO_Platform.dylib:
    @executable_path/../Plugins/Plugin.bundle/Contents/MacOS/libFOO_Platform.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 104.1.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)

tone

If use CMake, then add the following settings:
set_target_properties(xxxxx PROPERTIES
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS “@loader_path”
)
Or use XCode project, go to Build Settings, find LD_RUNPATH_SEARCH_PATHS, then set “@loader_path”
Build your target, then place your third part dynamic library into xxx.bundle/Contents/MacOS/ folder.

1 Like

After hours of trawling through search results and trying every solution I found, I finally stumbled across this thread.

I had a framework that I my plugin depended on and this is the only solution out of dozens that actually helped!

I’d like to add that you can automate the last step of @Ares09 's answer by going to Build Phases and adding a Copy Files step. Add your framework or library and set the destination option to Executables. This will copy it to the right place for you every time you build.