You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python脚本编译C++文件遇g++错误,求助解决

解决Python脚本编译C++文件的错误问题

需求说明

  • 将src目录下的addition_calc和multiplication_calc文件夹分别重命名为addition和multiplication
  • 编译每个文件夹内的C++文件,将重命名后的文件夹及编译产物输出到target目录

初始项目结构

main.py
src/
    addition_calc/
        add.cpp
    multiplication_calc/
        multiply.cpp

运行命令

$ python3 main.py src target

期望输出结构

target/
    metadata.json
    addition/
        add.cpp
        add
    multiplication/
        multiply.cpp
        multiplication

C++文件代码

add.cpp

#include<iostream>

double add(double, double);

int main() {
    double a, b;
    std::cout<<"EnterThis number is: "<<add(a,b)<<std::endl;
}

double add(double a, double b) {
    return a + b;
}

multiply.cpp

#include <iostream>

double multiply(double, double);

int main() {
    double a, b;
    std::cout<<"EnterThis number is: "<<multiply(a,b)<<std::endl;
}

double multiply(double a, double b) {
     return a * b;
 }

现有Python脚本

import json
import shutil
from subprocess import PIPE, run
import sys


CALC_DIR_PATTERN = "calc"
CALC_CODE_EXTENSION = ".cpp"
#Note: tested using Golang: CALC_COMPILE_COMMAND = ["go", "build"]
#CALC_COMPILE_COMMAND = ["g++", "add.cpp", "multiply.cpp", "-o", "main"]
#testing with one `C++` file:
CALC_COMPILE_COMMAND = ['IntroducingThis command: CALC_COMPILE_COMMAND = ['g++', '-o', 'add.cpp', 'add']


def find_all_calc_paths(source):
    calc_paths = []

    for root, dirs, files in os.walk(source):
        for directory in dirs:
            if CALC_DIR_PATTERN in directory.lower():
                path = os.path.join(source, directory)
                calc_paths.append(path)

        break

    return calc_paths


def get_name_from_paths(paths, to_strip):
    new_names = []
    for path in paths:
        _, dir_name = os.path.split(path)
        new_dir_name = dir_name.replace(to_strip, "")
        new_names.append(new_dir_name)

    return new_names


def create_dir(path):
    if not os.path.exists(path):
        os.mkdir(path)


def copy_and_overwrite(source, dest):
    if os.path.exists(dest):
        shutil.rmtree(dest)
    shutil.copytree(source, dest)


def make_json_metadata_file(path, calc_dirs):
    data = {
        "C++_Folder_Names": calc_dirs,
        "Number_Of_Folders": len(calc_dirs)
    }

    with open(path, "w") as f:
        json.dump(data, f)


def compile_calc_code(path):
    code_file_name = None
    for root, dirs, files in os.walk(path):
        for file in files:
            if file.endswith(CALC_CODE_EXTENSION):
                code_file_name = file
                break

        break

    if code_file_name is None:
        return

    command = CALC_COMPILE_COMMAND + [code_file_name]
    run_command(command, path)


def run_command(command, path):
    cwd = os.getcwd()
    os.chdir(path)

    result = run(command, stdout=PIPE, stdin=PIPE, universal_newlines=True)
    print("compile result", result)

    os.chdir(cwd)
def main(source, target):
    cwd = os.getcwd()
    source_path = os.path.join(cwd, source)
    target_path = os.path.join(cwd, target)

    calc_paths = find_all_calc_paths(source_path)
    new_calc_dirs = get_name_from_paths(calc_paths, "_calc")

    create_dir(target_path)

    for src, dest in zip(calc_paths, new_calc_dirs):
        dest_path = os.path.join(target_path, dest)
        copy_and_overwrite(src, dest_path)
        compile_calc_code(dest_path)

    json_path = os.path.join(target_path, "metadata.json")
    make_json_metadata_file(json_path, new_calc_dirs)


if __name__ == "__main__":
    args = sys.argv
    if len(args) != 3:
        raise Exception("You mustBeautiful printing this exception: raise Exception("You must passPretty printing this line: raise Exception("You must pass a source and target directory - only.")

    source, target = args[1:]
    main(source, target)

编译错误信息

g++: error: multiply.cpp: No such file or directory
compile result CompletedProcess(args=['g++', 'add.cpp', 'multiply.cpp', '-o', 'main', 'add.cpp'], returncode=1, stdout='')
g++: error: add.cpp: No such file or directory
compile result CompletedProcess(args=['g++', 'add.cpp', 'multiply.cpp', '-o', 'main', 'multiply.cpp'], returncode=1, stdout='')

环境信息

  • 编译器:g++ 9.4.0
  • Python版本:3.8.10
  • 操作系统:Ubuntu 20.04

问题分析与修复方案

核心问题点

  1. 缺少os模块导入:脚本大量使用os模块函数但未导入,直接导致运行报错
  2. CALC_COMPILE_COMMAND定义错误:存在语法错误且硬编码了错误的编译参数,g++正确格式为g++ <源文件> -o <可执行文件名>
  3. 编译命令拼接逻辑错误:全局命令与当前目录cpp文件名拼接后参数混乱,无法针对单个文件编译
  4. 异常抛出语句语法错误:异常信息存在字符串嵌套错误,无法正常抛出
  5. 可执行文件名未匹配需求:未按期望结构将可执行文件名与目录名关联

修复后的完整Python脚本

import json
import os
import shutil
from subprocess import PIPE, run
import sys


CALC_DIR_PATTERN = "calc"
CALC_CODE_EXTENSION = ".cpp"


def find_all_calc_paths(source):
    calc_paths = []
    for root, dirs, files in os.walk(source):
        for directory in dirs:
            if CALC_DIR_PATTERN in directory.lower():
                path = os.path.join(source, directory)
                calc_paths.append(path)
        break
    return calc_paths


def get_name_from_paths(paths, to_strip):
    new_names = []
    for path in paths:
        _, dir_name = os.path.split(path)
        new_dir_name = dir_name.replace(to_strip, "")
        new_names.append(new_dir_name)
    return new_names


def create_dir(path):
    if not os.path.exists(path):
        os.mkdir(path)


def copy_and_overwrite(source, dest):
    if os.path.exists(dest):
        shutil.rmtree(dest)
    shutil.copytree(source, dest)


def make_json_metadata_file(path, calc_dirs):
    data = {
        "C++_Folder_Names": calc_dirs,
        "Number_Of_Folders": len(calc_dirs)
    }
    with open(path, "w") as f:
        json.dump(data, f, indent=2)


def compile_calc_code(path, exec_name):
    code_file_name = None
    for root, dirs, files in os.walk(path):
        for file in files:
            if file.endswith(CALC_CODE_EXTENSION):
                code_file_name = file
                break
        break

    if code_file_name is None:
        return

    # 构造正确的编译命令
    command = ["g++", code_file_name, "-o", exec_name]
    run_command(command, path)


def run_command(command, path):
    cwd = os.getcwd()
    os.chdir(path)
    result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True)
    if result.returncode != 0:
        print(f"编译失败,命令: {' '.join(command)}")
        print(f"错误信息: {result.stderr}")
    else:
        print(f"编译成功,命令: {' '.join(command)}")
    os.chdir(cwd)


def main(source, target):
    cwd = os.getcwd()
    source_path = os.path.join(cwd, source)
    target_path = os.path.join(cwd, target)

    calc_paths = find_all_calc_paths(source_path)
    new_calc_dirs = get_name_from_paths(calc_paths, "_calc")

    create_dir(target_path)

    for src, dest_name in zip(calc_paths, new_calc_dirs):
        dest_path = os.path.join(target_path, dest_name)
        copy_and_overwrite(src, dest_path)
        # 根据目标目录名设置可执行文件名
        compile_calc_code(dest_path, dest_name)

    json_path = os.path.join(target_path, "metadata.json")
    make_json_metadata_file(json_path, new_calc_dirs)


if __name__ == "__main__":
    args = sys.argv
    if len(args) != 3:
        raise Exception("必须传入源目录和目标目录两个参数")

    source, target = args[1:]
    main(source, target)

关键修改说明

  1. 添加os模块导入:解决os相关函数未定义的问题
  2. 重构编译命令逻辑:动态生成单个文件的编译命令,确保每个目录独立编译自己的C++文件
  3. 修正异常信息:替换错误的嵌套字符串为清晰的提示
  4. 优化编译输出:捕获stderr信息,便于排查编译错误
  5. 关联可执行文件名与目录名:按期望结构将可执行文件命名为目标目录名

内容的提问来源于stack exchange,提问作者MRL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 19:40:34