feat(packaging): embed app icon + version metadata in the frozen exe
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -16,6 +16,8 @@ dist/
|
|||||||
# PyInstaller output
|
# PyInstaller output
|
||||||
/packaging/build/
|
/packaging/build/
|
||||||
/packaging/dist/
|
/packaging/dist/
|
||||||
|
# Generated at build time from cim_suite.__version__ (see packaging/suite.spec)
|
||||||
|
/packaging/_version_info.generated.txt
|
||||||
|
|
||||||
# Packaged portable-build zips — transient test artifacts, regenerated per build
|
# Packaged portable-build zips — transient test artifacts, regenerated per build
|
||||||
/packaging/CIM-Service-Suite_*.zip
|
/packaging/CIM-Service-Suite_*.zip
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
# Setup (ISCC.exe).
|
# Setup (ISCC.exe).
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
block_cipher = None
|
block_cipher = None
|
||||||
|
|
||||||
@@ -16,10 +17,21 @@ block_cipher = None
|
|||||||
# its parent and must be on pathex so `import cim_suite` resolves at build time.
|
# its parent and must be on pathex so `import cim_suite` resolves at build time.
|
||||||
_repo_root = os.path.dirname(SPECPATH)
|
_repo_root = os.path.dirname(SPECPATH)
|
||||||
|
|
||||||
|
# Make `import cim_suite` and the local `verinfo` helper importable while the spec runs.
|
||||||
|
for _p in (_repo_root, SPECPATH):
|
||||||
|
if _p not in sys.path:
|
||||||
|
sys.path.insert(0, _p)
|
||||||
|
|
||||||
|
import cim_suite # noqa: E402 (single-sourced version)
|
||||||
|
import verinfo # noqa: E402 (packaging/verinfo.py)
|
||||||
|
|
||||||
# Bundled brand fonts (Lato) live in the theme package and must be copied into the
|
# Bundled brand fonts (Lato) live in the theme package and must be copied into the
|
||||||
# frozen app at the same package-relative path so theme.fonts can find them.
|
# frozen app at the same package-relative path so theme.fonts can find them.
|
||||||
_font_src = os.path.join(_repo_root, "cim_suite", "core", "ui", "theme", "fonts")
|
_font_src = os.path.join(_repo_root, "cim_suite", "core", "ui", "theme", "fonts")
|
||||||
|
|
||||||
|
# The runtime window icon (cim_suite/shell/branding.py resolves it package-relative).
|
||||||
|
_app_icon_src = os.path.join(_repo_root, "cim_suite", "shell", "resources")
|
||||||
|
|
||||||
# IOModbus ships its device catalog (register maps) as a package resource; it must be
|
# IOModbus ships its device catalog (register maps) as a package resource; it must be
|
||||||
# copied into the frozen app at the same package-relative path so config.catalog_text
|
# copied into the frozen app at the same package-relative path so config.catalog_text
|
||||||
# (importlib.resources) can read it.
|
# (importlib.resources) can read it.
|
||||||
@@ -30,15 +42,26 @@ _iomodbus_res = os.path.join(_repo_root, "cim_suite", "modules", "iomodbus", "re
|
|||||||
_pyproject = os.path.join(_repo_root, "pyproject.toml")
|
_pyproject = os.path.join(_repo_root, "pyproject.toml")
|
||||||
_changelog = os.path.join(_repo_root, "CHANGELOG.md")
|
_changelog = os.path.join(_repo_root, "CHANGELOG.md")
|
||||||
|
|
||||||
|
# End-user run guide shipped at the bundle root (and inside the portable zip).
|
||||||
|
_readme = os.path.join(SPECPATH, "READ-ME-FIRST.txt")
|
||||||
|
|
||||||
|
# Exe icon + Windows version resource, both generated from single sources.
|
||||||
|
_icon = os.path.join(SPECPATH, "icon.ico")
|
||||||
|
_version_file = os.path.join(SPECPATH, "_version_info.generated.txt")
|
||||||
|
with open(_version_file, "w", encoding="utf-8") as _vf:
|
||||||
|
_vf.write(verinfo.render_version_resource(cim_suite.__version__))
|
||||||
|
|
||||||
a = Analysis(
|
a = Analysis(
|
||||||
[os.path.join(SPECPATH, "suite_launcher.py")],
|
[os.path.join(SPECPATH, "suite_launcher.py")],
|
||||||
pathex=[_repo_root],
|
pathex=[_repo_root],
|
||||||
binaries=[],
|
binaries=[],
|
||||||
datas=[
|
datas=[
|
||||||
(_font_src, os.path.join("cim_suite", "core", "ui", "theme", "fonts")),
|
(_font_src, os.path.join("cim_suite", "core", "ui", "theme", "fonts")),
|
||||||
|
(_app_icon_src, os.path.join("cim_suite", "shell", "resources")),
|
||||||
(_iomodbus_res, os.path.join("cim_suite", "modules", "iomodbus", "resources")),
|
(_iomodbus_res, os.path.join("cim_suite", "modules", "iomodbus", "resources")),
|
||||||
(_pyproject, "."),
|
(_pyproject, "."),
|
||||||
(_changelog, "."),
|
(_changelog, "."),
|
||||||
|
(_readme, "."),
|
||||||
],
|
],
|
||||||
hiddenimports=["serial.tools.list_ports", "openpyxl", "PySide6.QtCharts"],
|
hiddenimports=["serial.tools.list_ports", "openpyxl", "PySide6.QtCharts"],
|
||||||
hookspath=[],
|
hookspath=[],
|
||||||
@@ -71,7 +94,8 @@ exe = EXE(
|
|||||||
upx=False,
|
upx=False,
|
||||||
console=False,
|
console=False,
|
||||||
disable_windowed_traceback=False,
|
disable_windowed_traceback=False,
|
||||||
icon=None,
|
icon=_icon,
|
||||||
|
version=_version_file,
|
||||||
)
|
)
|
||||||
coll = COLLECT(
|
coll = COLLECT(
|
||||||
exe,
|
exe,
|
||||||
|
|||||||
Reference in New Issue
Block a user