Files
Compiler_GUI/backend/compileprocessmanager.cpp
2025-12-12 18:54:13 +08:00

133 lines
4.3 KiB
C++
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.

#include "compileprocessmanager.h"
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QTextStream>
#include <QStringConverter>
#include <QtGlobal>
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 <inputFilename>
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();
}