Files
full-stack-doc/backend/build_noshared.py
2025-10-14 20:05:29 +08:00

242 lines
6.7 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 -*-
"""
适用于无共享库Python环境的打包脚本
"""
import os
import sys
import shutil
import subprocess
from pathlib import Path
import argparse
def check_python_version():
"""检查Python版本"""
if sys.version_info < (3, 8):
print("错误: 需要Python 3.8或更高版本")
sys.exit(1)
print(f"[OK] Python版本: {sys.version}")
def check_dependencies():
"""检查必要的依赖"""
try:
import PyInstaller
print(f"[OK] PyInstaller版本: {PyInstaller.__version__}")
except ImportError:
print("错误: 未安装PyInstaller")
print("请运行: pip install pyinstaller")
sys.exit(1)
def clean_build_dirs():
"""清理之前的构建目录"""
dirs_to_clean = ['build', 'dist', '__pycache__']
for dir_name in dirs_to_clean:
if os.path.exists(dir_name):
print(f"清理目录: {dir_name}")
shutil.rmtree(dir_name)
# 清理Python缓存文件
for root, dirs, files in os.walk('.'):
for file in files:
if file.endswith('.pyc') or file.endswith('.pyo'):
os.remove(os.path.join(root, file))
if '__pycache__' in dirs:
shutil.rmtree(os.path.join(root, '__pycache__'))
def run_pyinstaller_noshared():
"""运行PyInstaller进行打包无共享库版本"""
print("开始打包(无共享库模式)...")
# 尝试多种打包方式
spec_files = ['build_noshared.spec', 'build.spec']
for spec_file in spec_files:
if os.path.exists(spec_file):
print(f"使用规格文件: {spec_file}")
# 构建命令
cmd = ['pyinstaller', '--clean', '--noupx', spec_file]
# 如果是build.spec添加额外参数
if spec_file == 'build.spec':
cmd.extend(['--noupx', '--debug', 'imports'])
try:
result = subprocess.run(cmd, check=True, capture_output=True, text=True)
print(f"[OK] PyInstaller执行成功 (使用 {spec_file})")
if result.stdout:
print("输出:", result.stdout)
return True
except subprocess.CalledProcessError as e:
print(f"使用 {spec_file} 打包失败: {e}")
if e.stderr:
print("错误输出:", e.stderr)
continue
print("错误: 所有打包方式都失败了")
return False
def create_simple_package():
"""创建简单的部署包不使用PyInstaller"""
print("创建简单部署包...")
deploy_dir = Path('deploy')
if deploy_dir.exists():
shutil.rmtree(deploy_dir)
deploy_dir.mkdir()
# 复制源代码
shutil.copytree('app', deploy_dir / 'app')
shutil.copy2('main.py', deploy_dir)
shutil.copy2('requirements.txt', deploy_dir)
shutil.copy2('.env.example', deploy_dir)
# 创建启动脚本
startup_script = '''#!/bin/bash
# 云盘后端服务启动脚本Python模式
# 进入脚本所在目录
cd "$(dirname "$0")"
# 检查Python环境
if ! command -v python3 &> /dev/null; then
echo "错误: 未找到python3"
exit 1
fi
# 检查虚拟环境
if [ ! -d "venv" ]; then
echo "创建虚拟环境..."
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
else
echo "激活虚拟环境..."
source venv/bin/activate
fi
# 检查环境文件
if [ ! -f ".env" ]; then
echo "警告: .env 文件不存在,将使用默认配置"
if [ -f ".env.example" ]; then
cp .env.example .env
echo "已复制 .env.example 为 .env请根据需要修改配置"
fi
fi
# 启动服务
echo "启动云盘后端服务..."
python main.py
'''
script_path = deploy_dir / 'start.sh'
with open(script_path, 'w', encoding='utf-8') as f:
f.write(startup_script)
os.chmod(script_path, 0o755)
# 创建安装脚本
install_script = '''#!/bin/bash
# 简单安装脚本
INSTALL_DIR="$HOME/cloud-drive"
echo "=== 云盘后端服务安装(简单版本) ==="
# 创建安装目录
mkdir -p "$INSTALL_DIR"
# 复制文件
cp -r * "$INSTALL_DIR/"
cd "$INSTALL_DIR"
# 设置权限
chmod +x start.sh
echo "=== 安装完成 ==="
echo "进入目录: cd $INSTALL_DIR"
echo "启动服务: ./start.sh"
'''
install_path = deploy_dir / 'install_simple.sh'
with open(install_path, 'w', encoding='utf-8') as f:
f.write(install_script)
os.chmod(install_path, 0o755)
print(f"[OK] 简单部署包创建完成: {deploy_dir.absolute()}")
return True
def create_deployment_package():
"""创建部署包"""
dist_dir = Path('dist')
deploy_dir = Path('deploy')
if deploy_dir.exists():
shutil.rmtree(deploy_dir)
deploy_dir.mkdir()
# 尝试复制可执行文件
exe_file = dist_dir / 'cloud-drive-server'
if exe_file.exists():
shutil.copy2(exe_file, deploy_dir)
print(f"[OK] 复制可执行文件到 {deploy_dir}")
return True
else:
print("警告: 未找到可执行文件,创建简单部署包")
return create_simple_package()
def main():
"""主函数"""
parser = argparse.ArgumentParser(description='云盘后端Linux打包工具无共享库版')
parser.add_argument('--clean', action='store_true', help='仅清理构建目录')
parser.add_argument('--no-clean', action='store_true', help='跳过清理步骤')
parser.add_argument('--simple', action='store_true', help='创建简单部署包不使用PyInstaller')
args = parser.parse_args()
print("=== 云盘后端Linux打包工具无共享库版 ===")
print(f"当前目录: {os.getcwd()}")
# 检查环境
check_python_version()
check_dependencies()
# 清理构建目录
if args.clean:
clean_build_dirs()
print("[OK] 清理完成")
return
if not args.no_clean:
clean_build_dirs()
if args.simple:
# 直接创建简单部署包
create_simple_package()
else:
# 尝试PyInstaller打包
if run_pyinstaller_noshared():
create_deployment_package()
else:
print("PyInstaller打包失败创建简单部署包...")
create_simple_package()
print("\n=== 打包完成 ===")
print("部署包位置: ./deploy/")
# 检查部署包内容
deploy_dir = Path('deploy')
if (deploy_dir / 'cloud-drive-server').exists():
print("✓ 可执行文件: cloud-drive-server")
print("运行方式: ./cloud-drive-server")
else:
print("✓ Python源代码包")
print("运行方式: ./start.sh")
print("安装方式: ./install_simple.sh")
if __name__ == '__main__':
main()