4
votes

I am having problems packaging my Qt app for Mac OS X.

I've read the documentation on Deploying an Application on Mac OS X but I'm still not sure what I'm doing wrong.

On my Mac, I have Qt5 installed on ~/Qt5.1.0/5.1.0/clang_64 (this is where the bin/ and lib/ folder resides)

I have a Qt application called "renamer" on ~/Documents/QtProjects/renamer/.

Using Qt Creator, I have built the release version of my application on ~/Documents/QtProjects/build-renamer-Desktop_Qt_5_1_0_clang_64bit-Release. So the first thing I did was run otool on my application:

$ cd ~/Documents/QtProjects/build-renamer-Desktop_Qt_5_1_0_clang_64bit-Release
$ otool -L renamer.app/Contents/MacOS/renamer

Here is the result:

renamer.app/Contents/MacOS/renamer:
    /Users/paul/Qt5.1.0//5.1.0/clang_64/lib/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.1.0, current version 5.1.0)
    /Users/paul/Qt5.1.0//5.1.0/clang_64/lib/QtGui.framework/Versions/5/QtGui (compatibility version 5.1.0, current version 5.1.0)
    /Users/paul/Qt5.1.0//5.1.0/clang_64/lib/QtCore.framework/Versions/5/QtCore (compatibility version 5.1.0, current version 5.1.0)
    /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 56.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)

The next thing I did was create a Frameworks directory inside my renamer.app bundle and copy the QtWidgets, QtGui and QtCore frameworks into the new directory:

$ cd ~/Documents/QtProjects/build-renamer-Desktop_Qt_5_1_0_clang_64bit-Release
$ mkdir renamer.app/Contents/Frameworks
$ cp -R ~/Qt5.1.0/5.1.0/clang_64/lib/QtCore.framework renamer.app/Contents/Frameworks
$ cp -R ~/Qt5.1.0/5.1.0/clang_64/lib/QtGui.framework renamer.app/Contents/Frameworks
$ cp -R ~/Qt5.1.0/5.1.0/clang_64/lib/QtWidgets.framework renamer.app/Contents/Frameworks

Then I ran install_name_tool to set the identification names for the QtWidgets, QtGui and QtCore frameworks:

$ cd ~/Documents/QtProjects/build-renamer-Desktop_Qt_5_1_0_clang_64bit-Release
$ install_name_tool -id @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore "renamer.app/Contents/Frameworks/QtCore.framework/Versions/5/QtCore"
$ install_name_tool -id @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui "renamer.app/Contents/Frameworks/QtGui.framework/Versions/5/QtGui"
$ install_name_tool -id @executable_path/../Frameworks/QtWidgets.framework/Versions/5/QtWidgets "renamer.app/Contents/Frameworks/QtWidgets.framework/Versions/5/QtWidgets"

Then I ensured that the application knows where to find the library:

$ cd ~/Documents/QtProjects/build-renamer-Desktop_Qt_5_1_0_clang_64bit-Release
$ install_name_tool -change /../Frameworks/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore "renamer.app/Contents/MacOS/renamer"
$ install_name_tool -change /../Frameworks/QtGui.framework/Versions/5/QtGui @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui "renamer.app/Contents/MacOS/renamer"
$ install_name_tool -change /../Frameworks/QtWidgets.framework/Versions/5/QtWidgets @executable_path/../Frameworks/QtWidgets.framework/Versions/5/QtWidgets "renamer.app/Contents/MacOS/renamer"

Finally, since the QtGui framework depends on QtCore and QtWidgets framework depends on QtGui/QtCore, I also changed the reference for QtGui and QtWidgets:

$ install_name_tool -change /../Frameworks/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore "renamer.app/Contents/Frameworks/QtGui.framework/Versions/5/QtGui"
$ install_name_tool -change /../Frameworks/QtGui.framework/Versions/5/QtGui @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui "renamer.app/Contents/Frameworks/QtWidgets.framework/Versions/5/QtWidgets"
$ install_name_tool -change /../Frameworks/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore "renamer.app/Contents/Frameworks/QtWidgets.framework/Versions/5/QtWidgets"

However, when I run otool -L renamer.app/Contents/MacOS/renamer again afterwards, nothing changes and I get the same output as before:

renamer.app/Contents/MacOS/renamer:
    /Users/paul/Qt5.1.0//5.1.0/clang_64/lib/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.1.0, current version 5.1.0)
    /Users/paul/Qt5.1.0//5.1.0/clang_64/lib/QtGui.framework/Versions/5/QtGui (compatibility version 5.1.0, current version 5.1.0)
    /Users/paul/Qt5.1.0//5.1.0/clang_64/lib/QtCore.framework/Versions/5/QtCore (compatibility version 5.1.0, current version 5.1.0)
    /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 56.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)

I thought that running otool -L renamer.app/Contents/MacOS/renamer would change the output to the new Qt paths, but it is still the same. I thought I followed all the steps, but it doesn't work. Did I miss a step or do something wrong? I am able to successfully deploy my program on Windows without a problem, but I'm having trouble on the Mac. How can I make it so that running otool will display the newly set path for finding the QtCore, QtGui and QtWidgets framework from within my renamer.app bundle?

I also tried to use macdeployqt to deploy my app, but my app doesn't work when I rename/remove the Qt library installed under ~/Qt5.1.0/5.1.0/clang_64. I tried the commands sudo macdeployqt renamer.app under my project folder after adding /bin to my PATH. The macdeployqt runs fine, but when I rename/remove Qt, my application no longer runs. I also ran otool after running macdeployqt, but the output hasn't changed. I think macdeployqt copies the necessary Qt libraries to the app bundle, but does not correctly change where to look for the qt libraries.

1
I installed Qt 5.1.1 this morning and was able to use macdeployqt to successfully deploy my app. Now when I rename/remove Qt, my app still runs without any problems.kimbaudi
I think install_name_tool does an exact string match, so if you use change but there's even a single character difference (and it's irrelevant if it were a path, like you have //) then it won't workStefano Borini

1 Answers

1
votes

As stefano pointed out in his comment install_name_tool can be very picky! You are using a path like /../Frameworks/QtCore.framework/Versions/5/QtCore when calling insall_name_tool while the reference should be /Users/paul/Qt5.10/etc. (exactly as shown by otool -L) However with Qt 5.2 using macdeployqt is much easier :)