Deploying Qt-based frameworks made simple
May 10th, 2009
Last time when I was deploying a Qt application on MacOS X I spent several hours struggling with otool and install_name_tool to make my app see all the bundled Qt frameworks and plugins. Then I found out that there is a dedicated tool for it, called macdeployqt and, what is more, it’s nothing new. To be honest, it’s so well known that it is currently shipped together with Qt. Shame on me.
Great then, macdeployqt reduces the deployment work to one line in terminal, and time thereof to several seconds :) However, my application, apart from Qt frameworks uses other custom, self-made frameworks that depend on Qt. It seems that macdeployqt doesn’t support deploying frameworks, as it searches for application binary located in <bundle_name>/Contents/MacOS, which simply doesn’t exist in a framework bundle. So I created a simple script, called frameworkdeployqt.pl that does the dirty work of deploying frameworks written in Qt. The basic concept is:
- you want to deploy a Qt application on MacOS X,
- your application uses custom/self-made/third-party frameworks written in Qt,
- all the frameworks are going to be located in
<bundle_name>/Contents/Frameworks.
Then you deploy the application in two simple steps:
- run
macdeployqtto copy needed Qt frameworks to the application bundle and adjust its internal framework references, - run
frameworkdeployqt.plto make your custom frameworks use Qt frameworks bundled with your application. You’ll of course need perl, but it comes out of the box with MacOS X.
The script looks for non-Qt frameworks inside the bundle given as an argument (namely, it searches <bundle_name>/Contents/Frameworks for frameworks other than Qt*) and then replaces their references to Qt frameworks so that they point to the ones that macdeployqt have just copied to the bundle. For now it’s a bit dumb, i.e. it doesn’t check the existence of Qt frameworks, so if your custom framework uses other Qt modules than the application (or macdeployqt somehow failed to copy them), you’ll have to copy them manually to the bundle.
Other drawback is that you can’t create a dmg image directly using macdeployqt, but anyway, if you happen to need frameworkdeployqt.pl, that dmg would have been useless for you.
The script is available from GitHub. Enjoy!
Qt and UIElement
February 21st, 2009
Those who ever happened to write an application for Mac have to realize the existence of Property List files – for storing user’s settings and defining details on app’s behavior inside the OS. For example, if you want your application to be an agent, i.e. run without menu bar and Dock icon, you set the appropriate flag in the Info.plist file inside the application bundle:
1 2 | <key>LSUIElement</key> <true/> |
Fair enough, if you’re an Objective-C Cocoa developer. But if you’re, let’s say, a C++ Qt programmer deploying your app on Mac OS X as yet another platform, you can end up with such a flood of (probably) unexplainable errors:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | ayoy@batory repo % ./qtwitter.app/Contents/MacOS/qtwitter 2009-02-22 00:14:40.420 qtwitter[46617:10b] *** _NSAutoreleaseNoPool(): Object 0x1315f30 of class NSCFString autoreleased with no pool in place - just leaking Stack: (0x9330173f 0x9320de32 0x92f1f1b1 0x92f1f21d 0x92f1f271 0x92f1d90c 0x92f1d9d2 0x92eb5b17 0x3d1f2b 0x9a3e08 0x94fd23 0x950096 0x6b64 0x653b 0x6469) (... boooooring ...) 2009-02-22 00:14:40.428 qtwitter[46617:10b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFBoolean length]: unrecognized selector sent to instance 0xa03d8400' 2009-02-22 00:14:40.429 qtwitter[46617:10b] Stack: ( 2465300747, 2491215419, 2465329930, 2465323276, 2465323474, 2464897815, 4005675, 10108424, 9764131, 9765014, 27492, 25915, 25705 ) zsh: trace trap ./qtwitter.app/Contents/MacOS/qtwitter |
Not that I dislike Macs, but that’s really uncool. Strictly speaking, the program is failing badly when trying to create an instance of QApplication. And this applies at least to Qt 4.4.3 and, as I suppose, the previous releases too. Now here comes the good news — we already have a release candidate of Qt 4.5, which can cope with the LSUIElement setting. So if you experience such a problem, just switch to the newest Qt available, it should be stable enough in most cases. And if you’re afraid of release candidates, just wait these few days until it becomes official.
