forked from qt-creator/qt-creator
Meson: Merge MesonProcess into project parser file pair
Only used there. Also remove the translation line in the test project to help with incomplete Qt 5 installations. Change-Id: Id7029b499cec69a7e1733e2ac4ade9026c522951 Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
@@ -23,8 +23,6 @@ add_qtc_plugin(MesonProjectManager
|
|||||||
mesoninfoparser.h
|
mesoninfoparser.h
|
||||||
mesonoutputparser.cpp
|
mesonoutputparser.cpp
|
||||||
mesonoutputparser.h
|
mesonoutputparser.h
|
||||||
mesonprocess.cpp
|
|
||||||
mesonprocess.h
|
|
||||||
mesonproject.cpp
|
mesonproject.cpp
|
||||||
mesonproject.h
|
mesonproject.h
|
||||||
mesonprojectimporter.cpp
|
mesonprojectimporter.cpp
|
||||||
|
|||||||
@@ -1,119 +0,0 @@
|
|||||||
// Copyright (C) 2020 Alexis Jeandet.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
|
||||||
|
|
||||||
#include "mesonprocess.h"
|
|
||||||
|
|
||||||
#include "mesonprojectmanagertr.h"
|
|
||||||
#include "toolwrapper.h"
|
|
||||||
|
|
||||||
#include <coreplugin/messagemanager.h>
|
|
||||||
#include <coreplugin/progressmanager/processprogress.h>
|
|
||||||
|
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
|
||||||
#include <projectexplorer/taskhub.h>
|
|
||||||
|
|
||||||
#include <utils/environment.h>
|
|
||||||
#include <utils/process.h>
|
|
||||||
#include <utils/stringutils.h>
|
|
||||||
|
|
||||||
#include <QLoggingCategory>
|
|
||||||
|
|
||||||
using namespace Core;
|
|
||||||
using namespace Utils;
|
|
||||||
|
|
||||||
namespace MesonProjectManager {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
static Q_LOGGING_CATEGORY(mesonProcessLog, "qtc.meson.buildsystem", QtWarningMsg);
|
|
||||||
|
|
||||||
MesonProcess::MesonProcess() = default;
|
|
||||||
MesonProcess::~MesonProcess() = default;
|
|
||||||
|
|
||||||
bool MesonProcess::run(const Command &command,
|
|
||||||
const Environment &env,
|
|
||||||
const QString &projectName,
|
|
||||||
bool captureStdo)
|
|
||||||
{
|
|
||||||
if (!sanityCheck(command))
|
|
||||||
return false;
|
|
||||||
m_stdo.clear();
|
|
||||||
ProjectExplorer::TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
|
|
||||||
setupProcess(command, env, projectName, captureStdo);
|
|
||||||
m_elapsed.start();
|
|
||||||
m_process->start();
|
|
||||||
qCDebug(mesonProcessLog()) << "Starting:" << command.toUserOutput();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MesonProcess::handleProcessDone()
|
|
||||||
{
|
|
||||||
if (m_process->result() != ProcessResult::FinishedWithSuccess) {
|
|
||||||
ProjectExplorer::TaskHub::addTask(ProjectExplorer::BuildSystemTask{
|
|
||||||
ProjectExplorer::Task::TaskType::Error, m_process->exitMessage()});
|
|
||||||
}
|
|
||||||
m_stdo = m_process->readAllRawStandardOutput();
|
|
||||||
m_stderr = m_process->readAllRawStandardError();
|
|
||||||
const QString elapsedTime = formatElapsedTime(m_elapsed.elapsed());
|
|
||||||
MessageManager::writeSilently(elapsedTime);
|
|
||||||
emit finished(m_process->exitCode(), m_process->exitStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
void MesonProcess::setupProcess(const Command &command, const Environment &env,
|
|
||||||
const QString &projectName, bool captureStdo)
|
|
||||||
{
|
|
||||||
if (m_process)
|
|
||||||
m_process.release()->deleteLater();
|
|
||||||
m_process.reset(new Process);
|
|
||||||
connect(m_process.get(), &Process::done, this, &MesonProcess::handleProcessDone);
|
|
||||||
if (!captureStdo) {
|
|
||||||
connect(m_process.get(), &Process::readyReadStandardOutput,
|
|
||||||
this, &MesonProcess::processStandardOutput);
|
|
||||||
connect(m_process.get(), &Process::readyReadStandardError,
|
|
||||||
this, &MesonProcess::processStandardError);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_process->setWorkingDirectory(command.workDir());
|
|
||||||
m_process->setEnvironment(env);
|
|
||||||
MessageManager::writeFlashing(Tr::tr("Running %1 in %2.")
|
|
||||||
.arg(command.toUserOutput(), command.workDir().toUserOutput()));
|
|
||||||
m_process->setCommand(command.cmdLine());
|
|
||||||
m_process->setTimeoutS(10);
|
|
||||||
ProcessProgress *progress = new ProcessProgress(m_process.get());
|
|
||||||
progress->setDisplayName(Tr::tr("Configuring \"%1\".").arg(projectName));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MesonProcess::sanityCheck(const Command &command) const
|
|
||||||
{
|
|
||||||
const auto &exe = command.cmdLine().executable();
|
|
||||||
if (!exe.exists()) {
|
|
||||||
//Should only reach this point if Meson exe is removed while a Meson project is opened
|
|
||||||
ProjectExplorer::TaskHub::addTask(
|
|
||||||
ProjectExplorer::BuildSystemTask{ProjectExplorer::Task::TaskType::Error,
|
|
||||||
Tr::tr("Executable does not exist: %1")
|
|
||||||
.arg(exe.toUserOutput())});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!exe.toFileInfo().isExecutable()) {
|
|
||||||
ProjectExplorer::TaskHub::addTask(
|
|
||||||
ProjectExplorer::BuildSystemTask{ProjectExplorer::Task::TaskType::Error,
|
|
||||||
Tr::tr("Command is not executable: %1")
|
|
||||||
.arg(exe.toUserOutput())});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MesonProcess::processStandardOutput()
|
|
||||||
{
|
|
||||||
const auto data = m_process->readAllRawStandardOutput();
|
|
||||||
MessageManager::writeSilently(QString::fromLocal8Bit(data));
|
|
||||||
emit readyReadStandardOutput(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MesonProcess::processStandardError()
|
|
||||||
{
|
|
||||||
MessageManager::writeSilently(QString::fromLocal8Bit(m_process->readAllRawStandardError()));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace MesonProjectManager
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
// Copyright (C) 2020 Alexis Jeandet.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QByteArray>
|
|
||||||
#include <QElapsedTimer>
|
|
||||||
#include <QObject>
|
|
||||||
#include <QProcess>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace Utils {
|
|
||||||
class Environment;
|
|
||||||
class Process;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace MesonProjectManager {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class Command;
|
|
||||||
|
|
||||||
class MesonProcess final : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
MesonProcess();
|
|
||||||
~MesonProcess();
|
|
||||||
bool run(const Command &command, const Utils::Environment &env,
|
|
||||||
const QString &projectName, bool captureStdo = false);
|
|
||||||
|
|
||||||
const QByteArray &stdOut() const { return m_stdo; }
|
|
||||||
const QByteArray &stdErr() const { return m_stderr; }
|
|
||||||
signals:
|
|
||||||
void finished(int exitCode, QProcess::ExitStatus exitStatus);
|
|
||||||
void readyReadStandardOutput(const QByteArray &data);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void handleProcessDone();
|
|
||||||
void setupProcess(const Command &command, const Utils::Environment &env,
|
|
||||||
const QString &projectName, bool captureStdo);
|
|
||||||
bool sanityCheck(const Command &command) const;
|
|
||||||
|
|
||||||
void processStandardOutput();
|
|
||||||
void processStandardError();
|
|
||||||
|
|
||||||
std::unique_ptr<Utils::Process> m_process;
|
|
||||||
QElapsedTimer m_elapsed;
|
|
||||||
QByteArray m_stdo;
|
|
||||||
QByteArray m_stderr;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace MesonProjectManager
|
|
||||||
@@ -49,8 +49,6 @@ Project {
|
|||||||
"mesonbuildconfiguration.h",
|
"mesonbuildconfiguration.h",
|
||||||
"mesonbuildsystem.cpp",
|
"mesonbuildsystem.cpp",
|
||||||
"mesonbuildsystem.h",
|
"mesonbuildsystem.h",
|
||||||
"mesonprocess.cpp",
|
|
||||||
"mesonprocess.h",
|
|
||||||
"mesonproject.cpp",
|
"mesonproject.cpp",
|
||||||
"mesonproject.h",
|
"mesonproject.h",
|
||||||
"mesonprojectimporter.cpp",
|
"mesonprojectimporter.cpp",
|
||||||
|
|||||||
@@ -4,25 +4,36 @@
|
|||||||
#include "mesonprojectparser.h"
|
#include "mesonprojectparser.h"
|
||||||
|
|
||||||
#include "mesoninfoparser.h"
|
#include "mesoninfoparser.h"
|
||||||
|
#include "mesonprojectmanagertr.h"
|
||||||
#include "mesonprojectnodes.h"
|
#include "mesonprojectnodes.h"
|
||||||
#include "mesontools.h"
|
#include "mesontools.h"
|
||||||
#include "projecttree.h"
|
#include "projecttree.h"
|
||||||
|
|
||||||
|
#include <coreplugin/messagemanager.h>
|
||||||
#include <coreplugin/messagemanager.h>
|
#include <coreplugin/messagemanager.h>
|
||||||
|
|
||||||
#include <projectexplorer/projectexplorer.h>
|
#include <projectexplorer/projectexplorer.h>
|
||||||
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
|
#include <projectexplorer/taskhub.h>
|
||||||
|
|
||||||
#include <utils/async.h>
|
#include <utils/async.h>
|
||||||
|
#include <utils/environment.h>
|
||||||
#include <utils/fileinprojectfinder.h>
|
#include <utils/fileinprojectfinder.h>
|
||||||
|
#include <utils/stringutils.h>
|
||||||
#include <QStringList>
|
|
||||||
#include <QTextStream>
|
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
|
#include <coreplugin/progressmanager/processprogress.h>
|
||||||
|
|
||||||
|
using namespace Core;
|
||||||
|
using namespace ProjectExplorer;
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace MesonProjectManager {
|
namespace MesonProjectManager {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
static Q_LOGGING_CATEGORY(mesonProcessLog, "qtc.meson.buildsystem", QtWarningMsg);
|
||||||
|
|
||||||
struct CompilerArgs
|
struct CompilerArgs
|
||||||
{
|
{
|
||||||
QStringList args;
|
QStringList args;
|
||||||
@@ -30,8 +41,8 @@ struct CompilerArgs
|
|||||||
ProjectExplorer::Macros macros;
|
ProjectExplorer::Macros macros;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::optional<QString> extractValueIfMatches(const QString &arg,
|
static std::optional<QString> extractValueIfMatches(const QString &arg,
|
||||||
const QStringList &candidates)
|
const QStringList &candidates)
|
||||||
{
|
{
|
||||||
for (const auto &flag : candidates) {
|
for (const auto &flag : candidates) {
|
||||||
if (arg.startsWith(flag))
|
if (arg.startsWith(flag))
|
||||||
@@ -40,11 +51,12 @@ inline std::optional<QString> extractValueIfMatches(const QString &arg,
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::optional<QString> extractInclude(const QString &arg)
|
static std::optional<QString> extractInclude(const QString &arg)
|
||||||
{
|
{
|
||||||
return extractValueIfMatches(arg, {"-I", "/I", "-isystem", "-imsvc", "/imsvc"});
|
return extractValueIfMatches(arg, {"-I", "/I", "-isystem", "-imsvc", "/imsvc"});
|
||||||
}
|
}
|
||||||
inline std::optional<ProjectExplorer::Macro> extractMacro(const QString &arg)
|
|
||||||
|
static std::optional<ProjectExplorer::Macro> extractMacro(const QString &arg)
|
||||||
{
|
{
|
||||||
auto define = extractValueIfMatches(arg, {"-D", "/D"});
|
auto define = extractValueIfMatches(arg, {"-D", "/D"});
|
||||||
if (define)
|
if (define)
|
||||||
@@ -93,18 +105,12 @@ MesonProjectParser::MesonProjectParser(const Utils::Id &meson,
|
|||||||
, m_meson{meson}
|
, m_meson{meson}
|
||||||
, m_projectName{project->displayName()}
|
, m_projectName{project->displayName()}
|
||||||
{
|
{
|
||||||
connect(&m_process, &MesonProcess::finished, this, &MesonProjectParser::processFinished);
|
|
||||||
connect(&m_process,
|
|
||||||
&MesonProcess::readyReadStandardOutput,
|
|
||||||
&m_outputParser,
|
|
||||||
&MesonOutputParser::readStdo);
|
|
||||||
|
|
||||||
// TODO re-think the way all BuildSystem/ProjectParser are tied
|
// TODO re-think the way all BuildSystem/ProjectParser are tied
|
||||||
// I take project info here, I also take build and src dir later from
|
// I take project info here, I also take build and src dir later from
|
||||||
// functions args.
|
// functions args.
|
||||||
auto fileFinder = new Utils::FileInProjectFinder;
|
auto fileFinder = new Utils::FileInProjectFinder;
|
||||||
fileFinder->setProjectDirectory(project->projectDirectory());
|
fileFinder->setProjectDirectory(project->projectDirectory());
|
||||||
fileFinder->setProjectFiles(project->files(ProjectExplorer::Project::AllFiles));
|
fileFinder->setProjectFiles(project->files(Project::AllFiles));
|
||||||
m_outputParser.setFileFinder(fileFinder);
|
m_outputParser.setFileFinder(fileFinder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +132,7 @@ bool MesonProjectParser::configure(const Utils::FilePath &sourcePath,
|
|||||||
m_pendingCommands.enqueue(
|
m_pendingCommands.enqueue(
|
||||||
std::make_tuple(MesonTools::mesonWrapper(m_meson)->regenerate(sourcePath, buildPath),
|
std::make_tuple(MesonTools::mesonWrapper(m_meson)->regenerate(sourcePath, buildPath),
|
||||||
false));
|
false));
|
||||||
return m_process.run(cmd, m_env, m_projectName);
|
return run(cmd, m_env, m_projectName);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MesonProjectParser::wipe(const Utils::FilePath &sourcePath,
|
bool MesonProjectParser::wipe(const Utils::FilePath &sourcePath,
|
||||||
@@ -149,7 +155,7 @@ bool MesonProjectParser::setup(const Utils::FilePath &sourcePath,
|
|||||||
if (forceWipe || isSetup(buildPath))
|
if (forceWipe || isSetup(buildPath))
|
||||||
cmdArgs << "--wipe";
|
cmdArgs << "--wipe";
|
||||||
auto cmd = MesonTools::mesonWrapper(m_meson)->setup(sourcePath, buildPath, cmdArgs);
|
auto cmd = MesonTools::mesonWrapper(m_meson)->setup(sourcePath, buildPath, cmdArgs);
|
||||||
return m_process.run(cmd, m_env, m_projectName);
|
return run(cmd, m_env, m_projectName);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MesonProjectParser::parse(const Utils::FilePath &sourcePath, const Utils::FilePath &buildPath)
|
bool MesonProjectParser::parse(const Utils::FilePath &sourcePath, const Utils::FilePath &buildPath)
|
||||||
@@ -170,18 +176,18 @@ bool MesonProjectParser::parse(const Utils::FilePath &sourcePath)
|
|||||||
m_srcDir = sourcePath;
|
m_srcDir = sourcePath;
|
||||||
m_introType = IntroDataType::stdo;
|
m_introType = IntroDataType::stdo;
|
||||||
m_outputParser.setSourceDirectory(sourcePath);
|
m_outputParser.setSourceDirectory(sourcePath);
|
||||||
return m_process.run(MesonTools::mesonWrapper(m_meson)->introspect(sourcePath),
|
return run(MesonTools::mesonWrapper(m_meson)->introspect(sourcePath),
|
||||||
m_env,
|
m_env,
|
||||||
m_projectName,
|
m_projectName,
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ProjectExplorer::BuildTargetInfo> MesonProjectParser::appsTargets() const
|
QList<BuildTargetInfo> MesonProjectParser::appsTargets() const
|
||||||
{
|
{
|
||||||
QList<ProjectExplorer::BuildTargetInfo> apps;
|
QList<BuildTargetInfo> apps;
|
||||||
for (const Target &target : m_parserResult.targets) {
|
for (const Target &target : m_parserResult.targets) {
|
||||||
if (target.type == Target::Type::executable) {
|
if (target.type == Target::Type::executable) {
|
||||||
ProjectExplorer::BuildTargetInfo bti;
|
BuildTargetInfo bti;
|
||||||
bti.displayName = target.name;
|
bti.displayName = target.name;
|
||||||
bti.buildKey = Target::fullName(m_buildDir, target);
|
bti.buildKey = Target::fullName(m_buildDir, target);
|
||||||
bti.displayNameUniquifier = bti.buildKey;
|
bti.displayNameUniquifier = bti.buildKey;
|
||||||
@@ -198,8 +204,8 @@ QList<ProjectExplorer::BuildTargetInfo> MesonProjectParser::appsTargets() const
|
|||||||
bool MesonProjectParser::startParser()
|
bool MesonProjectParser::startParser()
|
||||||
{
|
{
|
||||||
m_parserFutureResult = Utils::asyncRun(
|
m_parserFutureResult = Utils::asyncRun(
|
||||||
ProjectExplorer::ProjectExplorerPlugin::sharedThreadPool(),
|
ProjectExplorerPlugin::sharedThreadPool(),
|
||||||
[processOutput = m_process.stdOut(), introType = m_introType,
|
[processOutput = m_stdo, introType = m_introType,
|
||||||
buildDir = m_buildDir, srcDir = m_srcDir] {
|
buildDir = m_buildDir, srcDir = m_srcDir] {
|
||||||
if (introType == IntroDataType::file)
|
if (introType == IntroDataType::file)
|
||||||
return extractParserResults(srcDir, MesonInfoParser::parse(buildDir));
|
return extractParserResults(srcDir, MesonInfoParser::parse(buildDir));
|
||||||
@@ -245,13 +251,13 @@ void MesonProjectParser::update(const QFuture<MesonProjectParser::ParserData *>
|
|||||||
emit parsingCompleted(true);
|
emit parsingCompleted(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectExplorer::RawProjectPart MesonProjectParser::buildRawPart(
|
RawProjectPart MesonProjectParser::buildRawPart(
|
||||||
const Target &target,
|
const Target &target,
|
||||||
const Target::SourceGroup &sources,
|
const Target::SourceGroup &sources,
|
||||||
const ProjectExplorer::ToolChain *cxxToolChain,
|
const ToolChain *cxxToolChain,
|
||||||
const ProjectExplorer::ToolChain *cToolChain)
|
const ToolChain *cToolChain)
|
||||||
{
|
{
|
||||||
ProjectExplorer::RawProjectPart part;
|
RawProjectPart part;
|
||||||
part.setDisplayName(target.name);
|
part.setDisplayName(target.name);
|
||||||
part.setBuildSystemTarget(Target::fullName(m_buildDir, target));
|
part.setBuildSystemTarget(Target::fullName(m_buildDir, target));
|
||||||
part.setFiles(sources.sources + sources.generatedSources);
|
part.setFiles(sources.sources + sources.generatedSources);
|
||||||
@@ -275,13 +281,12 @@ void MesonProjectParser::processFinished(int exitCode, QProcess::ExitStatus exit
|
|||||||
else {
|
else {
|
||||||
// see comment near m_pendingCommands declaration
|
// see comment near m_pendingCommands declaration
|
||||||
std::tuple<Command, bool> args = m_pendingCommands.dequeue();
|
std::tuple<Command, bool> args = m_pendingCommands.dequeue();
|
||||||
m_process.run(std::get<0>(args), m_env, m_projectName, std::get<1>(args));
|
run(std::get<0>(args), m_env, m_projectName, std::get<1>(args));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (m_introType == IntroDataType::stdo) {
|
if (m_introType == IntroDataType::stdo) {
|
||||||
auto data = m_process.stdErr();
|
Core::MessageManager::writeSilently(QString::fromLocal8Bit(m_stderr));
|
||||||
Core::MessageManager::writeSilently(QString::fromLocal8Bit(data));
|
m_outputParser.readStdo(m_stderr);
|
||||||
m_outputParser.readStdo(data);
|
|
||||||
}
|
}
|
||||||
emit parsingCompleted(false);
|
emit parsingCompleted(false);
|
||||||
}
|
}
|
||||||
@@ -327,5 +332,93 @@ bool MesonProjectParser::usesSameMesonVersion(const Utils::FilePath &buildPath)
|
|||||||
auto meson = MesonTools::mesonWrapper(m_meson);
|
auto meson = MesonTools::mesonWrapper(m_meson);
|
||||||
return info && meson && info->mesonVersion == meson->version();
|
return info && meson && info->mesonVersion == meson->version();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool MesonProjectParser::run(const Command &command,
|
||||||
|
const Environment &env,
|
||||||
|
const QString &projectName,
|
||||||
|
bool captureStdo)
|
||||||
|
{
|
||||||
|
if (!sanityCheck(command))
|
||||||
|
return false;
|
||||||
|
m_stdo.clear();
|
||||||
|
ProjectExplorer::TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
|
||||||
|
setupProcess(command, env, projectName, captureStdo);
|
||||||
|
m_elapsed.start();
|
||||||
|
m_process->start();
|
||||||
|
qCDebug(mesonProcessLog()) << "Starting:" << command.toUserOutput();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MesonProjectParser::handleProcessDone()
|
||||||
|
{
|
||||||
|
if (m_process->result() != ProcessResult::FinishedWithSuccess) {
|
||||||
|
ProjectExplorer::TaskHub::addTask(ProjectExplorer::BuildSystemTask{
|
||||||
|
ProjectExplorer::Task::TaskType::Error, m_process->exitMessage()});
|
||||||
|
}
|
||||||
|
m_stdo = m_process->readAllRawStandardOutput();
|
||||||
|
m_stderr = m_process->readAllRawStandardError();
|
||||||
|
const QString elapsedTime = formatElapsedTime(m_elapsed.elapsed());
|
||||||
|
MessageManager::writeSilently(elapsedTime);
|
||||||
|
processFinished(m_process->exitCode(), m_process->exitStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MesonProjectParser::setupProcess(const Command &command, const Environment &env,
|
||||||
|
const QString &projectName, bool captureStdo)
|
||||||
|
{
|
||||||
|
if (m_process)
|
||||||
|
m_process.release()->deleteLater();
|
||||||
|
m_process.reset(new Process);
|
||||||
|
connect(m_process.get(), &Process::done, this, &MesonProjectParser::handleProcessDone);
|
||||||
|
if (!captureStdo) {
|
||||||
|
connect(m_process.get(), &Process::readyReadStandardOutput,
|
||||||
|
this, &MesonProjectParser::processStandardOutput);
|
||||||
|
connect(m_process.get(), &Process::readyReadStandardError,
|
||||||
|
this, &MesonProjectParser::processStandardError);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_process->setWorkingDirectory(command.workDir());
|
||||||
|
m_process->setEnvironment(env);
|
||||||
|
MessageManager::writeFlashing(Tr::tr("Running %1 in %2.")
|
||||||
|
.arg(command.toUserOutput(), command.workDir().toUserOutput()));
|
||||||
|
m_process->setCommand(command.cmdLine());
|
||||||
|
m_process->setTimeoutS(10);
|
||||||
|
ProcessProgress *progress = new ProcessProgress(m_process.get());
|
||||||
|
progress->setDisplayName(Tr::tr("Configuring \"%1\".").arg(projectName));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MesonProjectParser::sanityCheck(const Command &command) const
|
||||||
|
{
|
||||||
|
const auto &exe = command.cmdLine().executable();
|
||||||
|
if (!exe.exists()) {
|
||||||
|
//Should only reach this point if Meson exe is removed while a Meson project is opened
|
||||||
|
ProjectExplorer::TaskHub::addTask(
|
||||||
|
ProjectExplorer::BuildSystemTask{ProjectExplorer::Task::TaskType::Error,
|
||||||
|
Tr::tr("Executable does not exist: %1")
|
||||||
|
.arg(exe.toUserOutput())});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!exe.toFileInfo().isExecutable()) {
|
||||||
|
ProjectExplorer::TaskHub::addTask(
|
||||||
|
ProjectExplorer::BuildSystemTask{ProjectExplorer::Task::TaskType::Error,
|
||||||
|
Tr::tr("Command is not executable: %1")
|
||||||
|
.arg(exe.toUserOutput())});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MesonProjectParser::processStandardOutput()
|
||||||
|
{
|
||||||
|
const auto data = m_process->readAllRawStandardOutput();
|
||||||
|
MessageManager::writeSilently(QString::fromLocal8Bit(data));
|
||||||
|
m_outputParser.readStdo(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MesonProjectParser::processStandardError()
|
||||||
|
{
|
||||||
|
MessageManager::writeSilently(QString::fromLocal8Bit(m_process->readAllRawStandardError()));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace MesonProjectManager
|
} // namespace MesonProjectManager
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include "kitdata.h"
|
#include "kitdata.h"
|
||||||
#include "mesoninfoparser.h"
|
#include "mesoninfoparser.h"
|
||||||
#include "mesonoutputparser.h"
|
#include "mesonoutputparser.h"
|
||||||
#include "mesonprocess.h"
|
|
||||||
#include "mesonprojectnodes.h"
|
#include "mesonprojectnodes.h"
|
||||||
#include "mesonwrapper.h"
|
#include "mesonwrapper.h"
|
||||||
|
|
||||||
@@ -91,7 +90,6 @@ private:
|
|||||||
const ProjectExplorer::ToolChain *cxxToolChain,
|
const ProjectExplorer::ToolChain *cxxToolChain,
|
||||||
const ProjectExplorer::ToolChain *cToolChain);
|
const ProjectExplorer::ToolChain *cToolChain);
|
||||||
void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||||
MesonProcess m_process;
|
|
||||||
MesonOutputParser m_outputParser;
|
MesonOutputParser m_outputParser;
|
||||||
Utils::Environment m_env;
|
Utils::Environment m_env;
|
||||||
Utils::Id m_meson;
|
Utils::Id m_meson;
|
||||||
@@ -108,6 +106,22 @@ private:
|
|||||||
// maybe moving meson to build step could make this class simpler
|
// maybe moving meson to build step could make this class simpler
|
||||||
// also this should ease command dependencies
|
// also this should ease command dependencies
|
||||||
QQueue<std::tuple<Command, bool>> m_pendingCommands;
|
QQueue<std::tuple<Command, bool>> m_pendingCommands;
|
||||||
|
|
||||||
|
bool run(const Command &command, const Utils::Environment &env,
|
||||||
|
const QString &projectName, bool captureStdo = false);
|
||||||
|
|
||||||
|
void handleProcessDone();
|
||||||
|
void setupProcess(const Command &command, const Utils::Environment &env,
|
||||||
|
const QString &projectName, bool captureStdo);
|
||||||
|
bool sanityCheck(const Command &command) const;
|
||||||
|
|
||||||
|
void processStandardOutput();
|
||||||
|
void processStandardError();
|
||||||
|
|
||||||
|
std::unique_ptr<Utils::Process> m_process;
|
||||||
|
QElapsedTimer m_elapsed;
|
||||||
|
QByteArray m_stdo;
|
||||||
|
QByteArray m_stderr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ project('mesonsampleproject', 'cpp',default_options : ['cpp_std=c++11'])
|
|||||||
qt5 = import('qt5')
|
qt5 = import('qt5')
|
||||||
qt5dep = dependency('qt5', modules : ['Core', 'Widgets'])
|
qt5dep = dependency('qt5', modules : ['Core', 'Widgets'])
|
||||||
|
|
||||||
translations = qt5.compile_translations(ts_files : 'mesonsampleproject_fr_FR.ts', build_by_default : true)
|
#translations = qt5.compile_translations(ts_files : 'mesonsampleproject_fr_FR.ts', build_by_default : true)
|
||||||
|
|
||||||
generated_files = qt5.preprocess(
|
generated_files = qt5.preprocess(
|
||||||
moc_headers : 'mesonsampleproject.h',
|
moc_headers : 'mesonsampleproject.h',
|
||||||
|
|||||||
Reference in New Issue
Block a user