tosx.spec - electrum - Electrum Bitcoin wallet
HTML git clone https://git.parazyd.org/electrum
DIR Log
DIR Files
DIR Refs
DIR Submodules
---
tosx.spec (6236B)
---
1 # -*- mode: python -*-
2
3 from PyInstaller.utils.hooks import collect_data_files, collect_submodules, collect_dynamic_libs
4
5 import sys, os
6
7 PACKAGE='Electrum'
8 PYPKG='electrum'
9 MAIN_SCRIPT='run_electrum'
10 ICONS_FILE=PYPKG + '/gui/icons/electrum.icns'
11 APP_SIGN = os.environ.get('APP_SIGN', '')
12
13 def fail(*msg):
14 RED='\033[0;31m'
15 NC='\033[0m' # No Color
16 print("\r🗯 {}ERROR:{}".format(RED, NC), *msg)
17 sys.exit(1)
18
19 def codesign(identity, binary):
20 d = os.path.dirname(binary)
21 saved_dir=None
22 if d:
23 # switch to directory of the binary so codesign verbose messages don't include long path
24 saved_dir = os.path.abspath(os.path.curdir)
25 os.chdir(d)
26 binary = os.path.basename(binary)
27 os.system("codesign -v -f -s '{}' '{}'".format(identity, binary))==0 or fail("Could not code sign " + binary)
28 if saved_dir:
29 os.chdir(saved_dir)
30
31 def monkey_patch_pyinstaller_for_codesigning(identity):
32 # Monkey-patch PyInstaller so that we app-sign all binaries *after* they are modified by PyInstaller
33 # If we app-sign before that point, the signature will be invalid because PyInstaller modifies
34 # @loader_path in the Mach-O loader table.
35 try:
36 import PyInstaller.depend.dylib
37 _saved_func = PyInstaller.depend.dylib.mac_set_relative_dylib_deps
38 except (ImportError, NameError, AttributeError):
39 # Hmm. Likely wrong PyInstaller version.
40 fail("Could not monkey-patch PyInstaller for code signing. Please ensure that you are using PyInstaller 3.4.")
41 _signed = set()
42 def my_func(fn, distname):
43 _saved_func(fn, distname)
44 if (fn, distname) not in _signed:
45 codesign(identity, fn)
46 _signed.add((fn,distname)) # remember we signed it so we don't sign again
47 PyInstaller.depend.dylib.mac_set_relative_dylib_deps = my_func
48
49
50 for i, x in enumerate(sys.argv):
51 if x == '--name':
52 VERSION = sys.argv[i+1]
53 break
54 else:
55 raise Exception('no version')
56
57 electrum = os.path.abspath(".") + "/"
58 block_cipher = None
59
60 # see https://github.com/pyinstaller/pyinstaller/issues/2005
61 hiddenimports = []
62 hiddenimports += collect_submodules('pkg_resources') # workaround for https://github.com/pypa/setuptools/issues/1963
63 hiddenimports += collect_submodules('trezorlib')
64 hiddenimports += collect_submodules('safetlib')
65 hiddenimports += collect_submodules('btchip')
66 hiddenimports += collect_submodules('keepkeylib')
67 hiddenimports += collect_submodules('websocket')
68 hiddenimports += collect_submodules('ckcc')
69 hiddenimports += collect_submodules('bitbox02')
70 hiddenimports += ['PyQt5.QtPrintSupport'] # needed by Revealer
71
72 datas = [
73 (electrum + PYPKG + '/*.json', PYPKG),
74 (electrum + PYPKG + '/lnwire/*.csv', PYPKG + '/lnwire'),
75 (electrum + PYPKG + '/wordlist/english.txt', PYPKG + '/wordlist'),
76 (electrum + PYPKG + '/locale', PYPKG + '/locale'),
77 (electrum + PYPKG + '/plugins', PYPKG + '/plugins'),
78 (electrum + PYPKG + '/gui/icons', PYPKG + '/gui/icons'),
79 ]
80 datas += collect_data_files('trezorlib')
81 datas += collect_data_files('safetlib')
82 datas += collect_data_files('btchip')
83 datas += collect_data_files('keepkeylib')
84 datas += collect_data_files('ckcc')
85 datas += collect_data_files('bitbox02')
86
87 # Add the QR Scanner helper app
88 datas += [(electrum + "contrib/osx/CalinsQRReader/build/Release/CalinsQRReader.app", "./contrib/osx/CalinsQRReader/build/Release/CalinsQRReader.app")]
89
90 # Add libusb so Trezor and Safe-T mini will work
91 binaries = [(electrum + "contrib/osx/libusb-1.0.dylib", ".")]
92 binaries += [(electrum + "contrib/osx/libsecp256k1.0.dylib", ".")]
93
94 # Workaround for "Retro Look":
95 binaries += [b for b in collect_dynamic_libs('PyQt5') if 'macstyle' in b[0]]
96
97 # We don't put these files in to actually include them in the script but to make the Analysis method scan them for imports
98 a = Analysis([electrum+ MAIN_SCRIPT,
99 electrum+'electrum/gui/qt/main_window.py',
100 electrum+'electrum/gui/text.py',
101 electrum+'electrum/util.py',
102 electrum+'electrum/wallet.py',
103 electrum+'electrum/simple_config.py',
104 electrum+'electrum/bitcoin.py',
105 electrum+'electrum/dnssec.py',
106 electrum+'electrum/commands.py',
107 electrum+'electrum/plugins/cosigner_pool/qt.py',
108 electrum+'electrum/plugins/email_requests/qt.py',
109 electrum+'electrum/plugins/trezor/qt.py',
110 electrum+'electrum/plugins/safe_t/client.py',
111 electrum+'electrum/plugins/safe_t/qt.py',
112 electrum+'electrum/plugins/keepkey/qt.py',
113 electrum+'electrum/plugins/ledger/qt.py',
114 electrum+'electrum/plugins/coldcard/qt.py',
115 ],
116 binaries=binaries,
117 datas=datas,
118 hiddenimports=hiddenimports,
119 hookspath=[])
120
121 # http://stackoverflow.com/questions/19055089/pyinstaller-onefile-warning-pyconfig-h-when-importing-scipy-or-scipy-signal
122 for d in a.datas:
123 if 'pyconfig' in d[0]:
124 a.datas.remove(d)
125 break
126
127 # Strip out parts of Qt that we never use. Reduces binary size by tens of MBs. see #4815
128 qt_bins2remove=('qtweb', 'qt3d', 'qtgame', 'qtdesigner', 'qtquick', 'qtlocation', 'qttest', 'qtxml')
129 print("Removing Qt binaries:", *qt_bins2remove)
130 for x in a.binaries.copy():
131 for r in qt_bins2remove:
132 if x[0].lower().startswith(r):
133 a.binaries.remove(x)
134 print('----> Removed x =', x)
135
136 # If code signing, monkey-patch in a code signing step to pyinstaller. See: https://github.com/spesmilo/electrum/issues/4994
137 if APP_SIGN:
138 monkey_patch_pyinstaller_for_codesigning(APP_SIGN)
139
140 pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
141
142 exe = EXE(
143 pyz,
144 a.scripts,
145 exclude_binaries=True,
146 name=MAIN_SCRIPT,
147 debug=False,
148 strip=False,
149 upx=True,
150 icon=electrum+ICONS_FILE,
151 console=False,
152 )
153
154 app = BUNDLE(
155 exe,
156 a.binaries,
157 a.zipfiles,
158 a.datas,
159 version = VERSION,
160 name=PACKAGE + '.app',
161 icon=electrum+ICONS_FILE,
162 bundle_identifier=None,
163 info_plist={
164 'NSHighResolutionCapable': 'True',
165 'NSSupportsAutomaticGraphicsSwitching': 'True'
166 },
167 )