diff options
Diffstat (limited to 'src/plugins/mesonprojectmanager/project/mesonbuildsystem.cpp')
-rw-r--r-- | src/plugins/mesonprojectmanager/project/mesonbuildsystem.cpp | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/src/plugins/mesonprojectmanager/project/mesonbuildsystem.cpp b/src/plugins/mesonprojectmanager/project/mesonbuildsystem.cpp new file mode 100644 index 0000000000..dace993fe0 --- /dev/null +++ b/src/plugins/mesonprojectmanager/project/mesonbuildsystem.cpp @@ -0,0 +1,217 @@ +/**************************************************************************** +** +** Copyright (C) 2020 Alexis Jeandet. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "mesonbuildsystem.h" +#include "mesonbuildconfiguration.h" +#include <kithelper/kithelper.h> +#include <machinefiles/machinefilemanager.h> +#include <settings/general/settings.h> +#include <settings/tools/kitaspect/mesontoolkitaspect.h> +#include <projectexplorer/buildconfiguration.h> + +#include <QDir> +#include <QLoggingCategory> +#include <qtsupport/qtcppkitinfo.h> +#include <qtsupport/qtkitinformation.h> + +#define LEAVE_IF_BUSY() \ + { \ + if (m_parseGuard.guardsProject()) \ + return false; \ + } +#define LOCK() \ + { \ + m_parseGuard = guardParsingRun(); \ + } + +#define UNLOCK(success) \ + { \ + if (success) \ + m_parseGuard.markAsSuccess(); \ + m_parseGuard = {}; \ + }; + +namespace MesonProjectManager { +namespace Internal { +static Q_LOGGING_CATEGORY(mesonBuildSystemLog, "qtc.meson.buildsystem", QtDebugMsg); + +MesonBuildSystem::MesonBuildSystem(MesonBuildConfiguration *bc) + : ProjectExplorer::BuildSystem{bc} + , m_parser{MesonToolKitAspect::mesonToolId(bc->target()->kit()), + bc->environment(), + project()} +{ + init(); +} + +MesonBuildSystem::~MesonBuildSystem() +{ + qCDebug(mesonBuildSystemLog) << "dtor"; +} + +void MesonBuildSystem::triggerParsing() +{ + qCDebug(mesonBuildSystemLog) << "Trigger parsing"; + parseProject(); +} + +bool MesonBuildSystem::needsSetup() +{ + const Utils::FilePath &buildDir = buildConfiguration()->buildDirectory(); + return (!isSetup(buildDir) || !m_parser.usesSameMesonVersion(buildDir) + || !m_parser.matchesKit(m_kitData)); +} + +void MesonBuildSystem::parsingCompleted(bool success) +{ + if (success) { + setRootProjectNode(m_parser.takeProjectNode()); + if (kit() && buildConfiguration()) { + ProjectExplorer::KitInfo kitInfo{kit()}; + m_cppCodeModelUpdater.update( + {project(), + QtSupport::CppKitInfo(kit()), + buildConfiguration()->environment(), + m_parser.buildProjectParts(kitInfo.cxxToolChain, kitInfo.cToolChain)}); + } + setApplicationTargets(m_parser.appsTargets()); + UNLOCK(true); + emitBuildSystemUpdated(); + } else { + UNLOCK(false); + emitBuildSystemUpdated(); + } +} + +ProjectExplorer::Kit *MesonBuildSystem::MesonBuildSystem::kit() +{ + return buildConfiguration()->target()->kit(); +} + +QStringList MesonBuildSystem::configArgs(bool isSetup) +{ + if (!isSetup) + return m_pendingConfigArgs + mesonBuildConfiguration()->mesonConfigArgs(); + else { + return QStringList{QString("--native-file=%1") + .arg(MachineFileManager::machineFile(kit()).toString())} + + m_pendingConfigArgs + mesonBuildConfiguration()->mesonConfigArgs(); + } +} + +bool MesonBuildSystem::configure() +{ + LEAVE_IF_BUSY(); + qCDebug(mesonBuildSystemLog) << "Configure"; + if (needsSetup()) + return setup(); + LOCK(); + if (m_parser.configure(projectDirectory(), + buildConfiguration()->buildDirectory(), + configArgs(false))) { + return true; + } + UNLOCK(false); + return false; +} + +bool MesonBuildSystem::setup() +{ + LEAVE_IF_BUSY(); + LOCK(); + qCDebug(mesonBuildSystemLog) << "Setup"; + if (m_parser.setup(projectDirectory(), buildConfiguration()->buildDirectory(), configArgs(true))) + return true; + UNLOCK(false); + return false; +} + +bool MesonBuildSystem::wipe() +{ + LEAVE_IF_BUSY(); + LOCK(); + qCDebug(mesonBuildSystemLog) << "Wipe"; + if (m_parser.wipe(projectDirectory(), buildConfiguration()->buildDirectory(), configArgs(true))) + return true; + UNLOCK(false); + return false; +} + +MesonBuildConfiguration *MesonBuildSystem::mesonBuildConfiguration() +{ + return static_cast<MesonBuildConfiguration *>(buildConfiguration()); +} + +void MesonBuildSystem::init() +{ + qCDebug(mesonBuildSystemLog) << "Init"; + connect(buildConfiguration()->target(), &ProjectExplorer::Target::kitChanged, this, [this] { + updateKit(kit()); + }); + connect(mesonBuildConfiguration(), + &MesonBuildConfiguration::buildDirectoryChanged, + this, + [this]() { + updateKit(kit()); + this->triggerParsing(); + }); + connect(mesonBuildConfiguration(), &MesonBuildConfiguration::environmentChanged, this, [this]() { + m_parser.setEnvironment(buildConfiguration()->environment()); + }); + + connect(project(), &ProjectExplorer::Project::projectFileIsDirty, this, [this]() { + if (buildConfiguration()->isActive()) + parseProject(); + }); + connect(&m_parser, + &MesonProjectParser::parsingCompleted, + this, + &MesonBuildSystem::parsingCompleted); + updateKit(kit()); +} + +bool MesonBuildSystem::parseProject() +{ + QTC_ASSERT(buildConfiguration(), return false); + if (!isSetup(buildConfiguration()->buildDirectory()) && Settings::autorunMeson()) + return configure(); + LEAVE_IF_BUSY(); + LOCK(); + qCDebug(mesonBuildSystemLog) << "Starting parser"; + if (m_parser.parse(projectDirectory(), buildConfiguration()->buildDirectory())) + return true; + UNLOCK(false); + return false; +} + +void MesonBuildSystem::updateKit(ProjectExplorer::Kit *kit) +{ + QTC_ASSERT(kit, return ); + m_kitData = KitHelper::kitData(kit); + m_parser.setQtVersion(m_kitData.qtVersion); +} + +} // namespace Internal +} // namespace MesonProjectManager |