- README: 补充项目概述、技术栈、架构图(Mermaid)、插件生命周期时序图 - build.py: 补充模块和函数 docstring - core/__init__.py: 修正模块说明(工具箱→插件系统) - log.py: 修复过时注释,清理死代码,抑制第三方库日志刷屏 - plugin_registry.py: 修正矛盾注释,补充缺失日志,隐藏远程路径 - plugins.py: 修正过时注释,清理死代码和无用导入 - plugins_card.py: 修正错误类名注释,补充全量 docstring - main.py: 修正错误注释,补充启动/退出/插件加载日志
92 lines
2.6 KiB
Python
92 lines
2.6 KiB
Python
"""Nuitka 打包构建脚本。
|
|
|
|
将 main.py 编译为 Windows 独立可执行文件,并打包为便携式 zip。
|
|
需要安装 Nuitka 和 mingw64 编译器。
|
|
|
|
用法:
|
|
python build.py
|
|
"""
|
|
import os
|
|
import sys
|
|
import glob
|
|
import platform
|
|
import subprocess
|
|
from pathlib import Path
|
|
from zipfile import ZIP_DEFLATED, ZipFile
|
|
|
|
from main import APP_NAME, APP_VERSION
|
|
|
|
# 编译器选择
|
|
COMPILER = "mingw64"
|
|
|
|
# 输出路径
|
|
OUTPUT_PATH = Path('output')
|
|
RESOURCES_PATH = Path("resources")
|
|
RELEASE_PATH = OUTPUT_PATH / APP_NAME
|
|
BUILD_PATH = OUTPUT_PATH / f'{platform.system().lower()}-{platform.machine().lower()}'
|
|
|
|
|
|
def build_main():
|
|
"""使用 Nuitka 编译 main.py 为独立可执行文件。
|
|
|
|
编译选项:
|
|
- --standalone:不依赖本地 Python 环境
|
|
- --plugin-enable=pyside6:启用 PySide6 支持
|
|
- --include-module=runtime_hook:将启动钩子编入 exe
|
|
- --windows-console-mode=disable:不显示控制台窗口
|
|
"""
|
|
nuitka_cmd = [
|
|
sys.executable,
|
|
'-m',
|
|
'nuitka',
|
|
'--standalone',
|
|
'--show-memory',
|
|
'--show-progress',
|
|
'--plugin-enable=pyside6',
|
|
'--include-module=qt_material',
|
|
'--include-module=runtime_hook',
|
|
f"--include-data-dir={RESOURCES_PATH}=resources",
|
|
]
|
|
|
|
icon_path = str(RESOURCES_PATH / "main.ico")
|
|
if os.path.exists(icon_path):
|
|
nuitka_cmd.extend([
|
|
f'--windows-icon-from-ico={icon_path}',
|
|
])
|
|
nuitka_cmd.append(f'--output-dir={BUILD_PATH}')
|
|
if platform.system() == 'Windows':
|
|
nuitka_cmd.append('--windows-console-mode=disable')
|
|
nuitka_cmd.append(f'--{COMPILER}')
|
|
|
|
nuitka_cmd.append('./main.py')
|
|
|
|
result = subprocess.run(nuitka_cmd,shell=True)
|
|
if result.returncode != 0:
|
|
raise RuntimeError('Nuitka building failed.')
|
|
|
|
print('Building done.')
|
|
|
|
|
|
def create_zip():
|
|
"""将 Nuitka 编译产物打包为便携式 zip 文件。"""
|
|
file_list = glob.glob(f'{BUILD_PATH / APP_NAME / "dist"}', recursive=True)
|
|
file_list.sort()
|
|
|
|
if not os.path.exists(RELEASE_PATH):
|
|
os.mkdir(RELEASE_PATH)
|
|
|
|
portable_file = RELEASE_PATH / f'{APP_NAME}-{platform.system()}-{platform.machine()}-{APP_VERSION}.zip'
|
|
print('Creating portable package...')
|
|
|
|
with ZipFile(portable_file, 'w', compression=ZIP_DEFLATED) as zf:
|
|
for file in file_list:
|
|
file = Path(file)
|
|
name_in_zip = f'{APP_NAME}/{"/".join(file.parts[3:])}'
|
|
print(name_in_zip)
|
|
zf.write(file, name_in_zip)
|
|
|
|
print('Creating portable package done.')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
build_main() |