Qt Mac 应用程序无法创建独立的应用程序包(Qt Creator 构建)
Qt Mac Application Failed to Create Self-contained App Bundle (Qt Creator Build)
我将 Qt Creator 3.6.1
与 Qt 5.6.0 (Clang 7.0 (Apple), 64 bit)
一起使用,但在尝试创建用于部署的应用程序包时遇到了一些问题。
注:应用名称为bibi
Qt Creator
成功在 build-bibi-Desktop_Qt_5_6_0_clang_64bit-Release/
文件夹下生成 bibi.app
- 这个
bibi.app
未能 link Qt 在另一个 Mac 上成功
macdeployqt
没有解决问题
详情如下:
当 运行 bibi.app
在另一个 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)
树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
谢谢。
问题已解决
谢谢scott,问题解决了。以下是我未能成功创建独立应用程序包的原因:
otool -L
没有解析@rpath,我很困惑,因为它总是返回相同的输出
- 缺乏测试包是否已经包含所有框架的方法
总之,可以使用Scott的otool-rpath
、lsof
或者设置DYLD_PRINT_LIBRARIES
和DYLD_PRINT_TO_FILE
来解决问题。而且,我写了一个详细说明here。
假设您使用 qt-unified-max-x64-online.dmg 安装程序并将 Qt 安装到 $HOME/Qt
。您可以使用以下方法构建您的项目:
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)
这会创建一个应用程序包,但它会 NOT 运行 在普通用户的机器上。
查看包中隐藏的 Mach-O 可执行文件中的 RPATH:
otool-rpath ./*.app/Contents/MacOS/*
/Users/user/Qt/5.6/clang_64/lib
我在这里使用的是我自己编写的一个小 otool-rpath 脚本,用于说明目的。
RPATH 加上上面 otool -L
输出中列出的安装名称构成了动态链接器,dyld
,在 /Users/user/Qt/5.6/clang_64/lib
下寻找 Qt 框架。因此,它 NOT 对没有在同一位置安装 Qt 的用户有效。
要改变它,运行 Qt 的 macdeployqt
工具:
$QT_BIN_DIR/macdeployqt ./*.app -verbose=3 -always-overwrite -appstore-compliant
查看示例 macdeployqt
日志 here。
macdeployqt
创建独立的应用程序包。观察可执行文件中的 RPATH 如何从 /Users/user/Qt/5.6/clang_64/lib
变为 @executable_path/../Frameworks
:
otool-rpath ./*.app/Contents/MacOS/*
@executable_path/../Frameworks
@executable_path
做了显而易见的事情,并在 运行 时扩展了 dyld
到 bibi.app/Contents/MacOS
。可执行文件中的 RPATH 和安装名称一起使捆绑包中的动态链接在 运行 时起作用。
进一步阅读
您可以通过设置 DYLD_PRINT_LIBRARIES
和 DYLD_PRINT_TO_FILE
来获取动态链接器如何查找库的日志。 Example log. See dyld(1).
您可以使用 lsof -p $PID | grep QtCore
检查您的应用在 运行 时实际使用的框架副本。 Example log.
- Run-Path Dependent Libraries
- @executable path, @load path and @rpath
参考资料
关键字:“RPATH”,“INSTALL NAME”,“Mach-O动态链接".
请注意,ELF 中的 RPATH 具有细微不同的语义。
我将 Qt Creator 3.6.1
与 Qt 5.6.0 (Clang 7.0 (Apple), 64 bit)
一起使用,但在尝试创建用于部署的应用程序包时遇到了一些问题。
注:应用名称为bibi
Qt Creator
成功在build-bibi-Desktop_Qt_5_6_0_clang_64bit-Release/
文件夹下生成bibi.app
- 这个
bibi.app
未能 link Qt 在另一个 Mac 上成功
macdeployqt
没有解决问题
详情如下:
当 运行 bibi.app
在另一个 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)
树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
谢谢。
问题已解决
谢谢scott,问题解决了。以下是我未能成功创建独立应用程序包的原因:
otool -L
没有解析@rpath,我很困惑,因为它总是返回相同的输出- 缺乏测试包是否已经包含所有框架的方法
总之,可以使用Scott的otool-rpath
、lsof
或者设置DYLD_PRINT_LIBRARIES
和DYLD_PRINT_TO_FILE
来解决问题。而且,我写了一个详细说明here。
假设您使用 qt-unified-max-x64-online.dmg 安装程序并将 Qt 安装到 $HOME/Qt
。您可以使用以下方法构建您的项目:
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)
这会创建一个应用程序包,但它会 NOT 运行 在普通用户的机器上。
查看包中隐藏的 Mach-O 可执行文件中的 RPATH:
otool-rpath ./*.app/Contents/MacOS/*
/Users/user/Qt/5.6/clang_64/lib
我在这里使用的是我自己编写的一个小 otool-rpath 脚本,用于说明目的。
RPATH 加上上面 otool -L
输出中列出的安装名称构成了动态链接器,dyld
,在 /Users/user/Qt/5.6/clang_64/lib
下寻找 Qt 框架。因此,它 NOT 对没有在同一位置安装 Qt 的用户有效。
要改变它,运行 Qt 的 macdeployqt
工具:
$QT_BIN_DIR/macdeployqt ./*.app -verbose=3 -always-overwrite -appstore-compliant
查看示例 macdeployqt
日志 here。
macdeployqt
创建独立的应用程序包。观察可执行文件中的 RPATH 如何从 /Users/user/Qt/5.6/clang_64/lib
变为 @executable_path/../Frameworks
:
otool-rpath ./*.app/Contents/MacOS/*
@executable_path/../Frameworks
@executable_path
做了显而易见的事情,并在 运行 时扩展了 dyld
到 bibi.app/Contents/MacOS
。可执行文件中的 RPATH 和安装名称一起使捆绑包中的动态链接在 运行 时起作用。
进一步阅读
您可以通过设置
DYLD_PRINT_LIBRARIES
和DYLD_PRINT_TO_FILE
来获取动态链接器如何查找库的日志。 Example log. See dyld(1).您可以使用
lsof -p $PID | grep QtCore
检查您的应用在 运行 时实际使用的框架副本。 Example log.- Run-Path Dependent Libraries
- @executable path, @load path and @rpath
参考资料
关键字:“RPATH”,“INSTALL NAME”,“Mach-O动态链接".
请注意,ELF 中的 RPATH 具有细微不同的语义。