Подписать платформу для OSX 10.9
После использования macdeployqt
я подписываю свое приложение, чтобы избежать проблем с Gatekeeper.
Я могу использовать 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
В соответствии с http://furbo.org/2013/10/17/code-signing-and-mavericks/ кажется, что я должен подписать пакет фреймворка что-то вроде этого
$ 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
Ответы
Ответ 1
То же самое произошло сегодня утром. Приложение с кодовым названием кажется более строгим в OSX 10.9
Проблема вызвана тем, что macdeployqt не копирует файл info.plist оболочки Qt в пакет приложений.
Вы можете обойти эту проблему, сообщив script скопировать файлы вручную в файл встроенного фреймворка.
например.
$ cp ~/Qt5.2.0/5.2.0-beta1/clang_64/lib/QtCore.framework/Contents/Info.plist MyApplication.app/Contents/Frameworks/QtCore.framework/Resources/
Сделайте это для каждого из модулей qt, которые использует ваше приложение, ПОСЛЕ вызова macdeployqt *, но ПЕРЕД вызовом кода.
(* или mkdir каталогов назначения)
Кроме того, вызывайте коды в папках структуры, а не в подпапку версии.
то есть.
$ codesign --force --verify --verbose --sign "Developer ID Application: My ID" MyApplication.app/Contents/Frameworks/QtConcurrent.framework
Надеюсь, что это поможет.
Ответ 2
Резюме
- Исправьте искаженные структуры Qt, переместив Info.plist в папку "Ресурсы" на текущем уровне версии в рамках.
- Используйте параметр codeign --deep для одновременного подписания всех двоичных файлов в пакете, включая фреймворки и плагины.
Подробнее
Самый простой способ решить эту проблему - использовать параметр -deep-кодов. Этот вариант (который, как мне кажется, был представлен с Mavericks), подпишет все двоичные файлы в целевом пакете, включая основной двоичный файл приложения, а также его фреймворки и плагины.
Однако перед использованием этой опции (или любых других предложенных методов подписи) вы должны исправить фреймворки Qt в соответствии с другими сообщениями в этом потоке. По какой-то нечетной причине каркасы Qt, как построенные, не соответствуют нормам Apple, а также путают инструмент codeign. Это, в свою очередь, может привести к неправильному поведению, например замене символической ссылки верхнего уровня на фреймворк дополнительной копией подписанного двоичного файла.
Чтобы исправить фреймворки Qt, скопируйте Info.plist в папку "Ресурсы" в конкретной версии фреймворка, а не на верхний уровень фреймворка (как было ранее предложено). Кроме того, вы можете захотеть выбросить оригинальную копию 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 в "Другие флаги подписи кода":
OTHER_CODE_SIGN_FLAGS = --deep
Если у вас есть разные требования к кодовым обозначениям для вашего основного приложения, чем для ваших фреймворков или плагинов, вы можете использовать небольшой трюк. Сначала вы подписываете с помощью опции --deep, используя требования frameworks/plugins. Затем вы можете снова подписать параметр --force, но без опции --deep, указав требования уровня приложения. Результатом будет то, что основное приложение будет подписано с требованиями приложения, и все подзадачи будут подписаны с требованиями к фреймворкам/плагину.
Этот подход можно считать немного ленивым и расточительным, так как вы подписываете основное приложение дважды. Но это проще, чем альтернатива поиска и подписи всех вспомогательных двоичных файлов отдельно от двоичного файла основного приложения.
Ответ 3
Большое спасибо!
Вам также нужно подписать все плагины, используемые вашим приложением
то есть.
$ codesign --force --verify --verbose --sign "Developer ID Application: My ID" MyApplication.app/Contents/PlugIns/imageformats/libqgif.dylib
С уважением,
Райнер
Ответ 4
Я написал script на основе ответа Benoît, который выполняет работу по исправлению файла .app:
https://gist.github.com/kainjow/8059407
Код:
#!/usr/bin/env ruby
# Copies missing Info.plist files for a .app 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
Ответ 5
В соответствии с Apple docs вам нужно подписать папки версий, а не сама фрейм. Я пробовал это и сталкивался с двумя проблемами. Прежде всего, некоторые из файлов Info.plist из фреймворков Qt имеют неправильные исполняемые имена (суффикс _debug). После исправления мне удалось подписать все рамки "Apple way". Однако после этого я не смог подписать основное приложение и получил ошибки в основах Qt, которые я только что подписал.
Итак, странное, но работающее решение заключается в том, чтобы вместо этого подписывать папки фреймов. Это работает даже с неправильными именами исполняемых файлов в файлах Info.plist.
Ответ 6
Я использую этот script для исправления фреймворков QT 4.8 перед координированием. Надеюсь это поможет. Мне понадобилось около 3-4 дней, чтобы понять это (это было до сообщения в блоге QT).
# we need to massage qt frameworks so they get codesigned by the new codesign
# more information about this $#@[email protected]# piece of [email protected]#[email protected]$!
# 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