How to codesign a QT framework.
-
I am developing a QT application using Python3, PYQT language bindings, and the Pyinstaller utility to build the Mac app bundle. The app bundle gets created just fine and the application runs fine. My challenge now is to get the app code signed and notarized. My current problem occurs when I code sign the qt framework QtCore. Here is the file structure inside my app bundle...
MyApp.app/Contents/MacOS/PyQt5/Qt/lib/QtCore.FrameworkI've modified the framework file structure according to numerous posts etc. The root of the QtCore.Framework looks like this...
./QtCore - this is a link to the actual QtCore executable
./Resources - this is a link to current/resources
./Versions - folder with the versions in it
./Versions/Current - link to ./Versions/5
./Versions/5 - folder with version 5 stuff
./Versions/5/QtCore - the actual executable
./Versions/5/Resources - actual resources folder
./Versions/5/Resources/Info.PlistThis is the Info.Plist... I believe it has everything needed according to what I've read in other posts.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>QtCore</string>
<key>CFBundleExecutable</key>
<string>QtCore</string>
<key>CFBundleGetInfoString</key>
<string>Created by Qt/QMake</string>
<key>CFBundleIdentifier</key>
<string>org.qt-project.QtCore</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>5.13</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>5.13.1</string>
<key>NOTE</key>
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
</dict>
</plist>.Here are the code sign commands. Following the mantra of "sign everything" I start at the inside and work my way out
sudo codesign --verbose --force --sign "Developer ID Application: xxx" ./MyApp.app/Contents/MacOS/PyQt5/Qt/lib/QtCore.framework/versions/5/resources/Info.plist
resources folder can’t be signed
sudo codesign --verbose --force --sign "Developer ID Application: xxx" ./MyApp.app/Contents/MacOS/PyQt5/Qt/lib/QtCore.framework/versions/5/QtCore
sudo codesign --verbose --force --sign "Developer ID Application: xxx" ./MyApp.app/Contents/MacOS/PyQt5/Qt/lib/QtCore.framework/versions/5/_CodeSignature/CodeResources
_CodeSignature folder can’t be signed
sudo codesign --verbose --force --sign "Developer ID Application: xxx" ./MyApp.app/Contents/MacOS/PyQt5/Qt/lib/QtCore.framework/versions/5
signing the Current folder just resigns the 5 folder so this seems redundant
the Versions folder can’t be signed
the Resources link can’t be signed
signing the QtCore link will just resign the QtCore executable which I think then requires you to resign the 5 folder so we don’t do this.
sudo codesign verbose --force --sign "Developer ID Application: xxx" ./MyApp.app/Contents/MacOS/PyQt5/Qt/lib/QtCore.framework
The final codesign command produces the following error message..../MyApp.app/Contents/MacOS/PyQt5/Qt/lib/QtCore.framework: replacing existing signature
./MyApp.app/Contents/MacOS/PyQt5/Qt/lib/QtCore.framework: unsealed contents present in the root directory of an embedded frameworkCan anyone spot what I'm doing wrong? Thanks.
-
Hi,
afaik it should suffice to sign and notarise .app bundles and .dmg files:
To sign the .app bundle (you need to use your own ID's, keys etc. naturally):
unlock_keychain() s_arg = 'Developer ID Application: The Qt Company Oy ({0})'.format(os.environ['QT_CODESIGN_IDENTITY_KEY']) # "-o runtime" is required for notarization cmd_args = ['codesign', '-o', 'runtime', '--verbose=3', '-r', '/Users/qt/csreq_qt_company.txt', '-s', s_arg, file_path]
Then to notarise the .dmg file you can use the following Python script:
https://code.qt.io/cgit/qtsdk/qtsdk.git/tree/packaging-tools/notarize.py