Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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.Framework

    I'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.Plist

    This 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 framework

    Can 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


Log in to reply