|
3 | 3 | # * LD_LIBRARY_PATH=`echo $(python3-config --prefix)/lib` pyinstaller -F splitgraph.spec produces a single sgr binary in the dist/ folder
|
4 | 4 | # with libc being the only dynamic dependency (python interpreter included)
|
5 | 5 | # * can also do poetry install && poetry run pyinstaller -F splitgraph.spec to build the binary inside of the poetry's venv.
|
| 6 | +# * specifying `--onedir` instead of `-F` will compile a multi-file executable with COLLECT() |
| 7 | +# * e.g. : pyinstaller --clean --noconfirm --onedir splitgraph.spec |
6 | 8 |
|
| 9 | +import sys |
7 | 10 | import os
|
8 | 11 | import importlib
|
9 | 12 |
|
| 13 | +# Pass --onedir or -D to build a multi-file executable (dir with shlibs + exe) |
| 14 | +# Note: This is the same flag syntax as pyinstaller uses, but when using a |
| 15 | +# .spec file with pyinstaller, the flag is normally ignored, so we |
| 16 | +# explicitly check for it here. This way we can pass different arguments |
| 17 | +# to EXE() and conditionally call COLLECTION() without duplicating code. |
| 18 | +MAKE_EXE_COLLECTION = False |
| 19 | +if "--onedir" in sys.argv or "-D" in sys.argv: |
| 20 | + print("splitgraph.spec : --onedir was specified. Will build a multi-file executable...") |
| 21 | + MAKE_EXE_COLLECTION = True |
| 22 | + |
10 | 23 | block_cipher = None
|
11 | 24 |
|
12 | 25 | datas = []
|
@@ -43,18 +56,36 @@ a = Analysis(
|
43 | 56 | a.datas += Tree("./splitgraph/resources", "splitgraph/resources")
|
44 | 57 |
|
45 | 58 | pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
46 |
| -exe = EXE( |
47 |
| - pyz, |
48 |
| - a.scripts, |
49 |
| - a.binaries, |
50 |
| - a.zipfiles, |
51 |
| - a.datas, |
52 |
| - [], |
53 |
| - name="sgr", |
54 |
| - debug=False, |
55 |
| - bootloader_ignore_signals=False, |
56 |
| - strip=False, |
57 |
| - upx=True, |
58 |
| - runtime_tmpdir=None, |
59 |
| - console=True, |
60 |
| -) |
| 59 | + |
| 60 | +# Note: `exe` global is injected by pyinstaller. Can see the code for EXE at: |
| 61 | +# https://github.com/pyinstaller/pyinstaller/blob/15f23a8a89be5453b3520df8fc3e667346e103a6/PyInstaller/building/api.py |
| 62 | + |
| 63 | +# TOCS to include in EXE() when in single-file mode (default, i.e. no --onedir flag) |
| 64 | +all_tocs = [a.scripts, a.binaries, a.zipfiles, a.datas] |
| 65 | +# TOCS to include in EXE() when in multi-file mode (i.e., --onedir flag) |
| 66 | +exe_tocs = [a.scripts] |
| 67 | +# TOCS to include in COLL() when in multi-file mode (i.e., --onedir flag) |
| 68 | +coll_tocs = [a.binaries, a.zipfiles, a.datas] |
| 69 | + |
| 70 | +# When compiling single-file executable, we include every TOC in the EXE |
| 71 | +# When compiling multi-file executable, include some TOC in EXE, and rest in COLL |
| 72 | +exe_args = [pyz, *exe_tocs, []] if MAKE_EXE_COLLECTION else [pyz, *all_tocs, []] |
| 73 | + |
| 74 | +exe_kwargs_base = { |
| 75 | + "name": "sgr", |
| 76 | + "debug": False, |
| 77 | + "bootloader_ignore_signals": False, |
| 78 | + "strip_binaries": False, |
| 79 | + "runtime_tmpdir": None, |
| 80 | + "console": True, |
| 81 | +} |
| 82 | +# In multi-file mode, we exclude_binaries from EXE since they will be in COLL |
| 83 | +exe_kwargs_onedir = {**exe_kwargs_base, "upx": False, "exclude_binaries": True} |
| 84 | +# In single-file mode, we set upx: true because it works. (It might actually work in multi-file mode too) |
| 85 | +exe_kwargs_onefile = {**exe_kwargs_base, "upx": True, "exclude_binaries": False} |
| 86 | +exe_kwargs = exe_kwargs_onedir if MAKE_EXE_COLLECTION else exe_kwargs_onefile |
| 87 | + |
| 88 | +exe = EXE(*exe_args, **exe_kwargs) |
| 89 | + |
| 90 | +if MAKE_EXE_COLLECTION: |
| 91 | + coll = COLLECT(exe, *coll_tocs, name="sgr-pkg", strip=False, upx=False) |
0 commit comments