Permalink
Cannot retrieve contributors at this time
108 lines (84 sloc)
3.23 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python | |
| # vim:fileencoding=utf-8 | |
| # License: GPLv3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net> | |
| import os | |
| import plistlib | |
| from glob import glob | |
| from bypy.macos_sign import ( | |
| codesign, create_entitlements_file, make_certificate_useable, notarize_app, | |
| verify_signature | |
| ) | |
| from bypy.utils import current_dir | |
| entitlements = { | |
| # MAP_JIT is used by libpcre which is bundled with Qt | |
| 'com.apple.security.cs.allow-jit': True, | |
| # v8 and therefore WebEngine need this as they dont use MAP_JIT | |
| 'com.apple.security.cs.allow-unsigned-executable-memory': True, | |
| # calibre itself does not use DYLD env vars, but dont know about its | |
| # dependencies. | |
| 'com.apple.security.cs.allow-dyld-environment-variables': True, | |
| # Allow loading of unsigned plugins or frameworks | |
| # 'com.apple.security.cs.disable-library-validation': True, | |
| } | |
| def files_in(folder): | |
| for record in os.walk(folder): | |
| for f in record[-1]: | |
| yield os.path.join(record[0], f) | |
| def expand_dirs(items, exclude=lambda x: x.endswith('.so')): | |
| items = set(items) | |
| dirs = set(x for x in items if os.path.isdir(x)) | |
| items.difference_update(dirs) | |
| for x in dirs: | |
| items.update({y for y in files_in(x) if not exclude(y)}) | |
| return items | |
| def get_executable(info_path): | |
| with open(info_path, 'rb') as f: | |
| return plistlib.load(f)['CFBundleExecutable'] | |
| def find_sub_apps(contents_dir='.'): | |
| for app in glob(os.path.join(contents_dir, '*.app')): | |
| cdir = os.path.join(app, 'Contents') | |
| for sapp in find_sub_apps(cdir): | |
| yield sapp | |
| yield app | |
| def sign_MacOS(contents_dir='.'): | |
| # Sign everything in MacOS except the main executable | |
| # which will be signed automatically by codesign when | |
| # signing the app bundles | |
| with current_dir(os.path.join(contents_dir, 'MacOS')): | |
| exe = get_executable('../Info.plist') | |
| items = {x for x in os.listdir('.') if x != exe and not os.path.islink(x)} | |
| if items: | |
| codesign(items) | |
| def do_sign_app(appdir): | |
| appdir = os.path.abspath(appdir) | |
| with current_dir(os.path.join(appdir, 'Contents')): | |
| sign_MacOS() | |
| # Sign the sub application bundles | |
| sub_apps = list(find_sub_apps()) | |
| sub_apps.append('Frameworks/QtWebEngineCore.framework/Versions/Current/Helpers/QtWebEngineProcess.app') | |
| for sa in sub_apps: | |
| sign_MacOS(os.path.join(sa, 'Contents')) | |
| codesign(sub_apps) | |
| # Sign all .so files | |
| so_files = {x for x in files_in('.') if x.endswith('.so')} | |
| codesign(so_files) | |
| # Sign everything in PlugIns | |
| with current_dir('PlugIns'): | |
| items = set(os.listdir('.')) | |
| codesign(expand_dirs(items)) | |
| # Sign everything else in Frameworks | |
| with current_dir('Frameworks'): | |
| fw = set(glob('*.framework')) | |
| codesign(fw) | |
| items = set(os.listdir('.')) - fw | |
| codesign(expand_dirs(items)) | |
| # Now sign the main app | |
| codesign(appdir) | |
| verify_signature(appdir) | |
| return 0 | |
| def sign_app(appdir, notarize): | |
| create_entitlements_file(entitlements) | |
| with make_certificate_useable(): | |
| do_sign_app(appdir) | |
| if notarize: | |
| notarize_app(appdir) |