use pyinstaller for OSX builds

This commit is contained in:
ThomasV 2017-10-24 22:52:53 +02:00
parent 5665b42999
commit f7200cb616
4 changed files with 72 additions and 95 deletions

View File

@ -1,6 +1,7 @@
#!/bin/bash
rm -rf dist
export PYTHONHASHSEED=22
VERSION=`git describe --tags`
python3 setup-release.py py2app
pyinstaller --noconfirm --ascii contrib/osx.spec
hdiutil create -fs HFS+ -volname "Electrum" -srcfolder dist/Electrum.app dist/electrum-$VERSION.dmg

69
contrib/osx.spec Normal file
View File

@ -0,0 +1,69 @@
# -*- mode: python -*-
from PyInstaller.utils.hooks import collect_data_files, collect_submodules
home = '/Users/voegtlin/electrum/'
block_cipher=None
# see https://github.com/pyinstaller/pyinstaller/issues/2005
hiddenimports = []
hiddenimports += collect_submodules('trezorlib')
hiddenimports += collect_submodules('btchip')
hiddenimports += collect_submodules('keepkeylib')
datas = [
(home+'lib/currencies.json', 'electrum'),
(home+'lib/servers.json', 'electrum'),
(home+'lib/wordlist/english.txt', 'electrum/wordlist'),
(home+'lib/locale', 'electrum/locale'),
(home+'plugins', 'electrum_plugins'),
]
datas += collect_data_files('trezorlib')
datas += collect_data_files('btchip')
datas += collect_data_files('keepkeylib')
# We don't put these files in to actually include them in the script but to make the Analysis method scan them for imports
a = Analysis([home+'electrum',
home+'gui/qt/main_window.py',
home+'gui/text.py',
home+'lib/util.py',
home+'lib/wallet.py',
home+'lib/simple_config.py',
home+'lib/bitcoin.py',
home+'lib/dnssec.py',
home+'lib/commands.py',
home+'plugins/cosigner_pool/qt.py',
home+'plugins/email_requests/qt.py',
home+'plugins/trezor/client.py',
home+'plugins/trezor/qt.py',
home+'plugins/keepkey/qt.py',
home+'plugins/ledger/qt.py',
],
datas=datas,
hiddenimports=hiddenimports,
hookspath=[])
# http://stackoverflow.com/questions/19055089/pyinstaller-onefile-warning-pyconfig-h-when-importing-scipy-or-scipy-signal
for d in a.datas:
if 'pyconfig' in d[0]:
a.datas.remove(d)
break
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.datas,
name='Electrum',
debug=False,
strip=False,
upx=True,
icon=home+'electrum.icns',
console=False)
app = BUNDLE(exe,
name='Electrum.app',
icon=home+'electrum.icns',
bundle_identifier=None)

View File

@ -43,7 +43,7 @@ if jnius:
script_dir = os.path.dirname(os.path.realpath(__file__))
is_bundle = getattr(sys, 'frozen', False)
is_local = not is_bundle and os.path.exists(os.path.join(script_dir, "setup-release.py"))
is_local = not is_bundle and os.path.exists(os.path.join(script_dir, "electrum.desktop"))
is_android = 'ANDROID_DATA' in os.environ
# move this back to gui/kivy/__init.py once plugins are moved
@ -51,8 +51,6 @@ os.environ['KIVY_DATA_DIR'] = os.path.abspath(os.path.dirname(__file__)) + '/gui
if is_local or is_android:
sys.path.insert(0, os.path.join(script_dir, 'packages'))
elif is_bundle and sys.platform=='darwin':
is_local = True
def check_imports():
@ -75,8 +73,6 @@ def check_imports():
from google.protobuf import descriptor_pb2
from jsonrpclib import SimpleJSONRPCServer
# make sure that certificates are here
if is_bundle and sys.platform=='darwin':
requests.utils.DEFAULT_CA_BUNDLE_PATH = os.path.join(os.path.dirname(__file__), 'cacert.pem')
assert os.path.exists(requests.utils.DEFAULT_CA_BUNDLE_PATH)

View File

@ -1,89 +0,0 @@
"""
py2app/py2exe build script for Electrum
Usage (Mac OS X):
python setup.py py2app
Usage (Windows):
python setup.py py2exe
"""
from setuptools import setup
import os
import re
import shutil
import sys
from lib.version import ELECTRUM_VERSION as version
name = "Electrum"
mainscript = 'electrum'
if sys.version_info[:3] < (3, 4, 0):
print("Error: " + name + " requires Python version >= 3.4.0...")
sys.exit(1)
if sys.platform == 'darwin':
from plistlib import Plist
plist = Plist.fromFile('Info.plist')
plist.update(dict(CFBundleIconFile='electrum.icns'))
shutil.copy(mainscript, 'run_electrum.py')
mainscript = 'run_electrum.py'
extra_options = dict(
setup_requires=['py2app'],
app=[mainscript],
options=dict(py2app=dict(argv_emulation=False,
includes=['PyQt5.QtCore', 'PyQt5.QtGui', 'PyQt5.QtWebKit', 'PyQt5.QtNetwork', 'sip'],
packages=['lib', 'gui', 'plugins'],
iconfile='electrum.icns',
plist=plist,
resources=['icons', 'cacert.pem'])),
)
elif sys.platform == 'win32':
extra_options = dict(
setup_requires=['py2exe'],
app=[mainscript],
)
else:
extra_options = dict(
# Normally unix-like platforms will use "setup.py install"
# and install the main script as such
scripts=[mainscript],
)
setup(
name=name,
version=version,
**extra_options
)
from distutils import dir_util
if sys.platform == 'darwin':
# Remove the copied py file
os.remove(mainscript)
resource = "dist/" + name + ".app/Contents/Resources/"
# Try to locate qt_menu
# Let's try the port version first!
if os.path.isfile("/opt/local/lib/Resources/qt_menu.nib"):
qt_menu_location = "/opt/local/lib/Resources/qt_menu.nib"
else:
# No dice? Then let's try the brew version
if os.path.exists("/usr/local/Cellar"):
qt_menu_location = os.popen("find /usr/local/Cellar -name qt_menu.nib | tail -n 1").read()
# no brew, check /opt/local
else:
qt_menu_location = os.popen("find /opt/local -name qt_menu.nib | tail -n 1").read()
qt_menu_location = re.sub('\n', '', qt_menu_location)
if (len(qt_menu_location) == 0):
print("Sorry couldn't find your qt_menu.nib this probably won't work")
else:
print("Found your qib: " + qt_menu_location)
# Need to include a copy of qt_menu.nib
shutil.copytree(qt_menu_location, resource + "qt_menu.nib")
# Need to touch qt.conf to avoid loading 2 sets of Qt libraries
fname = resource + "qt.conf"
os.utime(fname, None)