mirror of
https://gitlab.com/openlp/packaging.git
synced 2024-12-22 13:02:50 +00:00
Fix Qt paths so that code signing works
This commit is contained in:
parent
e17dfb2dad
commit
499847bbcd
@ -1,5 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# OpenLP - Open Source Lyrics Projection #
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
@ -94,15 +94,15 @@ You may need to install chardet via pip::
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import plistlib
|
from pathlib import Path
|
||||||
import signal
|
from shutil import copy, copytree, move, rmtree
|
||||||
from shutil import copy, copytree
|
|
||||||
|
|
||||||
from macholib.MachO import MachO
|
from macholib.MachO import MachO
|
||||||
from macholib.util import flipwritable, in_system_path
|
from macholib.util import in_system_path
|
||||||
|
|
||||||
from builder import Builder
|
from builder import Builder
|
||||||
|
|
||||||
|
|
||||||
class MacOSXBuilder(Builder):
|
class MacOSXBuilder(Builder):
|
||||||
"""
|
"""
|
||||||
The :class:`MacosxBuilder` class encapsulates everything that is needed
|
The :class:`MacosxBuilder` class encapsulates everything that is needed
|
||||||
@ -119,6 +119,99 @@ class MacOSXBuilder(Builder):
|
|||||||
dir_size += os.path.getsize(filename)
|
dir_size += os.path.getsize(filename)
|
||||||
return dir_size
|
return dir_size
|
||||||
|
|
||||||
|
def _create_symlink(self, folder):
|
||||||
|
"""
|
||||||
|
Create the appropriate symlink in the MacOS folder pointing to the Resources folder.
|
||||||
|
"""
|
||||||
|
sibling = Path(str(folder).replace('MacOS', ''))
|
||||||
|
|
||||||
|
# PyQt5/Qt/qml/QtQml/Models.2
|
||||||
|
root = str(sibling).partition('Contents')[2].lstrip('/')
|
||||||
|
# ../../../../
|
||||||
|
backward = '../' * len(root.split('/'))
|
||||||
|
# ../../../../Resources/PyQt5/Qt/qml/QtQml/Models.2
|
||||||
|
good_path = f'{backward}Resources/{root}'
|
||||||
|
|
||||||
|
folder.symlink_to(good_path)
|
||||||
|
|
||||||
|
def _fix_qt_dll(self, dll):
|
||||||
|
"""
|
||||||
|
Fix the DLL lookup paths to use relative ones for Qt dependencies.
|
||||||
|
Inspiration: PyInstaller/depend/dylib.py:mac_set_relative_dylib_deps()
|
||||||
|
Currently one header is pointing to (we are in the Resources folder):
|
||||||
|
@loader_path/../../../../QtCore (it is referencing to the old MacOS folder)
|
||||||
|
It will be converted to:
|
||||||
|
@loader_path/../../../../../../MacOS/QtCore
|
||||||
|
"""
|
||||||
|
|
||||||
|
def match_func(pth):
|
||||||
|
"""
|
||||||
|
Callback function for MachO.rewriteLoadCommands() that is
|
||||||
|
called on every lookup path setted in the DLL headers.
|
||||||
|
By returning None for system libraries, it changes nothing.
|
||||||
|
Else we return a relative path pointing to the good file
|
||||||
|
in the MacOS folder.
|
||||||
|
"""
|
||||||
|
basename = os.path.basename(pth)
|
||||||
|
if not basename.startswith('Qt'):
|
||||||
|
return None
|
||||||
|
return f'@loader_path{good_path}/{basename}'
|
||||||
|
|
||||||
|
# Resources/PyQt5/Qt/qml/QtQuick/Controls.2/Fusion
|
||||||
|
root = str(dll.parent).partition('Contents')[2][1:]
|
||||||
|
# /../../../../../../..
|
||||||
|
backward = '/..' * len(root.split('/'))
|
||||||
|
# /../../../../../../../MacOS
|
||||||
|
good_path = f'{backward}/MacOS'
|
||||||
|
|
||||||
|
# Rewrite Mach headers with corrected @loader_path
|
||||||
|
dll = MachO(dll)
|
||||||
|
dll.rewriteLoadCommands(match_func)
|
||||||
|
with open(dll.filename, 'rb+') as f:
|
||||||
|
for header in dll.headers:
|
||||||
|
f.seek(0)
|
||||||
|
dll.write(f)
|
||||||
|
f.seek(0, 2)
|
||||||
|
f.flush()
|
||||||
|
|
||||||
|
def _find_problematic_qt_folders(self, folder):
|
||||||
|
"""
|
||||||
|
Recursively yields problematic folders (containing a dot in their name).
|
||||||
|
"""
|
||||||
|
for path in folder.iterdir():
|
||||||
|
if not path.is_dir() or path.is_symlink():
|
||||||
|
# Skip simlinks as they are allowed (even with a dot)
|
||||||
|
continue
|
||||||
|
if '.' in path.name:
|
||||||
|
yield path
|
||||||
|
else:
|
||||||
|
yield from self._find_problematic_qt_folders(path)
|
||||||
|
|
||||||
|
def _move_contents_to_resources(self, folder):
|
||||||
|
"""
|
||||||
|
Recursively move any non symlink file from a problematic folder to the sibling one in Resources.
|
||||||
|
"""
|
||||||
|
for path in folder.iterdir():
|
||||||
|
if path.is_symlink():
|
||||||
|
continue
|
||||||
|
if path.is_dir():
|
||||||
|
yield from self._move_contents_to_resources(path)
|
||||||
|
else:
|
||||||
|
sibling = Path(str(path).replace('MacOS', 'Resources'))
|
||||||
|
move(path, sibling)
|
||||||
|
yield sibling
|
||||||
|
|
||||||
|
def _fix_qt_paths(self):
|
||||||
|
"""
|
||||||
|
Fix the Qt paths
|
||||||
|
"""
|
||||||
|
app_path = Path(self.dist_app_path) / 'Contents' / 'MacOS'
|
||||||
|
for folder in self._find_problematic_qt_folders(app_path):
|
||||||
|
for problematic_file in self._move_contents_to_resources(folder):
|
||||||
|
self._fix_qt_dll(problematic_file)
|
||||||
|
rmtree(folder)
|
||||||
|
self._create_symlink(folder)
|
||||||
|
|
||||||
def _relink_mupdf(self, bin_name):
|
def _relink_mupdf(self, bin_name):
|
||||||
"""
|
"""
|
||||||
Relink mupdf to bundled libraries
|
Relink mupdf to bundled libraries
|
||||||
@ -181,7 +274,8 @@ class MacOSXBuilder(Builder):
|
|||||||
"""
|
"""
|
||||||
Copy Info.plist and OpenLP.icns to app bundle.
|
Copy Info.plist and OpenLP.icns to app bundle.
|
||||||
"""
|
"""
|
||||||
copy(self.icon_path, os.path.join(self.dist_app_path, 'Contents', 'Resources', os.path.basename(self.icon_path)))
|
copy(self.icon_path, os.path.join(self.dist_app_path, 'Contents', 'Resources',
|
||||||
|
os.path.basename(self.icon_path)))
|
||||||
# Add OpenLP version to Info.plist and put it to app bundle.
|
# Add OpenLP version to Info.plist and put it to app bundle.
|
||||||
fr = open(self.bundle_info_path, 'r')
|
fr = open(self.bundle_info_path, 'r')
|
||||||
fw = open(os.path.join(self.dist_app_path, 'Contents', os.path.basename(self.bundle_info_path)), 'w')
|
fw = open(os.path.join(self.dist_app_path, 'Contents', os.path.basename(self.bundle_info_path)), 'w')
|
||||||
@ -237,9 +331,10 @@ class MacOSXBuilder(Builder):
|
|||||||
|
|
||||||
os.chdir(os.path.dirname(self.dmg_settings_path))
|
os.chdir(os.path.dirname(self.dmg_settings_path))
|
||||||
self._run_command([self.dmgbuild_exe, '-s', self.dmg_settings_path, '-D', 'size={size}M'.format(size=size),
|
self._run_command([self.dmgbuild_exe, '-s', self.dmg_settings_path, '-D', 'size={size}M'.format(size=size),
|
||||||
'-D', 'icon={icon_path}'.format(icon_path=self.icon_path),
|
'-D', 'icon={icon_path}'.format(icon_path=self.icon_path),
|
||||||
'-D', 'app={dist_app_path}'.format(dist_app_path=self.dist_app_path), dmg_title, self.dmg_file],
|
'-D', 'app={dist_app_path}'.format(dist_app_path=self.dist_app_path), dmg_title,
|
||||||
'Unable to run dmgbuild')
|
self.dmg_file],
|
||||||
|
'Unable to run dmgbuild')
|
||||||
|
|
||||||
# Dmg done.
|
# Dmg done.
|
||||||
self._print('Finished creating dmg file, resulting file: %s' % self.dmg_file)
|
self._print('Finished creating dmg file, resulting file: %s' % self.dmg_file)
|
||||||
@ -299,6 +394,7 @@ class MacOSXBuilder(Builder):
|
|||||||
"""
|
"""
|
||||||
Build the actual DMG
|
Build the actual DMG
|
||||||
"""
|
"""
|
||||||
|
self._fix_qt_paths()
|
||||||
self._code_sign()
|
self._code_sign()
|
||||||
self._create_dmg()
|
self._create_dmg()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user