forked from qt-creator/qt-creator
CMake: Use line based QtcProcess callbacks in CMakeProcess
This also fixes a potential issue where contents in the local 'rest' strings outlive the process and get part of the next run. Change-Id: Ia9272bff80213084e430436d677183b4faabd250 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -42,17 +42,11 @@ namespace Internal {
|
|||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
|
|
||||||
static QString lineSplit(const QString &rest, const QByteArray &array, std::function<void(const QString &)> f)
|
static QString stripTrailingNewline(QString str)
|
||||||
{
|
{
|
||||||
QString tmp = rest + Utils::QtcProcess::normalizeNewlines(QString::fromLocal8Bit(array));
|
if (str.endsWith('\n'))
|
||||||
int start = 0;
|
str.chop(1);
|
||||||
int end = tmp.indexOf(QLatin1Char('\n'), start);
|
return str;
|
||||||
while (end >= 0) {
|
|
||||||
f(tmp.mid(start, end - start));
|
|
||||||
start = end + 1;
|
|
||||||
end = tmp.indexOf(QLatin1Char('\n'), start);
|
|
||||||
}
|
|
||||||
return tmp.mid(start);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CMakeProcess::CMakeProcess()
|
CMakeProcess::CMakeProcess()
|
||||||
@@ -64,9 +58,6 @@ CMakeProcess::CMakeProcess()
|
|||||||
CMakeProcess::~CMakeProcess()
|
CMakeProcess::~CMakeProcess()
|
||||||
{
|
{
|
||||||
if (m_process) {
|
if (m_process) {
|
||||||
processStandardOutput();
|
|
||||||
processStandardError();
|
|
||||||
|
|
||||||
m_process->disconnect();
|
m_process->disconnect();
|
||||||
Core::Reaper::reap(m_process.release());
|
Core::Reaper::reap(m_process.release());
|
||||||
}
|
}
|
||||||
@@ -86,7 +77,7 @@ void CMakeProcess::run(const BuildDirParameters ¶meters, const QStringList &
|
|||||||
CMakeTool *cmake = parameters.cmakeTool();
|
CMakeTool *cmake = parameters.cmakeTool();
|
||||||
QTC_ASSERT(parameters.isValid() && cmake, return);
|
QTC_ASSERT(parameters.isValid() && cmake, return);
|
||||||
|
|
||||||
const Utils::FilePath buildDirectory = parameters.buildDirectory;
|
const FilePath buildDirectory = parameters.buildDirectory;
|
||||||
QTC_ASSERT(buildDirectory.exists(), return);
|
QTC_ASSERT(buildDirectory.exists(), return);
|
||||||
|
|
||||||
const QString srcDir = parameters.sourceDirectory.path();
|
const QString srcDir = parameters.sourceDirectory.path();
|
||||||
@@ -98,7 +89,7 @@ void CMakeProcess::run(const BuildDirParameters ¶meters, const QStringList &
|
|||||||
// Always use the sourceDir: If we are triggered because the build directory is getting deleted
|
// Always use the sourceDir: If we are triggered because the build directory is getting deleted
|
||||||
// then we are racing against CMakeCache.txt also getting deleted.
|
// then we are racing against CMakeCache.txt also getting deleted.
|
||||||
|
|
||||||
auto process = std::make_unique<Utils::QtcProcess>();
|
auto process = std::make_unique<QtcProcess>();
|
||||||
m_processWasCanceled = false;
|
m_processWasCanceled = false;
|
||||||
|
|
||||||
m_cancelTimer.start();
|
m_cancelTimer.start();
|
||||||
@@ -106,10 +97,15 @@ void CMakeProcess::run(const BuildDirParameters ¶meters, const QStringList &
|
|||||||
process->setWorkingDirectory(buildDirectory);
|
process->setWorkingDirectory(buildDirectory);
|
||||||
process->setEnvironment(parameters.environment);
|
process->setEnvironment(parameters.environment);
|
||||||
|
|
||||||
connect(process.get(), &QtcProcess::readyReadStandardOutput,
|
process->setStdOutLineCallback([](const QString &s) {
|
||||||
this, &CMakeProcess::processStandardOutput);
|
BuildSystem::appendBuildSystemOutput(stripTrailingNewline(s));
|
||||||
connect(process.get(), &QtcProcess::readyReadStandardError,
|
});
|
||||||
this, &CMakeProcess::processStandardError);
|
|
||||||
|
process->setStdErrLineCallback([this](const QString &s) {
|
||||||
|
m_parser.appendMessage(s, StdErrFormat);
|
||||||
|
BuildSystem::appendBuildSystemOutput(stripTrailingNewline(s));
|
||||||
|
});
|
||||||
|
|
||||||
connect(process.get(), &QtcProcess::finished,
|
connect(process.get(), &QtcProcess::finished,
|
||||||
this, &CMakeProcess::handleProcessFinished);
|
this, &CMakeProcess::handleProcessFinished);
|
||||||
|
|
||||||
@@ -162,37 +158,14 @@ void CMakeProcess::setProgressValue(int p)
|
|||||||
m_future->setProgressValue(p);
|
m_future->setProgressValue(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeProcess::processStandardOutput()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_process, return);
|
|
||||||
|
|
||||||
static QString rest;
|
|
||||||
rest = lineSplit(rest, m_process->readAllStandardOutput(), [](const QString &s) {
|
|
||||||
BuildSystem::appendBuildSystemOutput(s);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMakeProcess::processStandardError()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_process, return);
|
|
||||||
|
|
||||||
static QString rest;
|
|
||||||
rest = lineSplit(rest, m_process->readAllStandardError(), [this](const QString &s) {
|
|
||||||
m_parser.appendMessage(s + '\n', Utils::StdErrFormat);
|
|
||||||
BuildSystem::appendBuildSystemOutput(s);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMakeProcess::handleProcessFinished()
|
void CMakeProcess::handleProcessFinished()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_process && m_future, return);
|
QTC_ASSERT(m_process && m_future, return);
|
||||||
|
|
||||||
m_cancelTimer.stop();
|
m_cancelTimer.stop();
|
||||||
|
|
||||||
processStandardOutput();
|
|
||||||
processStandardError();
|
|
||||||
|
|
||||||
const int code = m_process->exitCode();
|
const int code = m_process->exitCode();
|
||||||
|
|
||||||
QString msg;
|
QString msg;
|
||||||
if (m_process->exitStatus() != QProcess::NormalExit) {
|
if (m_process->exitStatus() != QProcess::NormalExit) {
|
||||||
if (m_processWasCanceled) {
|
if (m_processWasCanceled) {
|
||||||
@@ -206,7 +179,7 @@ void CMakeProcess::handleProcessFinished()
|
|||||||
m_lastExitCode = code;
|
m_lastExitCode = code;
|
||||||
|
|
||||||
if (!msg.isEmpty()) {
|
if (!msg.isEmpty()) {
|
||||||
BuildSystem::appendBuildSystemOutput(msg);
|
BuildSystem::appendBuildSystemOutput(msg + '\n');
|
||||||
TaskHub::addTask(BuildSystemTask(Task::Error, msg));
|
TaskHub::addTask(BuildSystemTask(Task::Error, msg));
|
||||||
m_future->reportCanceled();
|
m_future->reportCanceled();
|
||||||
} else {
|
} else {
|
||||||
@@ -218,7 +191,7 @@ void CMakeProcess::handleProcessFinished()
|
|||||||
emit finished();
|
emit finished();
|
||||||
|
|
||||||
const QString elapsedTime = Utils::formatElapsedTime(m_elapsed.elapsed());
|
const QString elapsedTime = Utils::formatElapsedTime(m_elapsed.elapsed());
|
||||||
BuildSystem::appendBuildSystemOutput(elapsedTime);
|
BuildSystem::appendBuildSystemOutput(elapsedTime + '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeProcess::checkForCancelled()
|
void CMakeProcess::checkForCancelled()
|
||||||
|
|||||||
@@ -59,10 +59,6 @@ public:
|
|||||||
void reportFinished(); // None of the progress related functions will work after this!
|
void reportFinished(); // None of the progress related functions will work after this!
|
||||||
void setProgressValue(int p);
|
void setProgressValue(int p);
|
||||||
|
|
||||||
// Process stdout/stderr:
|
|
||||||
void processStandardOutput();
|
|
||||||
void processStandardError();
|
|
||||||
|
|
||||||
int lastExitCode() const { return m_lastExitCode; }
|
int lastExitCode() const { return m_lastExitCode; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|||||||
Reference in New Issue
Block a user