summaryrefslogtreecommitdiffstats
path: root/packaging/win/meshbay-node.spec
diff options
context:
space:
mode:
Diffstat (limited to 'packaging/win/meshbay-node.spec')
-rw-r--r--packaging/win/meshbay-node.spec126
1 files changed, 126 insertions, 0 deletions
diff --git a/packaging/win/meshbay-node.spec b/packaging/win/meshbay-node.spec
new file mode 100644
index 0000000..f1f994d
--- /dev/null
+++ b/packaging/win/meshbay-node.spec
@@ -0,0 +1,126 @@
+# PyInstaller spec for the bundled Windows node daemon.
+#
+# Output: dist/meshbay-node/meshbay-node.exe (--onedir, relocatable)
+# Consumed by: packaging/win/build-node-runtime.ps1, which moves the tree to
+# packages/meshbay-client/node-runtime/ for electron-builder to carry as an
+# extraResource.
+#
+# The dependency set (aiortc, av, aioquic, pydantic-core, uvicorn, watchdog,
+# guessit, blake3, ...) has C/Rust extensions and does dynamic imports, so
+# each awkward package is pulled in whole with collect_all rather than left to
+# PyInstaller's static analysis. Add to COLLECT_ALL / HIDDEN / COPY_META when a
+# frozen run raises ModuleNotFoundError — that is the expected way this list grows.
+
+from PyInstaller.utils.hooks import collect_all, copy_metadata
+
+# Packages taken in full: data files + shared libs + every submodule.
+COLLECT_ALL = [
+ "meshbay_node",
+ "meshbay_common",
+ "aiortc",
+ "aioice",
+ "aioquic",
+ "av",
+ "cryptography",
+ "pylibsrtp",
+ "pyee",
+ "google_crc32c",
+ "pydantic",
+ "pydantic_core",
+ "fastapi",
+ "starlette",
+ "uvicorn",
+ "anyio",
+ "sniffio",
+ "h11",
+ "websockets",
+ "httpx",
+ "httpcore",
+ "watchdog",
+ "guessit",
+ "rebulk",
+ "babelfish",
+ "mutagen",
+ "PIL",
+ "blake3",
+ "msgpack",
+ "zstandard",
+ "aiosqlite",
+ "jwt",
+ "dns",
+ "tzdata",
+]
+
+# importlib.metadata lookups that survive freezing only if the dist-info is copied.
+COPY_META = [
+ "meshbay-node",
+ "meshbay-common",
+ "guessit",
+ "rebulk",
+ "babelfish",
+ "uvicorn",
+ "fastapi",
+]
+
+# Imports PyInstaller's static pass misses even with collect_all.
+HIDDEN = [
+ "uvicorn.logging",
+ "uvicorn.loops.auto",
+ "uvicorn.loops.asyncio",
+ "uvicorn.protocols.http.auto",
+ "uvicorn.protocols.http.h11_impl",
+ "uvicorn.protocols.websockets.auto",
+ "uvicorn.protocols.websockets.websockets_impl",
+ "uvicorn.lifespan.on",
+]
+
+datas, binaries, hiddenimports = [], [], list(HIDDEN)
+for pkg in COLLECT_ALL:
+ d, b, h = collect_all(pkg)
+ datas += d
+ binaries += b
+ hiddenimports += h
+for dist in COPY_META:
+ datas += copy_metadata(dist)
+
+a = Analysis(
+ ["node-entry.py"],
+ pathex=[],
+ binaries=binaries,
+ datas=datas,
+ hiddenimports=hiddenimports,
+ hookspath=[],
+ hooksconfig={},
+ runtime_hooks=[],
+ excludes=["tkinter", "pytest", "ruff", "piexif", "IPython"],
+ noarchive=False,
+)
+pyz = PYZ(a.pure)
+
+exe = EXE(
+ pyz,
+ a.scripts,
+ [],
+ exclude_binaries=True,
+ name="meshbay-node",
+ debug=False,
+ bootloader_ignore_signals=False,
+ strip=False,
+ upx=False,
+ console=True,
+ disable_windowed_traceback=False,
+ argv_emulation=False,
+ target_arch=None,
+ codesign_identity=None,
+ entitlements_file=None,
+ icon="../../packages/meshbay-client/build/icon.ico",
+)
+coll = COLLECT(
+ exe,
+ a.binaries,
+ a.datas,
+ strip=False,
+ upx=False,
+ upx_exclude=[],
+ name="meshbay-node",
+)