xianyu-backend-java/build_binary_module.py
zhinianboke 32af41f09f 修改
2025-09-29 16:10:58 +08:00

156 lines
4.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
把 utils/xianyu_slider_stealth.py 编译为可直接 import 的二进制扩展模块(.pyd/.so
- 使用 Nuitka 的 --module 模式
- 输出文件放到 utils/ 目录,名称为 xianyu_slider_stealth.<abi>.pyd/.so
- 这样 Python 将优先加载二进制扩展而不是同名 .py
"""
import sys
import subprocess
from pathlib import Path
SRC = Path("utils/xianyu_slider_stealth.py")
OUT_DIR = Path("utils")
def ensure_nuitka():
try:
import nuitka # noqa: F401
print("✓ Nuitka 已安装")
return True
except Exception:
print("✗ 未检测到 Nuitka。请先允许我安装: pip install nuitka ordered-set zstandard")
return False
def clean_old_files():
"""清理旧的编译产物"""
import os
import glob
patterns = [
"utils/xianyu_slider_stealth.*.pyd",
"utils/xianyu_slider_stealth.*.so",
"utils/xianyu_slider_stealth.build",
"utils/xianyu_slider_stealth.dist"
]
for pattern in patterns:
for file_path in glob.glob(pattern):
try:
if os.path.isfile(file_path):
os.remove(file_path)
print(f"✓ 已删除旧文件: {file_path}")
elif os.path.isdir(file_path):
import shutil
shutil.rmtree(file_path)
print(f"✓ 已删除旧目录: {file_path}")
except Exception as e:
print(f"⚠️ 无法删除 {file_path}: {e}")
def check_permissions():
"""检查目录权限"""
try:
test_file = OUT_DIR / "test_write.tmp"
test_file.write_text("test")
test_file.unlink()
return True
except Exception as e:
print(f"✗ 目录权限检查失败: {e}")
print("💡 请尝试以管理员身份运行此脚本")
return False
def build():
OUT_DIR.mkdir(parents=True, exist_ok=True)
# 检查权限
if not check_permissions():
return 1
# 清理旧文件
print("🧹 清理旧的编译产物...")
clean_old_files()
cmd = [
sys.executable, "-m", "nuitka",
"--module",
"--output-dir=%s" % str(OUT_DIR),
"--remove-output",
"--assume-yes-for-downloads",
"--show-progress",
"--python-flag=no_docstrings",
"--python-flag=no_warnings",
"--enable-plugin=anti-bloat",
# 降低内存占用,避免容器内 OOM
"--lto=no",
"--jobs=1",
str(SRC)
]
print("执行编译命令:\n ", " ".join(cmd))
try:
result = subprocess.run(cmd, text=True, timeout=300) # 5分钟超时
if result.returncode != 0:
print("✗ 编译失败 (Nuitka 返回非零)")
print("💡 可能的解决方案:")
print(" 1. 以管理员身份运行此脚本")
print(" 2. 关闭杀毒软件的实时保护")
print(" 3. 检查是否有其他Python进程在运行")
return 1
except subprocess.TimeoutExpired:
print("✗ 编译超时 (5分钟)")
return 1
except Exception as e:
print(f"✗ 编译过程中发生错误: {e}")
return 1
# 列出 utils 目录下的产物
built = sorted(p for p in OUT_DIR.glob("xianyu_slider_stealth.*.pyd"))
if not built:
built = sorted(p for p in OUT_DIR.glob("xianyu_slider_stealth.*.so"))
if not built:
print("✗ 未找到编译产物。请检查输出日志。")
return 2
print("\n✓ 编译产物:")
for p in built:
print(" -", p)
return 0
def main():
print("🔨 开始编译 xianyu_slider_stealth 模块...")
print("📁 项目目录:", Path.cwd())
if not SRC.exists():
print(f"✗ 源文件不存在: {SRC}")
return 1
print(f"📄 源文件: {SRC}")
print(f"📂 输出目录: {OUT_DIR}")
if not ensure_nuitka():
return 2
# 检查是否以管理员身份运行Windows
import os
if os.name == 'nt': # Windows
try:
import ctypes
is_admin = ctypes.windll.shell32.IsUserAnAdmin()
if not is_admin:
print("⚠️ 建议以管理员身份运行此脚本以避免权限问题")
except:
pass
return build()
if __name__ == "__main__":
raise SystemExit(main())