本文目录导读:

当然可以!批量编译是脚本的常见应用场景,给你几个实用示例:
Python批量编译多个文件
import os
import subprocess
from pathlib import Path
def batch_compile_python(source_dir="src", output_dir="build"):
"""批量编译Python文件为.pyc"""
os.makedirs(output_dir, exist_ok=True)
for file in Path(source_dir).glob("**/*.py"):
target = Path(output_dir) / file.relative_to(source_dir)
os.makedirs(target.parent, exist_ok=True)
# 使用py_compile编译单个文件
cmd = f"python -m py_compile {file}"
subprocess.run(cmd, shell=True)
print(f"编译: {file} -> {target}.pyc")
# 使用
batch_compile_python()
Shell脚本批量编译C/C++
#!/bin/bash
# batch_compile.sh
# 配置
SRC_DIR="src"
OUT_DIR="build"
CC="gcc"
CFLAGS="-Wall -O2"
# 创建输出目录
mkdir -p "$OUT_DIR"
# 批量编译C文件
for file in "$SRC_DIR"/*.c; do
if [ -f "$file" ]; then
filename=$(basename "$file" .c)
echo "编译: $file"
$CC $CFLAGS "$file" -o "$OUT_DIR/$filename" 2>&1 | tee "$OUT_DIR/$filename.log"
if [ $? -eq 0 ]; then
echo "✅ $filename 编译成功"
else
echo "❌ $filename 编译失败"
fi
fi
done
自动检测变化的编译脚本
import hashlib
import json
import os
from pathlib import Path
class SmartCompiler:
def __init__(self, cache_file=".compile_cache.json"):
self.cache_file = cache_file
self.cache = self._load_cache()
def _load_cache(self):
if os.path.exists(self.cache_file):
with open(self.cache_file, 'r') as f:
return json.load(f)
return {}
def _save_cache(self):
with open(self.cache_file, 'w') as f:
json.dump(self.cache, f, indent=2)
def _file_hash(self, filepath):
"""计算文件哈希值"""
hasher = hashlib.md5()
with open(filepath, 'rb') as f:
for chunk in iter(lambda: f.read(4096), b''):
hasher.update(chunk)
return hasher.hexdigest()
def needs_compile(self, filepath):
"""检查是否需要重新编译"""
current_hash = self._file_hash(filepath)
if filepath in self.cache:
return self.cache[filepath] != current_hash
return True
def compile_all(self, source_pattern="**/*.py"):
"""智能编译所有文件"""
for file in Path().glob(source_pattern):
if self.needs_compile(str(file)):
print(f"编译: {file}")
# 这里放实际编译命令
# os.system(f"python -m py_compile {file}")
self.cache[str(file)] = self._file_hash(str(file))
self._save_cache()
print("✅ 编译完成")
# 使用
compiler = SmartCompiler()
compiler.compile_all()
Makefile风格的编译脚本
import os
import sys
from concurrent.futures import ThreadPoolExecutor
class BatchCompiler:
def __init__(self):
self.config = {
'src_dir': './src',
'build_dir': './build',
'c_compiler': 'gcc',
'c_flags': '-Wall -O2',
'threads': 4
}
def compile_single(self, file_path):
"""单个文件编译"""
ext = os.path.splitext(file_path)[1]
target = os.path.join(
self.config['build_dir'],
os.path.relpath(file_path, self.config['src_dir'])
)
commands = {
'.c': f"{self.config['c_compiler']} {self.config['c_flags']} {file_path} -o {target}.out",
'.py': f"python -m py_compile {file_path}",
'.java': f"javac {file_path} -d {self.config['build_dir']}"
}
cmd = commands.get(ext)
if cmd:
os.makedirs(os.path.dirname(target), exist_ok=True)
result = os.system(cmd)
status = "✅" if result == 0 else "❌"
print(f"{status} {file_path}")
return result == 0
return False
def compile_all(self):
"""并行批量编译"""
# 收集所有源文件
files_to_compile = []
for root, dirs, files in os.walk(self.config['src_dir']):
for file in files:
files_to_compile.append(os.path.join(root, file))
# 并行编译
with ThreadPoolExecutor(max_workers=self.config['threads']) as executor:
results = executor.map(self.compile_single, files_to_compile)
success = sum(1 for r in results if r)
total = len(files_to_compile)
print(f"\n编译完成: {success}/{total} 成功")
# 使用
compiler = BatchCompiler()
compiler.compile_all()
带依赖管理的编译脚本
import json
from datetime import datetime
from pathlib import Path
class DependencyCompiler:
def __init__(self, config_file="compile_config.json"):
self.load_config(config_file)
def load_config(self, config_file):
if Path(config_file).exists():
with open(config_file) as f:
self.config = json.load(f)
else:
self.config = {
"project": "default",
"source_dir": ["src"],
"exclude": ["test", "backup"],
"output_dir": "build",
"compile_tool": "python",
"options": ["-O", "-m", "py_compile"]
}
def get_files(self):
"""获取需要编译的文件"""
files = []
for src_dir in self.config['source_dir']:
for ext in ['.py', '.java', '.cpp', '.c']:
for file in Path(src_dir).rglob(f"*{ext}"):
# 排除不需要的目录
if not any(exclude in str(file) for exclude in self.config['exclude']):
files.append(file)
return files
def check_dependencies(self, file_path):
"""检查文件依赖是否更新"""
# 这里可以实现更复杂的依赖检查
mod_time = file_path.stat().st_mtime
output_path = Path(self.config['output_dir']) / file_path
if not output_path.exists():
return True
return mod_time > output_path.stat().st_mtime
def compile(self):
"""主编译过程"""
files = self.get_files()
print(f"找到 {len(files)} 个文件待编译")
compiled = 0
failed = 0
for file in files:
if self.check_dependencies(file):
try:
# 根据文件类型选择编译方式
if file.suffix == '.py':
import py_compile
py_compile.compile(file, cfile=Path(self.config['output_dir'])/file.with_suffix('.pyc'))
elif file.suffix in ['.c', '.cpp']:
import subprocess
subprocess.run(['gcc', str(file), '-o',
Path(self.config['output_dir'])/file.with_suffix('.out')])
compiled += 1
print(f"✅ {file}")
except Exception as e:
failed += 1
print(f"❌ {file}: {e}")
else:
print(f"- {file} (已最新)")
print(f"\n结果: {compiled} 编译, {failed} 失败")
# 使用
compiler = DependencyCompiler()
compiler.compile()
使用建议
- 增量编译:只编译修改过的文件,节省时间
- 并行编译:利用多核CPU加速
- 错误处理:记录编译失败的日志
- 依赖管理:确定文件之间的编译顺序
这些脚本可以根据具体需求调整,支持不同类型的源码和编译器,需要我详细解释某个脚本的实现吗?