From 27586827238ca9079860e77a7b23ae20d163143e Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 25 Oct 2019 09:55:32 +0200 Subject: ProjectExplorer: Move BuildSystem owership to BuildConfiguration ... or Target. This patch moves build system from conceptually "one per project" to "one per target (i.e. per project-and-kit)" or "per BuildConfigurations" for targets where the builds differ significantly. Building requires usually items from the kit (Qt version, compiler, ...) so a target-agnostic build is practically almost always wrong. Moving the build system to the target also has the potential to solve issues caused by switching targets while parsing, that used Project::activeTarget() regularly, with potentially different results before and after the switch. This patch might create performance/size regressions when several targets are set up per project as the build system implementation's internal data are duplicated in this case. The idea is to fix that by sharing per-project pieces again in the project implementation once these problems occur. Change-Id: I87f640ce418b93175b5029124eaa55f3b8721dca Reviewed-by: Christian Stenger Reviewed-by: Christian Kandeler --- .../compilationdatabaseproject.cpp | 99 ++++++++++++---------- .../compilationdatabaseproject.h | 20 ++++- .../compilationdbparser.cpp | 2 +- .../compilationdbparser.h | 6 +- 4 files changed, 73 insertions(+), 54 deletions(-) (limited to 'src/plugins/compilationdatabaseprojectmanager') diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp index d9bf685f08..89f82a780f 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp @@ -337,9 +337,46 @@ void createTree(std::unique_ptr &root, } // anonymous namespace -void CompilationDatabaseProject::buildTreeAndProjectParts() +CompilationDatabaseBuildSystem::CompilationDatabaseBuildSystem(Target *target) + : BuildSystem(target) + , m_cppCodeModelUpdater(std::make_unique()) + , m_parseDelay(new QTimer(this)) + , m_deployFileWatcher(new FileSystemWatcher(this)) +{ + connect(target->project(), &CompilationDatabaseProject::rootProjectDirectoryChanged, + this, [this] { + m_projectFileHash.clear(); + m_parseDelay->start(); + }); + + connect(m_parseDelay, &QTimer::timeout, this, &CompilationDatabaseBuildSystem::reparseProject); + + m_parseDelay->setSingleShot(true); + m_parseDelay->setInterval(1000); + m_parseDelay->start(); + + connect(project(), &Project::projectFileIsDirty, this, &CompilationDatabaseBuildSystem::reparseProject); + + connect(m_deployFileWatcher, &FileSystemWatcher::fileChanged, + this, &CompilationDatabaseBuildSystem::updateDeploymentData); + connect(target->project(), &Project::activeTargetChanged, + this, &CompilationDatabaseBuildSystem::updateDeploymentData); +} + +CompilationDatabaseBuildSystem::~CompilationDatabaseBuildSystem() +{ + m_parserWatcher.cancel(); + m_parserWatcher.waitForFinished(); +} + +void CompilationDatabaseBuildSystem::triggerParsing() +{ + reparseProject(); +} + +void CompilationDatabaseBuildSystem::buildTreeAndProjectParts() { - ProjectExplorer::KitInfo kitInfo(this); + ProjectExplorer::KitInfo kitInfo(project()); QTC_ASSERT(kitInfo.isValid(), return); // Reset toolchains to pick them based on the database entries. kitInfo.cToolChain = nullptr; @@ -349,6 +386,7 @@ void CompilationDatabaseProject::buildTreeAndProjectParts() QTC_ASSERT(m_parser, return); const DbContents dbContents = m_parser->dbContents(); const DbEntry *prevEntry = nullptr; + Kit *kit = static_cast(project())->kit(); for (const DbEntry &entry : dbContents.entries) { if (prevEntry && prevEntry->flags == entry.flags) { rpps.back().files.append(entry.fileName.toString()); @@ -358,7 +396,7 @@ void CompilationDatabaseProject::buildTreeAndProjectParts() prevEntry = &entry; RawProjectPart rpp = makeRawProjectPart(projectFilePath(), - m_kit.get(), + kit, kitInfo, entry.workingDir, entry.fileName, @@ -381,7 +419,7 @@ void CompilationDatabaseProject::buildTreeAndProjectParts() auto root = std::make_unique(projectDirectory()); - createTree(root, rootProjectDirectory(), rpps, m_parser->scannedFiles()); + createTree(root, project()->rootProjectDirectory(), rpps, m_parser->scannedFiles()); root->addNode(std::make_unique(projectFilePath(), FileType::Project)); @@ -389,43 +427,26 @@ void CompilationDatabaseProject::buildTreeAndProjectParts() root->addNode(std::make_unique(Utils::FilePath::fromString(dbContents.extraFileName), FileType::Project)); - setRootProjectNode(std::move(root)); + project()->setRootProjectNode(std::move(root)); - m_cppCodeModelUpdater->update({this, kitInfo, activeParseEnvironment(), rpps}); + m_cppCodeModelUpdater->update({project(), kitInfo, activeParseEnvironment(), rpps}); updateDeploymentData(); } CompilationDatabaseProject::CompilationDatabaseProject(const Utils::FilePath &projectFile) : Project(Constants::COMPILATIONDATABASEMIMETYPE, projectFile) - , m_cppCodeModelUpdater(std::make_unique()) - , m_parseDelay(new QTimer(this)) - , m_deployFileWatcher(new FileSystemWatcher(this)) { setId(Constants::COMPILATIONDATABASEPROJECT_ID); setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); setDisplayName(projectDirectory().fileName()); + setBuildSystemCreator([](Target *t) { return new CompilationDatabaseBuildSystem(t); }); + m_kit.reset(KitManager::defaultKit()->clone()); addTargetForKit(m_kit.get()); - connect(this, &CompilationDatabaseProject::rootProjectDirectoryChanged, - this, [this] { - m_projectFileHash.clear(); - m_parseDelay->start(); - }); - setExtraProjectFiles( {projectFile.stringAppended(Constants::COMPILATIONDATABASEPROJECT_FILES_SUFFIX)}); - connect(m_parseDelay, &QTimer::timeout, this, &CompilationDatabaseProject::reparseProject); - - m_parseDelay->setSingleShot(true); - m_parseDelay->setInterval(1000); - - connect(this, &Project::projectFileIsDirty, this, &CompilationDatabaseProject::reparseProject); - connect(m_deployFileWatcher, &FileSystemWatcher::fileChanged, - this, &CompilationDatabaseProject::updateDeploymentData); - connect(this, &Project::activeTargetChanged, - this, &CompilationDatabaseProject::updateDeploymentData); } Utils::FilePath CompilationDatabaseProject::rootPathFromSettings() const @@ -442,26 +463,19 @@ Project::RestoreResult CompilationDatabaseProject::fromMap(const QVariantMap &ma QString *errorMessage) { Project::RestoreResult result = Project::fromMap(map, errorMessage); - if (result == Project::RestoreResult::Ok) { - const Utils::FilePath rootPath = rootPathFromSettings(); - if (rootPath.isEmpty()) - changeRootProjectDirectory(); // This triggers reparse itself. - else - reparseProject(); - } - return result; } -void CompilationDatabaseProject::reparseProject() +void CompilationDatabaseBuildSystem::reparseProject() { if (m_parser) { QTC_CHECK(isParsing()); m_parser->stop(); } - m_parser = new CompilationDbParser(displayName(), + const FilePath rootPath = static_cast(project())->rootPathFromSettings(); + m_parser = new CompilationDbParser(project()->displayName(), projectFilePath(), - rootPathFromSettings(), + rootPath, m_mimeBinaryCache, guardParsingRun(), this); @@ -475,17 +489,14 @@ void CompilationDatabaseProject::reparseProject() m_parser->start(); } -void CompilationDatabaseProject::updateDeploymentData() +void CompilationDatabaseBuildSystem::updateDeploymentData() { - Target * const target = activeTarget(); - if (!target) - return; const Utils::FilePath deploymentFilePath = projectDirectory() .pathAppended("QtCreatorDeployment.txt"); DeploymentData deploymentData; deploymentData.addFilesFromDeploymentFile(deploymentFilePath.toString(), projectDirectory().toString()); - target->setDeploymentData(deploymentData); + setDeploymentData(deploymentData); if (m_deployFileWatcher->files() != QStringList(deploymentFilePath.toString())) { m_deployFileWatcher->removeFiles(m_deployFileWatcher->files()); m_deployFileWatcher->addFile(deploymentFilePath.toString(), @@ -493,12 +504,6 @@ void CompilationDatabaseProject::updateDeploymentData() } } -CompilationDatabaseProject::~CompilationDatabaseProject() -{ - m_parserWatcher.cancel(); - m_parserWatcher.waitForFinished(); -} - static TextEditor::TextDocument *createCompilationDatabaseDocument() { auto doc = new TextEditor::TextDocument; diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h index 900f7d3675..98ff726a19 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h @@ -28,8 +28,11 @@ #include "compilationdatabaseutils.h" #include +#include #include + #include + #include #include @@ -52,20 +55,31 @@ class CompilationDatabaseProject : public ProjectExplorer::Project public: explicit CompilationDatabaseProject(const Utils::FilePath &filename); - ~CompilationDatabaseProject() override; + bool needsConfiguration() const override { return false; } + Utils::FilePath rootPathFromSettings() const; + ProjectExplorer::Kit *kit() const { return m_kit.get(); } + private: RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override; + std::unique_ptr m_kit; +}; + +class CompilationDatabaseBuildSystem : public ProjectExplorer::BuildSystem +{ +public: + explicit CompilationDatabaseBuildSystem(ProjectExplorer::Target *target); + ~CompilationDatabaseBuildSystem(); + + void triggerParsing() final; void reparseProject(); void updateDeploymentData(); void buildTreeAndProjectParts(); - Utils::FilePath rootPathFromSettings() const; QFutureWatcher m_parserWatcher; std::unique_ptr m_cppCodeModelUpdater; - std::unique_ptr m_kit; MimeBinaryCache m_mimeBinaryCache; QByteArray m_projectFileHash; QTimer * const m_parseDelay; diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.cpp index 374c245b23..1505dffa1a 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.cpp +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.cpp @@ -48,7 +48,7 @@ CompilationDbParser::CompilationDbParser(const QString &projectName, const FilePath &projectPath, const FilePath &rootPath, MimeBinaryCache &mimeBinaryCache, - ProjectExplorer::Project::ParseGuard &&guard, + BuildSystem::ParseGuard &&guard, QObject *parent) : QObject(parent) , m_projectName(projectName) diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.h b/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.h index ac5fbb0afb..dd126d9fd1 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.h +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.h @@ -27,7 +27,7 @@ #include "compilationdatabaseutils.h" -#include +#include #include @@ -56,7 +56,7 @@ public: const Utils::FilePath &projectPath, const Utils::FilePath &rootPath, MimeBinaryCache &mimeBinaryCache, - ProjectExplorer::Project::ParseGuard &&guard, + ProjectExplorer::BuildSystem::ParseGuard &&guard, QObject *parent = nullptr); @@ -91,7 +91,7 @@ private: QByteArray m_projectFileContents; QByteArray m_projectFileHash; - ProjectExplorer::Project::ParseGuard m_guard; + ProjectExplorer::BuildSystem::ParseGuard m_guard; }; } // namespace Internal -- cgit v1.2.3