How to embed a Framework in a Plugin in an App
This is not completely straightforward, or in other words it didn’t ran with the default Xcode setting straight out of the box.
So I set up a test app, that should look like this
Foo.app
Frameworks
A.framework
B.framework
Plugins
C.plugin
Frameworks
D.framework
Where Foo links against A, and C links against B and D.
The frameworks being linked must have a @rpath prefix
DYLIB_INSTALL_NAME_BASE = @rpath
. Otherwise the whole dyld search mechanism isn’t used. This value is used at link time to generate the proper INSTALL_NAME
for the shared library. Only with this set, will the loader at runtime get the idea to use LD_RUNPATH_SEARCH_PATHS
to search for it.
Remember that the INSTALL_NAME occurs in two places.
- In the executable of the Framework
- In the executable, that is linking this Framework.
The App searches @executable_path/../Frameworks
LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks
This value is used at runtime. Since the app is always the “root” @executable_path
is correct.
As
@loader_path
for Apps is the same as@executable_path
, using@loader_path
would be equally correct.
The Bundle searches @loader_path/../Frameworks
This should also work for frameworks, which embed other frameworks.
LD_RUNPATH_SEARCH_PATHS = $(inherited) @loader_path/../Frameworks
The @loader_path
is used for the frameworks embedded into the bundle. Interestingly the bundle LD_RUNPATH_SEARCH_PATHS
will be added to the Apps LD_RUNPATH_SEARCH_PATHS
, so it is neither necessary nor productive to specify @executable_path/../Frameworks
again.
The value of
@loader_path
for the Bundle will be different than that of the App. You can’t optimize theLD_RUNPATH_SEARCH_PATHS
setting for the Bundle away.The
$(inherited)
is just a Xcode setting mechanism. The observedLD_RUNPATH_SEARCH_PATHS
inheritance behaviour is not due to $(inherited)
You can check out my test project yourself:
git clone https://www.mulle-kybernetik.com/repositories/FrameworkEmbeddingTest
cd FrameworkEmbeddingTest
xcodebuild -configuration Release OBJROOT=build SYMROOT=build
cd build/Release/Foo.app/Contents/MacOS/
DYLD_PRINT_RPATHS=YES ./Foo
man dyld
tells you that you can use DYLD_PRINT_RPATHS=YES
to debug @rpath problems.
Post a comment
All comments are held for moderation; basic HTML formatting accepted.