Skip to content

osxrelocator: Fix dyld being unable to load all our libraries

amyspark requested to merge amyspark/cerbero:fix-dlopen-rpath-crash into main

Hi all,

When researching the construction of the monolithic GStreamer library/framework (see !1466), I found that Qt applications were totally unable to load GStreamer once deployed through macdeployqt. In my case, I was consuming the libraries in raw form, through a tarball I packaged myself, but @thewildtree also ran into the same issue when testing an app that consumes the official release.

Upon looking at the libraries, I quickly realised that all libraries had what looked like wrongly nested load commands, of the form @rpath/lib/libyadda.dylib. Although the RPATH entries looked reasonable at first glance, this is quickly not the case once the libraries are deployed, because the @rpath of such an app will point to the root of the Frameworks folder, and macdeployqt deploys the libraries in raw form there.

However, that's not all the story. @thewildtree's case revealed a much subtler and deadlier problem: the load commands themselves do not respect Apple's convention, leading dyld(1) to kill the application on sight. This is because, although OSXUniversalGenerator tries making the fat libraries relocatable (correctly) by changing their ID, there's no equivalent change made to any consumer. All load commands must equal the ID of the dylib being loaded 1.

This is easily fixed at a given recipe's post-install time by adjusting the library ID there, and fixing the rpaths so that they always point to the root of the library path.

There's an additional fix for gobject-introspection, g-ir-scanner relies implicitly on absolute dylib IDs because it never adds RPATH entries for the libraries it links the introspection binaries against.

Merge request reports