This commit is contained in:
root
2025-07-11 14:19:45 +08:00
parent dcc2b6684f
commit c2e219c125
9 changed files with 1541 additions and 1 deletions

View File

@@ -0,0 +1,46 @@
@echo off
REM Windows批处理脚本 - 构建Python Core
REM 用于Windows环境下构建Python可执行文件
echo 🚀 Building MixVideo V2 Python Core for Windows...
REM 检查Python是否安装
python --version >nul 2>&1
if errorlevel 1 (
echo ❌ Python is not installed or not in PATH
echo Please install Python 3.8+ and add it to PATH
pause
exit /b 1
)
REM 检查pip是否可用
python -m pip --version >nul 2>&1
if errorlevel 1 (
echo ❌ pip is not available
echo Please ensure pip is installed with Python
pause
exit /b 1
)
echo ✅ Python environment check passed
REM 切换到项目根目录
cd /d "%~dp0.."
REM 运行Python构建脚本
echo 📦 Running Python build script...
python scripts\build_python_core.py
if errorlevel 1 (
echo ❌ Build failed
pause
exit /b 1
)
echo ✅ Build completed successfully!
echo.
echo 📋 Next steps:
echo 1. Test the build: cargo tauri dev
echo 2. Build the app: cargo tauri build
echo.
pause

View File

@@ -0,0 +1,257 @@
#!/usr/bin/env python3
"""
构建脚本 - 将Python Core打包成独立可执行文件
"""
import os
import sys
import subprocess
import shutil
import platform
from pathlib import Path
def get_project_root():
"""获取项目根目录"""
current_file = Path(__file__).resolve()
# 从 scripts/build_python_core.py 回到项目根目录
return current_file.parent.parent
def install_dependencies():
"""安装构建依赖"""
print("📦 Installing build dependencies...")
dependencies = [
'pyinstaller>=5.0',
'requests',
'Pillow',
'opencv-python-headless', # 使用headless版本减少依赖
]
for dep in dependencies:
print(f"Installing {dep}...")
result = subprocess.run([
sys.executable, '-m', 'pip', 'install', dep
], capture_output=True, text=True)
if result.returncode != 0:
print(f"❌ Failed to install {dep}")
print(result.stderr)
return False
else:
print(f"✅ Installed {dep}")
return True
def clean_build_directory(python_core_dir):
"""清理构建目录"""
print("🧹 Cleaning build directories...")
dirs_to_clean = ['build', 'dist', '__pycache__']
for dir_name in dirs_to_clean:
dir_path = python_core_dir / dir_name
if dir_path.exists():
shutil.rmtree(dir_path)
print(f"Removed {dir_path}")
def build_executable(python_core_dir):
"""构建可执行文件"""
print("🔨 Building executable...")
spec_file = python_core_dir / 'build.spec'
if not spec_file.exists():
print(f"❌ Spec file not found: {spec_file}")
return False
# 运行PyInstaller
cmd = [
sys.executable, '-m', 'PyInstaller',
'--clean',
'--noconfirm',
str(spec_file)
]
print(f"Running: {' '.join(cmd)}")
result = subprocess.run(
cmd,
cwd=python_core_dir,
capture_output=True,
text=True
)
if result.returncode != 0:
print("❌ Build failed!")
print("STDOUT:", result.stdout)
print("STDERR:", result.stderr)
return False
print("✅ Build completed successfully!")
return True
def copy_to_sidecar_directory(project_root, python_core_dir):
"""复制可执行文件到Tauri sidecar目录"""
print("📁 Copying executable to sidecar directory...")
# 确定可执行文件名
system = platform.system().lower()
if system == 'windows':
exe_name = 'mixvideo-python-core.exe'
else:
exe_name = 'mixvideo-python-core'
# 源文件路径
source_exe = python_core_dir / 'dist' / exe_name
if not source_exe.exists():
print(f"❌ Executable not found: {source_exe}")
return False
# 目标目录
sidecar_dir = project_root / 'src-tauri' / 'binaries'
sidecar_dir.mkdir(exist_ok=True)
# 复制文件
target_exe = sidecar_dir / exe_name
shutil.copy2(source_exe, target_exe)
# 在Unix系统上设置执行权限
if system != 'windows':
os.chmod(target_exe, 0o755)
print(f"✅ Copied to: {target_exe}")
return True
def update_tauri_config(project_root):
"""更新Tauri配置文件以包含sidecar"""
print("⚙️ Updating Tauri configuration...")
import json
config_file = project_root / 'src-tauri' / 'tauri.conf.json'
if not config_file.exists():
print(f"❌ Tauri config not found: {config_file}")
return False
# 读取配置
with open(config_file, 'r', encoding='utf-8') as f:
config = json.load(f)
# 添加sidecar配置
if 'bundle' not in config:
config['bundle'] = {}
if 'externalBin' not in config['bundle']:
config['bundle']['externalBin'] = []
# 检查是否已经存在
sidecar_name = 'mixvideo-python-core'
existing = any(
item.get('name') == sidecar_name
for item in config['bundle']['externalBin']
if isinstance(item, dict)
)
if not existing:
config['bundle']['externalBin'].append({
"name": sidecar_name,
"src": f"binaries/{sidecar_name}",
"targets": ["all"]
})
# 写回配置
with open(config_file, 'w', encoding='utf-8') as f:
json.dump(config, f, indent=2, ensure_ascii=False)
print("✅ Updated Tauri configuration")
else:
print(" Sidecar already configured in Tauri")
return True
def verify_build(project_root):
"""验证构建结果"""
print("🔍 Verifying build...")
system = platform.system().lower()
exe_name = 'mixvideo-python-core.exe' if system == 'windows' else 'mixvideo-python-core'
sidecar_exe = project_root / 'src-tauri' / 'binaries' / exe_name
if not sidecar_exe.exists():
print(f"❌ Sidecar executable not found: {sidecar_exe}")
return False
# 测试执行
try:
result = subprocess.run([
str(sidecar_exe), '--version'
], capture_output=True, text=True, timeout=10)
if result.returncode == 0:
print("✅ Executable is working correctly")
print(f"Version output: {result.stdout.strip()}")
return True
else:
print(f"❌ Executable test failed: {result.stderr}")
return False
except subprocess.TimeoutExpired:
print("❌ Executable test timed out")
return False
except Exception as e:
print(f"❌ Executable test error: {e}")
return False
def main():
"""主函数"""
print("🚀 Building MixVideo V2 Python Core...")
project_root = get_project_root()
python_core_dir = project_root / 'python_core'
print(f"Project root: {project_root}")
print(f"Python core directory: {python_core_dir}")
if not python_core_dir.exists():
print(f"❌ Python core directory not found: {python_core_dir}")
sys.exit(1)
# 步骤1: 安装依赖
if not install_dependencies():
print("❌ Failed to install dependencies")
sys.exit(1)
# 步骤2: 清理构建目录
clean_build_directory(python_core_dir)
# 步骤3: 构建可执行文件
if not build_executable(python_core_dir):
print("❌ Failed to build executable")
sys.exit(1)
# 步骤4: 复制到sidecar目录
if not copy_to_sidecar_directory(project_root, python_core_dir):
print("❌ Failed to copy executable")
sys.exit(1)
# 步骤5: 更新Tauri配置
if not update_tauri_config(project_root):
print("❌ Failed to update Tauri configuration")
sys.exit(1)
# 步骤6: 验证构建
if not verify_build(project_root):
print("❌ Build verification failed")
sys.exit(1)
print("🎉 Build completed successfully!")
print("\n📋 Next steps:")
print("1. Test the sidecar: cargo tauri dev")
print("2. Build the app: cargo tauri build")
print("3. The Python core will be bundled with your app")
if __name__ == "__main__":
main()

53
scripts/build_python_core.sh Executable file
View File

@@ -0,0 +1,53 @@
#!/bin/bash
# Shell脚本 - 构建Python Core
# 用于Linux/macOS环境下构建Python可执行文件
set -e # 遇到错误时退出
echo "🚀 Building MixVideo V2 Python Core for $(uname)..."
# 检查Python是否安装
if ! command -v python3 &> /dev/null; then
if ! command -v python &> /dev/null; then
echo "❌ Python is not installed or not in PATH"
echo "Please install Python 3.8+ and add it to PATH"
exit 1
else
PYTHON_CMD="python"
fi
else
PYTHON_CMD="python3"
fi
echo "✅ Using Python: $PYTHON_CMD"
# 检查Python版本
PYTHON_VERSION=$($PYTHON_CMD --version 2>&1 | cut -d' ' -f2)
echo "Python version: $PYTHON_VERSION"
# 检查pip是否可用
if ! $PYTHON_CMD -m pip --version &> /dev/null; then
echo "❌ pip is not available"
echo "Please ensure pip is installed with Python"
exit 1
fi
echo "✅ Python environment check passed"
# 切换到项目根目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
cd "$PROJECT_ROOT"
echo "📁 Working directory: $PROJECT_ROOT"
# 运行Python构建脚本
echo "📦 Running Python build script..."
$PYTHON_CMD scripts/build_python_core.py
echo "✅ Build completed successfully!"
echo ""
echo "📋 Next steps:"
echo "1. Test the build: cargo tauri dev"
echo "2. Build the app: cargo tauri build"
echo ""