Add support for binary builds with PyInstaller

See https://tahoe-lafs.org/trac/tahoe-lafs/ticket/2729
This commit is contained in:
Chris Wood 2017-06-07 21:03:11 -04:00 committed by Brian Warner
parent 3f2f7dfb05
commit aaf167b877
2 changed files with 116 additions and 0 deletions

102
pyinstaller.spec Normal file
View File

@ -0,0 +1,102 @@
# -*- mode: python -*-
from __future__ import print_function
from distutils.sysconfig import get_python_lib
import hashlib
import os
import platform
import shutil
import struct
import sys
if not hasattr(sys, 'real_prefix'):
sys.exit("Please run inside a virtualenv with Tahoe-LAFS installed.")
# Ugly hack to disable the setuptools requirement asserted in '_auto_deps.py'.
# Without patching out this requirement, frozen binaries will fail at runtime.
autodeps_path = os.path.join(get_python_lib(), 'allmydata', '_auto_deps.py')
print("Patching '{}' to remove setuptools check...".format(autodeps_path))
autodeps_path_backup = autodeps_path + '.backup'
shutil.copy2(autodeps_path, autodeps_path_backup)
with open(autodeps_path_backup) as src, open(autodeps_path, 'w+') as dest:
dest.write(src.read().replace('"setuptools >=', '#"setuptools >='))
print("Done!")
options = [('u', None, 'OPTION')] # Unbuffered stdio
added_files = [
('COPYING.*', '.'),
('CREDITS', '.'),
('relnotes.txt', '.'),
('src/allmydata/web/*.xhtml', 'allmydata/web'),
('src/allmydata/web/static/*', 'allmydata/web/static'),
('src/allmydata/web/static/css/*', 'allmydata/web/static/css'),
('src/allmydata/web/static/img/*.png', 'allmydata/web/static/img')]
a = Analysis(
['static/tahoe.py'],
pathex=[],
binaries=None,
datas=added_files,
hiddenimports=['characteristic', 'cffi'],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=None)
pyz = PYZ(
a.pure,
a.zipped_data,
cipher=None)
exe = EXE(
pyz,
a.scripts,
options,
exclude_binaries=True,
name='tahoe',
debug=False,
strip=False,
upx=False,
console=True)
coll = COLLECT(
exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=False,
name='Tahoe-LAFS')
# Revert the '_auto_deps.py' patch above
shutil.move(autodeps_path_backup, autodeps_path)
print("Creating archive...")
platform_tag = platform.system().replace('Darwin', 'MacOS')
bitness_tag = str(struct.calcsize('P') * 8) + 'bit'
archive_name = 'Tahoe-LAFS-{}-{}'.format(platform_tag, bitness_tag)
if sys.platform == 'win32':
archive_format = 'zip'
archive_suffix = '.zip'
else:
archive_format = 'gztar'
archive_suffix = '.tar.gz'
base_name = os.path.join('dist', archive_name)
shutil.make_archive(base_name, archive_format, 'dist', 'Tahoe-LAFS')
print("Hashing (SHA256)...")
archive_path = base_name + archive_suffix
hasher = hashlib.sha256()
with open(archive_path, 'rb') as f:
for block in iter(lambda: f.read(4096), b''):
hasher.update(block)
print("{} {}".format(hasher.hexdigest(), archive_path))

14
tox.ini
View File

@ -102,3 +102,17 @@ deps =
skip_install = True
commands =
sphinx-build -b html -d {toxinidir}/docs/_build/doctrees {toxinidir}/docs {toxinidir}/docs/_build/html
[testenv:pyinstaller]
basepython=python2.7
# Do not use the '--editable' flag for this testenv as the 'pyinstaller.spec'
# script called below will need patch the source tree at build-time in order
# to remove the setuptools requirement from '_auto_deps.py' (and we want to
# avoid race-conditions when running tests in parallel, e.g., with "detox").
deps =
.
pyinstaller
# Setting PYTHONHASHSEED to a known value assists with reproducible builds.
# See https://pyinstaller.readthedocs.io/en/stable/advanced-topics.html#creating-a-reproducible-build
setenv=PYTHONHASHSEED=1
commands=pyinstaller -y --clean pyinstaller.spec