Morten
Uncategorized
Qt
Posted by Morten
 in Uncategorized, Qt
 on Thursday, August 23, 2007 @ 12:10

Applications for Mac OS X are usually distributed as self-contained application bundles, which are installed by copying them into the “Applications” folder using drag-and-drop in Finder. As the mac deployment guide points out, creating said bundles involves copying in the Qt frameworks (and plugins), and then fiddling with the install names using otool and install_name_tool.

This is all well and good, but it’s really a procedure that begs to be automated since you typically have to do it over and over again until the final bugs have been ironed out. (just ask any release manager in your vicinity :) )

Therefore the Mac team proudly presents the deployqt utility, which turns what used to be a 10-minute command line exercise into a simple call to ./deployqt myapplication.app.

Enjoy!

Update: deployqt now supports the Mac binary packages.

21 Responses to “Deploying Mac Applications Without the Hassle”

» Posted by tru
 on Thursday, August 23, 2007 @ 12:24

GREAT STUFF! Thanks a lot! Just a question, could this app be expanded to even include other libs than Qt ones? My app depends on a couple dylibs that I have to do the same procedure for also.

» Posted by Max Howell
 on Thursday, August 23, 2007 @ 12:51

Heh. We’ve spent many man hours tweaking our mac release script. Admitedly there’s a bunch of other steps it does. But still this is great thanks.

» Reply from Morten
 on Thursday, August 23, 2007 @ 14:38
Morten

tru: Right now it copies in anything that looks like a Qt framework (anything that contains the string “Qt” in fact). Extending it to automatically copy in everthing that’s needed should be possible, looks like the trick is to ignore anything in /System/Library/ and /usr/lib and the copy in everything else.

Max: Yep, creating a utility that automates deployment is hard because can be done in so many different ways, but deployqt can hopefully help a bit on the way.

» Posted by qtuser
 on Thursday, August 23, 2007 @ 15:21

I compiled this on 10.4.10 using Qt 4.3.1 with xcode.
I then did a “release” build of my app.
I then copied the deployQt app to the same directory as my release app.
Then I performed ./deployqt MyApp.app

This is what I got:

MyComputer:/Developer/DeveloperOutput/Release lou$ ./deployqt MyApp.app

ERROR: no file at “QtScript.framework/Versions/4/QtScript (compatibility version 4.3.0, current version 4.3.1)/lib/.framework/Versions//”
ERROR: no file at “QtSql.framework/Versions/4/QtSql (compatibility version 4.3.0, current version 4.3.1)/lib/.framework/Versions//”
ERROR: no file at “QtXml.framework/Versions/4/QtXml (compatibility version 4.3.0, current version 4.3.1)/lib/.framework/Versions//”
ERROR: no file at “QtGui.framework/Versions/4/QtGui (compatibility version 4.3.0, current version 4.3.1)/lib/.framework/Versions//”
ERROR: no file at “QtNetwork.framework/Versions/4/QtNetwork (compatibility version 4.3.0, current version 4.3.1)/lib/.framework/Versions//”
ERROR: no file at “QtCore.framework/Versions/4/QtCore (compatibility version 4.3.0, current version 4.3.1)/lib/.framework/Versions//”

» Posted by Tanner Lovelace
 on Thursday, August 23, 2007 @ 15:26

If it’s able to copy in other libraries too, this could be very useful for the KDE/Mac project.

Is there any support for copying data and resource files too?

» Posted by Daniel
 on Thursday, August 23, 2007 @ 15:44

Don’t work for me.
I installed the Qt Framework with the installer.
This error message comes up:

ERROR: no file at “QtSql.framework/Versions/4/QtSql (compatibility version 4.3.0, current version 4.3.1)/lib/.framework/Versions//”
ERROR: no file at “QtXml.framework/Versions/4/QtXml (compatibility version 4.3.0, current version 4.3.1)/lib/.framework/Versions//”
ERROR: no file at “QtGui.framework/Versions/4/QtGui (compatibility version 4.3.0, current version 4.3.1)/lib/.framework/Versions//”
ERROR: no file at “QtNetwork.framework/Versions/4/QtNetwork (compatibility version 4.3.0, current version 4.3.1)/lib/.framework/Versions//”
ERROR: no file at “QtCore.framework/Versions/4/QtCore (compatibility version 4.3.0, current version 4.3.1)/lib/.framework/Versions//”

What’s wrong???

» Posted by David Johnson
 on Thursday, August 23, 2007 @ 17:26

I wrote my own script to do the same thing, plus some other stuff besides (making dmg package). . I’ll have to play around with this new tool.

If this tool were to be included with Qt, then it’s utility would be greatly enhanced by being a “standard” Qt tool. Are there any plans for this?

» Posted by David Johnson
 on Thursday, August 23, 2007 @ 17:32

Oh, forget to mention. In regards to Tanner’s question about data and resource files, I use an install target in the project file. Like so:

macx {
CONFIG += x86 ppc
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4
QMAKE_MAC_SDK = /Developer/SDKs/MacOSX10.4u.sdk

data.path = myapp.app/Contents/Resources
data.files = data/* mac/document.icns
misc.path = myapp.app/Contents
misc.files = mac/Info.plist mac/PkgInfo
doc.path = myapp.app/Contents/Resources/en.lproj
doc.files = doc/en/*.html

INSTALLS += data misc doc
}

» Posted by uuilly
 on Thursday, August 23, 2007 @ 20:12

I just spent 3 days blindly floundering through this process and now you tell me!!! ;)

Truth be told it’s good stuff to know. I’m happy this script is here though…

Also the qt-deployment-mac docs that tell you how to do the install_name_tooling are not clear as to what the working directory be during different steps. I could be a moron but it hung me up for a while… And judging from the mailing list I’m not the only one…

Thanks for the script…

» Posted by qtuser
 on Thursday, August 23, 2007 @ 20:39

Daniel, I too used the Qt Installer app to install Qt 4.3.1.

I wonder if that is the problem…

» Posted by Daniel
 on Friday, August 24, 2007 @ 06:24

The installer puts the frameworks into /Library/Frameworks. The otool seem to ignore the path.
I changed the shared.cpp, so the deploy app finds the frameworks (with qmake -query QT_INSTALL_LIBS), but there is still a issue then with the install_name_tool (I don’t know what’s wrong).

» Reply from Morten
 on Friday, August 24, 2007 @ 09:15
Morten

Daniel/qtuser: I updated deployqt to support getting the frameworks from /Library/Frameworks. (deploying other framworks than Qt is still not supported)

There are currently no plans for including this with Qt, but from the response I got here I see that it might be a good idea :)

» Posted by Will Stokes
 on Friday, August 24, 2007 @ 14:13

My personal preference would be to have install_name_tool like support built into qmake. I already use qmake with INSTALLS to copy over one dylib I need. If I could just get qmake to run a post link command (install_name_tool) on the copied executable so that it properly finds the dylib when you run the app then all things would be rosy. Besides, this would be the utopia of automation since if it worked with XCode then it work occur automatically every time I build my app. As it stands while Qt Installer app is nifty, it still requires being run by hand which is a pain.

» Posted by qtuser
 on Friday, August 24, 2007 @ 14:58

Thanks Morton!

The new version seems to work. My app went from 28 megs to 58megs (and opening the package shows all the Qt frameworks (sql,xml,network,script). I don’t have a non-qt installed machine to test this out on.

So does this mean all I have to do to send a version of my app to another person (that does not have Qt libs on their machine) is to run this deploy tool and email them my app?

You are making things TOO easy :)

» Posted by qtuser
 on Friday, August 24, 2007 @ 15:09

I was thinking about ways to automate this further and one solution is apple’s tool called “Automator”.

In it you can visual write a “Script” that will send the deploy tool command via Terminal as well as copy the app to a desired final desitnation then launch a DMG creator app like DropDMG and upload it to a ftp site via one of many scriptable ftp clients on the Mac.

Of course all this can be done with a right click option in the finder since Automator allows for its scripts to be accessed from there as well.

Hope this helps.

Thanks again Morton.

» Posted by Daniel
 on Saturday, August 25, 2007 @ 07:46

Now it seems to work, thank you. But if I start my app on a another computer, it crashes.
The log says: … can’t open the library: QtCore.framework/Versions/4/QtCore (No such file or directory, errno = 2)

» Posted by Alex Popadich
 on Tuesday, August 28, 2007 @ 22:11

My application was also crashing with a … can’t open the library: QtCore.framework/Versions/4/QtCore. I use the binary installer for Qt installation. What I noticed was that the dependent frameworks were not being properly modified with the install_name_tool becaus they were not being referenced properly, in order to remedy this in the method deployQtFrameworks modify the line that reads:

const QString oldBinaryId = dependency.frameworkPath + “/” + dependency.binaryPath;
to:
const QString oldBinaryId = dependency.frameworkName + “/” + dependency.binaryPath;

and rebuild the deployqt tool. This did the trick for me.

Hope this helps.

» Posted by Daniel
 on Wednesday, August 29, 2007 @ 05:49

Thank you Alex. You did it.
Now it works.

» Reply from Morten
 on Wednesday, August 29, 2007 @ 14:45
Morten

I’ve updated the zip file to include this bugfix.
Alex: Thanks for the patch :)

» Posted by Nishant
 on Friday, August 31, 2007 @ 09:39

the first time i had a look at the qt docs about the install_name_tool stuff i new that i had to make a automatic utility for it. so i made
a similar utility 2 months ago.

i would advise u to keep the qt library files outside the app package to make the pakage size small. I keep the qt libs outside the pakage
just like in windows we have dll files. this helps when u need to distribute the updated app to your users, and users really dont want a
heay download.

» Posted by Manoj
 on Wednesday, September 12, 2007 @ 13:09

This is really a wonderful tool and saves us from a lot of hassle. I think, still this tool needs some update and requires to work perfectly for QT plugins. I am using it as follows:
./deployqt MyApplication.app ./Plugins
Where ./Plugins is a folder in the folder where MyApplication.app resides. The plugin folder contains libqjpeg.dylib (imageformats/libqjpeg.dylib) and it is not being copied by deployqt tool. If I put libqjpeg.dylib directly into Plugins folder (removing imageformats folder from the hierarchy), it copies the plugin into application plugins folder but now the application is not able to find the plugin.
I think, the utility should be updated in such a way that it works recursively for all folders in plugins folder. I will work on it, and someone has already worked upon, please let me know.



© 2008 Nokia Corporation and/or its subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation in Finland and/or other countries worldwide.
All other trademarks are property of their respective owners.