Skip to content

Commit 1b704d8

Browse files
committed
native
1 parent 2dd395d commit 1b704d8

File tree

2 files changed

+159
-0
lines changed

2 files changed

+159
-0
lines changed

build_native.py

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
import os
2+
import shutil
3+
import subprocess
4+
import sys
5+
import time
6+
7+
# TODO strip
8+
# pyinstaller ?
9+
# sudo pacman -S ccache
10+
11+
# --- Конфигурация сборки Nuitka ---
12+
13+
# Имя основного скрипта вашего приложения
14+
main_script = "xmlgenerator/bootstrap.py"
15+
16+
# Имя выходного исполняемого файла (без расширения)
17+
output_filename_base = "xmlgenerator"
18+
19+
# Директория для собранного файла
20+
output_dir = "dist_native"
21+
22+
# Собрать в один файл? (True/False)
23+
use_onefile = True
24+
25+
build_time = time.time()
26+
build_time = str(int(build_time))
27+
28+
file_ver = f"{build_time[-4]}.{build_time[-3]}.{build_time[-2]}.{build_time[-1]}"
29+
30+
print(file_ver)
31+
32+
# Дополнительные опции Nuitka (добавляйте сюда нужные флаги)
33+
extra_nuitka_options = [
34+
# "--show-progress",
35+
"--no-deployment-flag=self-execution", # Флаг для исправления ошибки
36+
"--standalone",
37+
# "--python-flag=no_site",
38+
# "--onefile-no-compression",
39+
"--follow-stdlib",
40+
# "--nofollow-import-to=tkinter",
41+
# "--include-package=some_package",
42+
43+
"--product-name=xmlgenerator",
44+
"--product-version=0.1.0",
45+
f"--file-version={file_ver}",
46+
"--onefile-tempdir-spec={CACHE_DIR}/{PRODUCT}/{VERSION}",
47+
48+
"--lto=yes", # Use link time optimizations (MSVC, gcc, clang).
49+
# "--static-libpython=yes", # Use static link library of Python undefined symbol: PyList_New
50+
51+
# "--plugin-list",
52+
"--enable-plugin=anti-bloat",
53+
"--enable-plugin=pylint-warnings",
54+
"--enable-plugin=no-qt",
55+
]
56+
57+
# --- Логика сборки ---
58+
59+
# Определяем базовое имя скрипта для имени директории сборки
60+
main_script_basename = os.path.splitext(os.path.basename(main_script))[0]
61+
62+
# Определяем ПОТЕНЦИАЛЬНЫЕ имена сборочных директорий Nuitka
63+
possible_temp_dirs = [
64+
# os.path.join(output_dir, f"{main_script_basename}.build"),
65+
# os.path.join(output_dir, f"{main_script_basename}.onefile-build"),
66+
]
67+
68+
# Определяем полное имя выходного файла с расширением для текущей ОС
69+
if sys.platform == "win32":
70+
output_filename = f"{output_filename_base}.exe"
71+
elif sys.platform == "darwin":
72+
output_filename = output_filename_base
73+
else: # Linux и другие
74+
output_filename = output_filename_base
75+
76+
# Формируем команду Nuitka
77+
command = [
78+
sys.executable, # Используем тот же python, что и для запуска скрипта
79+
"-m",
80+
"nuitka",
81+
f"--output-dir={output_dir}",
82+
f"--output-filename={output_filename}", # Указываем имя выходного файла
83+
]
84+
85+
if use_onefile:
86+
command.append("--onefile")
87+
88+
# Добавляем дополнительные опции
89+
command.extend(extra_nuitka_options)
90+
91+
# Добавляем главный скрипт в конец команды
92+
command.append(main_script)
93+
94+
print("Запуск Nuitka со следующей командой:")
95+
print(" ".join(command))
96+
print("-" * 30)
97+
98+
# Запускаем сборку с Popen для потокового вывода
99+
try:
100+
# --- Очистка выходной директории перед сборкой ---
101+
if os.path.exists(output_dir):
102+
print(f"Очистка существующей директории: {output_dir}")
103+
try:
104+
shutil.rmtree(output_dir)
105+
print("Директория успешно очищена.")
106+
except OSError as e:
107+
print(f"Ошибка при очистке директории {output_dir}: {e}")
108+
# Решаем, прерывать ли сборку, если очистка не удалась.
109+
# В данном случае, продолжим, т.к. makedirs может сработать.
110+
# ------------------------------------------------
111+
112+
# Убедимся, что директория существует (или создаем ее после очистки)
113+
os.makedirs(output_dir, exist_ok=True)
114+
115+
# Используем Popen и перенаправляем stderr в stdout для единого потока
116+
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, encoding='utf-8', errors='replace', bufsize=1)
117+
118+
print("--- Вывод Nuitka --- ")
119+
# Читаем вывод построчно в реальном времени
120+
if process.stdout:
121+
for line in iter(process.stdout.readline, ''):
122+
# Выводим каждую строку немедленно
123+
sys.stdout.write(line)
124+
sys.stdout.flush()
125+
process.stdout.close()
126+
127+
# Ждем завершения процесса и получаем код возврата
128+
return_code = process.wait()
129+
print("-" * 30)
130+
131+
if return_code == 0:
132+
print(f"Сборка успешно завершена! Исполняемый файл: {os.path.join(output_dir, output_filename)}")
133+
134+
# --- Удаление ВСЕХ известных сборочных директорий ---
135+
print("Попытка удаления временных сборочных директорий...")
136+
for temp_dir_path in possible_temp_dirs:
137+
if os.path.exists(temp_dir_path):
138+
print(f"Найден и удаляется: {temp_dir_path}")
139+
try:
140+
shutil.rmtree(temp_dir_path)
141+
print(f"Успешно удалено: {temp_dir_path}")
142+
except OSError as e:
143+
print(f"Ошибка при удалении {temp_dir_path}: {e}")
144+
# else:
145+
# Можно раскомментировать для отладки:
146+
# print(f"Директория не найдена: {temp_dir_path}")
147+
print("Очистка временных директорий завершена.")
148+
# --------------------------------------------------
149+
else:
150+
print(f"Ошибка во время сборки Nuitka (код возврата {return_code})")
151+
sys.exit(return_code) # Выходим с кодом ошибки Nuitka
152+
153+
except FileNotFoundError:
154+
print(f"Ошибка: Не удалось найти '{sys.executable} -m nuitka'. Убедитесь, что Nuitka установлена в вашем окружении.")
155+
sys.exit(1)
156+
except Exception as e:
157+
print(f"Произошла непредвиденная ошибка: {e}")
158+
sys.exit(1)

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ PyYAML==6.0.2
77
# dev
88
pytest==8.3.5
99
setuptools==77.0.3
10+
nuitka

0 commit comments

Comments
 (0)