From 895f8e73961d82a2a7971087df9248584eaa4eb0 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 27 Sep 2023 18:03:18 +0200 Subject: [PATCH] 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 --- .../mesonprojectmanager/CMakeLists.txt | 2 - .../mesonprojectmanager/mesonprocess.cpp | 119 ------------- .../mesonprojectmanager/mesonprocess.h | 54 ------ .../mesonprojectmanager.qbs | 2 - .../mesonprojectparser.cpp | 159 ++++++++++++++---- .../mesonprojectmanager/mesonprojectparser.h | 18 +- .../meson/mesonsampleproject/meson.build | 2 +- 7 files changed, 143 insertions(+), 213 deletions(-) delete mode 100644 src/plugins/mesonprojectmanager/mesonprocess.cpp delete mode 100644 src/plugins/mesonprojectmanager/mesonprocess.h diff --git a/src/plugins/mesonprojectmanager/CMakeLists.txt b/src/plugins/mesonprojectmanager/CMakeLists.txt index 33fc6b25b71..9fc1f89b6f8 100644 --- a/src/plugins/mesonprojectmanager/CMakeLists.txt +++ b/src/plugins/mesonprojectmanager/CMakeLists.txt @@ -23,8 +23,6 @@ add_qtc_plugin(MesonProjectManager mesoninfoparser.h mesonoutputparser.cpp mesonoutputparser.h - mesonprocess.cpp - mesonprocess.h mesonproject.cpp mesonproject.h mesonprojectimporter.cpp diff --git a/src/plugins/mesonprojectmanager/mesonprocess.cpp b/src/plugins/mesonprojectmanager/mesonprocess.cpp deleted file mode 100644 index 2e4ba024559..00000000000 --- a/src/plugins/mesonprojectmanager/mesonprocess.cpp +++ /dev/null @@ -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 -#include - -#include -#include - -#include -#include -#include - -#include - -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 diff --git a/src/plugins/mesonprojectmanager/mesonprocess.h b/src/plugins/mesonprojectmanager/mesonprocess.h deleted file mode 100644 index c01427c8fb9..00000000000 --- a/src/plugins/mesonprojectmanager/mesonprocess.h +++ /dev/null @@ -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 -#include -#include -#include - -#include - -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 m_process; - QElapsedTimer m_elapsed; - QByteArray m_stdo; - QByteArray m_stderr; -}; - -} // namespace Internal -} // namespace MesonProjectManager diff --git a/src/plugins/mesonprojectmanager/mesonprojectmanager.qbs b/src/plugins/mesonprojectmanager/mesonprojectmanager.qbs index 9167f025b20..df1c076eb60 100644 --- a/src/plugins/mesonprojectmanager/mesonprojectmanager.qbs +++ b/src/plugins/mesonprojectmanager/mesonprojectmanager.qbs @@ -49,8 +49,6 @@ Project { "mesonbuildconfiguration.h", "mesonbuildsystem.cpp", "mesonbuildsystem.h", - "mesonprocess.cpp", - "mesonprocess.h", "mesonproject.cpp", "mesonproject.h", "mesonprojectimporter.cpp", diff --git a/src/plugins/mesonprojectmanager/mesonprojectparser.cpp b/src/plugins/mesonprojectmanager/mesonprojectparser.cpp index 9de424bf282..a4ac7a13252 100644 --- a/src/plugins/mesonprojectmanager/mesonprojectparser.cpp +++ b/src/plugins/mesonprojectmanager/mesonprojectparser.cpp @@ -4,25 +4,36 @@ #include "mesonprojectparser.h" #include "mesoninfoparser.h" +#include "mesonprojectmanagertr.h" #include "mesonprojectnodes.h" #include "mesontools.h" #include "projecttree.h" +#include #include #include +#include +#include #include +#include #include - -#include -#include +#include #include +#include + +using namespace Core; +using namespace ProjectExplorer; +using namespace Utils; + namespace MesonProjectManager { namespace Internal { +static Q_LOGGING_CATEGORY(mesonProcessLog, "qtc.meson.buildsystem", QtWarningMsg); + struct CompilerArgs { QStringList args; @@ -30,8 +41,8 @@ struct CompilerArgs ProjectExplorer::Macros macros; }; -inline std::optional extractValueIfMatches(const QString &arg, - const QStringList &candidates) +static std::optional extractValueIfMatches(const QString &arg, + const QStringList &candidates) { for (const auto &flag : candidates) { if (arg.startsWith(flag)) @@ -40,11 +51,12 @@ inline std::optional extractValueIfMatches(const QString &arg, return std::nullopt; } -inline std::optional extractInclude(const QString &arg) +static std::optional extractInclude(const QString &arg) { return extractValueIfMatches(arg, {"-I", "/I", "-isystem", "-imsvc", "/imsvc"}); } -inline std::optional extractMacro(const QString &arg) + +static std::optional extractMacro(const QString &arg) { auto define = extractValueIfMatches(arg, {"-D", "/D"}); if (define) @@ -93,18 +105,12 @@ MesonProjectParser::MesonProjectParser(const Utils::Id &meson, , m_meson{meson} , 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 // I take project info here, I also take build and src dir later from // functions args. auto fileFinder = new Utils::FileInProjectFinder; fileFinder->setProjectDirectory(project->projectDirectory()); - fileFinder->setProjectFiles(project->files(ProjectExplorer::Project::AllFiles)); + fileFinder->setProjectFiles(project->files(Project::AllFiles)); m_outputParser.setFileFinder(fileFinder); } @@ -126,7 +132,7 @@ bool MesonProjectParser::configure(const Utils::FilePath &sourcePath, m_pendingCommands.enqueue( std::make_tuple(MesonTools::mesonWrapper(m_meson)->regenerate(sourcePath, buildPath), false)); - return m_process.run(cmd, m_env, m_projectName); + return run(cmd, m_env, m_projectName); } bool MesonProjectParser::wipe(const Utils::FilePath &sourcePath, @@ -149,7 +155,7 @@ bool MesonProjectParser::setup(const Utils::FilePath &sourcePath, if (forceWipe || isSetup(buildPath)) cmdArgs << "--wipe"; 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) @@ -170,18 +176,18 @@ bool MesonProjectParser::parse(const Utils::FilePath &sourcePath) m_srcDir = sourcePath; m_introType = IntroDataType::stdo; m_outputParser.setSourceDirectory(sourcePath); - return m_process.run(MesonTools::mesonWrapper(m_meson)->introspect(sourcePath), - m_env, - m_projectName, - true); + return run(MesonTools::mesonWrapper(m_meson)->introspect(sourcePath), + m_env, + m_projectName, + true); } -QList MesonProjectParser::appsTargets() const +QList MesonProjectParser::appsTargets() const { - QList apps; + QList apps; for (const Target &target : m_parserResult.targets) { if (target.type == Target::Type::executable) { - ProjectExplorer::BuildTargetInfo bti; + BuildTargetInfo bti; bti.displayName = target.name; bti.buildKey = Target::fullName(m_buildDir, target); bti.displayNameUniquifier = bti.buildKey; @@ -198,8 +204,8 @@ QList MesonProjectParser::appsTargets() const bool MesonProjectParser::startParser() { m_parserFutureResult = Utils::asyncRun( - ProjectExplorer::ProjectExplorerPlugin::sharedThreadPool(), - [processOutput = m_process.stdOut(), introType = m_introType, + ProjectExplorerPlugin::sharedThreadPool(), + [processOutput = m_stdo, introType = m_introType, buildDir = m_buildDir, srcDir = m_srcDir] { if (introType == IntroDataType::file) return extractParserResults(srcDir, MesonInfoParser::parse(buildDir)); @@ -245,13 +251,13 @@ void MesonProjectParser::update(const QFuture emit parsingCompleted(true); } -ProjectExplorer::RawProjectPart MesonProjectParser::buildRawPart( +RawProjectPart MesonProjectParser::buildRawPart( const Target &target, const Target::SourceGroup &sources, - const ProjectExplorer::ToolChain *cxxToolChain, - const ProjectExplorer::ToolChain *cToolChain) + const ToolChain *cxxToolChain, + const ToolChain *cToolChain) { - ProjectExplorer::RawProjectPart part; + RawProjectPart part; part.setDisplayName(target.name); part.setBuildSystemTarget(Target::fullName(m_buildDir, target)); part.setFiles(sources.sources + sources.generatedSources); @@ -275,13 +281,12 @@ void MesonProjectParser::processFinished(int exitCode, QProcess::ExitStatus exit else { // see comment near m_pendingCommands declaration std::tuple 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 { if (m_introType == IntroDataType::stdo) { - auto data = m_process.stdErr(); - Core::MessageManager::writeSilently(QString::fromLocal8Bit(data)); - m_outputParser.readStdo(data); + Core::MessageManager::writeSilently(QString::fromLocal8Bit(m_stderr)); + m_outputParser.readStdo(m_stderr); } emit parsingCompleted(false); } @@ -327,5 +332,93 @@ bool MesonProjectParser::usesSameMesonVersion(const Utils::FilePath &buildPath) auto meson = MesonTools::mesonWrapper(m_meson); 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 MesonProjectManager diff --git a/src/plugins/mesonprojectmanager/mesonprojectparser.h b/src/plugins/mesonprojectmanager/mesonprojectparser.h index 168b4f1448d..3a129d60af1 100644 --- a/src/plugins/mesonprojectmanager/mesonprojectparser.h +++ b/src/plugins/mesonprojectmanager/mesonprojectparser.h @@ -6,7 +6,6 @@ #include "kitdata.h" #include "mesoninfoparser.h" #include "mesonoutputparser.h" -#include "mesonprocess.h" #include "mesonprojectnodes.h" #include "mesonwrapper.h" @@ -91,7 +90,6 @@ private: const ProjectExplorer::ToolChain *cxxToolChain, const ProjectExplorer::ToolChain *cToolChain); void processFinished(int exitCode, QProcess::ExitStatus exitStatus); - MesonProcess m_process; MesonOutputParser m_outputParser; Utils::Environment m_env; Utils::Id m_meson; @@ -108,6 +106,22 @@ private: // maybe moving meson to build step could make this class simpler // also this should ease command dependencies QQueue> 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 m_process; + QElapsedTimer m_elapsed; + QByteArray m_stdo; + QByteArray m_stderr; }; } // namespace Internal diff --git a/tests/manual/meson/mesonsampleproject/meson.build b/tests/manual/meson/mesonsampleproject/meson.build index 901285a587e..8edea0d4d53 100644 --- a/tests/manual/meson/mesonsampleproject/meson.build +++ b/tests/manual/meson/mesonsampleproject/meson.build @@ -4,7 +4,7 @@ project('mesonsampleproject', 'cpp',default_options : ['cpp_std=c++11']) qt5 = import('qt5') 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( moc_headers : 'mesonsampleproject.h',