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

Adam Strzelecki ono at java.pl
Sat Aug 2 11:48:14 CEST 2014


> Actually you CAN add Info.plist to bundle-less apps using the linker arguments: `-sectcreate __TEXT __info_plist Info.plist` which will embed it in the binary. All OS X APIs handle this transparently. Though, LSEnvironment is not a good solution for the problem we are trying to solve here.

I was expecting that ;) But wasn't your intention to not modify binary once it has been built and not hardcode any paths into it?

> Why would you do any of these things?

Because you dislike adding absolute rpath to Qt SDK in built binary during dev process.

> "Inject"? DYLD_LIBRARY_PATH is an environment variable. You simply set it in the process's environment before spawning.

It is not so simple, first of all as you shown it works only from console, but if you launch it via GUI you need this variable to be set in launchd. As ~/.launchd.conf doesn't work anymore since Lion only permanent solution is to use /etc/launchd-user.conf which require admin to create/modify.

Secondly DYLD_LIBRARY_PATH has strong security implications as the path is searched BEFORE default locations. So it does in fact let you inject/replace libraries. This is the reason dyld disables that for any process running under root account.

man dyld

DYLD_LIBRARY_PATH

	The dynamic linker searches these directories BEFORE it searches the default locations for libraries.

What might be considered there is DYLD_FALLBACK_FRAMEWORK_PATH.


> In a terminal session, simply:
> 
> $ export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/path/to/Qt/Frameworks
> $ open /apps/MyApp.app
> 
> In Creator, just click run and this will be handled automatically. In qbs just type `qbs run -p foo` and this will be handled automatically.

This won't work for apps launched directly via Finder/Dock.


> ANY solution that involves placing absolute paths in ANY file inside the MyApp.app/ directory tree is a wrong solution.

You are wrong there. All system libs are referenced with their absolute paths.

Moreover the Qt's lib/ absolute path will be there only during development, in deployed binary absolute path will be removed via install_name_tool -delete_rpath.


> Note that Qt Creator already does the logical equivalent of what I described on Windows; the Qt libraries path is added to the PATH when the process is launched. Launching directly in Explorer doesn't work, and launching directly from Finder doesn't need to work either.

Currently it DOES WORK when launching via Finder, because it does hardcode absolute path, so I don't see any reason it should stop working. Also it does work like that on Linux too.


> This is closer to how the native tools do things anyways.

Which tools? AFAIK Xcode doesn't copy external frameworks into app bundle by default.

> Symlinks make no sense. Just copy the full frameworks, there is no disadvantage to this. This is the standard workflow for development on Apple platforms anyways and has been since NeXTSTEP.

See above.

> I'm sure someone will bring up "performance!!1" but that is a poor argument;

This is going off-topic. It was about to bring @rpath to Qt frameworks not rework entire workflow.

>> 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.
> 
> It might need them. Depends if we change macdeployqt to place a dylibs (non-frameworks) build of Qt libraries inside Libraries instead of Frameworks. Not a major part of the discussion anyways, just an idea.

I don't see point of handling some custom scenarios that anyway are not what is expected (standard) app bundle.

> Let's use standard solutions instead of strange contraptions. Standard solutions involve @rpath along with DYLD_LIBRARY_PATH, copying frameworks at build time, or both (preferably both).

I am sorry, but you are wrong. DYLD_LIBRARY_PATH is nowhere used in Xcode and DYLD_ variables exist for dyld debug purposes.

Try to create simple framework and see what happens, checkout install name of built framework.

$ otool -L /Users/ono/Library/Developer/Xcode/DerivedData/TestFramework-aduwyulqilsereeqgoizoxubgbdy/Build/Products/Debug/TestFramework.framework/TestFramework 
/Users/ono/Library/Developer/Xcode/DerivedData/TestFramework-aduwyulqilsereeqgoizoxubgbdy/Build/Products/Debug/TestFramework.framework/TestFramework:
	/Library/Frameworks/TestFramework.framework/Versions/A/TestFramework (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 20.0.0)
	/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1056.13.0)
	/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)



Now create a Cocoa app and framework from the framework project as see how the framework is referred and check if you can find the framework inside bundle.

$ otool -L /Users/ono/Library/Developer/Xcode/DerivedData/SampleApp-fwmalbohyjlyqgdhjvnicwjqqmfr/Build/Products/Debug/SampleApp.app/Contents/MacOS/SampleApp 
/Users/ono/Library/Developer/Xcode/DerivedData/SampleApp-fwmalbohyjlyqgdhjvnicwjqqmfr/Build/Products/Debug/SampleApp.app/Contents/MacOS/SampleApp:
	/Library/Frameworks/TestFramework.framework/Versions/A/TestFramework (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 20.0.0)
	/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1056.13.0)
	/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
	/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1265.19.0)

-- 
Adam


More information about the Development mailing list