I'm using Qt Creator 3.6.1
with Qt 5.6.0 (Clang 7.0 (Apple), 64 bit)
, and I encountered some problems while trying to create an app bundle for deployment.
Note: the app name is called bibi
Qt Creator
successfully generated bibi.app
under build-bibi-Desktop_Qt_5_6_0_clang_64bit-Release/
folderbibi.app
failed to link Qt successfully on the other Macmacdeployqt
doesn't solve the problemFollowings are the details:
Error screenshot when running bibi.app
on the other Mac:
otool
> otool -L build-bibi-Desktop_Qt_5_6_0_clang_64bit-Release/bibi.app/Contents/MacOS/bibi
build-bibi-Desktop_Qt_5_6_0_clang_64bit-Release/bibi.app/Contents/MacOS/bibi:
@rpath/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.6.0, current version 5.6.0)
@rpath/QtGui.framework/Versions/5/QtGui (compatibility version 5.6.0, current version 5.6.0)
@rpath/QtCore.framework/Versions/5/QtCore (compatibility version 5.6.0, current version 5.6.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/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
macdeployqt
> which macdeployqt
/Users/<myusername>/Qt/5.6/clang_64/bin/macdeployqt
> macdeployqt bibi.app
> otool -L bibi.app/Contents/MacOS/bibi
bibi.app/Contents/MacOS/bibi:
@rpath/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.6.0, current version 5.6.0)
@rpath/QtGui.framework/Versions/5/QtGui (compatibility version 5.6.0, current version 5.6.0)
@rpath/QtCore.framework/Versions/5/QtCore (compatibility version 5.6.0, current version 5.6.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/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
tree bibi.app
bibi.app
├── Contents
│ ├── Frameworks
│ │ ├── QtCore.framework
│ │ │ ├── QtCore -> Versions/Current/QtCore
│ │ │ ├── Resources -> Versions/Current/Resources
│ │ │ └── Versions
│ │ │ ├── 5
│ │ │ │ ├── QtCore
│ │ │ │ └── Resources
│ │ │ │ └── Info.plist
│ │ │ └── Current -> 5
│ │ ├── QtDBus.framework
│ │ │ ├── QtDBus -> Versions/Current/QtDBus
│ │ │ ├── Resources -> Versions/Current/Resources
│ │ │ └── Versions
│ │ │ ├── 5
│ │ │ │ ├── QtDBus
│ │ │ │ └── Resources
│ │ │ │ └── Info.plist
│ │ │ └── Current -> 5
│ │ ├── QtGui.framework
│ │ │ ├── QtGui -> Versions/Current/QtGui
│ │ │ ├── Resources -> Versions/Current/Resources
│ │ │ └── Versions
│ │ │ ├── 5
│ │ │ │ ├── QtGui
│ │ │ │ └── Resources
│ │ │ │ └── Info.plist
│ │ │ └── Current -> 5
│ │ ├── QtPrintSupport.framework
│ │ │ ├── QtPrintSupport -> Versions/Current/QtPrintSupport
│ │ │ ├── Resources -> Versions/Current/Resources
│ │ │ └── Versions
│ │ │ ├── 5
│ │ │ │ ├── QtPrintSupport
│ │ │ │ └── Resources
│ │ │ │ └── Info.plist
│ │ │ └── Current -> 5
│ │ └── QtWidgets.framework
│ │ ├── QtWidgets -> Versions/Current/QtWidgets
│ │ ├── Resources -> Versions/Current/Resources
│ │ └── Versions
│ │ ├── 5
│ │ │ ├── QtWidgets
│ │ │ └── Resources
│ │ │ └── Info.plist
│ │ └── Current -> 5
│ ├── Info.plist
│ ├── MacOS
│ │ └── bibi
│ ├── PkgInfo
│ ├── PlugIns
│ │ ├── imageformats
│ │ │ ├── libqdds.dylib
│ │ │ ├── libqgif.dylib
│ │ │ ├── libqicns.dylib
│ │ │ ├── libqico.dylib
│ │ │ ├── libqjpeg.dylib
│ │ │ ├── libqtga.dylib
│ │ │ ├── libqtiff.dylib
│ │ │ ├── libqwbmp.dylib
│ │ │ └── libqwebp.dylib
│ │ ├── platforms
│ │ │ └── libqcocoa.dylib
│ │ └── printsupport
│ │ └── libcocoaprintersupport.dylib
│ └── Resources
│ ├── empty.lproj
│ └── qt.conf
└── Icon\r
38 directories, 32 files
Thanks.
Thanks scottt, and the problem is solved. Here are the reasons I failed to create self-contained app bundle successfully:
otool -L
didn't resolve @rpath, and I was confused since it always returned me the same outputIn short, the problem can be solve by using Scott's otool-rpath
, lsof
, or setting DYLD_PRINT_LIBRARIES
and DYLD_PRINT_TO_FILE
. And, I've written a note with details here.
Assuming you used the qt-unified-max-x64-online.dmg installer and installed Qt into $HOME/Qt
. You can build your project with:
cd MY-QT-PROJECT
QT_BIN_DIR=$HOME/Qt/5.6/clang_64/bin
make clean
$QT_BIN_DIR/qmake -config release
make -j$(getconf NPROCESSORS_ONLN)
This creates an app bundle but it would NOT run on regular users' machines.
Look at the RPATH in the Mach-O executable buried in the bundle:
otool-rpath ./*.app/Contents/MacOS/*
/Users/user/Qt/5.6/clang_64/lib
I'm using a small otool-rpath script I wrote myself here for illustrative purposes.
That RPATH plus the install names listed in your otool -L
output above make the dynamic linker, dyld
, look for Qt frameworks under /Users/user/Qt/5.6/clang_64/lib
. Thus, it would NOT work for users who haven't installed Qt in the same location.
To change that, run Qt’s macdeployqt
tool:
$QT_BIN_DIR/macdeployqt ./*.app -verbose=3 -always-overwrite -appstore-compliant
See an example macdeployqt
log here.
macdeployqt
creates self-contained app bundles. Observe how the RPATH in the executable changed from /Users/user/Qt/5.6/clang_64/lib
to @executable_path/../Frameworks
:
otool-rpath ./*.app/Contents/MacOS/*
@executable_path/../Frameworks
@executable_path
does the obvious thing and is expanded by dyld
to bibi.app/Contents/MacOS
at run time. The RPATH in the executable and the install names together make dynamic linking within the bundle work at run time.
You can get a log of how the dynamic linker looks up libraries by setting DYLD_PRINT_LIBRARIES
and DYLD_PRINT_TO_FILE
. Example log. See dyld(1).
You can use lsof -p $PID | grep QtCore
to inspect which copy of the framework is actually used by your app at run-time. Example log.
Keywords: "RPATH", "INSTALL NAME", "Mach-O dynamic linking".
Note that RPATH in ELF has subtlely different semantics.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With