首页 文章

无法在 OS X 上使用 Qt 框架签署应用程序包 10.10

提问于
浏览
4

我在签署基于 Qt 的应用程序 un OS X 时遇到问题。我正在使用 Qt 5.3.2.

我已经阅读了包含矛盾信息的各种信息来源。

以下是运行bin/macdeployqt Qt 实用程序后应用程序包的内容

SimpleHello.app/
    Contents/
        Info.plist
        PkgInfo
        Frameworks/
            QtCore.framework/
                Resources/
                Versions/
                    5/
                        QtCore
            QtGui.framework/  ... same as Qt core
            QtPrintSupport.framework/  ... same as Qt core
            QtWidgets.framework/  ... same as Qt core
        MacOS/
            SimpleHello
        PlugIns/ ... some plugins
        Resources/
            empty.lproj
            qt.conf

第一:

我试过了:http://successfulsoftware.net/2012/08/30/how-to-sign-your-mac-os-x-app-for-gatekeeper/

但是,它似乎在 OS X 10.10 Yosemite 中无效

第二:

我试过了:签署 OSX 框架 10.9

我能够在没有任何错误的情况下签署整个应用程序。但是,当运行spctl来验证应用程序的有效性时,我得到了

spctl -a -vvvv SimpleHello.app
SimpleHello.app/: rejected
source=obsolete resource envelope
origin=Developer ID Application: MY CERTIFICATE

另外,在使用 codesign 验证签名时,我得到:

codesign --verify --deep --verbose=4 SimpleHello.app
--prepared:/My/Path/SimpleHello.app/Contents/Frameworks/QtCore.framework
--validated:/My/Path/SimpleHello.app/Contents/Frameworks/QtCore.framework
SimpleHello.app/: embedded framework contains modified or invalid version
In subcomponent: /My/Path/SimpleHello.app/Contents/Frameworks/QtCore.framework

第三:

在代码签名验证中添加--no-strict选项根据:导出存档时出错

它修复了代码签名验证的问题,但没有解决spctl问题。

向前:

我在签署框架时尝试添加--no-legacy-signing选项。但是,在验证捆绑签名时(包括codesignspctl)我收到此错误

codesign --verify --deep --verbose=4 SimpleHello.app
SimpleHello.app/: code has no resources but signature indicates they must be present

第五:

根据以下内容修改框架结构:http://qt-project.org/forums/viewthread/47768https://gist.github.com/kingcheez/6154462d7734e0c0f3a4

在这种情况下,我在尝试签署框架时遇到此错误

SimpleHello.app/Contents/Frameworks/QtCore.framework: unsealed contents present in the root directory of an embedded framework
SimpleHello.app/Contents/Frameworks/QtGui.framework: unsealed contents present in the root directory of an embedded framework
SimpleHello.app/Contents/Frameworks/QtPrintSupport.framework: unsealed contents present in the root directory of an embedded framework
SimpleHello.app/Contents/Frameworks/QtWidgets.framework: unsealed contents present in the root directory of an embedded framework

编辑:似乎unsealed contents present in the root directory of an embedded framework的问题是因为其中一个 simlink 格式不正确。它是:

QtCore.framework.framework/Versions/Current -> 5/

代替

QtCore.framework.framework/Versions/Current -> 5

在这个修复之后,我仍然得到与第六相同的结果。

第六:

在为框架调用codesign时添加了--no-strict选项。我能够签署所有框架,除了一个

SimpleHello.app//Contents/Frameworks/QtCore.framework: signed bundle with Mach-O thin (x86_64) [.]
SimpleHello.app//Contents/Frameworks/QtGui.framework: signed bundle with Mach-O thin (x86_64) [.]
SimpleHello.app//Contents/Frameworks/QtPrintSupport.framework: code object is not signed at all
In subcomponent: /My/Path/SimpleHello.app/Contents/Frameworks/QtPrintSupport.framework/Versions/Current/QtPrintSupport
SimpleHello.app//Contents/Frameworks/QtWidgets.framework: signed bundle with Mach-O thin (x86_64) [.]

第七:

我发布了这个问题,因为我不知道该找什么

2 回答

  • 3

    在进一步挖掘之后,我弄清楚第七节中的问题是什么:一些 Qt 框架在 Info.plist 文件中包含错误信息(框架名称以_debug 结尾)

    我推出了这个修复所有问题的脚本(还有一些硬编码的值可能会通过对脚本的一些改进来处理)

    #!/bin/bash
    # Script name: deploy.sh
    
    # Following environment variables must be defined:
    # - QT_FRAMEWORK_PATH
    # - QT_BIN_PATH
    # - CERTIFICATE
    # - FRAMEWORKS
    # - BAD_FRAMEWORKS
    
    # retrieve bundle name from first parameter
    BUNDLE_NAME=$1
    
    # Run QT tool to deploy
    ${QT_BIN_PATH}/macdeployqt $BUNDLE_NAME
    
    # FIX ISSUE 6
    # Please note that Qt5 frameworks have incorrect layout after SDK build, so this isn't just a problem with `macdeployqt` but whole framework assembly part.
    # Present
    #   QtCore.framework/
    #       Contents/
    #           Info.plist
    #       QtCore    -> Versions/Current/QtCore
    #       Versions/
    #           Current -> 5
    #           5/
    #               QtCore
    # After macdeployqt
    #   QtCore.framework/
    #       Resources/
    #       Versions/
    #           5/
    #               QtCore
    #
    # Expected
    #   QtCore.framework/
    #       QtCore    -> Versions/Current/QtCore
    #       Resources -> Versions/Current/Resources
    #       Versions/
    #           Current -> 5
    #           5/
    #               QtCore
    #               Resources/
    #                   Info.plist
    # So in order to comply with expected layout: https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html
    
    for CURRENT_FRAMEWORK in ${FRAMEWORKS}; do
        echo "Processing framework: ${CURRENT_FRAMEWORK}"
    
        echo "Deleting existing resource folder"
        rmdir ${BUNDLE_NAME}/Contents/Frameworks/${CURRENT_FRAMEWORK}.framework/Resources
    
        echo "create resource folder"
        mkdir -p ${BUNDLE_NAME}/Contents/Frameworks/${CURRENT_FRAMEWORK}.framework/Versions/5/Resources
    
        echo "create copy resource file"
        cp ${QT_FRAMEWORK_PATH}/${CURRENT_FRAMEWORK}.framework/Contents/Info.plist $BUNDLE_NAME/Contents/Frameworks/${CURRENT_FRAMEWORK}.framework/Versions/5/Resources/
    
        echo "create symbolic links"
        ln -nfs 5                                     ${BUNDLE_NAME}/Contents/Frameworks/${CURRENT_FRAMEWORK}.framework/Versions/Current
        ln -nfs Versions/Current/${CURRENT_FRAMEWORK} ${BUNDLE_NAME}/Contents/Frameworks/${CURRENT_FRAMEWORK}.framework/${CURRENT_FRAMEWORK}
        ln -nfs Versions/Current/Resources            ${BUNDLE_NAME}/Contents/Frameworks/${CURRENT_FRAMEWORK}.framework/Resources
    done
    
    # FIX ISSUE 7
    echo "***** Correct Frameworks Info.plist file*****"
    
    for CURRENT_FRAMEWORK in ${BAD_FRAMEWORKS}; do
        echo "Correcting bad framework Info.plist: ${CURRENT_FRAMEWORK}"
        TMP=$(sed 's/_debug//g' ${BUNDLE_NAME}/Contents/Frameworks/${CURRENT_FRAMEWORK}.framework/Resources/Info.plist)
        echo "$TMP" > ${BUNDLE_NAME}/Contents/Frameworks/${CURRENT_FRAMEWORK}.framework/Resources/Info.plist
    done
    
    # SIGNING FIXED FRAMEWORK
    CODESIGN_OPTIONS="--verbose=4"
    
    #echo "******* Sign QtWebEngineProcess ***********"
    #codesign --force --verify ${CODESIGN_OPTIONS} --sign "$CERTIFICATE" $BUNDLE_NAME/Contents/Frameworks/QtWebEngineCore.framework/Versions/Current/Helpers/QtWebEngineProcess.app
    echo "******* Sign Frameworks-subApps ***********"
    codesign --force --verify ${CODESIGN_OPTIONS} --sign "$CERTIFICATE" $BUNDLE_NAME/Contents/Frameworks/*.framework/Versions/*/*/*.app
    
    echo "******* Signing Frameworks ***********"
    for CURRENT_FRAMEWORK in ${FRAMEWORKS}; do
        echo "Signing framework: ${CURRENT_FRAMEWORK}"
        codesign --force --verify ${CODESIGN_OPTIONS} --sign "$CERTIFICATE" $BUNDLE_NAME/Contents/Frameworks/${CURRENT_FRAMEWORK}.framework
    done
    
    # Sign plugins
    echo "******* Signing Plugins ***********"
    codesign --force --verify ${CODESIGN_OPTIONS} --sign "${CERTIFICATE}" ${BUNDLE_NAME}/Contents/Plugins/*/*.dylib
    
    # Sign bundle itself
    echo "******* Signing Bundle ***********"
    codesign --force --verify ${CODESIGN_OPTIONS} --sign "$CERTIFICATE" $BUNDLE_NAME
    
    # Verify
    
    echo "******* Verify Bundle ***********"
    codesign --verify --deep ${CODESIGN_OPTIONS} $BUNDLE_NAME
    
    echo "******* Verify Bundle using dpctl ***********"
    spctl -a -vvvv $BUNDLE_NAME
    

    至于调用脚本:

    # Define environment variables
    export QT_FRAMEWORK_PATH=/Path/To/Qt_5.3.2/5.3/clang_64/lib
    export QT_BIN_PATH=/Path/To/Qt_5.3.2/5.3/clang_64/bin
    export CERTIFICATE="Developer ID Application: My Certificate"
    export FRAMEWORKS="QtCore QtGui QtPrintSupport QtWidgets"
    export BAD_FRAMEWORKS="QtPrintSupport"
    
    # Call itself
    deploy.sh SimpleHello.app
    

    使用此脚本,最终输出为:

    SimpleHello.app/: accepted
    source=Developer ID
    origin=Developer ID Application: My Certificate (HASH)
    
  • 0

    我运行 macdeployqt 后运行类似于此的脚本:

    #!/bin/bash
    
    #copy .plist files to frameworks
    cp "/usr/local/Trolltech/Qt-4.8.5/lib/QtCore.framework/Contents/Info.plist" "SimpleHello.app/Contents/Frameworks/QtCore.framework/Resources/Info.plist"
    #copy folders to proper location
    cp -r "SimpleHello.app/Contents/Frameworks/QtCore.framework/Resources" "SimpleHello.app/Contents/Frameworks/QtCore.framework/Versions/4/Resources"
    #delete old folders
    rm -rf "SimpleHello.app/Contents/Frameworks/QtCore.framework/Resources"
    #create symlinks
    ln -s "Versions/4/Resources" "SimpleHello.app/Contents/Frameworks/QtCore.framework/Resources"
    

    之后,我使用:

    codesign --deep -f -s
    

    它工作正常,只需以类似的方式添加缺少的框架。我没有用 qt 5 尝试过,但它可能适用于它。

相关问题