Problems with deploying for mac
-
I'm having problems using macdeployqt to set up my qt application. I've run it with various switches and still get the same result. Whenever I try to launch the program through the deployed bundle, it immediately crashes on QMainWindow::showMaximized(). If I run it through the console directly(so I can see stderr), I get the following messages:
@On Mac OS X, you might be loading two sets of Qt binaries into the same process. Check that all plugins are compiled against the right Qt binaries. Export DYLD_PRINT_LIBRARIES=1 and check that only one set of binaries are being loaded.
QObject::moveToThread: Current thread (0x10141dd30) is not the object's thread (0x103000c10).
Cannot move to target thread (0x10141dd30)@Looks pretty suspicious... I exported that environment variable and ran the program again on the console, but I don't see any qt libraries in the output from dyld so I haven't found that particularly helpful. I have also run otool -L on most of the frameworks and the executable, which indicated nothing out of the ordinary (all libraries@ were executable_path/../.*). Running otool -L on plugins however produces some interesting results. On PlugIns/imageformats/libqjpeg.dylib I see this in the l@ist:
@/Users/my_user/QtSDK/Desktop/Qt/4.8.1/gcc/plugins/imageformats/libqjpeg.dylib (compatibility version 0.0.0, current version 0.0.0)@
And of course if I run otool on that path, I see dependencies on:
@/Users/my_user/QtSDK/Desktop/Qt/4.8.1/gcc/plugins/imageformats/libqjpeg.dylib (compatibility version 0.0.0, current version 0.0.0)
/Users/my_user/QtSDK/Desktop/Qt/4.8.1/gcc/lib/QtGui.framework/Versions/4/QtGui (compatibility version 4.8.0, current version 4.8.1)
/Users/my_user/QtSDK/Desktop/Qt/4.8.1/gcc/lib/QtCore.framework/Versions/4/QtCore (compatibility version 4.8.0, current version 4.8.1)
/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 123.0.0)@I assume this is where the loading two sets of Qt binaries comes from but I'm not sure how to fix it. Any suggestions?
-
You don't want any dependencies on dylibs / framewoirks with absolute paths other than the system ones. The plugins don't seem to be updated by macdeployqt to point to the right version of Qt (which is the one in the .app bundle, and should be referenced using @executable_path or something of this order).
You can either rely on macdeployqt (and find the proper flags), or use otool yourself which was my way of doing those things on Mac OS X. -
I'm not sure if I made it clear enough in my original post, but the plugin libqjpeg.dylib is linked to itself using the absolute path. Macdeployqt fixes the links to QtGui and QtCore but doesn't fix the self link. None of the macdeployqt flags seem to fix this so I guess I'm stuck with otool?
Why does it self link anyway? Is that a thing with dylibs (every dylib I've run otool on seems to do that)?
-
It is not a self link, it is the ID of the library. It is set with an absolute path. You should update it to be just libqjpeg.dylib using @install_name_tool -id libqjpeg.dylib libqjpeg.dylib@
The tool is install_name_tool, not otool sorry for the confusion. -
I fixed all of the plugins using install_name_tool. When I use otool I now get:
@libqjpeg.dylib (compatibility version 0.0.0, current version 0.0.0)
@executable_path/../Frameworks/QtGui.framework/Versions/4/QtGui (compatibility version 4.8.0, current version 4.8.1)
@executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore (compatibility version 4.8.0, current version 4.8.1)
/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 123.0.0)@However, it still doesn't work.
I've run otool again on all the plugins, frameworks, and the executable, I'm not seeing any obvious problems with the app bundle.
I'm still getting errors at the top though saying classes are defined in both the package dll and the /local/path/to/qt/ dlls so there must be a bad reference still somewhere :/.
-
QLibraryInfo seems to be indicating that the plugins are loading from the wrong location. It isn't respecting qt.conf(even though it's embedded as a resource in the path (/qt/etc/qt.conf). It also isn't respecting the QT_PLUGIN_PATH environment variable. The library info prints that I'm using are after a QApplication is created so it isn't that.
Here's a snippet:
@int main(int argc, char *argv[])
{
QApplication a(argc, argv);qDebug() << "CORE APPLICATION EXISTS: " << (QCoreApplication::instance() != NULL); qDebug() << "CORE APPLICATION PATH: " << QCoreApplication::applicationDirPath(); qDebug() << "qt.conf " << QFile::exists(QLatin1String(":/qt/etc/qt.conf")); qDebug() << "LIBRARIES LOADED: " << QCoreApplication::libraryPaths(); qDebug() << "PREFIX PATH" << QLibraryInfo::location(QLibraryInfo::PrefixPath); qDebug() << "PLUGINS PATH" << QLibraryInfo::location(QLibraryInfo::PluginsPath);@
Results in:
CORE APPLICATION EXISTS: true
CORE APPLICATION PATH: "/Users/my_user/my_app/MyApp.app/Contents/MacOS"
qt.conf true
LIBRARIES LOADED: ("/Users/my_user/QtSDK/Desktop/Qt/4.8.1/gcc/plugins", "/Users/my_user/my_app/MyApp.app/Contents/PlugIns", "/Users/my_user/my_app/MyApp.app/Contents/MacOS")
PREFIX PATH "/Users/my_user/QtSDK/Desktop/Qt/4.8.1/gcc"
PLUGINS PATH "/Users/my_user/QtSDK/Desktop/Qt/4.8.1/gcc/plugins"The middle entry on libraries loaded actually appears to be from the QT_PLUGIN_PATH export
EDIT: I figured out was wrong with qt.conf. I was calling QImageReader::supportedImageFormats() in global scope. Apparently it was causing QLibraryInfo to cache a bad QSettings object.