131 lines
5.0 KiB
RPMSpec
131 lines
5.0 KiB
RPMSpec
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
|
"""PyInstaller 打包配置。
|
|||
|
|
|
|||
|
|
由 ``packaging/build_pyinstaller.py`` 调用 —— 选项通过**环境变量**传进来
|
|||
|
|
(spec 文件本身不接受命令行参数,这是 PyInstaller 的既定用法):
|
|||
|
|
|
|||
|
|
=========================== ==========================================
|
|||
|
|
环境变量 作用
|
|||
|
|
=========================== ==========================================
|
|||
|
|
``CLG_NAME`` 产物名(默认 chongming-license-gui)
|
|||
|
|
``CLG_ONEFILE`` ``1`` = 单文件(默认),``0`` = 目录模式
|
|||
|
|
``CLG_CONSOLE`` ``1`` = 带控制台窗口(排查启动问题用)
|
|||
|
|
``CLG_ICON`` .ico 路径(由 ``_common.build_app_icon()`` 生成)
|
|||
|
|
=========================== ==========================================
|
|||
|
|
"""
|
|||
|
|
import os
|
|||
|
|
from pathlib import Path
|
|||
|
|
|
|||
|
|
ROOT = Path(SPECPATH).resolve().parent # noqa: F821 - SPECPATH 由 PyInstaller 注入
|
|||
|
|
|
|||
|
|
NAME = os.environ.get("CLG_NAME", "chongming-license-gui")
|
|||
|
|
ONEFILE = os.environ.get("CLG_ONEFILE", "1") == "1"
|
|||
|
|
CONSOLE = os.environ.get("CLG_CONSOLE", "0") == "1"
|
|||
|
|
ICON = os.environ.get("CLG_ICON") or None
|
|||
|
|
|
|||
|
|
# PySide6 装了整套 Addons(Qt3D / WebEngine / Charts…),本工具一个都不用。
|
|||
|
|
# PyInstaller 的 PySide6 hook 只打包"被 import 到的" Qt 模块,但显式排除能兜住
|
|||
|
|
# 间接依赖,避免几百 MB 的模块被拖进来。
|
|||
|
|
# 注:排除不存在的模块是安全的(PyInstaller 只按名字匹配)。
|
|||
|
|
EXCLUDES = [
|
|||
|
|
# 3D / 图形 / 可视化
|
|||
|
|
"PySide6.Qt3DAnimation", "PySide6.Qt3DCore", "PySide6.Qt3DExtras",
|
|||
|
|
"PySide6.Qt3DInput", "PySide6.Qt3DLogic", "PySide6.Qt3DRender",
|
|||
|
|
"PySide6.QtCharts", "PySide6.QtDataVisualization", "PySide6.QtGraphs",
|
|||
|
|
"PySide6.QtGraphsWidgets", "PySide6.QtCanvasPainter",
|
|||
|
|
# Web / QML / Quick(体积最大的一批)
|
|||
|
|
"PySide6.QtWebEngineCore", "PySide6.QtWebEngineWidgets",
|
|||
|
|
"PySide6.QtWebEngineQuick", "PySide6.QtWebView", "PySide6.QtWebChannel",
|
|||
|
|
"PySide6.QtWebSockets", "PySide6.QtHttpServer",
|
|||
|
|
"PySide6.QtQml", "PySide6.QtQuick", "PySide6.QtQuick3D",
|
|||
|
|
"PySide6.QtQuickControls2", "PySide6.QtQuickWidgets", "PySide6.QtQuickTest",
|
|||
|
|
# 多媒体 / 设备 / 传感器
|
|||
|
|
"PySide6.QtMultimedia", "PySide6.QtMultimediaWidgets", "PySide6.QtSpatialAudio",
|
|||
|
|
"PySide6.QtTextToSpeech", "PySide6.QtBluetooth", "PySide6.QtNfc",
|
|||
|
|
"PySide6.QtPositioning", "PySide6.QtLocation", "PySide6.QtSensors",
|
|||
|
|
"PySide6.QtSerialPort", "PySide6.QtSerialBus", "PySide6.QtRemoteObjects",
|
|||
|
|
"PySide6.QtScxml", "PySide6.QtStateMachine", "PySide6.QtAxContainer",
|
|||
|
|
# 文档 / 设计器 / 测试 / 数据库 / 容器
|
|||
|
|
"PySide6.QtPdf", "PySide6.QtPdfWidgets", "PySide6.QtDesigner",
|
|||
|
|
"PySide6.QtUiTools", "PySide6.QtHelp", "PySide6.QtTest",
|
|||
|
|
"PySide6.QtSql", "PySide6.QtDBus", "PySide6.QtConcurrent",
|
|||
|
|
"PySide6.QtNetworkAuth", "PySide6.QtXml", "PySide6.QtSvgWidgets",
|
|||
|
|
"PySide6.QtOpenGL", "PySide6.QtOpenGLWidgets",
|
|||
|
|
# 与本工具无关的标准库大件
|
|||
|
|
"tkinter", "pydoc_data",
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
a = Analysis( # noqa: F821
|
|||
|
|
[str(ROOT / "packaging" / "launcher.py")],
|
|||
|
|
# 用源码树解析本包,而不是依赖 editable 安装(冻结工具对 .pth 式
|
|||
|
|
# editable 安装的解析并不可靠)
|
|||
|
|
pathex=[str(ROOT / "src")],
|
|||
|
|
binaries=[],
|
|||
|
|
datas=[], # 无数据文件:图标与样式表都是运行时生成的
|
|||
|
|
# PySide6.QtSvg 是显式 import,正常能被扫到;这里再钉一遍 —— 少了它
|
|||
|
|
# 图标会全部变空白,而且不报错
|
|||
|
|
hiddenimports=["PySide6.QtSvg"],
|
|||
|
|
hookspath=[],
|
|||
|
|
hooksconfig={},
|
|||
|
|
runtime_hooks=[],
|
|||
|
|
excludes=EXCLUDES,
|
|||
|
|
noarchive=False,
|
|||
|
|
optimize=0,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
pyz = PYZ(a.pure) # noqa: F821
|
|||
|
|
|
|||
|
|
if ONEFILE:
|
|||
|
|
# 单文件:自解压到临时目录再运行(分发最省事,首次启动稍慢)
|
|||
|
|
exe = EXE( # noqa: F821
|
|||
|
|
pyz,
|
|||
|
|
a.scripts,
|
|||
|
|
a.binaries,
|
|||
|
|
a.datas,
|
|||
|
|
[],
|
|||
|
|
name=NAME,
|
|||
|
|
debug=False,
|
|||
|
|
bootloader_ignore_signals=False,
|
|||
|
|
strip=False,
|
|||
|
|
# UPX 压缩容易触发杀软误报,也会损坏部分 Qt DLL,明确关掉
|
|||
|
|
upx=False,
|
|||
|
|
upx_exclude=[],
|
|||
|
|
runtime_tmpdir=None,
|
|||
|
|
console=CONSOLE,
|
|||
|
|
disable_windowed_traceback=False,
|
|||
|
|
argv_emulation=False,
|
|||
|
|
target_arch=None,
|
|||
|
|
codesign_identity=None,
|
|||
|
|
entitlements_file=None,
|
|||
|
|
icon=ICON,
|
|||
|
|
)
|
|||
|
|
else:
|
|||
|
|
# 目录模式:启动更快,适合放在固定办公机上长期使用
|
|||
|
|
exe = EXE( # noqa: F821
|
|||
|
|
pyz,
|
|||
|
|
a.scripts,
|
|||
|
|
[],
|
|||
|
|
exclude_binaries=True,
|
|||
|
|
name=NAME,
|
|||
|
|
debug=False,
|
|||
|
|
bootloader_ignore_signals=False,
|
|||
|
|
strip=False,
|
|||
|
|
upx=False,
|
|||
|
|
console=CONSOLE,
|
|||
|
|
disable_windowed_traceback=False,
|
|||
|
|
argv_emulation=False,
|
|||
|
|
target_arch=None,
|
|||
|
|
codesign_identity=None,
|
|||
|
|
entitlements_file=None,
|
|||
|
|
icon=ICON,
|
|||
|
|
)
|
|||
|
|
coll = COLLECT( # noqa: F821
|
|||
|
|
exe,
|
|||
|
|
a.binaries,
|
|||
|
|
a.datas,
|
|||
|
|
strip=False,
|
|||
|
|
upx=False,
|
|||
|
|
upx_exclude=[],
|
|||
|
|
name=NAME,
|
|||
|
|
)
|