import subprocess import shutil import os import PySide6 USE_NUITKA = True # переключатель: True — сборка через Nuitka, False — через PyInstaller pyside6_path = os.path.dirname(PySide6.__file__) plugins_platforms_path = os.path.join(pyside6_path, "plugins", "platforms") dist_path = os.path.abspath(".") # итоговая папка с exe work_path = os.path.abspath("./build_temp") # временная папка для PyInstaller spec_path = os.path.abspath("./build_temp") # папка exдля spec-файлов PyInstaller script_dir = os.path.dirname(os.path.abspath(__file__)) libclang_path = os.path.join(script_dir, "libclang.dll") libssl_orig = os.path.join(script_dir, "libssl-3-x64.dll") libcrypto_orig = os.path.join(script_dir, "libcrypto-3-x64.dll") # Собираем бинарники и данные для PyInstaller add_binary_list = [f"{libclang_path};."] if os.path.exists(libssl_orig): add_binary_list.append(f"{libssl_orig};libssl.dll") else: print("WARNING: libssl-3-x64.dll не найден, OpenSSL не будет включён") if os.path.exists(libcrypto_orig): add_binary_list.append(f"{libcrypto_orig};libcrypto.dll") else: print("WARNING: libcrypto-3-x64.dll не найден, OpenSSL не будет включён") from PyInstaller.utils.hooks import collect_data_files datas = [] datas += collect_data_files('PySide6', includes=['plugins/platforms/*']) datas += collect_data_files('PySide6', includes=['plugins/styles/*']) datas += collect_data_files('PySide6', includes=['plugins/imageformats/*']) add_data_list = [f"{src};{dest}" for src, dest in datas] script_path = "./Src/setupVars_GUI.py" output_name = "DebugVarEdit" env = os.environ.copy() env["CC"] = r"C:\Users\I\AppData\Local\Nuitka\Nuitka\Cache\DOWNLOADS\gcc\x86_64\14.2.0posix-19.1.1-12.0.0-msvcrt-r2\bin\gcc.exe" env["CXX"] = r"C:\Users\I\AppData\Local\Nuitka\Nuitka\Cache\DOWNLOADS\gcc\x86_64\14.2.0posix-19.1.1-12.0.0-msvcrt-r2\bin\g++.exe" if not USE_NUITKA: # PyInstaller команда cmd = [ "pyinstaller", "--onefile", "--name", output_name, *[item for add_bin in add_binary_list for item in ("--add-binary", add_bin)], *[item for add_dat in add_data_list for item in ("--add-data", add_dat)], "--distpath", dist_path, "--workpath", work_path, "--specpath", spec_path, "--hidden-import", "PySide6.QtWidgets", "--hidden-import", "PySide6.QtGui", "--hidden-import", "PySide6.QtCore", "--windowed", script_path ] else: # Nuitka команда # Формируем --include-data-dir для плагинов PySide6 (datas как в PyInstaller) # Было — неправильный способ: передаёт файлы plugin_dirs = set() for src, dest in datas: src_dir = os.path.dirname(src) dest_root = dest.split("/", 1)[0] if "/" in dest else dest plugin_dirs.add((src_dir, dest_root)) include_data_dirs = [ f"--include-data-dir={src}={dest}" for src, dest in plugin_dirs ] include_data_files = [] for dll_path, dll_name in [(libclang_path, "libclang.dll"), (libssl_orig, "libssl.dll"), (libcrypto_orig, "libcrypto.dll")]: if os.path.exists(dll_path): include_data_files.append(f"--include-data-file={dll_path}={dll_name}") cmd = [ "python", "-m", "nuitka", "--standalone", # полностью независимый билд (аналог PyInstaller --onefile/--onedir) "--onefile", # упаковать в один exe (экспериментально) "--enable-plugin=pyside6", "--windows-console-mode=disable", f"--output-dir={dist_path}", f"--output-filename={output_name}.exe", ] + include_data_dirs + [ script_path ] # Удаляем временные папки, если они у тебя есть temp_dirs = ["build_temp", "__pycache__"] # добавь свои папки с временными файлами for d in temp_dirs: if os.path.exists(d): shutil.rmtree(d) print("Выполняется сборка:") print(" ".join(cmd)) result = subprocess.run(cmd, env=env) if result.returncode == 0: # Чистим временные папки, только для PyInstaller (для Nuitka обычно не нужно) if not USE_NUITKA: for folder in ["build_temp", "__pycache__"]: if os.path.exists(folder): shutil.rmtree(folder) print("Сборка успешно завершена!") else: print("Сборка завершилась с ошибкой.")