1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
# -*- mode: python ; coding: utf-8 -*-
import glob
import os
import sys
def find_libffi_dll():
"""
Find the libffi-*.dll file required for _ctypes on Windows.
Searches in common locations for standard, venv, and Conda Python.
"""
if sys.platform != "win32":
return []
print("--- PyInstaller Build Environment ---")
print(f" - Python Executable: {sys.executable}")
print(f" - sys.prefix: {sys.prefix}")
if hasattr(sys, "base_prefix"):
print(f" - sys.base_prefix: {sys.base_prefix}")
else:
print(" - sys.base_prefix: Not available")
conda_prefix = os.environ.get("CONDA_PREFIX")
print(f" - CONDA_PREFIX env var: {conda_prefix}")
search_paths = []
# Active environment's DLLs directory
search_paths.append(os.path.join(sys.prefix, "DLLs"))
# Base Python installation's directories (if in a venv)
if hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix:
search_paths.append(os.path.join(sys.base_prefix, "DLLs"))
search_paths.append(os.path.join(sys.base_prefix, "Library", "bin"))
# Conda environment's directory (if CONDA_PREFIX is set)
if conda_prefix:
search_paths.append(os.path.join(conda_prefix, "Library", "bin"))
print("\n--- Potential Search Paths for libffi ---")
for p in search_paths:
print(f" - Path: {p}, Exists? {os.path.isdir(p)}")
print("\n--- Searching for libffi DLL on Windows ---")
unique_paths = sorted(list(set(p for p in search_paths if os.path.isdir(p))))
for path in unique_paths:
print(f" - Checking: {path}")
dll_pattern = os.path.join(path, "libffi-*.dll")
found_dlls = glob.glob(dll_pattern)
if found_dlls:
dll_path = found_dlls[0]
print(f" - Found: {dll_path}")
return [(dll_path, ".")] # (source, destination_in_bundle)
print("\nERROR: Could not find libffi-*.dll on Windows.")
sys.exit(1)
# --- PyInstaller Spec ---
app_name = 'PicoStream'
binaries = find_libffi_dll() if sys.platform == "win32" else []
a = Analysis(
['picostream/main.py'],
pathex=[],
binaries=binaries,
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=None,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=None)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name=app_name,
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True, # useful for debugging for now
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=None,
)
# NOTE: The absence of a COLLECT block is what defines a one-file build.
|