Skip to content

Commit 6bc9790

Browse files
committed
Excluding system libraries from PyInstaller (experimental)
1 parent a23aeae commit 6bc9790

4 files changed

Lines changed: 111 additions & 16 deletions

File tree

BUILDING.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,28 @@
33
To build Timecard, we recommend using Python 3.7 and creating a virtual
44
environment.
55

6-
Run the following in a virtual environment to build Timecard:
6+
If you're on a Linux system, you can use the provided Makefile:
7+
8+
```
9+
make build
10+
```
11+
12+
Alternatively, run the following in a virtual environment to build Timecard:
713

814
```
915
pip install pyinstaller
1016
pip install -r requirements.txt
1117
pyinstaller --clean --windowed timecard_app.spec
1218
```
1319

14-
The distribution folder is `dist/timecard_app`. To start the application,
15-
run `dist/timecard_app/timecard_app`.
20+
The distribution folder is `dist/timecard_app`, and the standalone binary is
21+
at `dist/timecard_app/timecard_app`.
1622

1723
## Debian Package
1824

1925
The Debian packaging is configured to build an executable using
2026
a virtual environment and PyInstaller. Standard Debian packaging commands
2127
apply.
28+
29+
WARNING: This should be considered experimental right now. I have yet to add
30+
the rest of the dependencies stripped out of the PyInstaller.

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
#!/usr/bin/make -f
22

3+
none:
4+
@echo "build Build as single file."
5+
@echo "build_folder Build as single folder."
6+
@echo "clean Clean build artifacts."
7+
38
clean:
49
rm -rf dist/
510
rm -rf build/

timecard_app.spec

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,47 @@
11
# -*- mode: python ; coding: utf-8 -*-
22

3+
def filter_binaries(all_binaries):
4+
exclude_binaries = set()
5+
for binary, path, type in all_binaries:
6+
if type != "BINARY":
7+
continue
8+
if "site-packages" in path:
9+
continue
10+
if "libpython3" in binary:
11+
continue
12+
13+
exclude_binaries.add((binary, path, type))
14+
15+
binaries = [x for x in all_binaries if x not in exclude_binaries]
16+
17+
with open('dist/binary_list.txt', 'w') as file:
18+
for name, path, type in binaries:
19+
print(f".. Including {type} {path}")
20+
file.write(f"Including {type} {path}.\n")
21+
22+
file.write("\n")
23+
24+
for name, path, type in exclude_binaries:
25+
print(f">> EXCLUDING {type} {path}")
26+
file.write(f"EXCLUDING {type} {path}.\n")
27+
28+
file.write("\n")
29+
30+
info = "On Debian, use `dpkg -S <pkg_name> to find dependency packages."
31+
32+
print(info)
33+
file.write(f"{info}\n")
34+
35+
return binaries
36+
337
block_cipher = None
438

539
added_files = [
640
('timecard/resources', 'timecard/resources')
741
]
842

943
a = Analysis(['timecard_app.py'],
10-
pathex=['/home/jason/Code/Repositories/timecard'],
44+
pathex=['./timecard'],
1145
binaries=[],
1246
datas=added_files,
1347
hiddenimports=['PySide2'],
@@ -17,20 +51,26 @@ a = Analysis(['timecard_app.py'],
1751
win_no_prefer_redirects=False,
1852
win_private_assemblies=False,
1953
cipher=block_cipher,
20-
noarchive=False)
21-
pyz = PYZ(a.pure, a.zipped_data,
22-
cipher=block_cipher)
54+
noarchive=False
55+
)
56+
57+
pyz = PYZ(a.pure,
58+
a.zipped_data,
59+
cipher=block_cipher
60+
)
61+
2362
exe = EXE(pyz,
2463
a.scripts,
25-
a.binaries,
64+
filter_binaries(a.binaries),
2665
a.zipfiles,
2766
a.datas,
2867
[],
29-
name='timecard',
68+
name='timecard_app',
3069
debug=False,
3170
bootloader_ignore_signals=False,
3271
strip=False,
3372
upx=True,
3473
upx_exclude=[],
3574
runtime_tmpdir=None,
36-
console=False )
75+
console=False
76+
)

timecard_app_folder.spec

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,47 @@
11
# -*- mode: python ; coding: utf-8 -*-
22

3+
def filter_binaries(all_binaries):
4+
exclude_binaries = set()
5+
for binary, path, type in all_binaries:
6+
if type != "BINARY":
7+
continue
8+
if "site-packages" in path:
9+
continue
10+
if "libpython3" in binary:
11+
continue
12+
13+
exclude_binaries.add((binary, path, type))
14+
15+
binaries = [x for x in all_binaries if x not in exclude_binaries]
16+
17+
with open('dist/binary_list.txt', 'w') as file:
18+
for name, path, type in binaries:
19+
print(f".. Including {type} {path}")
20+
file.write(f"Including {type} {path}.\n")
21+
22+
file.write("\n")
23+
24+
for name, path, type in exclude_binaries:
25+
print(f">> EXCLUDING {type} {path}")
26+
file.write(f"EXCLUDING {type} {path}.\n")
27+
28+
file.write("\n")
29+
30+
info = "On Debian, use `dpkg -S <pkg_name> to find dependency packages."
31+
32+
print(info)
33+
file.write(f"{info}\n")
34+
35+
return binaries
36+
337
block_cipher = None
438

539
added_files = [
640
('timecard/resources', 'timecard/resources')
741
]
842

943
a = Analysis(['timecard_app.py'],
10-
pathex=['/home/jason/Code/Repositories/timecard'],
44+
pathex=['./timecard'],
1145
binaries=[],
1246
datas=added_files,
1347
hiddenimports=['PySide2'],
@@ -17,9 +51,14 @@ a = Analysis(['timecard_app.py'],
1751
win_no_prefer_redirects=False,
1852
win_private_assemblies=False,
1953
cipher=block_cipher,
20-
noarchive=False)
21-
pyz = PYZ(a.pure, a.zipped_data,
22-
cipher=block_cipher)
54+
noarchive=False
55+
)
56+
57+
pyz = PYZ(a.pure,
58+
a.zipped_data,
59+
cipher=block_cipher
60+
)
61+
2362
exe = EXE(pyz,
2463
a.scripts,
2564
[],
@@ -29,9 +68,11 @@ exe = EXE(pyz,
2968
bootloader_ignore_signals=False,
3069
strip=False,
3170
upx=True,
32-
console=False )
71+
console=False
72+
)
73+
3374
coll = COLLECT(exe,
34-
a.binaries,
75+
filter_binaries(a.binaries),
3576
a.zipfiles,
3677
a.datas,
3778
strip=False,

0 commit comments

Comments
 (0)