diff --git a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp index d41777e21e4..fd768d576bb 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp @@ -32,9 +32,12 @@ #include #include +#include #include #include +#include + using namespace Utils; namespace CMakeProjectManager { @@ -52,7 +55,7 @@ static QString stripTrailingNewline(QString str) CMakeProcess::CMakeProcess() { connect(&m_cancelTimer, &QTimer::timeout, this, &CMakeProcess::checkForCancelled); - m_cancelTimer.setInterval(500); + m_cancelTimer.setInterval(50); } CMakeProcess::~CMakeProcess() @@ -61,8 +64,9 @@ CMakeProcess::~CMakeProcess() m_parser.flush(); if (m_future) { - reportCanceled(); - reportFinished(); + // None of the progress related functions will work after this! + m_future->reportCanceled(); + m_future->reportFinished(); } } @@ -104,25 +108,26 @@ void CMakeProcess::run(const BuildDirParameters ¶meters, const QStringList & // 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. - auto process = std::make_unique(); + m_process.reset(new QtcProcess); m_processWasCanceled = false; m_cancelTimer.start(); - process->setWorkingDirectory(buildDirectory); - process->setEnvironment(parameters.environment); + m_process->setWorkingDirectory(buildDirectory); + m_process->setEnvironment(parameters.environment); - process->setStdOutLineCallback([](const QString &s) { + m_process->setStdOutLineCallback([](const QString &s) { BuildSystem::appendBuildSystemOutput(stripTrailingNewline(s)); }); - process->setStdErrLineCallback([this](const QString &s) { + m_process->setStdErrLineCallback([this](const QString &s) { m_parser.appendMessage(s, StdErrFormat); BuildSystem::appendBuildSystemOutput(stripTrailingNewline(s)); }); - connect(process.get(), &QtcProcess::finished, - this, &CMakeProcess::handleProcessFinished); + connect(m_process.get(), &QtcProcess::done, this, [this] { + handleProcessDone(m_process->resultData()); + }); CommandLine commandLine(cmakeExecutable); commandLine.addArgs({"-S", sourceDirectory.path(), "-B", buildDirectory.path()}); @@ -133,72 +138,44 @@ void CMakeProcess::run(const BuildDirParameters ¶meters, const QStringList & BuildSystem::startNewBuildSystemOutput( tr("Running %1 in %2.").arg(commandLine.toUserOutput()).arg(buildDirectory.toUserOutput())); - auto future = std::make_unique>(); - future->setProgressRange(0, 1); - Core::ProgressManager::addTimedTask(*future.get(), + m_future.reset(new QFutureInterface); + m_future->setProgressRange(0, 1); + Core::ProgressManager::addTimedTask(*m_future.get(), tr("Configuring \"%1\"").arg(parameters.projectName), "CMake.Configure", 10); - process->setUseCtrlCStub(true); - process->setCommand(commandLine); + m_process->setCommand(commandLine); emit started(); m_elapsed.start(); - process->start(); - - m_process = std::move(process); - m_future = std::move(future); + m_process->start(); } -void CMakeProcess::terminate() +void CMakeProcess::stop() { if (m_process) { m_processWasCanceled = true; - m_process->terminate(); + m_process->close(); + handleProcessDone({15, QProcess::CrashExit, QProcess::Crashed, {}}); } } -QProcess::ProcessState CMakeProcess::state() const -{ - if (m_process) - return m_process->state(); - return QProcess::NotRunning; -} - -void CMakeProcess::reportCanceled() +void CMakeProcess::handleProcessDone(const Utils::ProcessResultData &resultData) { QTC_ASSERT(m_future, return); - m_future->reportCanceled(); -} - -void CMakeProcess::reportFinished() -{ - QTC_ASSERT(m_future, return); - m_future->reportFinished(); - m_future.reset(); -} - -void CMakeProcess::setProgressValue(int p) -{ - QTC_ASSERT(m_future, return); - m_future->setProgressValue(p); -} - -void CMakeProcess::handleProcessFinished() -{ - QTC_ASSERT(m_process && m_future, return); m_cancelTimer.stop(); - const int code = m_process->exitCode(); + const int code = resultData.m_exitCode; QString msg; - if (m_process->exitStatus() != QProcess::NormalExit) { - if (m_processWasCanceled) { + if (resultData.m_error == QProcess::FailedToStart) { + msg = tr("CMake process failed to start."); + } else if (resultData.m_exitStatus != QProcess::NormalExit) { + if (m_processWasCanceled) msg = tr("CMake process was canceled by the user."); - } else { + else msg = tr("CMake process crashed."); - } } else if (code != 0) { msg = tr("CMake process exited with exit code %1.").arg(code); } @@ -227,8 +204,7 @@ void CMakeProcess::checkForCancelled() if (m_future->isCanceled()) { m_cancelTimer.stop(); - m_processWasCanceled = true; - m_process->close(); + stop(); } } diff --git a/src/plugins/cmakeprojectmanager/cmakeprocess.h b/src/plugins/cmakeprojectmanager/cmakeprocess.h index 49e6596cf4c..fd29fa59496 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprocess.h +++ b/src/plugins/cmakeprojectmanager/cmakeprocess.h @@ -30,15 +30,21 @@ #include #include -#include #include -#include #include #include #include -namespace Utils { class QtcProcess; } +QT_BEGIN_NAMESPACE +template +class QFutureInterface; +QT_END_NAMESPACE + +namespace Utils { +class ProcessResultData; +class QtcProcess; +} namespace CMakeProjectManager { namespace Internal { @@ -49,18 +55,10 @@ class CMakeProcess : public QObject public: CMakeProcess(); - CMakeProcess(const CMakeProcess&) = delete; ~CMakeProcess(); void run(const BuildDirParameters ¶meters, const QStringList &arguments); - void terminate(); - - QProcess::ProcessState state() const; - - // Update progress information: - void reportCanceled(); - void reportFinished(); // None of the progress related functions will work after this! - void setProgressValue(int p); + void stop(); int lastExitCode() const { return m_lastExitCode; } @@ -69,7 +67,7 @@ signals: void finished(); private: - void handleProcessFinished(); + void handleProcessDone(const Utils::ProcessResultData &resultData); void checkForCancelled(); std::unique_ptr m_process; diff --git a/src/plugins/cmakeprojectmanager/fileapireader.cpp b/src/plugins/cmakeprojectmanager/fileapireader.cpp index aa50147aab4..dd14a5dc3b3 100644 --- a/src/plugins/cmakeprojectmanager/fileapireader.cpp +++ b/src/plugins/cmakeprojectmanager/fileapireader.cpp @@ -175,7 +175,7 @@ void FileApiReader::stop() void FileApiReader::stopCMakeRun() { if (m_cmakeProcess) - m_cmakeProcess->terminate(); + m_cmakeProcess->stop(); } bool FileApiReader::isParsing() const