[Development] Qt 4.x and Qt 5 frameworks should use @rpath (QTBUG-31814)

Adam Strzelecki ono at java.pl
Fri Aug 1 21:01:30 CEST 2014


>> All we need to do is build all Qt dylibs with install_name = @rpath/pathrelative_to_lib_folder/some.dylib and make sure qmake adds following linker flags to all apps linking to Qt:
> 
> Just @rpath/QtModuleName.framework/Versions/A/QtModuleName and @rpath/qtsomethingorother.dylib

I am sorry, you are right, we don't have umbrella frameworks in Qt so this should be sufficient.

> No - don't include the last one. macdeployqt (nor any other tool) should NOT modify the binaries at all (modifying is bad for codesigning too). This is why we have DYLD_LIBRARY_PATH (see below).

I believe we had this discussion in the bug report thread. The problem with DYLD_LIBRARY_PATH is that you need to inject it somehow to process launching the app:

(1) if we put it into Info.plist it won't work for bundle less apps (i.e. for simple testing)
(2) if we put it into user's .bash_profile then it won't work in apps launched via Finder, as launchd does not run/respect .bash_profile
(3) if we use launched setenv it will work just for single UI session
(4) if we put it /etc/launchd-user.conf then we need admin rights + we may likely break other apps

So altogether this is safest solution. Please note that if we gonna deploy Qt frameworks via macdeployqt we need to resign application anyway because app bundle gonna be changed.

> No, QMAKE_INSTALLNAMEPREFIX, which is set to "@rpath" (as opposed to an absolute path as is done currently).

You're right, this is much simpler. Of course my previous solution was considering umbrella frameworks, or frameworks having plugins inside of them, that's why prefix matching.

>> Once this is done qtbase Qmake project should define QMAKE_RPATHPREFIX to be Qt SDK install_prefix/lib during build process.
> 
> No replacement needs to be done. (…)

I meant changes that has to be done in Qt SDK build process itself (which is defined in quake projects in qtbase repo). In this case each Qt module should set QMAKE_INSTALLNAMEPREFIX=@rpath on Mac.

> export QT_INSTALL_LIBS=$(qmake -query QT_INSTALL_LIBS)
> export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:$QT_INSTALL_LIBS
> /apps/MyApp.app/Contents/MacOS/MyApp

This solution will work only if you are going to launch the app in terminal or your tool (i.e. Qt Creator) will be able to figure out it needs to set DYLD_LIBRARY_PATH which is far to complicated.

> What might be good, too, is a QMAKE_EMBEDDED_FRAMEWORKS or somesuch which copies the Qt frameworks into the application bundle at build time (though you'd still set DYLD_LIBRARY_PATH because not everyone would necessarily use QMAKE_EMBEDDED_FRAMEWORKS). No reason to postpone that step to macdeployqt; this is how the native Apple tools work anyways. Ossi will disagree with me here and say that anything to do with creating bundle structures is a deployment step only, though. :)

Well, to be frank there is a simple workaround for that :) Why not symlink Qt frameworks at build time, then replace symlinks with real copies on deployment step?

So the easiest solution would be to symlink Qt frameworks when your create app bundle otherwise add /full/path/to/qt when you use bundle-less app. No need to mess with DYLD_LIBRARY_PATH.

> Also, I'd add @executable_path/../Libraries and @loader_path/../Libraries to the search path as well. While less commonly known/used (and found in at least some official Apple documentation), some people do like to put frameworks in $CONTENTS_FOLDER_PATH/Frameworks and dylibs in $CONTENTS_FOLDER_PATH/Libraries.

I don't think you should add these by default since Qt doesn't need them, so unlikely your app need them. If you use some 2rd party library you are free to extend QMAKE_RPATH list yourself.

Cheers,
-- 
Adam


More information about the Development mailing list