# -*- mode: python ; coding: utf-8 -*- # Build order: updater.spec FIRST, then main.spec. # main.exe embeds dist/updater.exe so users can deploy main.exe alone; # the embedded updater is auto-extracted next to main.exe on first launch. import os # release.ps1 stages updater.exe at build/staging/updater.exe # (avoids PyInstaller --clean wiping dist/updater.exe before main build). _extra_datas = [] _staged = 'build/staging/updater.exe' _fallback = 'dist/updater.exe' if os.path.exists(_staged): _extra_datas.append((_staged, '.')) elif os.path.exists(_fallback): _extra_datas.append((_fallback, '.')) # 번들 폰트 (NanumSquare) — utils/font_loader.py 가 _MEIPASS/font/ 에서 로드 _font_files = [ 'NanumSquareL.ttf', 'NanumSquareR.ttf', 'NanumSquareB.ttf', 'NanumSquareEB.ttf', 'NanumSquare_acR.ttf', 'NanumSquare_acB.ttf', ] _font_datas = [ (os.path.join('font', f), 'font') for f in _font_files if os.path.exists(os.path.join('font', f)) ] a = Analysis( ['main.py'], pathex=[], binaries=[], datas=[('3d-alarm.png', '.')] + _extra_datas + _font_datas, hiddenimports=[ 'holidays', 'holidays.countries.south_korea', 'win32evtlog', 'win32evtlogutil', 'matplotlib.backends.backend_qtagg', # frozen 차트 백엔드 (chart_widget 우선 import) 'matplotlib.backends.backend_qt5agg', 'PyQt5.QtSvg', 'PyQt5.sip', # matplotlib qt_compat가 sip 사용 'numpy.core._multiarray_tests', # numpy import 체인이 참조 (frozen 차트 깨짐 방지) ], hookspath=[], hooksconfig={}, runtime_hooks=[], # numpy.testing 제외 금지 — numpy.core._multiarray_tests 참조가 끊겨 matplotlib import 실패함 excludes=['pandas', 'PyQt5.QtWebEngineWidgets'], noarchive=False, optimize=0, ) pyz = PYZ(a.pure) exe = EXE( pyz, a.scripts, a.binaries, a.datas, [], name='main', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, upx_exclude=[], runtime_tmpdir=None, console=False, disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, icon=['3d-alarm.ico'], )