Qt Mac应用程序无法创建自包含应用程序包(Qt Creator Build)

时间:2016-04-29 13:02:30

标签: macos qt dyld otool macdeployqt

我正在Qt Creator 3.6.1使用Qt 5.6.0 (Clang 7.0 (Apple), 64 bit),我在尝试创建应用包以进行部署时遇到了一些问题。

注意:应用名称称为bibi

  1. Qt Creatorbibi.app文件夹
  2. 下成功生成build-bibi-Desktop_Qt_5_6_0_clang_64bit-Release/
  3. bibi.app无法在其他Mac上成功链接Qt
  4. macdeployqt无法解决问题
  5. 以下是详细信息:

    在另一台Mac上运行bibi.app时出现错误屏幕截图:

    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
    

    感谢。

    解决问题

    谢谢scottt,问题解决了。以下是我无法成功创建自包含应用包的原因:

    • otool -L没有解决@rpath,我很困惑因为它总是给我输出相同的输出
    • 缺乏测试捆绑包是否已经自包含所有框架的方法

    简而言之,可以使用Scott的otool-rpathlsof或设置DYLD_PRINT_LIBRARIESDYLD_PRINT_TO_FILE来解决问题。而且,我已经写了一份详细信息here

1 个答案:

答案 0 :(得分:5)

假设您使用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框架。因此,对于未在同一位置安装Qt的用户, NOT 工作。

要更改它,请运行Qt的macdeployqt工具:

$QT_BIN_DIR/macdeployqt ./*.app -verbose=3 -always-overwrite -appstore-compliant

查看示例macdeployqt log 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和安装名称一起使捆绑包内的动态链接在运行时工作。

进一步阅读

参考

关键字:“ RPATH ”,“安装名称”,“ Mach-O动态链接”。

请注意,ELF中的 RPATH 具有微妙的语义。