diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp index be570ad6812..4e3a67e3397 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp +++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -95,6 +96,18 @@ Utils::FilePath BuildDirManager::workDirectory(const BuildDirParameters ¶met return Utils::FilePath::fromString(tmpDirIt->second->path()); } +void BuildDirManager::updateReparseParameters(const int parameters) +{ + m_reparseParameters |= parameters; +} + +int BuildDirManager::takeReparseParameters() +{ + int result = m_reparseParameters; + m_reparseParameters = REPARSE_DEFAULT; + return result; +} + void BuildDirManager::emitDataAvailable() { if (!isParsing()) @@ -108,6 +121,14 @@ void BuildDirManager::emitErrorOccured(const QString &message) const m_isHandlingError = false; } +void BuildDirManager::emitReparseRequest() const +{ + if (m_reparseParameters & REPARSE_URGENT) + emit requestReparse(); + else + emit requestDelayedReparse(); +} + void BuildDirManager::updateReaderType(const BuildDirParameters &p, std::function todo) { @@ -208,7 +229,7 @@ void BuildDirManager::stopParsingAndClearState() } void BuildDirManager::setParametersAndRequestParse(const BuildDirParameters ¶meters, - int reparseOptions) + const int reparseParameters) { if (!parameters.cmakeTool()) { TaskHub::addTask(Task::Error, @@ -222,9 +243,9 @@ void BuildDirManager::setParametersAndRequestParse(const BuildDirParameters &par m_parameters = parameters; m_parameters.workDirectory = workDirectory(parameters); + updateReparseParameters(reparseParameters); - updateReaderType(m_parameters, - [this, reparseOptions]() { emit requestReparse(reparseOptions); }); + updateReaderType(m_parameters, [this]() { emitReparseRequest(); }); } CMakeBuildConfiguration *BuildDirManager::buildConfiguration() const @@ -248,7 +269,8 @@ void BuildDirManager::becameDirty() if (!tool->isAutoRun()) return; - emit requestReparse(REPARSE_CHECK_CONFIGURATION | REPARSE_SCAN); + updateReparseParameters(REPARSE_CHECK_CONFIGURATION | REPARSE_SCAN); + emit requestReparse(); } void BuildDirManager::resetData() @@ -276,19 +298,30 @@ bool BuildDirManager::persistCMakeState() return true; } -void BuildDirManager::parse(int reparseParameters) +void BuildDirManager::requestFilesystemScan() { - qCDebug(cmakeBuildDirManagerLog) - << "Parse called with flags:" << flagsString(reparseParameters); + updateReparseParameters(REPARSE_SCAN); +} +bool BuildDirManager::isFilesystemScanRequested() const +{ + return m_reparseParameters & REPARSE_SCAN; +} + +void BuildDirManager::parse() +{ QTC_ASSERT(m_parameters.isValid(), return ); QTC_ASSERT(m_reader, return); - QTC_ASSERT((reparseParameters & REPARSE_IGNORE) == 0, return); m_reader->stop(); TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM); + int reparseParameters = takeReparseParameters(); + + qCDebug(cmakeBuildDirManagerLog) + << "Parse called with flags:" << flagsString(reparseParameters); + const QString cache = m_parameters.workDirectory.pathAppended("CMakeCache.txt").toString(); if (!QFileInfo::exists(cache)) { reparseParameters |= REPARSE_FORCE_CONFIGURATION | REPARSE_FORCE_CMAKE_RUN; @@ -323,8 +356,10 @@ QVector BuildDirManager::takeProjectFilesToWatch() if (!toWatch.isEmpty()) { connect(project(), &Project::projectFileIsDirty, this, [this]() { - if (m_parameters.cmakeTool() && m_parameters.cmakeTool()->isAutoRun()) - requestReparse(REPARSE_DEFAULT); + if (m_parameters.cmakeTool() && m_parameters.cmakeTool()->isAutoRun()) { + updateReparseParameters(REPARSE_DEFAULT); + emit requestReparse(); + } }); } else { disconnect(project(), nullptr, this, nullptr); @@ -452,8 +487,6 @@ QString BuildDirManager::flagsString(int reparseFlags) result += " CHECK_CONFIG"; if (reparseFlags & REPARSE_SCAN) result += " SCAN"; - if (reparseFlags & REPARSE_IGNORE) - result += " IGNORE"; } return result.trimmed(); } diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.h b/src/plugins/cmakeprojectmanager/builddirmanager.h index 99a1e7adb0b..136ebc1c686 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.h +++ b/src/plugins/cmakeprojectmanager/builddirmanager.h @@ -60,6 +60,17 @@ class BuildDirManager : public QObject Q_OBJECT public: + enum ReparseParameters { + REPARSE_DEFAULT = 0, // Nothing special:-) + REPARSE_FORCE_CMAKE_RUN = (1 << 0), // Force cmake to run + REPARSE_FORCE_CONFIGURATION = (1 << 1), // Force configuration arguments to cmake + REPARSE_CHECK_CONFIGURATION = (1 << 2), // Check for on-disk config and QtC config diff + REPARSE_SCAN = (1 << 3), // Run filesystem scan + REPARSE_URGENT = (1 << 4), // Do not delay the parser run by 1s + }; + + static QString flagsString(int reparseFlags); + BuildDirManager(CMakeProject *project); ~BuildDirManager() final; @@ -67,7 +78,8 @@ public: void stopParsingAndClearState(); - void setParametersAndRequestParse(const BuildDirParameters ¶meters, int reparseOptions); + void setParametersAndRequestParse(const BuildDirParameters ¶meters, + const int reparseOptions); // nullptr if the BC is not active anymore! CMakeBuildConfiguration *buildConfiguration() const; CMakeProject *project() const {return m_project; } @@ -78,7 +90,9 @@ public: void resetData(); bool persistCMakeState(); - void parse(int reparseParameters); + void requestFilesystemScan(); + bool isFilesystemScanRequested() const; + void parse(); QVector takeProjectFilesToWatch(); std::unique_ptr generateProjectTree(const QList &allFiles, @@ -91,32 +105,20 @@ public: static CMakeConfig parseCMakeConfiguration(const Utils::FilePath &cacheFile, QString *errorMessage); - enum ReparseParameters { - REPARSE_DEFAULT = BuildSystem::PARAM_DEFAULT, // use defaults - REPARSE_URGENT = BuildSystem::PARAM_URGENT, // Do not wait for more requests, start ASAP - REPARSE_IGNORE = BuildSystem::PARAM_IGNORE, - - REPARSE_FORCE_CMAKE_RUN = (1 - << (BuildSystem::PARAM_CUSTOM_OFFSET + 0)), // Force cmake to run - REPARSE_FORCE_CONFIGURATION = (1 << (BuildSystem::PARAM_CUSTOM_OFFSET - + 1)), // Force configuration arguments to cmake - REPARSE_CHECK_CONFIGURATION - = (1 << (BuildSystem::PARAM_CUSTOM_OFFSET - + 2)), // Check and warn if on-disk config and QtC config differ - REPARSE_SCAN = (1 << (BuildSystem::PARAM_CUSTOM_OFFSET + 3)), // Run filesystem scan - }; - - static QString flagsString(int reparseFlags); - signals: - void requestReparse(int reparseParameters) const; + void requestReparse() const; + void requestDelayedReparse() const; void parsingStarted() const; void dataAvailable() const; void errorOccured(const QString &err) const; private: + void updateReparseParameters(const int parameters); + int takeReparseParameters(); + void emitDataAvailable(); void emitErrorOccured(const QString &message) const; + void emitReparseRequest() const; bool checkConfiguration(); Utils::FilePath workDirectory(const BuildDirParameters ¶meters) const; @@ -129,6 +131,7 @@ private: void becameDirty(); BuildDirParameters m_parameters; + int m_reparseParameters; CMakeProject *m_project = nullptr; mutable std::unordered_map> m_buildDirToTempDir; mutable std::unique_ptr m_reader; diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 2a96c9b1f43..26c7327a0bc 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -93,12 +93,13 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *parent, Core::Id id) BuildSystem *bs = qobject_cast(project()->buildSystem()); // BuildDirManager: - connect(&m_buildDirManager, &BuildDirManager::requestReparse, this, [this, bs](int options) { - if (isActive()) { - qCDebug(cmakeBuildConfigurationLog) - << "Passing on reparse request with flags" << BuildDirManager::flagsString(options); - bs->requestParse(options); - } + connect(&m_buildDirManager, &BuildDirManager::requestReparse, this, [this, bs]() { + if (isActive()) + bs->requestParse(); + }); + connect(&m_buildDirManager, &BuildDirManager::requestDelayedReparse, this, [this, bs]() { + if (isActive()) + bs->requestDelayedParse(); }); connect(&m_buildDirManager, &BuildDirManager::dataAvailable, diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index a0203742965..200f8018541 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -30,38 +30,6 @@ #include "cmakeprojectconstants.h" #include "cmakeprojectnodes.h" -#if 0 -#include "cmakebuildstep.h" -#include "cmakekitinformation.h" -#include "cmakeprojectmanager.h" -#include "cmakeprojectnodes.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#endif - #include #include #include @@ -79,85 +47,12 @@ using namespace ProjectExplorer; using namespace Utils; -namespace { - -CMakeProjectManager::Internal::CMakeBuildConfiguration *activeBc(Project *p) -{ - if (!p) - return nullptr; - - return qobject_cast( - p->activeTarget() ? p->activeTarget()->activeBuildConfiguration() : nullptr); -} - -} // namespace - namespace CMakeProjectManager { using namespace Internal; Q_LOGGING_CATEGORY(cmakeBuildSystemLog, "qtc.cmake.buildsystem", QtWarningMsg); -// -------------------------------------------------------------------- -// BuildSystem: -// -------------------------------------------------------------------- - -BuildSystem::BuildSystem(Project *project) - : m_project(project) -{ - QTC_CHECK(project); - - // Timer: - m_delayedParsingTimer.setSingleShot(true); - - connect(&m_delayedParsingTimer, &QTimer::timeout, this, &BuildSystem::triggerParsing); -} - -BuildSystem::~BuildSystem() = default; - -Project *BuildSystem::project() const -{ - return m_project; -} - -bool BuildSystem::isWaitingForParse() const -{ - return m_delayedParsingTimer.isActive(); -} - -void BuildSystem::requestParse(int reparseParameters) -{ - QTC_ASSERT(!(reparseParameters & PARAM_ERROR), return ); - if (reparseParameters & PARAM_IGNORE) - return; - - m_delayedParsingTimer.setInterval((reparseParameters & PARAM_URGENT) ? 0 : 1000); - m_delayedParsingTimer.start(); - m_delayedParsingParameters = m_delayedParsingParameters | reparseParameters; -} - -void BuildSystem::triggerParsing() -{ - int parameters = m_delayedParsingParameters; - m_delayedParsingParameters = BuildSystem::PARAM_DEFAULT; - - QTC_CHECK(!m_project->isParsing()); - QTC_ASSERT((parameters & BuildSystem::PARAM_ERROR) == 0, return ); - if (parameters & BuildSystem::PARAM_IGNORE) - return; - - // Clear buildsystem specific parameters before passing them on! - parameters = parameters - & ~(BuildSystem::PARAM_ERROR | BuildSystem::PARAM_IGNORE - | BuildSystem::PARAM_URGENT); - - { - ParsingContext ctx(m_project->guardParsingRun(), parameters, m_project, activeBc(m_project)); - if (validateParsingContext(ctx)) - parseProject(std::move(ctx)); - } -} - // -------------------------------------------------------------------- // CMakeBuildSystem: // -------------------------------------------------------------------- @@ -227,13 +122,12 @@ void CMakeBuildSystem::parseProject(ParsingContext &&ctx) m_currentContext = std::move(ctx); auto bc = qobject_cast(m_currentContext.buildConfiguration); - - int parameters = m_currentContext.parameters; + QTC_ASSERT(bc, return ); if (m_allFiles.isEmpty()) - parameters |= BuildDirManager::REPARSE_SCAN; + bc->m_buildDirManager.requestFilesystemScan(); - m_waitingForScan = parameters & BuildDirManager::REPARSE_SCAN; + m_waitingForScan = bc->m_buildDirManager.isFilesystemScanRequested(); m_waitingForParse = true; m_combinedScanAndParseResult = true; @@ -246,7 +140,7 @@ void CMakeBuildSystem::parseProject(ParsingContext &&ctx) "CMake.Scan.Tree"); } - bc->m_buildDirManager.parse(parameters); + bc->m_buildDirManager.parse(); } void CMakeBuildSystem::handleTreeScanningFinished() diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h index c30a29d5a78..1170a38e120 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h @@ -25,20 +25,12 @@ #pragma once -#include -#include - -#include +#include namespace CppTools { class CppProjectUpdater; } // namespace CppTools -namespace ProjectExplorer { -class BuildConfiguration; -class ExtraCompiler; -} // namespace ProjectExplorer - namespace CMakeProjectManager { class CMakeProject; @@ -47,88 +39,11 @@ namespace Internal { class CMakeBuildConfiguration; } // namespace Internal -// -------------------------------------------------------------------- -// BuildSystem: -// -------------------------------------------------------------------- - -class BuildSystem : public QObject -{ - Q_OBJECT - -public: - const static int PARAM_CUSTOM_OFFSET = 3; - enum Parameters : int { - PARAM_DEFAULT = 0, // use defaults - - PARAM_IGNORE = (1 << (PARAM_CUSTOM_OFFSET - 3)), // Ignore this request without raising a fuss - PARAM_ERROR = (1 << (PARAM_CUSTOM_OFFSET - 2)), // Ignore this request and warn - - PARAM_URGENT = (1 << (PARAM_CUSTOM_OFFSET - 1)), // Do not wait for more requests, start ASAP - }; - - explicit BuildSystem(ProjectExplorer::Project *project); - ~BuildSystem() override; - - BuildSystem(const BuildSystem &other) = delete; - - ProjectExplorer::Project *project() const; - - bool isWaitingForParse() const; - void requestParse(int reparseParameters); // request a (delayed!) parser run. - -protected: - class ParsingContext - { - public: - ParsingContext() = default; - - ParsingContext(const ParsingContext &other) = delete; - ParsingContext &operator=(const ParsingContext &other) = delete; - ParsingContext(ParsingContext &&other) = default; - ParsingContext &operator=(ParsingContext &&other) = default; - - ProjectExplorer::Project::ParseGuard guard; - - int parameters = PARAM_DEFAULT; - ProjectExplorer::Project *project = nullptr; - ProjectExplorer::BuildConfiguration *buildConfiguration = nullptr; - - private: - ParsingContext(ProjectExplorer::Project::ParseGuard &&g, - int params, - ProjectExplorer::Project *p, - ProjectExplorer::BuildConfiguration *bc) - : guard(std::move(g)) - , parameters(params) - , project(p) - , buildConfiguration(bc) - {} - - friend class BuildSystem; - }; - - virtual bool validateParsingContext(const ParsingContext &ctx) - { - Q_UNUSED(ctx) - return true; - } - - virtual void parseProject(ParsingContext &&ctx) = 0; // actual code to parse project - -private: - void triggerParsing(); - - ProjectExplorer::Project *m_project; - - QTimer m_delayedParsingTimer; - int m_delayedParsingParameters = PARAM_DEFAULT; -}; - // -------------------------------------------------------------------- // CMakeBuildSystem: // -------------------------------------------------------------------- -class CMakeBuildSystem : public BuildSystem +class CMakeBuildSystem : public ProjectExplorer::BuildSystem { Q_OBJECT diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index caa8e0eb130..13dae9c4406 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -85,14 +85,14 @@ static CMakeBuildConfiguration *activeBc(const CMakeProject *p) CMakeProject::CMakeProject(const FilePath &fileName) : Project(Constants::CMAKEMIMETYPE, fileName) { - m_buildsystem = std::make_unique(this); - setId(CMakeProjectManager::Constants::CMAKEPROJECT_ID); setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); setDisplayName(projectDirectory().fileName()); setCanBuildProducts(); setKnowsAllBuildExecutables(false); setHasMakeInstallEquivalent(true); + + setBuildSystem(std::make_unique(this)); } CMakeProject::~CMakeProject() = default; diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h index 75a8ed81c41..cf7a1f058ee 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.h +++ b/src/plugins/cmakeprojectmanager/cmakeproject.h @@ -32,10 +32,8 @@ #include "cmakebuildtarget.h" #include "cmakeprojectimporter.h" -#include +#include #include -#include -#include #include @@ -50,8 +48,6 @@ namespace ProjectExplorer { class FileNode; } namespace CMakeProjectManager { -class BuildSystem; - namespace Internal { class CMakeBuildConfiguration; class CMakeBuildSettingsWidget; @@ -66,8 +62,6 @@ public: explicit CMakeProject(const Utils::FilePath &filename); ~CMakeProject() final; - BuildSystem *buildSystem() const { return m_buildsystem.get(); } - ProjectExplorer::Tasks projectIssues(const ProjectExplorer::Kit *k) const final; void runCMake(); @@ -94,11 +88,6 @@ private: mutable std::unique_ptr m_projectImporter; - std::unique_ptr m_buildsystem; - - // friend class Internal::CMakeBuildConfiguration; - // friend class Internal::CMakeBuildSettingsWidget; - friend class CMakeBuildSystem; }; diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp index 21be7d1995d..10f8202ad5d 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp @@ -32,12 +32,13 @@ #include "cmaketoolmanager.h" #include "cmakeprojectnodes.h" -#include -#include +#include #include #include -#include #include +#include +#include +#include #include #include #include diff --git a/src/plugins/projectexplorer/CMakeLists.txt b/src/plugins/projectexplorer/CMakeLists.txt index 2e065ea3bf4..0476aea722f 100644 --- a/src/plugins/projectexplorer/CMakeLists.txt +++ b/src/plugins/projectexplorer/CMakeLists.txt @@ -21,6 +21,7 @@ add_qtc_plugin(ProjectExplorer buildstep.cpp buildstep.h buildsteplist.cpp buildsteplist.h buildstepspage.cpp buildstepspage.h + buildsystem.cpp buildsystem.h buildtargetinfo.h clangparser.cpp clangparser.h codestylesettingspropertiespage.cpp codestylesettingspropertiespage.h codestylesettingspropertiespage.ui diff --git a/src/plugins/projectexplorer/buildsystem.cpp b/src/plugins/projectexplorer/buildsystem.cpp new file mode 100644 index 00000000000..84c9b123811 --- /dev/null +++ b/src/plugins/projectexplorer/buildsystem.cpp @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** 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 "buildsystem.h" + +#include "buildconfiguration.h" +#include "target.h" + +#include + +using namespace Utils; + +namespace ProjectExplorer { + +// -------------------------------------------------------------------- +// BuildSystem: +// -------------------------------------------------------------------- + +BuildSystem::BuildSystem(Project *project) + : m_project(project) +{ + QTC_CHECK(project); + + // Timer: + m_delayedParsingTimer.setSingleShot(true); + + connect(&m_delayedParsingTimer, &QTimer::timeout, this, &BuildSystem::triggerParsing); +} + +Project *BuildSystem::project() const +{ + return m_project; +} + +bool BuildSystem::isWaitingForParse() const +{ + return m_delayedParsingTimer.isActive(); +} + +void BuildSystem::requestParse() +{ + requestParse(0); +} + +void BuildSystem::requestDelayedParse() +{ + requestParse(1000); +} + +void BuildSystem::requestParse(int delay) +{ + m_delayedParsingTimer.setInterval(delay); + m_delayedParsingTimer.start(); +} + +void BuildSystem::triggerParsing() +{ + QTC_CHECK(!project()->isParsing()); + + Project *p = project(); + Target *t = p->activeTarget(); + BuildConfiguration *bc = t ? t->activeBuildConfiguration() : nullptr; + + MacroExpander *e = nullptr; + if (bc) + e = bc->macroExpander(); + else if (t) + e = t->macroExpander(); + else + e = p->macroExpander(); + + Utils::Environment env = p->activeParseEnvironment(); + + ParsingContext ctx(p->guardParsingRun(), p, bc, e, env); + + if (validateParsingContext(ctx)) + parseProject(std::move(ctx)); +} + +} // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/buildsystem.h b/src/plugins/projectexplorer/buildsystem.h new file mode 100644 index 00000000000..dd8456074c8 --- /dev/null +++ b/src/plugins/projectexplorer/buildsystem.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** 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. +** +****************************************************************************/ + +#pragma once + +#include "projectexplorer_export.h" + +#include "project.h" +#include "treescanner.h" + +#include + +namespace ProjectExplorer { + +class BuildConfiguration; +class ExtraCompiler; + +// -------------------------------------------------------------------- +// BuildSystem: +// -------------------------------------------------------------------- + +class PROJECTEXPLORER_EXPORT BuildSystem : public QObject +{ + Q_OBJECT + +public: + explicit BuildSystem(Project *project); + + BuildSystem(const BuildSystem &other) = delete; + + Project *project() const; + + bool isWaitingForParse() const; + + void requestParse(); + void requestDelayedParse(); + +protected: + class ParsingContext + { + public: + ParsingContext() = default; + + ParsingContext(const ParsingContext &other) = delete; + ParsingContext &operator=(const ParsingContext &other) = delete; + ParsingContext(ParsingContext &&other) = default; + ParsingContext &operator=(ParsingContext &&other) = default; + + Project::ParseGuard guard; + + Project *project = nullptr; + BuildConfiguration *buildConfiguration = nullptr; + Utils::MacroExpander *expander = nullptr; + Utils::Environment environment; + + private: + ParsingContext(Project::ParseGuard &&g, + Project *p, + BuildConfiguration *bc, + Utils::MacroExpander *e, + Utils::Environment &env) + : guard(std::move(g)) + , project(p) + , buildConfiguration(bc) + , expander(e) + , environment(env) + {} + + friend class BuildSystem; + }; + + virtual bool validateParsingContext(const ParsingContext &ctx) + { + Q_UNUSED(ctx) + return true; + } + + virtual void parseProject(ParsingContext &&ctx) = 0; // actual code to parse project + +private: + void requestParse(int delay); // request a (delayed!) parser run. + void triggerParsing(); + + QTimer m_delayedParsingTimer; + + Project *m_project; +}; + +} // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index d881c80ce06..1d7cd11d9cc 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -27,6 +27,7 @@ #include "buildconfiguration.h" #include "buildinfo.h" +#include "buildsystem.h" #include "deployconfiguration.h" #include "editorconfiguration.h" #include "kit.h" @@ -182,6 +183,7 @@ public: bool m_knowsAllBuildExecutables = true; bool m_hasMakeInstallEquivalent = false; bool m_needsBuildConfigurations = true; + std::unique_ptr m_buildSystem; std::unique_ptr m_document; std::vector> m_extraProjectDocuments; std::unique_ptr m_rootProjectNode; @@ -253,6 +255,11 @@ bool Project::canBuildProducts() const return d->m_canBuildProducts; } +BuildSystem *Project::buildSystem() const +{ + return d->m_buildSystem.get(); +} + Utils::FilePath Project::projectFilePath() const { QTC_ASSERT(d->m_document, return Utils::FilePath()); @@ -879,6 +886,12 @@ Utils::Environment Project::activeParseEnvironment() const return result; } +void Project::setBuildSystem(std::unique_ptr &&bs) +{ + QTC_ASSERT(!bs->parent(), bs->setParent(nullptr)); + d->m_buildSystem = std::move(bs); +} + Core::Context Project::projectContext() const { return Core::Context(d->m_id); diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index 082010d6c3e..c4f29f0d1a8 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -50,6 +50,7 @@ class MacroExpander; namespace ProjectExplorer { class BuildInfo; +class BuildSystem; class ContainerNode; class EditorConfiguration; class FolderNode; @@ -85,6 +86,8 @@ public: QString mimeType() const; bool canBuildProducts() const; + BuildSystem *buildSystem() const; + Utils::FilePath projectFilePath() const; Utils::FilePath projectDirectory() const; static Utils::FilePath projectDirectory(const Utils::FilePath &top); @@ -234,6 +237,8 @@ public: // as the main project file. void setExtraProjectFiles(const QVector &projectDocumentPaths); + Utils::Environment activeParseEnvironment() const; + signals: void projectFileIsDirty(const Utils::FilePath &path); @@ -294,7 +299,7 @@ protected: static ProjectExplorer::Task createProjectTask(ProjectExplorer::Task::TaskType type, const QString &description); - Utils::Environment activeParseEnvironment() const; + void setBuildSystem(std::unique_ptr &&bs); // takes ownership! private: // Helper methods to manage parsing state and signalling diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro index 90e9ed264c9..f8d9045712f 100644 --- a/src/plugins/projectexplorer/projectexplorer.pro +++ b/src/plugins/projectexplorer/projectexplorer.pro @@ -13,6 +13,7 @@ HEADERS += projectexplorer.h \ addrunconfigdialog.h \ ansifilterparser.h \ buildinfo.h \ + buildsystem.h \ clangparser.h \ configtaskhandler.h \ desktoprunconfiguration.h \ @@ -170,6 +171,7 @@ SOURCES += projectexplorer.cpp \ addrunconfigdialog.cpp \ ansifilterparser.cpp \ buildinfo.cpp \ + buildsystem.cpp \ clangparser.cpp \ configtaskhandler.cpp \ desktoprunconfiguration.cpp \ diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs index 926e6fc0815..1708495ca25 100644 --- a/src/plugins/projectexplorer/projectexplorer.qbs +++ b/src/plugins/projectexplorer/projectexplorer.qbs @@ -40,6 +40,7 @@ Project { "buildstep.cpp", "buildstep.h", "buildsteplist.cpp", "buildsteplist.h", "buildstepspage.cpp", "buildstepspage.h", + "buildsystem.cpp", "buildsystem.h", "buildtargetinfo.h", "clangparser.cpp", "clangparser.h", "codestylesettingspropertiespage.cpp", "codestylesettingspropertiespage.h", "codestylesettingspropertiespage.ui",