#include "compileprocessmanager.h" #include #include #include #include #include #include CompileProcessManager::CompileProcessManager(QObject *parent) : QObject(parent) { m_process = new QProcess(this); connect(m_process, &QProcess::finished, this, &CompileProcessManager::onProcessFinished); } void CompileProcessManager::setBackendProgram(const QString &programPath) { m_backendProgram = programPath; } void CompileProcessManager::setProjectRoot(const QString &rootPath) { m_projectRoot = rootPath; } void CompileProcessManager::generateAsm(const QString &inputFileName, const QString &outputFileName) { if (m_backendProgram.isEmpty()) { emit processError(tr("mini_c 可执行文件路径未设置")); return; } // 项目根目录(如果没设就用当前工作目录) QDir root(m_projectRoot.isEmpty() ? QDir::currentPath() : m_projectRoot); // 拼出源文件完整路径:root + "test.c" QString inputPath = root.filePath(inputFileName); if (!QFileInfo::exists(inputPath)) { emit processError(tr("源文件不存在: %1").arg(inputPath)); return; } // 若之前还有进程在跑,先结束(简单粗暴版) if (m_process->state() != QProcess::NotRunning) { m_process->kill(); m_process->waitForFinished(); } m_isAsmOperation = true; m_pendingInputFile = inputPath; m_pendingOutputFile = outputFileName.isEmpty() ? QStringLiteral("1.s") : outputFileName; // 把工作目录设为项目根目录:这样 mini_c 写 "1.s" 就会写到项目根目录 QString workingDir = root.absolutePath(); m_process->setWorkingDirectory(workingDir); // mini_c 调用形式:mini_c asm m_process->setProgram(m_backendProgram); QStringList args; args << QStringLiteral("asm") << inputPath; m_process->setArguments(args); m_process->setProcessChannelMode(QProcess::SeparateChannels); m_process->start(); // 不用 waitForFinished,异步等 finished 信号 } void CompileProcessManager::onProcessFinished(int exitCode, QProcess::ExitStatus status) { QString stdoutText = QString::fromUtf8(m_process->readAllStandardOutput()); QString stderrText = QString::fromUtf8(m_process->readAllStandardError()); if (status != QProcess::NormalExit && exitCode == 0) { exitCode = -1; } QString asmText; QString finalOutputPath; if (m_isAsmOperation) { // mini_c 当前实现中,汇编输出写到固定文件 "1.s" QDir workDir(m_process->workingDirectory()); QString tmpAsmPath = workDir.filePath(QStringLiteral("1.s")); if (exitCode == 0 && QFileInfo::exists(tmpAsmPath)) { // 读出 1.s 内容 QFile f(tmpAsmPath); if (f.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&f); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) in.setEncoding(QStringConverter::Utf8); #endif asmText = in.readAll(); f.close(); } else { stderrText += QStringLiteral( "\n[CompileProcessManager] 无法打开汇编输出文件: %1\n" ).arg(tmpAsmPath); } // 如果用户希望输出文件名不是 "1.s",比如 "test.s",就复制一份 finalOutputPath = workDir.filePath(m_pendingOutputFile); if (finalOutputPath != tmpAsmPath) { QFile::remove(finalOutputPath); // 不成功也无所谓 QFile::copy(tmpAsmPath, finalOutputPath); // 覆盖为目标文件名 } } else { if (exitCode == 0) { stderrText += QStringLiteral( "\n[CompileProcessManager] 未找到 mini_c 生成的 1.s 文件。\n" ); } } } // 把汇编文本 + 文件路径 + stdout/stderr + exitCode 一次性丢给前端 emit asmGenerated(asmText, finalOutputPath, stdoutText, stderrText, exitCode); // 重置状态 m_isAsmOperation = false; m_pendingInputFile.clear(); m_pendingOutputFile.clear(); }