# -*- 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.