QtBundle
So maybe you've spent an afternoon writing a small utility in Qt, or maybe you're finally ready to have your friends beta-test your latest kick-arse mega-app. The problem now comes — how do you package it for them? If your friends are Linux users, they'll probably be happy building it from source, so the only potential problem they face is the lengthy download and compilation of the Qt source code (if it's not already installed). If your friends are Windows users, you'll probably use NSIS, and all you need to do is throw in the Qt DLLs and maybe mingw10.dll (if you compiled with MinGW). On the Mac however, you face a more difficult problem.
Both QMake and CMake are capable of producing MacOS X bundles, but send this to a friend and you'll rapidly notice that it's not distributable in this form. The fact is that the executable in your bundle is dynamically linked to the Qt libraries on your system using hard-coded paths. Since they don't exist on your friend's computer, the application will clearly fail to load:
dannpg@Lemmie ~/Desktop]otool -L backgammon.app/Contents/MacOS/backgammon
backgammon.app/Contents/MacOS/backgammon:
/usr/local/Trolltech/Qt-4.4.0/lib/QtGui.framework/Versions/4/QtGui (compatibility version 4.4.0, current version 4.4.0)
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 136.0.0)
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 949.33.0)
/usr/local/Trolltech/Qt-4.4.0/lib/QtCore.framework/Versions/4/QtCore (compatibility version 4.4.0, current version 4.4.0)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.3)
/usr/local/Trolltech/Qt-4.4.0/lib/QtSvg.framework/Versions/4/QtSvg (compatibility version 4.4.0, current version 4.4.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.4.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.1.1)
The next port of call is the Qt documentation: Deploying an Application on Qt/Mac. That document outlines how to create a self-contained bundle for your Qt/Mac application, so that your friends need nothing more than to double-click on your application and go.
That document is really helpful, but if you're anything like me, you've become somewhat frustrated with performing this tediously laborious task every time you want to send a bundle to a friend. To that end I spent this Saturday writing a bash script to do the job for me. Simply pass it a bundle directory and it will fix all the dependency paths in your bundle's executables, copy in the required Qt frameworks, and fix their dependencies and IDs. The required Qt modules are auto-detected from the output of otool. The only problem with the script currently is that it isn't able to manage plugins for you. This isn't a biggie for me right now, but if someone gets around to tweaking the script to help with plugins, do let me know :) The script itself is attached; I do hope someone else finds it useful!
dannpg@Lemmie ~/Desktop]qtbundle backgammon.app
Fixing bundle executables:
backgammon
Copying and fixing Qt Frameworks:
QtGui
QtCore
QtSvg
dannpg@Lemmie ~/Desktop]otool -L backgammon.app/Contents/MacOS/backgammon
backgammon.app/Contents/MacOS/backgammon:
@executable_path/../Frameworks/QtGui.framework/Versions/4/QtGui (compatibility version 4.4.0, current version 4.4.0)
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 136.0.0)
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 949.33.0)
@executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore (compatibility version 4.4.0, current version 4.4.0)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.3)
@executable_path/../Frameworks/QtSvg.framework/Versions/4/QtSvg (compatibility version 4.4.0, current version 4.4.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.4.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.1.1)
Danns.co.uk