[Solved] Deploying Mac App (app bundle within app bundle)
-
I have a Mac application I'm attempting to deploy. It is contained in a standard Mac "bundle". In the Mac bundle I have a "support app" which is also a standard Mac bundle. Essentially an app bundle within an app bundle.
@
Main.app
v ContentsFramework
v MacOS
Database
Graphics
Help
Support.app
Main
Resources
@When I run or debug in the Qt Creator development environment, both the Main app and the Support app work fine and as expected.
The Support app is a process that gets launched by Main.
I packaged everything with the "macdeployqt" tool with the following command:
@
macdeployqt Main.app -dmg
@When deployed on a Mac without the Qt development environment, the Main app works fine..it knows where the deployed Qt Framework Libraries are located. The Support app does not and throws the following Error message:
@
Dyld Error Message:
Library not loaded: QtGui.framework/Versions/4/QtGui
Referenced from: /Volumes/Main/Main.app/Contents/MacOS/Support.app/Contents/MacOS/Support
Reason: image not found
@I used the "otool" to check the application dependancies and got the following output.
@
Last login: Sun Feb 5 09:51:34 on ttys000
My-Mac-mini:~ PSI$ cd '/Users/PSI/Projects/Qt-SFAX-4.7.2/SFA-build-desktop/'My-Mac-mini:SFA-build-desktop PSI$ otool -L Main.app/Contents/MacOs/Main
Main.app/Contents/MacOs/Main:
QtWebKit.framework/Versions/4/QtWebKit (compatibility version 4.7.0, current version 4.7.0)
QtXml.framework/Versions/4/QtXml (compatibility version 4.7.0, current version 4.7.0)
QtGui.framework/Versions/4/QtGui (compatibility version 4.7.0, current version 4.7.0)
QtNetwork.framework/Versions/4/QtNetwork (compatibility version 4.7.0, current version 4.7.0)
QtCore.framework/Versions/4/QtCore (compatibility version 4.7.0, current version 4.7.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 625.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)My-Mac-mini:SFA-build-desktop PSI$ otool -L Main.app/Contents/MacOs/Support.app/Contents/MacOs/Support
Main.app/Contents/MacOs/Support.app/Contents/MacOs/Support:
QtGui.framework/Versions/4/QtGui (compatibility version 4.7.0, current version 4.7.0)
QtNetwork.framework/Versions/4/QtNetwork (compatibility version 4.7.0, current version 4.7.0)
QtCore.framework/Versions/4/QtCore (compatibility version 4.7.0, current version 4.7.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 625.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)My-Mac-mini:SFA-build-desktop PSI$
@
Is my problem that I just need to tell the Support app where the Qt Framework is located at deploy time by using the "install_name_tool -id" and "install_name_tool -change" commands as outlined in the article at http://developer.qt.nokia.com/doc/qt-4.8/deployment-mac.html ?Something like..
@
install_name_tool -id @executable_path/../../../../Frameworks/QtGui.framework/Versions/4/QtGui
Support.app/../../../../Frameworks/QtGui.framework/Versions/4/QtGuiinstall_name_tool -change QtGui.framework/Versions/4/QtGui
@executable_path/../../../../Frameworks/QtGui.framework/Versions/4/QtGui
Support.app/Contents/MacOs/Support
@..or is there a better way to do this..maybe at compile or link time within the Qt Creator build??
Any help or suggestions would be appreciated.
-
You're right with your guess. It's just a matter of the correct paths to be passed to install_name_tool. Unfortunately, the macdeployqt tool doesn't support nested applications here, as it seems. I've never used macdeployqt, as I have my own set of scripts for doing that task (macdeployqt came up too late :) ). So, you'll have to manipulate the Support.app's paths manually.
-
Volker, thanks for the reply.
manipulate the Support.app’s paths manually.
By this, I assume you mean use the "install_name_tool -change" option to change the links in the Support.app by doing…@
$ install_name_tool -change
QtGui.framework/Versions/4/QtGui
@executable_path/../../../../Frameworks/QtGui.framework/Versions/4/QtGui
Support.app/Contents/MacOs/Support
$ install_name_tool -change
QtNetwork.framework/Versions/4/QtNetwork
@executable_path/../../../../Frameworks/QtNetwork.framework/Versions/4/QtNetwork
Support.app/Contents/MacOs/Support
$ install_name_tool -change
QtCore.framework/Versions/4/QtCore
@executable_path/../../../../Frameworks/QtCore.framework/Versions/4/QtCore
Support.app/Contents/MacOs/Support
@
Doing the above is similar to what's being done in the example at: http://developer.qt.nokia.com/doc/qt-4.8/deployment-mac.html ..so I did that.But I'm confused as to why the example does this:
"Finally, since the QtGui framework depends on QtCore, we must remember to change the reference for QtGui:"
@
install_name_tool -change
path/to/Qt/lib/QtCore.framework/Versions/4.0/QtCore
@executable_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore
plugandpaint.app/Contents/Frameworks/QtGui.framework/Versions/4.0/QtGui
@Since doing the -change above didn't make sense for my situation, I did not do that step. My assumption is that when I run the "macdeployqt" utility, that this is or will be done. My reason for making that assumption is that the Main.app runs fine when it is deployed to another Mac as a .dmg so the associations for QtCore and QtGui are established already.
I used the "otool -L" to verify that the changes were made. They were.
@
My-Mac-mini:MacOS PSI$ otool -L Support
Support:
@executable_path/../../../../Frameworks/QtGui.framework/Versions/4/QtGui (compatibility version 4.7.0, current version 4.7.0)
@executable_path/../../../../Frameworks/QtNetwork.framework/Versions/4/QtNetwork (compatibility version 4.7.0, current version 4.7.0)
@executable_path/../../../../Frameworks/QtCore.framework/Versions/4/QtCore (compatibility version 4.7.0, current version 4.7.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 625.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)
My-Mac-mini:MacOS PSI$
@I assumed that after making the "-changes" to the Support.app that I would be able to test it locally on in the Qt Creator environment.
When I run the Main.app which launches Support.app, I now get the following errors:
@
License::SupportAppReadCErr: "QCoreApplication::applicationDirPath: Please instantiate the QApplication object first
QObject: Cannot create children for a parent that is in a different thread.
(Parent is MainWindow(0x7fff5fbff870), parent's thread is QThread(0x10200cf90), current thread is QThread(0x101428b50)
QSocketNotifier: Can only be used with threads started with QThread"
@ -
macdeployqt should handle the case for changing the path in QtGui.framework - the paths look good to me.
Hm, the error looks strange. Seems that you do some initialization before your QApplication is created.
-
Not really solved. Gave up on the app bundle within app bundle concept.
Changed the helper app to be just a unix executable at the same level as the main app.
Manually changed the @executable_paths within the helper and all seems to work.