实用脚本能批量编译吗?

wen 实用脚本 8

本文目录导读:

实用脚本能批量编译吗?

  1. Python批量编译多个文件
  2. Shell脚本批量编译C/C++
  3. 自动检测变化的编译脚本
  4. Makefile风格的编译脚本
  5. 带依赖管理的编译脚本
  6. 使用建议

当然可以!批量编译是脚本的常见应用场景,给你几个实用示例:

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()

使用建议

  1. 增量编译:只编译修改过的文件,节省时间
  2. 并行编译:利用多核CPU加速
  3. 错误处理:记录编译失败的日志
  4. 依赖管理:确定文件之间的编译顺序

这些脚本可以根据具体需求调整,支持不同类型的源码和编译器,需要我详细解释某个脚本的实现吗?

抱歉,评论功能暂时关闭!