[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 Contents

    Framework
    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/QtGui

    install_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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.