Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 签署OSX 10.9的框架_Macos_Qt_Code Signing - Fatal编程技术网

Macos 签署OSX 10.9的框架

Macos 签署OSX 10.9的框架,macos,qt,code-signing,Macos,Qt,Code Signing,使用macdeployqt后,我对我的应用程序进行签名,以避免网守问题 我可以在所有框架和捆绑包内的所有东西上使用codesign,但是当我对捆绑包进行签名时,我会遇到一个错误: $ codesign --force --verify --verbose --sign "Developer ID Application: My ID" MyApplication.app MyApplication.app: bundle format unrecognized, invalid, or unsu

使用
macdeployqt
后,我对我的应用程序进行签名,以避免网守问题

我可以在所有框架和捆绑包内的所有东西上使用
codesign
,但是当我对捆绑包进行签名时,我会遇到一个错误:

$ codesign --force --verify --verbose --sign "Developer ID Application: My ID" MyApplication.app
MyApplication.app: bundle format unrecognized, invalid, or unsuitable
In subcomponent: /Users/username/Dev/Apps/MyApplication/MyApplication.app/Contents/Frameworks/QtConcurrent.framework
如果我检查签名:

$codesign -vvv MyApplication.app/Contents/Frameworks/QtConcurrent.framework/Versions/5/QtConcurrent 
MyApplication.app/Contents/Frameworks/QtConcurrent.framework/Versions/5/QtConcurrent: valid on disk
MyApplication.app/Contents/Frameworks/QtConcurrent.framework/Versions/5/QtConcurrent: satisfies its Designated Requirement
据我所知,我似乎应该签署这样的框架包

$ codesign --force --verify --verbose --sign "Developer ID Application: My ID" MyApplication.app/Contents/Frameworks/QtConcurrent.framework/Versions/5
但这导致了

MyApplication.app/Contents/Frameworks/QtConcurrent.framework/Versions/5: bundle format unrecognized, invalid, or unsuitable

今天早上也犯了同样的错误。在OSX 10.9上,协同设计应用程序似乎更为严格

该问题是由macdeployqt未将Qt框架捆绑包的info.plist文件复制到应用捆绑包中引起的

您可以通过告诉脚本手动将文件复制到嵌入式框架的捆绑文件中来解决此问题

e、 g

在调用macdeployqt*之后,但在调用codesign之前,对应用程序使用的每个qt模块执行此操作。 (*或mkdir目标目录)

另外,在框架的文件夹上调用codesign,而不是在版本子文件夹上

i、 e

希望这有帮助。

非常感谢

您还必须对应用程序使用的所有插件进行签名

i、 e

致以最良好的祝愿


Rainer

我根据Benoît的答案编写了一个脚本,用于修补。应用程序:

守则:

#!/usr/bin/env ruby

# Copies missing Info.plist files for a .app's Qt frameworks installed
# from macdeployqt. Without the plists, 'codesign' fails on 10.9 with
# "bundle format unrecognized, invalid, or unsuitable".
#
# Example usage:
# ruby macdeployqt_fix_frameworks.rb /Users/me/Qt5.2.0/5.2.0/clang_64/ MyProgram.app
#
# Links:
# https://bugreports.qt-project.org/browse/QTBUG-23268
# http://stackoverflow.com/questions/19637131/sign-a-framework-for-osx-10-9
# http://qt-project.org/forums/viewthread/35312

require 'fileutils'

qtdir = ARGV.shift
dotapp = ARGV.shift

abort "Missing args." if !qtdir || !dotapp
abort "\"#{qtdir}\" invalid" if !File.exists?(qtdir) || !File.directory?(qtdir)
abort "\"#{dotapp}\" invalid" if !File.exists?(dotapp) || !File.directory?(dotapp)

frameworksDir = File.join(dotapp, 'Contents', 'Frameworks')
Dir.foreach(frameworksDir) do |framework|
next if !framework.match(/^Qt.*.framework$/)
fullPath = File.join(frameworksDir, framework)
destPlist = File.join(fullPath, 'Resources', 'Info.plist')
next if File.exists?(destPlist)
srcPlist = File.join(qtdir, 'lib', framework, 'Contents', 'Info.plist')
abort "Source plist not found: \"#{srcPlist}\"" if !File.exists?(srcPlist)
FileUtils.cp(srcPlist, destPlist)
end 
根据需要,您需要签署版本文件夹,而不是框架本身。我试过了,但遇到了两个问题。首先,Qt框架的一些Info.plist文件具有不正确的可执行文件名(a_debug后缀)。修复后,我成功地以“苹果方式”签署了所有框架。然而,在这样做之后,我无法对主应用程序进行签名,并且在我刚刚签名的Qt框架上出现了错误


因此,一个奇怪但有效的解决方案是对框架文件夹进行签名。即使Info.plist文件中的可执行文件名不正确,这也适用。

摘要

  • 通过将Info.plist移动到框架中当前版本级别的Resources文件夹,修复格式错误的Qt框架
  • 使用codesign--deep选项一次对包中的所有二进制文件(包括框架和插件)进行签名
  • 详细信息

    解决此问题的最简单方法是使用--deep代码设计选项。这个选项(我相信是在Mavericks中引入的)将对目标包中的所有二进制文件进行签名,包括主应用程序二进制文件及其框架和插件

    但是,在使用此选项(或任何其他建议的签名技术)之前,必须根据此线程上的其他帖子修复Qt框架。出于某种奇怪的原因,构建的Qt框架不符合苹果的框架规范,会混淆代码设计工具。这反过来会导致不良行为,如用已签名框架二进制文件的附加副本替换框架的顶级符号链接

    要修复Qt框架,您应该将Info.plist复制到框架特定版本的Resources文件夹中,而不是复制到框架的顶层(如前面所建议的)。此外,您可能希望在应用程序包框架中丢弃Info.plist的原始副本,因为它基本上位于错误的位置

    具体来说,您应该这样做,根据需要修复每个框架:

    mkdir -p MyKillerApp.app/Contents/Frameworks/QtCore.framework/Versions/Current/Resources
    cp lib/QtCore.framework/Contents/Info.plist MyKillerApp.app/Contents/Frameworks/QtCore.framework/Versions/Current/Resources
    rm -rf MyKillerApp.app/Contents/Frameworks/QtCore.framework/Contents
    
    以上假设框架中存在“版本/当前”符号链接。我认为所有构建的Qt库都是如此。但是如果您的构建不是这样,那么您可以使用特定的版本文件夹名称(如“4”),而不是“当前”符号链接

    规范化框架后,您可以使用--deep选项对应用程序包中的所有二进制文件进行签名:

    codesign --deep --force --verify --sign "Developer ID Application: My ID" MyKillerApp.app
    
    或者,如果已在项目级别为部署后处理启用了代码设计,则只需在“其他代码签名标志”中传递--deep选项即可:

    如果主应用程序的代码设计要求与框架或插件不同,可以使用一些技巧。首先,使用框架/插件需求使用--deep选项进行签名。然后可以使用--force选项再次签名,但不使用--deep选项,指定应用程序级别的要求。结果是,主应用程序将按照应用程序要求进行签名,所有子二进制文件将按照框架/插件要求进行签名


    这种方法可能被认为有点懒惰和浪费,因为您要对主应用程序进行两次签名。但是它比从主应用程序二进制文件中分别查找和签名所有子二进制文件更简单。

    我使用此脚本在代码签名之前更正QT 4.8框架。希望这有帮助。我和一位同事花了大约3-4天的时间才弄明白这一点(这是在QT发表博文之前)

    #我们需要改进qt框架,让它们通过新的代码设计进行代码设计
    #有关此$#@$!@的详细信息一块$@#$@$!
    # http://blog.qt.digia.com/blog/2014/10/29/an-update-on-os-x-code-signing/
    QT_LIB_DIR=$(qmake-query QT_INSTALL_LIBS)
    对于$中的i(查找“$APP/Contents/Frameworks/”-名称Qt\*.framework);做
    FW_NAME=$(basename“$i”)
    FW_SHORTNAME=$(basename-s.framework“$i”)
    mv“$i/Resources”“$i/Versions/4”
    ln-s版本/当前/资源“$i/”
    ln-s Versions/Current/${FW_SHORTNAME}“$i/${FW_SHORTNAME}”
    ln-s 4“$i/版本/当前”
    cp“${QT_LIB_DIR}/${FW_NAME}/Contents/Info.plist”“$i/Resources”
    chmod u+w“$i/Resources/Info.plist”
    #现在真正的魔法来了,我们必须在Info.plist中添加CbundLeIdentifier和CbundLeverVersion
    awk“/{print\”CbundleIdentifier\norg.qt项目。${FW_SHORTNAME}\“}1”“$i/Resources/Info.plist”>“$i/Resources/Info.plist.tmp”
    mv“$i/Resources/Info.plist.tmp”“$i/Resources/Info.plist”
    awk'/{print“CbundLeverVersion\n4.8”}1'$i/Resources/Info.plist“>“$i/Resources/Info.plist.tmp”
    mv“$i/资源/英寸
    
    #!/usr/bin/env ruby
    
    # Copies missing Info.plist files for a .app's Qt frameworks installed
    # from macdeployqt. Without the plists, 'codesign' fails on 10.9 with
    # "bundle format unrecognized, invalid, or unsuitable".
    #
    # Example usage:
    # ruby macdeployqt_fix_frameworks.rb /Users/me/Qt5.2.0/5.2.0/clang_64/ MyProgram.app
    #
    # Links:
    # https://bugreports.qt-project.org/browse/QTBUG-23268
    # http://stackoverflow.com/questions/19637131/sign-a-framework-for-osx-10-9
    # http://qt-project.org/forums/viewthread/35312
    
    require 'fileutils'
    
    qtdir = ARGV.shift
    dotapp = ARGV.shift
    
    abort "Missing args." if !qtdir || !dotapp
    abort "\"#{qtdir}\" invalid" if !File.exists?(qtdir) || !File.directory?(qtdir)
    abort "\"#{dotapp}\" invalid" if !File.exists?(dotapp) || !File.directory?(dotapp)
    
    frameworksDir = File.join(dotapp, 'Contents', 'Frameworks')
    Dir.foreach(frameworksDir) do |framework|
    next if !framework.match(/^Qt.*.framework$/)
    fullPath = File.join(frameworksDir, framework)
    destPlist = File.join(fullPath, 'Resources', 'Info.plist')
    next if File.exists?(destPlist)
    srcPlist = File.join(qtdir, 'lib', framework, 'Contents', 'Info.plist')
    abort "Source plist not found: \"#{srcPlist}\"" if !File.exists?(srcPlist)
    FileUtils.cp(srcPlist, destPlist)
    end 
    
    mkdir -p MyKillerApp.app/Contents/Frameworks/QtCore.framework/Versions/Current/Resources
    cp lib/QtCore.framework/Contents/Info.plist MyKillerApp.app/Contents/Frameworks/QtCore.framework/Versions/Current/Resources
    rm -rf MyKillerApp.app/Contents/Frameworks/QtCore.framework/Contents
    
    codesign --deep --force --verify --sign "Developer ID Application: My ID" MyKillerApp.app
    
    OTHER_CODE_SIGN_FLAGS = --deep
    
    # we need to massage qt frameworks so they get codesigned by the new codesign
    # more information about this $#@$!@# piece of $@#$@$!
    # http://blog.qt.digia.com/blog/2014/10/29/an-update-on-os-x-code-signing/
    
    QT_LIB_DIR=$(qmake -query QT_INSTALL_LIBS)
    for i in $(find "$APP/Contents/Frameworks/" -name Qt\*.framework); do
       FW_NAME=$(basename "$i")
       FW_SHORTNAME=$(basename -s ".framework" "$i")
       mv "$i/Resources" "$i/Versions/4"
       ln -s Versions/Current/Resources "$i/"
       ln -s Versions/Current/${FW_SHORTNAME} "$i/${FW_SHORTNAME}"
       ln -s 4 "$i/Versions/Current"
       cp "${QT_LIB_DIR}/${FW_NAME}/Contents/Info.plist" "$i/Resources"
       chmod u+w "$i/Resources/Info.plist"
       # now comes the real magic, we have to add CFBundleIdentifier and CFBundleVersion to the Info.plist
       awk "/<\/dict>/{print \"<key>CFBundleIdentifier</key>\n<string>org.qt-project.${FW_SHORTNAME}</string>\"}1" "$i/Resources/Info.plist" > "$i/Resources/Info.plist.tmp"
       mv "$i/Resources/Info.plist.tmp" "$i/Resources/Info.plist"
       awk '/<\/dict>/{print "<key>CFBundleVersion</key>\n<string>4.8</string>"}1' "$i/Resources/Info.plist" > "$i/Resources/Info.plist.tmp"
       mv "$i/Resources/Info.plist.tmp" "$i/Resources/Info.plist"
    done