[Packaging] Simplify PyInstaller spec file

This makes the process of editing the file much more pleasant and
removes duplicate code.

Fixed collecting twisted package which brings both build speed
improvements but also decreases package size, as it stops PyInstaller
from bundling tests (actually, some tests might even execute during
import and break build if they're designed to throw!) used by
PyInstaller

Closes: https://github.com/deluge-torrent/deluge/pull/342
This commit is contained in:
Cirno the Strongest 2022-01-21 23:03:02 +01:00 committed by Calum Lind
commit e75ef7e31f
No known key found for this signature in database
GPG key ID: 90597A687B836BA3

View file

@ -1,322 +1,200 @@
# -*- mode: python ; coding: utf-8 -*- # -*- mode: python ; coding: utf-8 -*-
import os import os
import sys import sys
import deluge.common import deluge.common
from PyInstaller.compat import is_win from PyInstaller.utils.hooks import collect_all, collect_submodules, copy_metadata
from PyInstaller.utils.hooks import collect_all, copy_metadata
datas = [] datas = []
binaries = [] binaries = []
hiddenimports = ['pygame'] hiddenimports = ['pygame']
runtime_hooks_gtk = [os.path.join(SPECPATH, 'pyi_rth_gtk_csd.py')]
# Collect Meta Data # Collect Meta Data
datas += copy_metadata('deluge', recursive=True) datas += copy_metadata('deluge', recursive=True)
datas += copy_metadata('service-identity', recursive=True) datas += copy_metadata('service-identity', recursive=True)
# Add Deluge Hidden Imports # Add Deluge Hidden Imports
tmp_ret = collect_all('deluge') hiddenimports += collect_submodules('deluge')
hiddenimports += tmp_ret[2]
#Add Hidden Imports for Plugins # Add stdlib as Hidden Imports.
tmp_ret2 = collect_all('twisted') # This is filtered list that excludes some common examples or stuff not useful in plugins (such as tty, mailbox, turtledemo etc.).
hiddenimports += tmp_ret2[2] # It is safe to assume that 90% of that list would already be included anyway.
stdlib = [
'string',
're',
'unicodedata',
'struct',
'codecs',
'datetime',
'zoneinfo',
'calendar',
'collections',
'array',
'weakref',
'types',
'copy',
'enum',
'numbers',
'math',
'cmath',
'decimal',
'fractions',
'random',
'statistics',
'itertools',
'functools',
'operator',
'pathlib',
'fileinput',
'stat',
'tempfile',
'glob',
'fnmatch',
'shutil',
'pickle',
'copyreg',
'shelve',
'marshal',
'dom',
'sqlite3',
'zlib',
'gzip',
'bz2',
'lzma',
'csv',
'hashlib',
'hmac',
'secrets',
'os',
'io',
'time',
'logging',
'platform',
'errno',
'queue',
'socket',
'ssl',
'email',
'json',
'mimetypes',
'base64',
'binhex',
'binascii',
'quopri',
'uu',
'html',
'xml',
'urllib',
'http',
'ftplib',
'smtplib',
'uuid',
'xmlrpc.client',
'ipaddress',
'locale',
'sys',
]
for module in stdlib:
hiddenimports += collect_submodules(module, filter=lambda name: 'test' not in name)
# Add Hidden Imports for Plugins
hiddenimports += collect_submodules('twisted', filter=lambda name: 'test' not in name)
datas += copy_metadata('twisted', recursive=True) datas += copy_metadata('twisted', recursive=True)
# Get build_version from installed deluge. # Copy UI/Plugin files to where pyinstaller expects
build_version = deluge.common.get_version() datas += [('../../deluge/ui', 'deluge/ui'), ('../../deluge/plugins', 'deluge/plugins')]
#Copy UI/Plugin files to where pyinstaller expects # List of executables to produce
datas += [ ('../../deluge/ui', 'deluge/ui'), executables = {
('../../deluge/plugins', 'deluge/plugins') ] 'deluge-script.pyw': {
'name': 'deluge',
'console': False,
'gtk': True,
},
'deluge-gtk-script.pyw': {
'name': 'deluge-gtk',
'console': False,
'gtk': True,
},
'deluge-debug-script.py': {
'name': 'deluge-debug',
'console': True,
'gtk': True,
},
'deluge-console-script.py': {
'name': 'deluge-console',
'console': True,
'gtk': False,
},
'deluged-script.py': {
'name': 'deluged',
'console': False,
'gtk': False,
},
'deluged-debug-script.py': {
'name': 'deluged-debug',
'console': True,
'gtk': False,
},
'deluge-web-debug-script.py': {
'name': 'deluge-web-debug',
'console': False,
'gtk': False,
},
'deluge-web-script.py': {
'name': 'deluge-web',
'console': True,
'gtk': False,
},
}
analysis = {}
exe = {}
coll = []
block_cipher = None # Perform analysis
for e, d in executables.items():
runtime_hooks = []
if d['gtk']:
runtime_hooks += [os.path.join(SPECPATH, 'pyi_rth_gtk_csd.py')]
analysis[e] = Analysis(
a = Analysis([os.path.abspath(os.path.join(HOMEPATH,os.pardir,os.pardir)) + '\Scripts\deluge-console-script.py'], [os.path.abspath(os.path.join(HOMEPATH, os.pardir, os.pardir, 'Scripts', e))],
pathex=[], pathex=[],
binaries=binaries, binaries=binaries,
datas=datas, datas=datas,
hiddenimports=hiddenimports, hiddenimports=hiddenimports,
hookspath=[], hookspath=[],
hooksconfig={}, hooksconfig={},
runtime_hooks=[], runtime_hooks=runtime_hooks,
excludes=[], excludes=[],
win_no_prefer_redirects=False, win_no_prefer_redirects=False,
win_private_assemblies=False, win_private_assemblies=False,
cipher=block_cipher, cipher=None,
noarchive=False) noarchive=False,
pyz = PYZ(a.pure, a.zipped_data, )
cipher=block_cipher)
exe = EXE(pyz, # Executable
a.scripts, for e, d in executables.items():
exe[e] = EXE(
PYZ(analysis[e].pure, analysis[e].zipped_data, cipher=None),
analysis[e].scripts,
[], [],
exclude_binaries=True, exclude_binaries=True,
name='deluge-console', name=d['name'],
debug=False, debug=False,
bootloader_ignore_signals=False, bootloader_ignore_signals=False,
strip=False, strip=False,
upx=True, upx=True,
icon='../../deluge/ui/data/pixmaps/deluge.ico', icon='../../deluge/ui/data/pixmaps/deluge.ico',
console=True, console=d['console'],
disable_windowed_traceback=False, disable_windowed_traceback=False,
target_arch=None, target_arch=None,
codesign_identity=None, codesign_identity=None,
entitlements_file=None ) entitlements_file=None,
)
b = Analysis([os.path.abspath(os.path.join(HOMEPATH,os.pardir,os.pardir)) + '\Scripts\deluge-gtk-script.pyw'], # Collect
pathex=[], for e, d in executables.items():
binaries=binaries, coll += exe[e], analysis[e].binaries, analysis[e].zipfiles, analysis[e].datas
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=runtime_hooks_gtk,
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyzb = PYZ(b.pure, b.zipped_data,
cipher=block_cipher)
exeb = EXE(pyzb,
b.scripts,
[],
exclude_binaries=True,
name='deluge-gtk',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
icon='../../deluge/ui/data/pixmaps/deluge.ico',
console=False,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
c = Analysis([os.path.abspath(os.path.join(HOMEPATH,os.pardir,os.pardir)) + '\Scripts\deluged-script.py'], COLLECT(*coll, strip=False, upx=True, upx_exclude=[], name='Deluge')
pathex=[],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyzc = PYZ(c.pure, c.zipped_data,
cipher=block_cipher)
exec = EXE(pyzc,
c.scripts,
[],
exclude_binaries=True,
name='deluged',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
icon='../../deluge/ui/data/pixmaps/deluge.ico',
console=False,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
d = Analysis([os.path.abspath(os.path.join(HOMEPATH,os.pardir,os.pardir)) + '\Scripts\deluged-debug-script.py'],
pathex=[],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyzd = PYZ(d.pure, d.zipped_data,
cipher=block_cipher)
exed = EXE(pyzd,
d.scripts,
[],
exclude_binaries=True,
name='deluged-debug',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
icon='../../deluge/ui/data/pixmaps/deluge.ico',
console=True,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
e = Analysis([os.path.abspath(os.path.join(HOMEPATH,os.pardir,os.pardir)) + '\Scripts\deluge-debug-script.py'],
pathex=[],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=runtime_hooks_gtk,
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyze = PYZ(e.pure, e.zipped_data,
cipher=block_cipher)
exee = EXE(pyze,
e.scripts,
[],
exclude_binaries=True,
name='deluge-debug',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
icon='../../deluge/ui/data/pixmaps/deluge.ico',
console=True,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
f = Analysis([os.path.abspath(os.path.join(HOMEPATH,os.pardir,os.pardir)) + '\Scripts\deluge-script.pyw'],
pathex=[],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=runtime_hooks_gtk,
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyzf = PYZ(f.pure, f.zipped_data,
cipher=block_cipher)
exef = EXE(pyzf,
f.scripts,
[],
exclude_binaries=True,
name='deluge',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
icon='../../deluge/ui/data/pixmaps/deluge.ico',
console=False,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
g = Analysis([os.path.abspath(os.path.join(HOMEPATH,os.pardir,os.pardir)) + '\Scripts\deluge-web-debug-script.py'],
pathex=[],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyzg = PYZ(g.pure, g.zipped_data,
cipher=block_cipher)
exeg = EXE(pyzg,
g.scripts,
[],
exclude_binaries=True,
name='deluge-web-debug',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
icon='../../deluge/ui/data/pixmaps/deluge.ico',
console=True,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
h = Analysis([os.path.abspath(os.path.join(HOMEPATH,os.pardir,os.pardir)) + '\Scripts\deluge-web-script.py'],
pathex=[],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyzh = PYZ(h.pure, h.zipped_data,
cipher=block_cipher)
exeh = EXE(pyzh,
h.scripts,
[],
exclude_binaries=True,
name='deluge-web',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
icon='../../deluge/ui/data/pixmaps/deluge.ico',
console=False,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
exeb,
b.binaries,
b.zipfiles,
b.datas,
exec,
c.binaries,
c.zipfiles,
c.datas,
exed,
d.binaries,
d.zipfiles,
d.datas,
exee,
e.binaries,
e.zipfiles,
e.datas,
exef,
f.binaries,
f.zipfiles,
f.datas,
exeg,
g.binaries,
g.zipfiles,
g.datas,
exeh,
h.binaries,
h.zipfiles,
h.datas,
strip=False,
upx=True,
upx_exclude=[],
name='Deluge')