official 0.1.0 version
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from PyInstaller.building.api import COLLECT, EXE, PYZ
|
||||
@@ -13,6 +15,50 @@ SPEC_DIR = Path(SPECPATH).resolve()
|
||||
REPO_ROOT = SPEC_DIR.parents[1]
|
||||
BRANDING_DIR = REPO_ROOT / "shared" / "resources" / "branding"
|
||||
ENTRY = SPEC_DIR / "entry.py"
|
||||
#: What ``setup.ps1`` recorded about this machine (interpreter, and where its runtime DLLs
|
||||
#: live when that interpreter is not a python.org one).
|
||||
BUILD_ENV_STAMP = REPO_ROOT / ".venv-build" / "orisys-build-env.json"
|
||||
|
||||
#: The runtime DLLs an Anaconda interpreter keeps in ``<prefix>\Library\bin`` or
|
||||
#: ``<prefix>\DLLs``. PyInstaller does not search those directories, so a frozen app built
|
||||
#: without them dies before it can log anything:
|
||||
#: ``ImportError: DLL load failed while importing pyexpat`` (libexpat)
|
||||
#: ``ImportError: DLL load failed while importing _ctypes`` (ffi-8)
|
||||
#: Building with python.org CPython avoids the whole list; when ``setup.ps1`` accepts a conda
|
||||
#: interpreter it records the directory, and this is where that decision is honoured.
|
||||
_RUNTIME_DLLS = (
|
||||
"libexpat.dll",
|
||||
"expat.dll",
|
||||
"ffi-8.dll",
|
||||
"ffi-7.dll",
|
||||
"ffi.dll",
|
||||
"libssl-3-x64.dll",
|
||||
"libcrypto-3-x64.dll",
|
||||
"sqlite3.dll",
|
||||
"liblzma.dll",
|
||||
"libbz2.dll",
|
||||
"zlib.dll",
|
||||
)
|
||||
|
||||
|
||||
def _extra_runtime_binaries() -> list[tuple[str, str]]:
|
||||
"""Runtime DLLs from a non-python.org interpreter, as ``(source, dest)`` pairs."""
|
||||
folders: list[str] = []
|
||||
try:
|
||||
stamp = json.loads(BUILD_ENV_STAMP.read_text(encoding="utf-8"))
|
||||
folders.extend(str(item) for item in (stamp.get("extra_dll_dirs") or ()))
|
||||
except Exception:
|
||||
# No stamp (a spec run by hand): fall back to the environment, if it says it is conda.
|
||||
prefix = os.environ.get("CONDA_PREFIX")
|
||||
if prefix:
|
||||
folders.append(os.path.join(prefix, "Library", "bin"))
|
||||
out: list[tuple[str, str]] = []
|
||||
for folder in folders:
|
||||
for name in _RUNTIME_DLLS:
|
||||
candidate = Path(folder) / name
|
||||
if candidate.is_file():
|
||||
out.append((str(candidate), "."))
|
||||
return out
|
||||
|
||||
|
||||
def _branding_datas() -> list[tuple[str, str]]:
|
||||
@@ -30,7 +76,7 @@ block_cipher = None
|
||||
# Config is copied beside the EXE by build.ps1 (writable / editable).
|
||||
# Branding + package data go into _internal via Analysis datas.
|
||||
datas = _branding_datas()
|
||||
binaries: list = []
|
||||
binaries: list = _extra_runtime_binaries()
|
||||
hiddenimports = [
|
||||
"cv2",
|
||||
"PyQt5.sip",
|
||||
@@ -68,7 +114,12 @@ a = Analysis(
|
||||
runtime_hooks=[],
|
||||
excludes=[
|
||||
"open3d",
|
||||
"orisys.finger.viewer",
|
||||
# NOTE: `orisys.finger` imports `.viewer` at module level, and `finger/viewer.py`
|
||||
# imports open3d *inside* its functions — so bundling it costs a few KB of Python and
|
||||
# pulls in no Open3D. Excluding it made `import orisys.finger` raise
|
||||
# ModuleNotFoundError in the frozen app, which took the whole window down with it
|
||||
# (the app cannot even reach logging). The `open3d` entry above is the one that
|
||||
# matters.
|
||||
"tkinter",
|
||||
"matplotlib",
|
||||
"IPython",
|
||||
|
||||
Reference in New Issue
Block a user