aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorhjk <hjk@qt.io>2019-10-25 09:55:32 +0200
committerhjk <hjk@qt.io>2019-11-19 11:05:52 +0000
commit27586827238ca9079860e77a7b23ae20d163143e (patch)
tree2197dc7f97a4a70524381071888336558dc0b4a3 /src/plugins
parent9073c46c9c431ec0e83987a5781163ca7b1f7ea7 (diff)
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 <christian.stenger@qt.io> Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/android/androidextralibrarylistmodel.cpp6
-rw-r--r--src/plugins/android/androidrunconfiguration.cpp2
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp17
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.h10
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp4
-rw-r--r--src/plugins/autotoolsprojectmanager/makefileparserthread.cpp7
-rw-r--r--src/plugins/autotoolsprojectmanager/makefileparserthread.h6
-rw-r--r--src/plugins/baremetal/baremetalrunconfiguration.cpp2
-rw-r--r--src/plugins/boot2qt/qdbrunconfiguration.cpp2
-rw-r--r--src/plugins/cmakeprojectmanager/builddirmanager.cpp42
-rw-r--r--src/plugins/cmakeprojectmanager/builddirmanager.h15
-rw-r--r--src/plugins/cmakeprojectmanager/builddirparameters.cpp4
-rw-r--r--src/plugins/cmakeprojectmanager/builddirparameters.h4
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp233
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h28
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp13
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildstep.cpp13
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp414
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsystem.h58
-rw-r--r--src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp7
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeproject.cpp93
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeproject.h12
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp50
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectmanager.h6
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp5
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp23
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp99
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h20
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdbparser.cpp2
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdbparser.h6
-rw-r--r--src/plugins/designer/codemodelhelpers.cpp18
-rw-r--r--src/plugins/genericprojectmanager/genericproject.cpp83
-rw-r--r--src/plugins/ios/iosrunconfiguration.cpp18
-rw-r--r--src/plugins/ios/iosrunconfiguration.h2
-rw-r--r--src/plugins/nim/nimconstants.h4
-rw-r--r--src/plugins/nim/project/nimblebuildconfiguration.cpp32
-rw-r--r--src/plugins/nim/project/nimblebuildconfiguration.h6
-rw-r--r--src/plugins/nim/project/nimblebuildsystem.cpp100
-rw-r--r--src/plugins/nim/project/nimblebuildsystem.h42
-rw-r--r--src/plugins/nim/project/nimbleproject.cpp65
-rw-r--r--src/plugins/nim/project/nimbleproject.h49
-rw-r--r--src/plugins/nim/project/nimblerunconfiguration.cpp17
-rw-r--r--src/plugins/nim/project/nimblerunconfiguration.h3
-rw-r--r--src/plugins/nim/project/nimbletaskstep.cpp6
-rw-r--r--src/plugins/nim/project/nimbletaskstepwidget.cpp14
-rw-r--r--src/plugins/nim/project/nimbletaskstepwidget.h3
-rw-r--r--src/plugins/nim/project/nimbuildconfiguration.cpp2
-rw-r--r--src/plugins/nim/project/nimbuildsystem.cpp42
-rw-r--r--src/plugins/nim/project/nimbuildsystem.h12
-rw-r--r--src/plugins/nim/project/nimcompilerbuildstep.cpp4
-rw-r--r--src/plugins/nim/project/nimcompilerbuildstepconfigwidget.cpp2
-rw-r--r--src/plugins/nim/project/nimproject.cpp18
-rw-r--r--src/plugins/nim/project/nimproject.h5
-rw-r--r--src/plugins/projectexplorer/buildconfiguration.cpp32
-rw-r--r--src/plugins/projectexplorer/buildconfiguration.h5
-rw-r--r--src/plugins/projectexplorer/buildsettingspropertiespage.cpp20
-rw-r--r--src/plugins/projectexplorer/buildstep.cpp7
-rw-r--r--src/plugins/projectexplorer/buildstep.h3
-rw-r--r--src/plugins/projectexplorer/buildstepspage.cpp4
-rw-r--r--src/plugins/projectexplorer/buildstepspage.h2
-rw-r--r--src/plugins/projectexplorer/buildsystem.cpp217
-rw-r--r--src/plugins/projectexplorer/buildsystem.h118
-rw-r--r--src/plugins/projectexplorer/customexecutablerunconfiguration.cpp5
-rw-r--r--src/plugins/projectexplorer/customexecutablerunconfiguration.h1
-rw-r--r--src/plugins/projectexplorer/deploymentdataview.cpp5
-rw-r--r--src/plugins/projectexplorer/desktoprunconfiguration.cpp29
-rw-r--r--src/plugins/projectexplorer/desktoprunconfiguration.h4
-rw-r--r--src/plugins/projectexplorer/makestep.cpp2
-rw-r--r--src/plugins/projectexplorer/project.cpp144
-rw-r--r--src/plugins/projectexplorer/project.h97
-rw-r--r--src/plugins/projectexplorer/projectexplorer.cpp4
-rw-r--r--src/plugins/projectexplorer/projectmodels.cpp16
-rw-r--r--src/plugins/projectexplorer/projectnodes.cpp5
-rw-r--r--src/plugins/projectexplorer/projecttree.cpp13
-rw-r--r--src/plugins/projectexplorer/projecttree.h4
-rw-r--r--src/plugins/projectexplorer/runconfiguration.cpp38
-rw-r--r--src/plugins/projectexplorer/runconfiguration.h7
-rw-r--r--src/plugins/projectexplorer/runcontrol.cpp2
-rw-r--r--src/plugins/projectexplorer/session.cpp11
-rw-r--r--src/plugins/projectexplorer/session.h6
-rw-r--r--src/plugins/projectexplorer/target.cpp105
-rw-r--r--src/plugins/projectexplorer/target.h20
-rw-r--r--src/plugins/python/pythonproject.cpp40
-rw-r--r--src/plugins/python/pythonproject.h1
-rw-r--r--src/plugins/python/pythonrunconfiguration.cpp2
-rw-r--r--src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp30
-rw-r--r--src/plugins/qbsprojectmanager/qbsbuildconfiguration.h10
-rw-r--r--src/plugins/qbsprojectmanager/qbsbuildstep.cpp27
-rw-r--r--src/plugins/qbsprojectmanager/qbsbuildstep.h2
-rw-r--r--src/plugins/qbsprojectmanager/qbscleanstep.cpp10
-rw-r--r--src/plugins/qbsprojectmanager/qbscleanstep.h2
-rw-r--r--src/plugins/qbsprojectmanager/qbsinstallstep.cpp8
-rw-r--r--src/plugins/qbsprojectmanager/qbsnodes.cpp193
-rw-r--r--src/plugins/qbsprojectmanager/qbsnodes.h30
-rw-r--r--src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp14
-rw-r--r--src/plugins/qbsprojectmanager/qbsnodetreebuilder.h2
-rw-r--r--src/plugins/qbsprojectmanager/qbsproject.cpp474
-rw-r--r--src/plugins/qbsprojectmanager/qbsproject.h70
-rw-r--r--src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp38
-rw-r--r--src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h4
-rw-r--r--src/plugins/qbsprojectmanager/qbsprojectparser.cpp6
-rw-r--r--src/plugins/qbsprojectmanager/qbsprojectparser.h5
-rw-r--r--src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp6
-rw-r--r--src/plugins/qmakeprojectmanager/profileeditor.cpp7
-rw-r--r--src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp25
-rw-r--r--src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h6
-rw-r--r--src/plugins/qmakeprojectmanager/qmakemakestep.cpp24
-rw-r--r--src/plugins/qmakeprojectmanager/qmakenodes.cpp63
-rw-r--r--src/plugins/qmakeprojectmanager/qmakenodes.h34
-rw-r--r--src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp29
-rw-r--r--src/plugins/qmakeprojectmanager/qmakenodetreebuilder.h6
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp79
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeparsernodes.h12
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeproject.cpp421
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeproject.h128
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp9
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp7
-rw-r--r--src/plugins/qmakeprojectmanager/qmakestep.cpp23
-rw-r--r--src/plugins/qmlprojectmanager/qmlproject.cpp246
-rw-r--r--src/plugins/qmlprojectmanager/qmlproject.h61
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectnodes.cpp103
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectnodes.h8
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp63
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h2
-rw-r--r--src/plugins/qnx/qnxrunconfiguration.cpp2
-rw-r--r--src/plugins/remotelinux/makeinstallstep.cpp3
-rw-r--r--src/plugins/remotelinux/remotelinuxrunconfiguration.cpp2
127 files changed, 2511 insertions, 2502 deletions
diff --git a/src/plugins/android/androidextralibrarylistmodel.cpp b/src/plugins/android/androidextralibrarylistmodel.cpp
index 0890cbefb3..58c6c2c8a7 100644
--- a/src/plugins/android/androidextralibrarylistmodel.cpp
+++ b/src/plugins/android/androidextralibrarylistmodel.cpp
@@ -45,11 +45,11 @@ AndroidExtraLibraryListModel::AndroidExtraLibraryListModel(ProjectExplorer::Targ
{
updateModel();
- connect(target->project(), &ProjectExplorer::Project::parsingStarted,
+ connect(target, &Target::parsingStarted,
this, &AndroidExtraLibraryListModel::updateModel);
- connect(target->project(), &ProjectExplorer::Project::parsingFinished,
+ connect(target, &Target::parsingFinished,
this, &AndroidExtraLibraryListModel::updateModel);
- connect(target, &ProjectExplorer::Target::activeRunConfigurationChanged,
+ connect(target, &Target::activeRunConfigurationChanged,
this, &AndroidExtraLibraryListModel::updateModel);
}
diff --git a/src/plugins/android/androidrunconfiguration.cpp b/src/plugins/android/androidrunconfiguration.cpp
index ac4aa5f0c0..1d562ad16b 100644
--- a/src/plugins/android/androidrunconfiguration.cpp
+++ b/src/plugins/android/androidrunconfiguration.cpp
@@ -132,7 +132,7 @@ AndroidRunConfiguration::AndroidRunConfiguration(Target *target, Core::Id id)
postStartShellCmdAspect->setSettingsKey("Android.PostStartShellCmdListKey");
postStartShellCmdAspect->setLabel(tr("Shell commands to run on Android device after application quits."));
- connect(target->project(), &Project::parsingFinished, this, [this] {
+ connect(target, &Target::parsingFinished, this, [this] {
updateTargetInformation();
AndroidManager::updateGradleProperties(this->target(), buildKey());
});
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp b/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp
index 177ebdad2f..9a9e69a08f 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp
+++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp
@@ -42,13 +42,13 @@ using namespace ProjectExplorer;
namespace AutotoolsProjectManager {
namespace Internal {
-AutotoolsBuildSystem::AutotoolsBuildSystem(Project *project)
- : BuildSystem(project)
+AutotoolsBuildSystem::AutotoolsBuildSystem(Target *target)
+ : BuildSystem(target)
, m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
{
- connect(project, &Project::activeBuildConfigurationChanged, this, [this]() { requestParse(); });
+ connect(target, &Target::activeBuildConfigurationChanged, this, [this]() { requestParse(); });
- connect(project, &Project::projectFileIsDirty, this, [this]() { requestParse(); });
+ connect(target->project(), &Project::projectFileIsDirty, this, [this]() { requestParse(); });
}
AutotoolsBuildSystem::~AutotoolsBuildSystem()
@@ -62,7 +62,7 @@ AutotoolsBuildSystem::~AutotoolsBuildSystem()
}
}
-void AutotoolsBuildSystem::parseProject(BuildSystem::ParsingContext &&ctx)
+void AutotoolsBuildSystem::triggerParsing()
{
if (m_makefileParserThread) {
// The thread is still busy parsing a previous configuration.
@@ -78,8 +78,7 @@ void AutotoolsBuildSystem::parseProject(BuildSystem::ParsingContext &&ctx)
}
// Parse the makefile asynchronously in a thread
- m_makefileParserThread = new MakefileParserThread(project()->projectFilePath().toString(),
- std::move(ctx.guard));
+ m_makefileParserThread = new MakefileParserThread(this);
connect(m_makefileParserThread,
&MakefileParserThread::finished,
@@ -114,7 +113,7 @@ void AutotoolsBuildSystem::makefileParsingFinished()
QVector<Utils::FilePath> filesToWatch;
// Apply sources to m_files, which are returned at AutotoolsBuildSystem::files()
- const QFileInfo fileInfo = project()->projectFilePath().toFileInfo();
+ const QFileInfo fileInfo = projectFilePath().toFileInfo();
const QDir dir = fileInfo.absoluteDir();
const QStringList files = m_makefileParserThread->sources();
foreach (const QString& file, files)
@@ -202,7 +201,7 @@ void AutotoolsBuildSystem::updateCppCodeModel()
rpp.setMacros(m_makefileParserThread->macros());
rpp.setFiles(m_files);
- m_cppCodeModelUpdater->update({project(), kitInfo, project()->activeParseEnvironment(), {rpp}});
+ m_cppCodeModelUpdater->update({project(), kitInfo, activeParseEnvironment(), {rpp}});
}
} // namespace Internal
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.h b/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.h
index 8bbad6a580..3af006b094 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.h
+++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.h
@@ -29,12 +29,9 @@
#include <projectexplorer/buildsystem.h>
-namespace Utils { class FileSystemWatcher; }
-
namespace CppTools { class CppProjectUpdater; }
namespace AutotoolsProjectManager {
-
namespace Internal {
class MakefileParserThread;
@@ -44,13 +41,12 @@ class AutotoolsBuildSystem : public ProjectExplorer::BuildSystem
Q_OBJECT
public:
- explicit AutotoolsBuildSystem(ProjectExplorer::Project *project);
+ explicit AutotoolsBuildSystem(ProjectExplorer::Target *target);
~AutotoolsBuildSystem() override;
-protected:
- void parseProject(ParsingContext &&ctx) final;
-
private:
+ void triggerParsing() final;
+
/**
* Is invoked when the makefile parsing by m_makefileParserThread has
* been finished. Adds all sources and files into the project tree and
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp b/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp
index 977ddade3e..6aaf8f64a2 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp
+++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp
@@ -36,7 +36,9 @@
#include "makestep.h"
#include <coreplugin/icontext.h>
+
#include <projectexplorer/projectmanager.h>
+#include <projectexplorer/target.h>
namespace AutotoolsProjectManager {
namespace Internal {
@@ -50,7 +52,7 @@ AutotoolsProject::AutotoolsProject(const Utils::FilePath &fileName)
setHasMakeInstallEquivalent(true);
- setBuildSystemCreator([](Project *p) { return new AutotoolsBuildSystem(p); });
+ setBuildSystemCreator([](ProjectExplorer::Target *t) { return new AutotoolsBuildSystem(t); });
}
class AutotoolsProjectPluginPrivate
diff --git a/src/plugins/autotoolsprojectmanager/makefileparserthread.cpp b/src/plugins/autotoolsprojectmanager/makefileparserthread.cpp
index fa225f6945..1a88febbf8 100644
--- a/src/plugins/autotoolsprojectmanager/makefileparserthread.cpp
+++ b/src/plugins/autotoolsprojectmanager/makefileparserthread.cpp
@@ -31,10 +31,9 @@
using namespace AutotoolsProjectManager::Internal;
-MakefileParserThread::MakefileParserThread(const QString &makefile,
- ProjectExplorer::Project::ParseGuard &&guard)
- : m_parser(makefile)
- , m_guard(std::move(guard))
+MakefileParserThread::MakefileParserThread(ProjectExplorer::BuildSystem *bs)
+ : m_parser(bs->projectFilePath().toString()),
+ m_guard(bs->guardParsingRun())
{
connect(&m_parser, &MakefileParser::status,
this, &MakefileParserThread::status);
diff --git a/src/plugins/autotoolsprojectmanager/makefileparserthread.h b/src/plugins/autotoolsprojectmanager/makefileparserthread.h
index 63d86190e2..75547af1dc 100644
--- a/src/plugins/autotoolsprojectmanager/makefileparserthread.h
+++ b/src/plugins/autotoolsprojectmanager/makefileparserthread.h
@@ -29,7 +29,7 @@
#include "makefileparser.h"
-#include <projectexplorer/project.h>
+#include <projectexplorer/buildsystem.h>
#include <projectexplorer/projectmacro.h>
#include <QMutex>
@@ -54,7 +54,7 @@ class MakefileParserThread : public QThread
using Macros = ProjectExplorer::Macros;
public:
- MakefileParserThread(const QString &makefile, ProjectExplorer::Project::ParseGuard &&guard);
+ explicit MakefileParserThread(ProjectExplorer::BuildSystem *bs);
/** @see QThread::run() */
void run() override;
@@ -143,7 +143,7 @@ private:
QStringList m_cflags; ///< Return value for MakefileParserThread::cflags()
QStringList m_cxxflags; ///< Return value for MakefileParserThread::cxxflags()
- ProjectExplorer::Project::ParseGuard m_guard;
+ ProjectExplorer::BuildSystem::ParseGuard m_guard;
};
} // namespace Internal
diff --git a/src/plugins/baremetal/baremetalrunconfiguration.cpp b/src/plugins/baremetal/baremetalrunconfiguration.cpp
index 8ba44b9343..c182025a61 100644
--- a/src/plugins/baremetal/baremetalrunconfiguration.cpp
+++ b/src/plugins/baremetal/baremetalrunconfiguration.cpp
@@ -55,7 +55,7 @@ BareMetalRunConfiguration::BareMetalRunConfiguration(Target *target, Core::Id id
this, &BareMetalRunConfiguration::updateTargetInformation);
connect(target, &Target::kitChanged,
this, &BareMetalRunConfiguration::updateTargetInformation); // Handles device changes, etc.
- connect(target->project(), &Project::parsingFinished,
+ connect(target, &Target::parsingFinished,
this, &BareMetalRunConfiguration::updateTargetInformation);
}
diff --git a/src/plugins/boot2qt/qdbrunconfiguration.cpp b/src/plugins/boot2qt/qdbrunconfiguration.cpp
index d1abe58229..65df670342 100644
--- a/src/plugins/boot2qt/qdbrunconfiguration.cpp
+++ b/src/plugins/boot2qt/qdbrunconfiguration.cpp
@@ -91,7 +91,7 @@ QdbRunConfiguration::QdbRunConfiguration(Target *target, Core::Id id)
this, &QdbRunConfiguration::updateTargetInformation);
connect(target, &Target::kitChanged,
this, &QdbRunConfiguration::updateTargetInformation);
- connect(target->project(), &Project::parsingFinished,
+ connect(target, &Target::parsingFinished,
this, &QdbRunConfiguration::updateTargetInformation);
setDefaultDisplayName(tr("Run on Boot2Qt Device"));
diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp
index aa0caae7ec..e5af6025f6 100644
--- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp
+++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp
@@ -65,24 +65,29 @@ Q_LOGGING_CATEGORY(cmakeBuildDirManagerLog, "qtc.cmake.builddirmanager", QtWarni
// BuildDirManager:
// --------------------------------------------------------------------
-BuildDirManager::BuildDirManager(CMakeProject *project) : m_project(project) { assert(project); }
+BuildDirManager::BuildDirManager(CMakeBuildSystem *buildSystem)
+ : m_buildSystem(buildSystem)
+{
+ assert(buildSystem);
+}
BuildDirManager::~BuildDirManager() = default;
-Utils::FilePath BuildDirManager::workDirectory(const BuildDirParameters &parameters) const
+FilePath BuildDirManager::workDirectory(const BuildDirParameters &parameters) const
{
const Utils::FilePath bdir = parameters.buildDirectory;
const CMakeTool *cmake = parameters.cmakeTool();
if (bdir.exists()) {
m_buildDirToTempDir.erase(bdir);
return bdir;
- } else {
- if (cmake && cmake->autoCreateBuildDirectory()) {
- if (!QDir().mkpath(bdir.toString()))
- emitErrorOccured(tr("Failed to create build directory \"%1\".").arg(bdir.toUserOutput()));
- return bdir;
- }
}
+
+ if (cmake && cmake->autoCreateBuildDirectory()) {
+ if (!QDir().mkpath(bdir.toString()))
+ emitErrorOccured(tr("Failed to create build directory \"%1\".").arg(bdir.toUserOutput()));
+ return bdir;
+ }
+
auto tmpDirIt = m_buildDirToTempDir.find(bdir);
if (tmpDirIt == m_buildDirToTempDir.end()) {
auto ret = m_buildDirToTempDir.emplace(std::make_pair(bdir, std::make_unique<Utils::TemporaryDirectory>("qtc-cmake-XXXXXXXX")));
@@ -290,22 +295,20 @@ void BuildDirManager::setParametersAndRequestParse(const BuildDirParameters &par
updateReaderType(m_parameters, [this]() { emitReparseRequest(); });
}
-CMakeBuildConfiguration *BuildDirManager::buildConfiguration() const
+CMakeBuildSystem *BuildDirManager::buildSystem() const
{
- if (m_project->activeTarget() && m_project->activeTarget()->activeBuildConfiguration() == m_parameters.buildConfiguration)
- return m_parameters.buildConfiguration;
- return nullptr;
+ return m_buildSystem;
}
FilePath BuildDirManager::buildDirectory() const
{
- return buildConfiguration() ? m_parameters.buildDirectory : FilePath();
+ return m_parameters.buildDirectory;
}
void BuildDirManager::becameDirty()
{
qCDebug(cmakeBuildDirManagerLog) << "BuildDirManager: becameDirty was triggered.";
- if (isParsing() || !buildConfiguration())
+ if (isParsing() || !buildSystem())
return;
const CMakeTool *tool = m_parameters.cmakeTool();
@@ -444,7 +447,7 @@ static CMakeBuildTarget utilityTarget(const QString &title, const BuildDirManage
target.title = title;
target.targetType = UtilityType;
target.workingDirectory = bdm->buildDirectory();
- target.sourceDirectory = bdm->project()->projectDirectory();
+ target.sourceDirectory = bdm->buildSystem()->project()->projectDirectory();
return target;
}
@@ -528,13 +531,10 @@ QString BuildDirManager::flagsString(int reparseFlags)
bool BuildDirManager::checkConfiguration()
{
- CMakeBuildConfiguration *bc = buildConfiguration();
- QTC_ASSERT(m_parameters.isValid() || !bc, return false);
-
if (m_parameters.workDirectory != m_parameters.buildDirectory) // always throw away changes in the tmpdir!
return false;
- const CMakeConfig cache = bc->configurationFromCMake();
+ const CMakeConfig cache = m_buildSystem->cmakeBuildConfiguration()->configurationFromCMake();
if (cache.isEmpty())
return false; // No cache file yet.
@@ -586,8 +586,8 @@ bool BuildDirManager::checkConfiguration()
box->exec();
if (box->clickedButton() == applyButton) {
m_parameters.configuration = newConfig;
- QSignalBlocker blocker(bc);
- bc->setConfigurationForCMake(newConfig);
+ QSignalBlocker blocker(m_buildSystem->buildConfiguration());
+ m_buildSystem->cmakeBuildConfiguration()->setConfigurationForCMake(newConfig);
return false;
} else if (box->clickedButton() == defaultButton)
return true;
diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.h b/src/plugins/cmakeprojectmanager/builddirmanager.h
index d3537104cc..2be437c31b 100644
--- a/src/plugins/cmakeprojectmanager/builddirmanager.h
+++ b/src/plugins/cmakeprojectmanager/builddirmanager.h
@@ -27,7 +27,6 @@
#include "builddirparameters.h"
#include "builddirreader.h"
-#include "cmakebuildsystem.h"
#include "cmakebuildtarget.h"
#include "cmakeconfigitem.h"
@@ -46,14 +45,11 @@
namespace ProjectExplorer { class FileNode; }
namespace CMakeProjectManager {
-
-class CMakeProject;
-class CMakeTool;
-
namespace Internal {
-class CMakeProjectNode;
class CMakeBuildConfiguration;
+class CMakeBuildSystem;
+class CMakeProjectNode;
class BuildDirManager : public QObject
{
@@ -71,7 +67,7 @@ public:
static QString flagsString(int reparseFlags);
- BuildDirManager(CMakeProject *project);
+ explicit BuildDirManager(CMakeBuildSystem *buildSystem);
~BuildDirManager() final;
bool isParsing() const;
@@ -81,8 +77,7 @@ public:
void setParametersAndRequestParse(const BuildDirParameters &parameters,
const int reparseOptions);
// nullptr if the BC is not active anymore!
- CMakeBuildConfiguration *buildConfiguration() const;
- CMakeProject *project() const {return m_project; }
+ CMakeBuildSystem *buildSystem() const;
Utils::FilePath buildDirectory() const;
void clearCache();
@@ -133,7 +128,7 @@ private:
BuildDirParameters m_parameters;
int m_reparseParameters;
- CMakeProject *m_project = nullptr;
+ CMakeBuildSystem *m_buildSystem = nullptr;
mutable std::unordered_map<Utils::FilePath, std::unique_ptr<Utils::TemporaryDirectory>> m_buildDirToTempDir;
mutable std::unique_ptr<BuildDirReader> m_reader;
mutable bool m_isHandlingError = false;
diff --git a/src/plugins/cmakeprojectmanager/builddirparameters.cpp b/src/plugins/cmakeprojectmanager/builddirparameters.cpp
index 160b50bef1..6bf4ccc8c3 100644
--- a/src/plugins/cmakeprojectmanager/builddirparameters.cpp
+++ b/src/plugins/cmakeprojectmanager/builddirparameters.cpp
@@ -45,7 +45,7 @@ BuildDirParameters::BuildDirParameters() = default;
BuildDirParameters::BuildDirParameters(CMakeBuildConfiguration *bc)
{
- buildConfiguration = bc;
+ initialized = bc != nullptr;
const Kit *k = bc->target()->kit();
@@ -82,7 +82,7 @@ BuildDirParameters::BuildDirParameters(CMakeBuildConfiguration *bc)
generatorArguments = CMakeGeneratorKitAspect::generatorArguments(k);
}
-bool BuildDirParameters::isValid() const { return buildConfiguration && cmakeTool(); }
+bool BuildDirParameters::isValid() const { return initialized && cmakeTool(); }
CMakeTool *BuildDirParameters::cmakeTool() const
{
diff --git a/src/plugins/cmakeprojectmanager/builddirparameters.h b/src/plugins/cmakeprojectmanager/builddirparameters.h
index d0bd9dd783..740327dcad 100644
--- a/src/plugins/cmakeprojectmanager/builddirparameters.h
+++ b/src/plugins/cmakeprojectmanager/builddirparameters.h
@@ -42,14 +42,14 @@ class CMakeBuildConfiguration;
class BuildDirParameters {
public:
BuildDirParameters();
- BuildDirParameters(CMakeBuildConfiguration *bc);
+ explicit BuildDirParameters(CMakeBuildConfiguration *bc);
BuildDirParameters(const BuildDirParameters &other);
BuildDirParameters &operator=(const BuildDirParameters &other);
bool isValid() const;
CMakeTool *cmakeTool() const;
- CMakeBuildConfiguration *buildConfiguration = nullptr;
+ bool initialized = false;
QString projectName;
Utils::FilePath sourceDirectory;
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
index a638ec439a..d08f14feab 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
@@ -84,101 +84,17 @@ const char CONFIGURATION_KEY[] = "CMake.Configuration";
CMakeBuildConfiguration::CMakeBuildConfiguration(Target *parent, Core::Id id)
: BuildConfiguration(parent, id)
- , m_buildDirManager(qobject_cast<CMakeProject *>(parent->project()))
{
+ m_buildSystem = new CMakeBuildSystem(this);
setBuildDirectory(shadowBuildDirectory(project()->projectFilePath(),
target()->kit(),
displayName(),
BuildConfiguration::Unknown));
+}
- BuildSystem *bs = qobject_cast<CMakeBuildSystem *>(project()->buildSystem());
-
- // BuildDirManager:
- 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,
- this,
- &CMakeBuildConfiguration::handleParsingSucceeded);
- connect(&m_buildDirManager,
- &BuildDirManager::errorOccured,
- this,
- &CMakeBuildConfiguration::handleParsingFailed);
- connect(&m_buildDirManager, &BuildDirManager::parsingStarted, this, [this]() {
- clearError(CMakeBuildConfiguration::ForceEnabledChanged::True);
- });
-
- // Kit changed:
- connect(KitManager::instance(), &KitManager::kitUpdated, this, [this](Kit *k) {
- if (k != target()->kit())
- return; // not for us...
- // Build configuration has not changed, but Kit settings might have:
- // reparse and check the configuration, independent of whether the reader has changed
- m_buildDirManager.setParametersAndRequestParse(BuildDirParameters(this),
- BuildDirManager::REPARSE_CHECK_CONFIGURATION);
- });
-
- // Became active/inactive:
- connect(project(), &Project::activeBuildConfigurationChanged, this, [this]() {
- if (isActive()) {
- // Build configuration has switched:
- // * Check configuration if reader changes due to it not existing yet:-)
- // * run cmake without configuration arguments if the reader stays
- m_buildDirManager
- .setParametersAndRequestParse(BuildDirParameters(this),
- BuildDirManager::REPARSE_CHECK_CONFIGURATION);
- } else {
- m_buildDirManager.stopParsingAndClearState();
- }
- });
-
- // BuildConfiguration changed:
- connect(this, &CMakeBuildConfiguration::environmentChanged, this, [this]() {
- if (isActive()) {
- // The environment on our BC has changed:
- // * Error out if the reader updates, cannot happen since all BCs share a target/kit.
- // * run cmake without configuration arguments if the reader stays
- m_buildDirManager
- .setParametersAndRequestParse(BuildDirParameters(this),
- BuildDirManager::REPARSE_CHECK_CONFIGURATION);
- }
- });
- connect(this, &CMakeBuildConfiguration::buildDirectoryChanged, this, [this]() {
- if (isActive()) {
- // The build directory of our BC has changed:
- // * Error out if the reader updates, cannot happen since all BCs share a target/kit.
- // * run cmake without configuration arguments if the reader stays
- // If no configuration exists, then the arguments will get added automatically by
- // the reader.
- m_buildDirManager
- .setParametersAndRequestParse(BuildDirParameters(this),
- BuildDirManager::REPARSE_CHECK_CONFIGURATION);
- }
- });
- connect(this, &CMakeBuildConfiguration::configurationForCMakeChanged, this, [this]() {
- if (isActive()) {
- // The CMake configuration has changed on our BC:
- // * Error out if the reader updates, cannot happen since all BCs share a target/kit.
- // * run cmake with configuration arguments if the reader stays
- m_buildDirManager
- .setParametersAndRequestParse(BuildDirParameters(this),
- BuildDirManager::REPARSE_FORCE_CONFIGURATION);
- }
- });
-
- connect(parent->project(), &Project::projectFileIsDirty, this, [this]() {
- if (isActive()) {
- m_buildDirManager
- .setParametersAndRequestParse(BuildDirParameters(this),
- BuildDirManager::REPARSE_DEFAULT);
- }
- });
+CMakeBuildConfiguration::~CMakeBuildConfiguration()
+{
+ delete m_buildSystem;
}
void CMakeBuildConfiguration::initialize()
@@ -284,82 +200,11 @@ bool CMakeBuildConfiguration::fromMap(const QVariantMap &map)
return true;
}
-const QList<BuildTargetInfo> CMakeBuildConfiguration::appTargets() const
-{
- QList<BuildTargetInfo> appTargetList;
- const bool forAndroid = DeviceTypeKitAspect::deviceTypeId(target()->kit())
- == Android::Constants::ANDROID_DEVICE_TYPE;
- for (const CMakeBuildTarget &ct : m_buildTargets) {
- if (ct.targetType == UtilityType)
- continue;
-
- if (ct.targetType == ExecutableType || (forAndroid && ct.targetType == DynamicLibraryType)) {
- BuildTargetInfo bti;
- bti.displayName = ct.title;
- bti.targetFilePath = ct.executable;
- bti.projectFilePath = ct.sourceDirectory.stringAppended("/");
- bti.workingDirectory = ct.workingDirectory;
- bti.buildKey = ct.title;
-
- // Workaround for QTCREATORBUG-19354:
- bti.runEnvModifier = [this](Environment &env, bool) {
- if (HostOsInfo::isWindowsHost()) {
- const Kit *k = target()->kit();
- if (const QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(k))
- env.prependOrSetPath(qt->binPath().toString());
- }
- };
-
- appTargetList.append(bti);
- }
- }
-
- return appTargetList;
-}
-
-DeploymentData CMakeBuildConfiguration::deploymentData() const
-{
- DeploymentData result;
-
- QDir sourceDir = target()->project()->projectDirectory().toString();
- QDir buildDir = buildDirectory().toString();
- QString deploymentPrefix;
- QString deploymentFilePath = sourceDir.filePath("QtCreatorDeployment.txt");
- bool hasDeploymentFile = QFileInfo::exists(deploymentFilePath);
- if (!hasDeploymentFile) {
- deploymentFilePath = buildDir.filePath("QtCreatorDeployment.txt");
- hasDeploymentFile = QFileInfo::exists(deploymentFilePath);
- }
- if (!hasDeploymentFile)
- return result;
-
- deploymentPrefix = result.addFilesFromDeploymentFile(deploymentFilePath,
- sourceDir.absolutePath());
- for (const CMakeBuildTarget &ct : m_buildTargets) {
- if (ct.targetType == ExecutableType || ct.targetType == DynamicLibraryType) {
- if (!ct.executable.isEmpty()
- && result.deployableForLocalFile(ct.executable).localFilePath() != ct.executable) {
- result.addFile(ct.executable.toString(),
- deploymentPrefix + buildDir.relativeFilePath(ct.executable.toFileInfo().dir().path()),
- DeployableFile::TypeExecutable);
- }
- }
- }
- return result;
-}
-QStringList CMakeBuildConfiguration::buildTargetTitles() const
-{
- return transform(m_buildTargets, &CMakeBuildTarget::title);
-}
-const QList<CMakeBuildTarget> &CMakeBuildConfiguration::buildTargets() const
-{
- return m_buildTargets;
-}
FilePath CMakeBuildConfiguration::shadowBuildDirectory(const FilePath &projectFilePath,
const Kit *k,
@@ -408,11 +253,6 @@ void CMakeBuildConfiguration::setConfigurationFromCMake(const CMakeConfig &confi
m_configurationFromCMake = config;
}
-void CMakeBuildConfiguration::setBuildTargets(const QList<CMakeBuildTarget> &targets)
-{
- m_buildTargets = targets;
-}
-
void CMakeBuildConfiguration::setConfigurationForCMake(const QList<ConfigModel::DataItem> &items)
{
const CMakeConfig newConfig = Utils::transform(items, [](const ConfigModel::DataItem &i) {
@@ -548,64 +388,6 @@ void CMakeBuildConfiguration::setWarning(const QString &message)
emit warningOccured(m_warning);
}
-void CMakeBuildConfiguration::handleParsingSucceeded()
-{
- if (!isActive()) {
- m_buildDirManager.stopParsingAndClearState();
- return;
- }
-
- clearError();
-
- QString errorMessage;
- {
- const QList<CMakeBuildTarget> buildTargets = m_buildDirManager.takeBuildTargets(
- errorMessage);
- checkAndReportError(errorMessage);
- setBuildTargets(buildTargets);
- }
-
- {
- const CMakeConfig cmakeConfig = m_buildDirManager.takeCMakeConfiguration(errorMessage);
- checkAndReportError(errorMessage);
- setConfigurationFromCMake(cmakeConfig);
- }
-
- {
- target()->setApplicationTargets(appTargets());
- target()->setDeploymentData(deploymentData());
- }
-
- static_cast<CMakeBuildSystem *>(project()->buildSystem())->handleParsingSuccess(this);
-}
-
-void CMakeBuildConfiguration::handleParsingFailed(const QString &msg)
-{
- setError(msg);
-
- QString errorMessage;
- setConfigurationFromCMake(m_buildDirManager.takeCMakeConfiguration(errorMessage));
- // ignore errorMessage here, we already got one.
-
- static_cast<CMakeBuildSystem *>(project()->buildSystem())->handleParsingError(this);
-}
-
-std::unique_ptr<CMakeProjectNode> CMakeBuildConfiguration::generateProjectTree(
- const QList<const FileNode *> &allFiles)
-{
- QString errorMessage;
- auto root = m_buildDirManager.generateProjectTree(allFiles, errorMessage);
- checkAndReportError(errorMessage);
- return root;
-}
-
-void CMakeBuildConfiguration::checkAndReportError(QString &errorMessage)
-{
- if (!errorMessage.isEmpty()) {
- setError(errorMessage);
- errorMessage.clear();
- }
-}
QString CMakeBuildConfiguration::error() const
{
@@ -775,5 +557,10 @@ CMakeProject *CMakeBuildConfiguration::project() const
return qobject_cast<CMakeProject *>(BuildConfiguration::project());
}
+BuildSystem *CMakeBuildConfiguration::buildSystem() const
+{
+ return m_buildSystem;
+}
+
} // namespace Internal
} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
index 833f77131f..70f1b17a74 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
+++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
@@ -34,13 +34,12 @@
#include <projectexplorer/deploymentdata.h>
namespace CMakeProjectManager {
-class CMakeBuildSystem;
-class CMakeExtraBuildInfo;
class CMakeProject;
namespace Internal {
class BuildDirManager;
+class CMakeBuildSystem;
class CMakeBuildSettingsWidget;
class CMakeBuildConfiguration : public ProjectExplorer::BuildConfiguration
@@ -49,6 +48,7 @@ class CMakeBuildConfiguration : public ProjectExplorer::BuildConfiguration
friend class ProjectExplorer::BuildConfigurationFactory;
CMakeBuildConfiguration(ProjectExplorer::Target *parent, Core::Id id);
+ ~CMakeBuildConfiguration() final;
public:
void emitBuildTypeChanged();
@@ -61,17 +61,14 @@ public:
CMakeProject *project() const;
- QStringList buildTargetTitles() const;
- const QList<CMakeBuildTarget> &buildTargets() const;
- const QList<ProjectExplorer::BuildTargetInfo> appTargets() const;
- ProjectExplorer::DeploymentData deploymentData() const;
-
static Utils::FilePath
shadowBuildDirectory(const Utils::FilePath &projectFilePath, const ProjectExplorer::Kit *k,
const QString &bcName, BuildConfiguration::BuildType buildType);
// Context menu action:
void buildTarget(const QString &buildTarget);
+ ProjectExplorer::BuildSystem *buildSystem() const final;
+
signals:
void errorOccured(const QString &message);
void warningOccured(const QString &message);
@@ -92,7 +89,6 @@ private:
enum ForceEnabledChanged { False, True };
void clearError(ForceEnabledChanged fec = ForceEnabledChanged::False);
- void setBuildTargets(const QList<CMakeBuildTarget> &targets);
void setConfigurationFromCMake(const CMakeConfig &config);
void setConfigurationForCMake(const QList<ConfigModel::DataItem> &items);
void setConfigurationForCMake(const CMakeConfig &config);
@@ -100,27 +96,17 @@ private:
void setError(const QString &message);
void setWarning(const QString &message);
- void handleParsingSucceeded();
- void handleParsingFailed(const QString &msg);
-
- std::unique_ptr<CMakeProjectNode> generateProjectTree(
- const QList<const ProjectExplorer::FileNode *> &allFiles);
-
- void checkAndReportError(QString &errorMessage);
-
- Internal::BuildDirManager m_buildDirManager;
-
CMakeConfig m_configurationForCMake;
CMakeConfig m_initialConfiguration;
QString m_error;
QString m_warning;
CMakeConfig m_configurationFromCMake;
- QList<CMakeBuildTarget> m_buildTargets;
+ CMakeBuildSystem *m_buildSystem = nullptr;
friend class CMakeBuildSettingsWidget;
- friend class CMakeProjectManager::CMakeBuildSystem;
- friend class CMakeProjectManager::CMakeProject;
+ friend class CMakeBuildSystem;
+ friend class CMakeProject;
friend class BuildDirManager;
};
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp
index 710828ff01..1652ed959f 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp
@@ -59,6 +59,8 @@
#include <QStyledItemDelegate>
#include <QMenu>
+using namespace ProjectExplorer;
+
namespace CMakeProjectManager {
namespace Internal {
@@ -102,7 +104,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setColumnStretch(1, 10);
- auto project = static_cast<CMakeProject *>(bc->project());
+ auto project = bc->project();
auto buildDirChooser = new Utils::PathChooser;
buildDirChooser->setBaseFileName(project->projectDirectory());
@@ -245,21 +247,20 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
setError(bc->error());
setWarning(bc->warning());
- connect(project, &ProjectExplorer::Project::parsingStarted, this, [this]() {
+ connect(bc->target(), &Target::parsingStarted, this, [this]() {
updateButtonState();
m_configView->setEnabled(false);
m_showProgressTimer.start();
});
- if (project->isParsing())
+ if (bc->buildSystem()->isParsing())
m_showProgressTimer.start();
else {
m_configModel->setConfiguration(m_buildConfiguration->configurationFromCMake());
m_configView->expandAll();
}
- connect(project, &ProjectExplorer::Project::parsingFinished,
- this, [this, buildDirChooser, stretcher]() {
+ connect(bc->target(), &Target::parsingFinished, this, [this, buildDirChooser, stretcher] {
m_configModel->setConfiguration(m_buildConfiguration->configurationFromCMake());
m_configView->expandAll();
m_configView->setEnabled(true);
@@ -363,7 +364,7 @@ void CMakeBuildSettingsWidget::setWarning(const QString &message)
void CMakeBuildSettingsWidget::updateButtonState()
{
- const bool isParsing = m_buildConfiguration->project()->isParsing();
+ const bool isParsing = m_buildConfiguration->buildSystem()->isParsing();
const bool hasChanges = m_configModel->hasChanges();
m_resetButton->setEnabled(hasChanges && !isParsing);
m_reconfigureButton->setEnabled((hasChanges || m_configModel->hasCMakeChanges()) && !isParsing);
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
index 00032dabff..67d6bc5252 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
@@ -26,6 +26,7 @@
#include "cmakebuildstep.h"
#include "cmakebuildconfiguration.h"
+#include "cmakebuildsystem.h"
#include "cmakekitinformation.h"
#include "cmakeparser.h"
#include "cmakeprojectconstants.h"
@@ -91,7 +92,7 @@ CMakeBuildStep::CMakeBuildStep(BuildStepList *bsl) :
setLowPriority();
connect(target(), &Target::kitChanged, this, &CMakeBuildStep::cmakeCommandChanged);
- connect(project(), &Project::parsingFinished,
+ connect(target(), &Target::parsingFinished,
this, &CMakeBuildStep::handleBuildTargetChanges);
}
@@ -221,17 +222,17 @@ void CMakeBuildStep::doRun()
QTC_ASSERT(bc, return);
m_waiting = false;
- auto p = static_cast<CMakeProject *>(bc->project());
- if (p->persistCMakeState()) {
+ auto bs = static_cast<CMakeBuildSystem *>(buildConfiguration()->buildSystem());
+ if (bs->persistCMakeState()) {
emit addOutput(tr("Persisting CMake state..."), BuildStep::OutputFormat::NormalMessage);
m_waiting = true;
- } else if (p->mustUpdateCMakeStateBeforeBuild()) {
+ } else if (buildConfiguration()->buildSystem()->isWaitingForParse()) {
emit addOutput(tr("Running CMake in preparation to build..."), BuildStep::OutputFormat::NormalMessage);
m_waiting = true;
}
if (m_waiting) {
- m_runTrigger = connect(project(), &Project::parsingFinished,
+ m_runTrigger = connect(target(), &Target::parsingFinished,
this, [this](bool success) { handleProjectWasParsed(success); });
} else {
runImpl();
@@ -367,7 +368,7 @@ Utils::CommandLine CMakeBuildStep::cmakeCommand(RunConfiguration *rc) const
QStringList CMakeBuildStep::knownBuildTargets()
{
- auto bc = qobject_cast<CMakeBuildConfiguration *>(buildConfiguration());
+ auto bc = qobject_cast<CMakeBuildSystem *>(buildConfiguration()->buildSystem());
return bc ? bc->buildTargetTitles() : QStringList();
}
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
index ae1e20972f..b84a39625b 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
@@ -30,13 +30,18 @@
#include "cmakeprojectconstants.h"
#include "cmakeprojectnodes.h"
+#include <android/androidconstants.h>
+
#include <coreplugin/progressmanager/progressmanager.h>
#include <cpptools/cppprojectupdater.h>
#include <cpptools/generatedcodemodelsupport.h>
+#include <projectexplorer/kitmanager.h>
#include <projectexplorer/project.h>
#include <projectexplorer/target.h>
#include <qmljs/qmljsmodelmanagerinterface.h>
+
#include <qtsupport/qtcppkitinfo.h>
+#include <qtsupport/qtkitinformation.h>
#include <utils/fileutils.h>
#include <utils/mimetypes/mimetype.h>
@@ -48,8 +53,7 @@ using namespace ProjectExplorer;
using namespace Utils;
namespace CMakeProjectManager {
-
-using namespace Internal;
+namespace Internal {
Q_LOGGING_CATEGORY(cmakeBuildSystemLog, "qtc.cmake.buildsystem", QtWarningMsg);
@@ -57,15 +61,15 @@ Q_LOGGING_CATEGORY(cmakeBuildSystemLog, "qtc.cmake.buildsystem", QtWarningMsg);
// CMakeBuildSystem:
// --------------------------------------------------------------------
-CMakeBuildSystem::CMakeBuildSystem(Project *project)
- : BuildSystem(project)
+CMakeBuildSystem::CMakeBuildSystem(CMakeBuildConfiguration *bc)
+ : BuildSystem(bc)
+ , m_buildConfiguration(bc)
+ , m_buildDirManager(this)
, m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
{
// TreeScanner:
- connect(&m_treeScanner,
- &TreeScanner::finished,
- this,
- &CMakeBuildSystem::handleTreeScanningFinished);
+ connect(&m_treeScanner, &TreeScanner::finished,
+ this, &CMakeBuildSystem::handleTreeScanningFinished);
m_treeScanner.setFilter([this](const MimeType &mimeType, const FilePath &fn) {
// Mime checks requires more resources, so keep it last in check list
@@ -98,6 +102,109 @@ CMakeBuildSystem::CMakeBuildSystem(Project *project)
}
return type;
});
+
+ // BuildDirManager:
+ connect(&m_buildDirManager, &BuildDirManager::requestReparse, this, [this] {
+ if (m_buildConfiguration->isActive())
+ requestParse();
+ });
+ connect(&m_buildDirManager, &BuildDirManager::requestDelayedReparse, this, [this] {
+ if (m_buildConfiguration->isActive())
+ requestDelayedParse();
+ });
+
+ connect(&m_buildDirManager, &BuildDirManager::dataAvailable,
+ this, &CMakeBuildSystem::handleParsingSucceeded);
+
+ connect(&m_buildDirManager, &BuildDirManager::errorOccured,
+ this, &CMakeBuildSystem::handleParsingFailed);
+
+ connect(&m_buildDirManager, &BuildDirManager::parsingStarted, this, [this]() {
+ m_buildConfiguration->clearError(CMakeBuildConfiguration::ForceEnabledChanged::True);
+ });
+
+ // Kit changed:
+ connect(KitManager::instance(), &KitManager::kitUpdated, this, [this](Kit *k) {
+ if (k != target()->kit())
+ return; // not for us...
+ // Build configuration has not changed, but Kit settings might have:
+ // reparse and check the configuration, independent of whether the reader has changed
+ m_buildDirManager.setParametersAndRequestParse(BuildDirParameters(m_buildConfiguration),
+ BuildDirManager::REPARSE_CHECK_CONFIGURATION);
+ });
+
+ // Became active/inactive:
+ connect(project(), &Project::activeTargetChanged, this, [this](Target *t) {
+ if (t == target()) {
+ // Build configuration has switched:
+ // * Check configuration if reader changes due to it not existing yet:-)
+ // * run cmake without configuration arguments if the reader stays
+ m_buildDirManager
+ .setParametersAndRequestParse(BuildDirParameters(m_buildConfiguration),
+ BuildDirManager::REPARSE_CHECK_CONFIGURATION);
+ } else {
+ m_buildDirManager.stopParsingAndClearState();
+ }
+ });
+ connect(target(), &Target::activeBuildConfigurationChanged, this, [this](BuildConfiguration *bc) {
+ if (m_buildConfiguration->isActive()) {
+ if (m_buildConfiguration == bc) {
+ // Build configuration has switched:
+ // * Check configuration if reader changes due to it not existing yet:-)
+ // * run cmake without configuration arguments if the reader stays
+ m_buildDirManager
+ .setParametersAndRequestParse(BuildDirParameters(m_buildConfiguration),
+ BuildDirManager::REPARSE_CHECK_CONFIGURATION);
+ } else {
+ m_buildDirManager.stopParsingAndClearState();
+ }
+ }
+ });
+
+ // BuildConfiguration changed:
+ connect(m_buildConfiguration, &CMakeBuildConfiguration::environmentChanged, this, [this]() {
+ if (m_buildConfiguration->isActive()) {
+ // The environment on our BC has changed:
+ // * Error out if the reader updates, cannot happen since all BCs share a target/kit.
+ // * run cmake without configuration arguments if the reader stays
+ m_buildDirManager
+ .setParametersAndRequestParse(BuildDirParameters(m_buildConfiguration),
+ BuildDirManager::REPARSE_CHECK_CONFIGURATION);
+ }
+ });
+ connect(m_buildConfiguration, &CMakeBuildConfiguration::buildDirectoryChanged, this, [this]() {
+ if (m_buildConfiguration->isActive()) {
+ // The build directory of our BC has changed:
+ // * Error out if the reader updates, cannot happen since all BCs share a target/kit.
+ // * run cmake without configuration arguments if the reader stays
+ // If no configuration exists, then the arguments will get added automatically by
+ // the reader.
+ m_buildDirManager
+ .setParametersAndRequestParse(BuildDirParameters(m_buildConfiguration),
+ BuildDirManager::REPARSE_CHECK_CONFIGURATION);
+ }
+ });
+ connect(m_buildConfiguration, &CMakeBuildConfiguration::configurationForCMakeChanged, this, [this]() {
+ if (m_buildConfiguration->isActive()) {
+ // The CMake configuration has changed on our BC:
+ // * Error out if the reader updates, cannot happen since all BCs share a target/kit.
+ // * run cmake with configuration arguments if the reader stays
+ m_buildDirManager
+ .setParametersAndRequestParse(BuildDirParameters(m_buildConfiguration),
+ BuildDirManager::REPARSE_FORCE_CONFIGURATION);
+ }
+ });
+
+ connect(project(), &Project::projectFileIsDirty, this, [this]() {
+ if (m_buildConfiguration->isActive()) {
+ m_buildDirManager
+ .setParametersAndRequestParse(BuildDirParameters(m_buildConfiguration),
+ BuildDirManager::REPARSE_DEFAULT);
+ }
+ });
+
+ m_buildDirManager.setParametersAndRequestParse(BuildDirParameters(m_buildConfiguration),
+ BuildDirManager::REPARSE_CHECK_CONFIGURATION);
}
CMakeBuildSystem::~CMakeBuildSystem()
@@ -112,36 +219,84 @@ CMakeBuildSystem::~CMakeBuildSystem()
qDeleteAll(m_allFiles);
}
-bool CMakeBuildSystem::validateParsingContext(const ParsingContext &ctx)
+void CMakeBuildSystem::triggerParsing()
{
- QTC_ASSERT(!m_currentContext.guard.guardsProject(), return false);
- return ctx.project && qobject_cast<CMakeBuildConfiguration *>(ctx.buildConfiguration);
-}
-
-void CMakeBuildSystem::parseProject(ParsingContext &&ctx)
-{
- m_currentContext = std::move(ctx);
-
- auto bc = qobject_cast<CMakeBuildConfiguration *>(m_currentContext.buildConfiguration);
- QTC_ASSERT(bc, return );
+ m_currentGuard = guardParsingRun();
if (m_allFiles.isEmpty())
- bc->m_buildDirManager.requestFilesystemScan();
+ m_buildDirManager.requestFilesystemScan();
- m_waitingForScan = bc->m_buildDirManager.isFilesystemScanRequested();
+ m_waitingForScan = m_buildDirManager.isFilesystemScanRequested();
m_waitingForParse = true;
m_combinedScanAndParseResult = true;
if (m_waitingForScan) {
QTC_CHECK(m_treeScanner.isFinished());
- m_treeScanner.asyncScanForFiles(m_currentContext.project->projectDirectory());
+ m_treeScanner.asyncScanForFiles(projectDirectory());
Core::ProgressManager::addTask(m_treeScanner.future(),
tr("Scan \"%1\" project tree")
- .arg(m_currentContext.project->displayName()),
+ .arg(project()->displayName()),
"CMake.Scan.Tree");
}
- bc->m_buildDirManager.parse();
+ m_buildDirManager.parse();
+}
+
+QStringList CMakeBuildSystem::filesGeneratedFrom(const QString &sourceFile) const
+{
+ QFileInfo fi(sourceFile);
+ FilePath project = projectDirectory();
+ FilePath baseDirectory = FilePath::fromString(fi.absolutePath());
+
+ while (baseDirectory.isChildOf(project)) {
+ const FilePath cmakeListsTxt = baseDirectory.pathAppended("CMakeLists.txt");
+ if (cmakeListsTxt.exists())
+ break;
+ baseDirectory = baseDirectory.parentDir();
+ }
+
+ QDir srcDirRoot = QDir(project.toString());
+ QString relativePath = srcDirRoot.relativeFilePath(baseDirectory.toString());
+ QDir buildDir = QDir(target()->activeBuildConfiguration()->buildDirectory().toString());
+ QString generatedFilePath = buildDir.absoluteFilePath(relativePath);
+
+ if (fi.suffix() == "ui") {
+ generatedFilePath += "/ui_";
+ generatedFilePath += fi.completeBaseName();
+ generatedFilePath += ".h";
+ return {QDir::cleanPath(generatedFilePath)};
+ }
+ if (fi.suffix() == "scxml") {
+ generatedFilePath += "/";
+ generatedFilePath += QDir::cleanPath(fi.completeBaseName());
+ return {generatedFilePath + ".h", generatedFilePath + ".cpp"};
+ }
+
+ // TODO: Other types will be added when adapters for their compilers become available.
+ return {};
+}
+
+void CMakeBuildSystem::runCMake()
+{
+ BuildDirParameters parameters(m_buildConfiguration);
+ m_buildDirManager.setParametersAndRequestParse(parameters,
+ BuildDirManager::REPARSE_CHECK_CONFIGURATION
+ | BuildDirManager::REPARSE_FORCE_CMAKE_RUN
+ | BuildDirManager::REPARSE_URGENT);
+}
+
+void CMakeBuildSystem::runCMakeAndScanProjectTree()
+{
+ BuildDirParameters parameters(m_buildConfiguration);
+ m_buildDirManager.setParametersAndRequestParse(parameters,
+ BuildDirManager::REPARSE_CHECK_CONFIGURATION
+ | BuildDirManager::REPARSE_SCAN);
+}
+
+void CMakeBuildSystem::buildCMakeTarget(const QString &buildTarget)
+{
+ QTC_ASSERT(!buildTarget.isEmpty(), return);
+ m_buildConfiguration->buildTarget(buildTarget);
}
void CMakeBuildSystem::handleTreeScanningFinished()
@@ -156,11 +311,18 @@ void CMakeBuildSystem::handleTreeScanningFinished()
combineScanAndParse();
}
-void CMakeBuildSystem::handleParsingSuccess(CMakeBuildConfiguration *bc)
+bool CMakeBuildSystem::persistCMakeState()
{
- if (bc != m_currentContext.buildConfiguration)
- return; // Not current information, ignore.
+ return m_buildDirManager.persistCMakeState();
+}
+
+void CMakeBuildSystem::clearCMakeCache()
+{
+ m_buildDirManager.clearCache();
+}
+void CMakeBuildSystem::handleParsingSuccess()
+{
QTC_ASSERT(m_waitingForParse, return );
m_waitingForParse = false;
@@ -168,11 +330,8 @@ void CMakeBuildSystem::handleParsingSuccess(CMakeBuildConfiguration *bc)
combineScanAndParse();
}
-void CMakeBuildSystem::handleParsingError(CMakeBuildConfiguration *bc)
+void CMakeBuildSystem::handleParsingError()
{
- if (bc != m_currentContext.buildConfiguration)
- return; // Not current information, ignore.
-
QTC_CHECK(m_waitingForParse);
m_waitingForParse = false;
@@ -181,35 +340,51 @@ void CMakeBuildSystem::handleParsingError(CMakeBuildConfiguration *bc)
combineScanAndParse();
}
+std::unique_ptr<CMakeProjectNode>
+ CMakeBuildSystem::generateProjectTree(const QList<const FileNode *> &allFiles)
+{
+ QString errorMessage;
+ auto root = m_buildDirManager.generateProjectTree(allFiles, errorMessage);
+ checkAndReportError(errorMessage);
+ return root;
+}
+
void CMakeBuildSystem::combineScanAndParse()
{
- auto bc = qobject_cast<CMakeBuildConfiguration *>(m_currentContext.buildConfiguration);
- if (bc && bc->isActive()) {
+ if (m_buildConfiguration->isActive()) {
if (m_waitingForParse || m_waitingForScan)
return;
if (m_combinedScanAndParseResult) {
- updateProjectData(qobject_cast<CMakeProject *>(m_currentContext.project), bc);
- m_currentContext.guard.markAsSuccess();
+ updateProjectData();
+ m_currentGuard.markAsSuccess();
}
}
- m_currentContext = BuildSystem::ParsingContext();
+ m_currentGuard = {};
+}
+
+void CMakeBuildSystem::checkAndReportError(QString &errorMessage)
+{
+ if (!errorMessage.isEmpty()) {
+ m_buildConfiguration->setError(errorMessage);
+ errorMessage.clear();
+ }
}
-void CMakeBuildSystem::updateProjectData(CMakeProject *p, CMakeBuildConfiguration *bc)
+void CMakeBuildSystem::updateProjectData()
{
qCDebug(cmakeBuildSystemLog) << "Updating CMake project data";
- QTC_ASSERT(m_treeScanner.isFinished() && !bc->m_buildDirManager.isParsing(), return );
+ QTC_ASSERT(m_treeScanner.isFinished() && !m_buildDirManager.isParsing(), return);
- project()->setExtraProjectFiles(bc->m_buildDirManager.takeProjectFilesToWatch());
+ m_buildConfiguration->project()->setExtraProjectFiles(m_buildDirManager.takeProjectFilesToWatch());
- CMakeConfig patchedConfig = bc->configurationFromCMake();
+ CMakeConfig patchedConfig = m_buildConfiguration->configurationFromCMake();
{
CMakeConfigItem settingFileItem;
settingFileItem.key = "ANDROID_DEPLOYMENT_SETTINGS_FILE";
- settingFileItem.value = bc->buildDirectory()
+ settingFileItem.value = m_buildConfiguration->buildDirectory()
.pathAppended("android_deployment_settings.json")
.toString()
.toUtf8();
@@ -218,7 +393,7 @@ void CMakeBuildSystem::updateProjectData(CMakeProject *p, CMakeBuildConfiguratio
{
QSet<QString> res;
QStringList apps;
- for (const auto &target : bc->buildTargets()) {
+ for (const auto &target : m_buildTargets) {
if (target.targetType == CMakeProjectManager::DynamicLibraryType) {
res.insert(target.executable.parentDir().toString());
apps.push_back(target.executable.toUserOutput());
@@ -241,14 +416,15 @@ void CMakeBuildSystem::updateProjectData(CMakeProject *p, CMakeBuildConfiguratio
}
}
+ Project *p = project();
{
- auto newRoot = bc->generateProjectTree(m_allFiles);
+ auto newRoot = generateProjectTree(m_allFiles);
if (newRoot) {
p->setRootProjectNode(std::move(newRoot));
if (p->rootProjectNode())
p->setDisplayName(p->rootProjectNode()->displayName());
- for (const CMakeBuildTarget &bt : bc->buildTargets()) {
+ for (const CMakeBuildTarget &bt : m_buildTargets) {
const QString buildKey = bt.title;
if (ProjectNode *node = p->findNodeForBuildKey(buildKey)) {
if (auto targetNode = dynamic_cast<CMakeTargetNode *>(node))
@@ -260,7 +436,7 @@ void CMakeBuildSystem::updateProjectData(CMakeProject *p, CMakeBuildConfiguratio
{
qDeleteAll(m_extraCompilers);
- m_extraCompilers = findExtraCompilers(p);
+ m_extraCompilers = findExtraCompilers();
CppTools::GeneratedCodeModelSupport::update(m_extraCompilers);
qCDebug(cmakeBuildSystemLog) << "Extra compilers updated.";
}
@@ -270,9 +446,9 @@ void CMakeBuildSystem::updateProjectData(CMakeProject *p, CMakeBuildConfiguratio
{
QString errorMessage;
- RawProjectParts rpps = bc->m_buildDirManager.createRawProjectParts(errorMessage);
+ RawProjectParts rpps = m_buildDirManager.createRawProjectParts(errorMessage);
if (!errorMessage.isEmpty())
- bc->setError(errorMessage);
+ m_buildConfiguration->setError(errorMessage);
qCDebug(cmakeBuildSystemLog) << "Raw project parts created." << errorMessage;
for (RawProjectPart &rpp : rpps) {
@@ -284,22 +460,147 @@ void CMakeBuildSystem::updateProjectData(CMakeProject *p, CMakeBuildConfiguratio
rpp.setFlagsForC({kitInfo.cToolChain, rpp.flagsForC.commandLineFlags});
}
- m_cppCodeModelUpdater->update({p, kitInfo, bc->environment(), rpps});
+ m_cppCodeModelUpdater->update({p, kitInfo, m_buildConfiguration->environment(), rpps});
}
{
- updateQmlJSCodeModel(p, bc);
+ updateQmlJSCodeModel();
}
emit p->fileListChanged();
- emit bc->emitBuildTypeChanged();
+ emit m_buildConfiguration->emitBuildTypeChanged();
- bc->m_buildDirManager.resetData();
+ m_buildDirManager.resetData();
qCDebug(cmakeBuildSystemLog) << "All CMake project data up to date.";
}
-QList<ProjectExplorer::ExtraCompiler *> CMakeBuildSystem::findExtraCompilers(CMakeProject *p)
+void CMakeBuildSystem::handleParsingSucceeded()
+{
+ if (!m_buildConfiguration->isActive()) {
+ m_buildDirManager.stopParsingAndClearState();
+ return;
+ }
+
+ m_buildConfiguration->clearError();
+
+ QString errorMessage;
+ {
+ m_buildTargets = m_buildDirManager.takeBuildTargets(errorMessage);
+ checkAndReportError(errorMessage);
+ }
+
+ {
+ const CMakeConfig cmakeConfig = m_buildDirManager.takeCMakeConfiguration(errorMessage);
+ checkAndReportError(errorMessage);
+ m_buildConfiguration->setConfigurationFromCMake(cmakeConfig);
+ }
+
+ setApplicationTargets(appTargets());
+ setDeploymentData(deploymentData());
+
+ handleParsingSuccess();
+}
+
+void CMakeBuildSystem::handleParsingFailed(const QString &msg)
+{
+ m_buildConfiguration->setError(msg);
+
+ QString errorMessage;
+ m_buildConfiguration->setConfigurationFromCMake(m_buildDirManager.takeCMakeConfiguration(errorMessage));
+ // ignore errorMessage here, we already got one.
+
+ handleParsingError();
+}
+
+BuildConfiguration *CMakeBuildSystem::buildConfiguration() const
+{
+ return m_buildConfiguration;
+}
+
+CMakeBuildConfiguration *CMakeBuildSystem::cmakeBuildConfiguration() const
+{
+ return m_buildConfiguration;
+}
+
+const QList<BuildTargetInfo> CMakeBuildSystem::appTargets() const
+{
+ QList<BuildTargetInfo> appTargetList;
+ const bool forAndroid = DeviceTypeKitAspect::deviceTypeId(target()->kit())
+ == Android::Constants::ANDROID_DEVICE_TYPE;
+ for (const CMakeBuildTarget &ct : m_buildTargets) {
+ if (ct.targetType == UtilityType)
+ continue;
+
+ if (ct.targetType == ExecutableType || (forAndroid && ct.targetType == DynamicLibraryType)) {
+ BuildTargetInfo bti;
+ bti.displayName = ct.title;
+ bti.targetFilePath = ct.executable;
+ bti.projectFilePath = ct.sourceDirectory.stringAppended("/");
+ bti.workingDirectory = ct.workingDirectory;
+ bti.buildKey = ct.title;
+
+ // Workaround for QTCREATORBUG-19354:
+ bti.runEnvModifier = [this](Environment &env, bool) {
+ if (HostOsInfo::isWindowsHost()) {
+ const Kit *k = target()->kit();
+ if (const QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(k))
+ env.prependOrSetPath(qt->binPath().toString());
+ }
+ };
+
+ appTargetList.append(bti);
+ }
+ }
+
+ return appTargetList;
+}
+
+QStringList CMakeBuildSystem::buildTargetTitles() const
+{
+ return transform(m_buildTargets, &CMakeBuildTarget::title);
+}
+
+const QList<CMakeBuildTarget> &CMakeBuildSystem::buildTargets() const
+{
+ return m_buildTargets;
+}
+
+DeploymentData CMakeBuildSystem::deploymentData() const
+{
+ DeploymentData result;
+
+ QDir sourceDir = target()->project()->projectDirectory().toString();
+ QDir buildDir = buildConfiguration()->buildDirectory().toString();
+
+ QString deploymentPrefix;
+ QString deploymentFilePath = sourceDir.filePath("QtCreatorDeployment.txt");
+
+ bool hasDeploymentFile = QFileInfo::exists(deploymentFilePath);
+ if (!hasDeploymentFile) {
+ deploymentFilePath = buildDir.filePath("QtCreatorDeployment.txt");
+ hasDeploymentFile = QFileInfo::exists(deploymentFilePath);
+ }
+ if (!hasDeploymentFile)
+ return result;
+
+ deploymentPrefix = result.addFilesFromDeploymentFile(deploymentFilePath,
+ sourceDir.absolutePath());
+ for (const CMakeBuildTarget &ct : m_buildTargets) {
+ if (ct.targetType == ExecutableType || ct.targetType == DynamicLibraryType) {
+ if (!ct.executable.isEmpty()
+ && result.deployableForLocalFile(ct.executable).localFilePath() != ct.executable) {
+ result.addFile(ct.executable.toString(),
+ deploymentPrefix + buildDir.relativeFilePath(ct.executable.toFileInfo().dir().path()),
+ DeployableFile::TypeExecutable);
+ }
+ }
+ }
+
+ return result;
+}
+
+QList<ProjectExplorer::ExtraCompiler *> CMakeBuildSystem::findExtraCompilers()
{
qCDebug(cmakeBuildSystemLog) << "Finding Extra Compilers: start.";
@@ -315,6 +616,7 @@ QList<ProjectExplorer::ExtraCompiler *> CMakeBuildSystem::findExtraCompilers(CMa
<< fileExtensions;
// Find all files generated by any of the extra compilers, in a rather crude way.
+ Project *p = project();
const FilePathList fileList = p->files([&fileExtensions, p](const Node *n) {
if (!p->SourceFiles(n))
return false;
@@ -336,7 +638,7 @@ QList<ProjectExplorer::ExtraCompiler *> CMakeBuildSystem::findExtraCompilers(CMa
});
QTC_ASSERT(factory, continue);
- QStringList generated = p->filesGeneratedFrom(file.toString());
+ QStringList generated = filesGeneratedFrom(file.toString());
qCDebug(cmakeBuildSystemLog)
<< "Finding Extra Compilers: generated files:" << generated;
if (generated.isEmpty())
@@ -355,19 +657,20 @@ QList<ProjectExplorer::ExtraCompiler *> CMakeBuildSystem::findExtraCompilers(CMa
return extraCompilers;
}
-void CMakeBuildSystem::updateQmlJSCodeModel(CMakeProject *p, CMakeBuildConfiguration *bc)
+void CMakeBuildSystem::updateQmlJSCodeModel()
{
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
if (!modelManager)
return;
+ Project *p = project();
QmlJS::ModelManagerInterface::ProjectInfo projectInfo = modelManager
->defaultProjectInfoForProject(p);
projectInfo.importPaths.clear();
- const CMakeConfig &cm = bc->configurationFromCMake();
+ const CMakeConfig &cm = m_buildConfiguration->configurationFromCMake();
const QString cmakeImports = QString::fromUtf8(CMakeConfigItem::valueOf("QML_IMPORT_PATH", cm));
foreach (const QString &cmakeImport, CMakeConfigItem::cmakeSplitValue(cmakeImports))
@@ -376,4 +679,5 @@ void CMakeBuildSystem::updateQmlJSCodeModel(CMakeProject *p, CMakeBuildConfigura
modelManager->updateProjectInfo(projectInfo, p);
}
+} // namespace Internal
} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h
index c1325dcc0c..66806b1911 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h
@@ -25,8 +25,12 @@
#pragma once
+#include "builddirmanager.h"
+
#include <projectexplorer/buildsystem.h>
+namespace ProjectExplorer { class ExtraCompiler; }
+
namespace CppTools {
class CppProjectUpdater;
} // namespace CppTools
@@ -37,7 +41,6 @@ class CMakeProject;
namespace Internal {
class CMakeBuildConfiguration;
-} // namespace Internal
// --------------------------------------------------------------------
// CMakeBuildSystem:
@@ -48,12 +51,10 @@ class CMakeBuildSystem : public ProjectExplorer::BuildSystem
Q_OBJECT
public:
- explicit CMakeBuildSystem(ProjectExplorer::Project *project);
+ explicit CMakeBuildSystem(CMakeBuildConfiguration *bc);
~CMakeBuildSystem() final;
-protected:
- bool validateParsingContext(const ParsingContext &ctx) final;
- void parseProject(ParsingContext &&ctx) final;
+ void triggerParsing() final;
bool supportsAction(ProjectExplorer::Node *context,
ProjectExplorer::ProjectAction action,
@@ -62,20 +63,49 @@ protected:
bool addFiles(ProjectExplorer::Node *context,
const QStringList &filePaths, QStringList *) final;
-private:
+ QStringList filesGeneratedFrom(const QString &sourceFile) const final;
+
+ void runCMake();
+ void runCMakeAndScanProjectTree();
+
+ // Context menu actions:
+ void buildCMakeTarget(const QString &buildTarget);
// Treescanner states:
void handleTreeScanningFinished();
+ bool persistCMakeState();
+ void clearCMakeCache();
+
// Parser states:
- void handleParsingSuccess(Internal::CMakeBuildConfiguration *bc);
- void handleParsingError(Internal::CMakeBuildConfiguration *bc);
+ void handleParsingSuccess();
+ void handleParsingError();
+
+ ProjectExplorer::BuildConfiguration *buildConfiguration() const;
+ CMakeBuildConfiguration *cmakeBuildConfiguration() const;
+
+ const QList<ProjectExplorer::BuildTargetInfo> appTargets() const;
+ QStringList buildTargetTitles() const;
+ const QList<CMakeBuildTarget> &buildTargets() const;
+ ProjectExplorer::DeploymentData deploymentData() const;
+
+private:
+ std::unique_ptr<CMakeProjectNode> generateProjectTree(
+ const QList<const ProjectExplorer::FileNode *> &allFiles);
// Combining Treescanner and Parser states:
void combineScanAndParse();
- void updateProjectData(CMakeProject *p, Internal::CMakeBuildConfiguration *bc);
- QList<ProjectExplorer::ExtraCompiler *> findExtraCompilers(CMakeProject *p);
- void updateQmlJSCodeModel(CMakeProject *p, Internal::CMakeBuildConfiguration *bc);
+ void checkAndReportError(QString &errorMessage);
+
+ void updateProjectData();
+ QList<ProjectExplorer::ExtraCompiler *> findExtraCompilers();
+ void updateQmlJSCodeModel();
+
+ void handleParsingSucceeded();
+ void handleParsingFailed(const QString &msg);
+
+ CMakeBuildConfiguration *m_buildConfiguration = nullptr;
+ BuildDirManager m_buildDirManager;
ProjectExplorer::TreeScanner m_treeScanner;
QHash<QString, bool> m_mimeBinaryCache;
@@ -85,12 +115,12 @@ private:
bool m_waitingForParse = false;
bool m_combinedScanAndParseResult = false;
- ParsingContext m_currentContext;
+ ParseGuard m_currentGuard;
CppTools::CppProjectUpdater *m_cppCodeModelUpdater = nullptr;
QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers;
-
- friend class Internal::CMakeBuildConfiguration; // For handleParsing* callbacks
+ QList<CMakeBuildTarget> m_buildTargets;
};
+} // namespace Internal
} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp b/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp
index f7149a4eb2..0f48dc2830 100644
--- a/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp
@@ -66,12 +66,11 @@ void CMakeTargetLocatorFilter::prepareSearch(const QString &entry)
auto cmakeProject = qobject_cast<const CMakeProject *>(p);
if (!cmakeProject || !cmakeProject->activeTarget())
continue;
- auto bc = qobject_cast<CMakeBuildConfiguration *>(
- cmakeProject->activeTarget()->activeBuildConfiguration());
- if (!bc)
+ auto bs = qobject_cast<CMakeBuildSystem *>(cmakeProject->activeTarget()->buildSystem());
+ if (!bs)
continue;
- const QList<CMakeBuildTarget> buildTargets = bc->buildTargets();
+ const QList<CMakeBuildTarget> buildTargets = bs->buildTargets();
for (const CMakeBuildTarget &target : buildTargets) {
const int index = target.title.indexOf(entry);
if (index >= 0) {
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
index e44018affd..ddcba34840 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
@@ -68,11 +68,6 @@ namespace CMakeProjectManager {
using namespace Internal;
-static CMakeBuildConfiguration *activeBc(const CMakeProject *p)
-{
- return qobject_cast<CMakeBuildConfiguration *>(p->activeTarget() ? p->activeTarget()->activeBuildConfiguration() : nullptr);
-}
-
// QtCreator CMake Generator wishlist:
// Which make targets we need to build to get all executables
// What is the actual compiler executable
@@ -90,8 +85,6 @@ CMakeProject::CMakeProject(const FilePath &fileName)
setCanBuildProducts();
setKnowsAllBuildExecutables(false);
setHasMakeInstallEquivalent(true);
-
- setBuildSystemCreator([](Project *p) { return new CMakeBuildSystem(p); });
}
CMakeProject::~CMakeProject() = default;
@@ -108,38 +101,6 @@ Tasks CMakeProject::projectIssues(const Kit *k) const
return result;
}
-void CMakeProject::runCMake()
-{
- CMakeBuildConfiguration *bc = activeBc(this);
- if (isParsing() || !bc)
- return;
-
- BuildDirParameters parameters(bc);
- bc->m_buildDirManager.setParametersAndRequestParse(parameters,
- BuildDirManager::REPARSE_CHECK_CONFIGURATION
- | BuildDirManager::REPARSE_FORCE_CMAKE_RUN
- | BuildDirManager::REPARSE_URGENT);
-}
-
-void CMakeProject::runCMakeAndScanProjectTree()
-{
- CMakeBuildConfiguration *bc = activeBc(this);
- if (isParsing() || !bc)
- return;
-
- BuildDirParameters parameters(bc);
- bc->m_buildDirManager.setParametersAndRequestParse(parameters,
- BuildDirManager::REPARSE_CHECK_CONFIGURATION
- | BuildDirManager::REPARSE_SCAN);
-}
-
-void CMakeProject::buildCMakeTarget(const QString &buildTarget)
-{
- QTC_ASSERT(!buildTarget.isEmpty(), return);
- CMakeBuildConfiguration *bc = activeBc(this);
- if (bc)
- bc->buildTarget(buildTarget);
-}
ProjectImporter *CMakeProject::projectImporter() const
{
@@ -148,19 +109,6 @@ ProjectImporter *CMakeProject::projectImporter() const
return m_projectImporter.get();
}
-bool CMakeProject::persistCMakeState()
-{
- CMakeBuildConfiguration *bc = activeBc(this);
- return bc ? bc->m_buildDirManager.persistCMakeState() : false;
-}
-
-void CMakeProject::clearCMakeCache()
-{
- CMakeBuildConfiguration *bc = activeBc(this);
- if (bc)
- bc->m_buildDirManager.clearCache();
-}
-
bool CMakeProject::setupTarget(Target *t)
{
t->updateDefaultBuildConfigurations();
@@ -170,42 +118,6 @@ bool CMakeProject::setupTarget(Target *t)
return true;
}
-QStringList CMakeProject::filesGeneratedFrom(const QString &sourceFile) const
-{
- if (!activeTarget())
- return QStringList();
- QFileInfo fi(sourceFile);
- FilePath project = projectDirectory();
- FilePath baseDirectory = FilePath::fromString(fi.absolutePath());
-
- while (baseDirectory.isChildOf(project)) {
- const FilePath cmakeListsTxt = baseDirectory.pathAppended("CMakeLists.txt");
- if (cmakeListsTxt.exists())
- break;
- baseDirectory = baseDirectory.parentDir();
- }
-
- QDir srcDirRoot = QDir(project.toString());
- QString relativePath = srcDirRoot.relativeFilePath(baseDirectory.toString());
- QDir buildDir = QDir(activeTarget()->activeBuildConfiguration()->buildDirectory().toString());
- QString generatedFilePath = buildDir.absoluteFilePath(relativePath);
-
- if (fi.suffix() == "ui") {
- generatedFilePath += "/ui_";
- generatedFilePath += fi.completeBaseName();
- generatedFilePath += ".h";
- return QStringList(QDir::cleanPath(generatedFilePath));
- } else if (fi.suffix() == "scxml") {
- generatedFilePath += "/";
- generatedFilePath += QDir::cleanPath(fi.completeBaseName());
- return QStringList({generatedFilePath + ".h",
- generatedFilePath + ".cpp"});
- } else {
- // TODO: Other types will be added when adapters for their compilers become available.
- return QStringList();
- }
-}
-
ProjectExplorer::DeploymentKnowledge CMakeProject::deploymentKnowledge() const
{
return !files([](const ProjectExplorer::Node *n) {
@@ -232,9 +144,4 @@ MakeInstallCommand CMakeProject::makeInstallCommand(const Target *target,
return cmd;
}
-bool CMakeProject::mustUpdateCMakeStateBeforeBuild() const
-{
- return buildSystem()->isWaitingForParse();
-}
-
} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h
index 1b5dcca35c..484e860097 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.h
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.h
@@ -49,24 +49,12 @@ public:
ProjectExplorer::Tasks projectIssues(const ProjectExplorer::Kit *k) const final;
- void runCMake();
- void runCMakeAndScanProjectTree();
-
- // Context menu actions:
- void buildCMakeTarget(const QString &buildTarget);
-
ProjectExplorer::ProjectImporter *projectImporter() const final;
- bool persistCMakeState();
- void clearCMakeCache();
- bool mustUpdateCMakeStateBeforeBuild() const;
-
protected:
bool setupTarget(ProjectExplorer::Target *t) final;
private:
- QStringList filesGeneratedFrom(const QString &sourceFile) const final;
-
ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override;
ProjectExplorer::MakeInstallCommand makeInstallCommand(const ProjectExplorer::Target *target,
const QString &installRoot) override;
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp
index 10f8202ad5..be27ebb4f1 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp
@@ -78,7 +78,7 @@ CMakeManager::CMakeManager() :
command->setAttribute(Core::Command::CA_Hide);
mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_DEPLOY);
connect(m_runCMakeAction, &QAction::triggered, [this]() {
- runCMake(SessionManager::startupProject());
+ runCMake(SessionManager::startupBuildSystem());
});
command = Core::ActionManager::registerAction(m_clearCMakeCacheAction,
@@ -86,7 +86,7 @@ CMakeManager::CMakeManager() :
command->setAttribute(Core::Command::CA_Hide);
mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_DEPLOY);
connect(m_clearCMakeCacheAction, &QAction::triggered, [this]() {
- clearCMakeCache(SessionManager::startupProject());
+ clearCMakeCache(SessionManager::startupBuildSystem());
});
command = Core::ActionManager::registerAction(m_runCMakeActionContextMenu,
@@ -95,7 +95,7 @@ CMakeManager::CMakeManager() :
mproject->addAction(command, ProjectExplorer::Constants::G_PROJECT_BUILD);
msubproject->addAction(command, ProjectExplorer::Constants::G_PROJECT_BUILD);
connect(m_runCMakeActionContextMenu, &QAction::triggered, [this]() {
- runCMake(ProjectTree::currentProject());
+ runCMake(ProjectTree::currentBuildSystem());
});
m_buildFileContextMenu = new QAction(tr("Build"), this);
@@ -111,7 +111,7 @@ CMakeManager::CMakeManager() :
command->setAttribute(Core::Command::CA_Hide);
mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_DEPLOY);
connect(m_rescanProjectAction, &QAction::triggered, [this]() {
- rescanProject(ProjectTree::currentProject());
+ rescanProject(ProjectTree::currentBuildSystem());
});
m_buildFileAction = new Utils::ParameterAction(tr("Build File"), tr("Build File \"%1\""),
@@ -146,34 +146,29 @@ void CMakeManager::updateCmakeActions()
enableBuildFileMenus(ProjectTree::currentNode());
}
-void CMakeManager::clearCMakeCache(Project *project)
+void CMakeManager::clearCMakeCache(BuildSystem *buildSystem)
{
- auto cmakeProject = qobject_cast<CMakeProject *>(project);
- if (!cmakeProject || !cmakeProject->activeTarget() || !cmakeProject->activeTarget()->activeBuildConfiguration())
- return;
+ auto cmakeBuildSystem = dynamic_cast<CMakeBuildSystem *>(buildSystem);
+ QTC_ASSERT(cmakeBuildSystem, return);
- cmakeProject->clearCMakeCache();
+ cmakeBuildSystem->clearCMakeCache();
}
-void CMakeManager::runCMake(Project *project)
+void CMakeManager::runCMake(BuildSystem *buildSystem)
{
- auto cmakeProject = qobject_cast<CMakeProject *>(project);
- if (!cmakeProject || !cmakeProject->activeTarget() || !cmakeProject->activeTarget()->activeBuildConfiguration())
- return;
-
- if (!ProjectExplorerPlugin::saveModifiedFiles())
- return;
+ auto cmakeBuildSystem = dynamic_cast<CMakeBuildSystem *>(buildSystem);
+ QTC_ASSERT(cmakeBuildSystem, return);
- cmakeProject->runCMake();
+ if (ProjectExplorerPlugin::saveModifiedFiles())
+ cmakeBuildSystem->runCMake();
}
-void CMakeManager::rescanProject(Project *project)
+void CMakeManager::rescanProject(BuildSystem *buildSystem)
{
- auto cmakeProject = qobject_cast<CMakeProject *>(project);
- if (!cmakeProject || !cmakeProject->activeTarget() || !cmakeProject->activeTarget()->activeBuildConfiguration())
- return;
+ auto cmakeBuildSystem = dynamic_cast<CMakeBuildSystem *>(buildSystem);
+ QTC_ASSERT(cmakeBuildSystem, return);
- cmakeProject->runCMakeAndScanProjectTree();// by my experience: every rescan run requires cmake run too
+ cmakeBuildSystem->runCMakeAndScanProjectTree();// by my experience: every rescan run requires cmake run too
}
void CMakeManager::updateBuildFileAction()
@@ -235,14 +230,15 @@ void CMakeManager::buildFile(Node *node)
CMakeTargetNode *targetNode = dynamic_cast<CMakeTargetNode *>(fileNode->parentProjectNode());
if (!targetNode)
return;
- auto cmakeProject = static_cast<CMakeProject *>(project);
- Target *target = cmakeProject->activeTarget();
+ Target *target = project->activeTarget();
+ QTC_ASSERT(target, return);
const QString generator = CMakeGeneratorKitAspect::generator(target->kit());
const QString relativeSource = fileNode->filePath().relativeChildPath(targetNode->filePath()).toString();
const QString objExtension = Utils::HostOsInfo::isWindowsHost() ? QString(".obj") : QString(".o");
Utils::FilePath targetBase;
+ BuildConfiguration *bc = target->activeBuildConfiguration();
+ QTC_ASSERT(bc, return);
if (generator == "Ninja") {
- BuildConfiguration *bc = target->activeBuildConfiguration();
const Utils::FilePath relativeBuildDir = targetNode->buildDirectory().relativeChildPath(
bc->buildDirectory());
targetBase = relativeBuildDir
@@ -253,7 +249,9 @@ void CMakeManager::buildFile(Node *node)
.arg(generator));
return;
}
- cmakeProject->buildCMakeTarget(targetBase.pathAppended(relativeSource).toString() + objExtension);
+
+ static_cast<CMakeBuildSystem *>(bc->buildSystem())
+ ->buildCMakeTarget(targetBase.pathAppended(relativeSource).toString() + objExtension);
}
void CMakeManager::buildFileContextMenu()
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h
index eab78b190a..db3b10b6e2 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h
@@ -45,9 +45,9 @@ public:
private:
void updateCmakeActions();
- void clearCMakeCache(ProjectExplorer::Project *project);
- void runCMake(ProjectExplorer::Project *project);
- void rescanProject(ProjectExplorer::Project *project);
+ void clearCMakeCache(ProjectExplorer::BuildSystem *buildSystem);
+ void runCMake(ProjectExplorer::BuildSystem *buildSystem);
+ void rescanProject(ProjectExplorer::BuildSystem *buildSystem);
void buildFileContextMenu();
void buildFile(ProjectExplorer::Node *node = nullptr);
void updateBuildFileAction();
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
index 9943ca5784..46c50104ed 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
@@ -265,7 +265,10 @@ Utils::optional<Utils::FilePath> CMakeTargetNode::visibleAfterAddFileAction() co
void CMakeTargetNode::build()
{
- static_cast<CMakeProject *>(getProject())->buildCMakeTarget(displayName());
+ Project *p = getProject();
+ Target *t = p ? p->activeTarget() : nullptr;
+ if (t)
+ static_cast<CMakeBuildSystem *>(t->buildSystem())->buildCMakeTarget(displayName());
}
void CMakeTargetNode::setTargetInformation(const QList<Utils::FilePath> &artifacts,
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
index 9eeeb71048..701b192b5b 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
@@ -47,6 +47,7 @@
#include <projectexplorer/projectmanager.h>
#include <projectexplorer/projecttree.h>
#include <projectexplorer/runcontrol.h>
+#include <projectexplorer/target.h>
#include <texteditor/snippets/snippetprovider.h>
@@ -70,8 +71,6 @@ public:
ParameterAction::AlwaysEnabled/*handled manually*/
};
- QMetaObject::Connection m_actionConnect;
-
CMakeSettingsPage settingsPage;
CMakeSpecificSettingsPage specificSettings{CMakeProjectPlugin::projectTypeSpecificSettings()};
@@ -129,6 +128,13 @@ bool CMakeProjectPlugin::initialize(const QStringList & /*arguments*/, QString *
connect(ProjectTree::instance(), &ProjectTree::currentNodeChanged,
this, &CMakeProjectPlugin::updateContextActions);
+ connect(&d->buildTargetContextAction, &ParameterAction::triggered, this, [] {
+ if (auto bs = qobject_cast<CMakeBuildSystem *>(ProjectTree::currentBuildSystem())) {
+ auto targetNode = dynamic_cast<const CMakeTargetNode *>(ProjectTree::currentNode());
+ bs->buildCMakeTarget(targetNode ? targetNode->displayName() : QString());
+ }
+ });
+
return true;
}
@@ -140,24 +146,13 @@ void CMakeProjectPlugin::extensionsInitialized()
void CMakeProjectPlugin::updateContextActions()
{
- Project *project = ProjectTree::currentProject();
- const Node *node = ProjectTree::currentNode();
- auto targetNode = dynamic_cast<const CMakeTargetNode *>(node);
- // as targetNode can be deleted while the menu is open, we keep only the
+ auto targetNode = dynamic_cast<const CMakeTargetNode *>(ProjectTree::currentNode());
const QString targetDisplayName = targetNode ? targetNode->displayName() : QString();
- auto cmProject = dynamic_cast<CMakeProject *>(project);
// Build Target:
- disconnect(d->m_actionConnect);
d->buildTargetContextAction.setParameter(targetDisplayName);
d->buildTargetContextAction.setEnabled(targetNode);
d->buildTargetContextAction.setVisible(targetNode);
- if (cmProject && targetNode) {
- d->m_actionConnect = connect(&d->buildTargetContextAction, &ParameterAction::triggered,
- cmProject, [cmProject, targetDisplayName]() {
- cmProject->buildCMakeTarget(targetDisplayName);
- });
- }
}
} // Internal
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<ProjectNode> &root,
} // anonymous namespace
-void CompilationDatabaseProject::buildTreeAndProjectParts()
+CompilationDatabaseBuildSystem::CompilationDatabaseBuildSystem(Target *target)
+ : BuildSystem(target)
+ , m_cppCodeModelUpdater(std::make_unique<CppTools::CppProjectUpdater>())
+ , 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<CompilationDatabaseProject *>(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<ProjectNode>(projectDirectory());
- createTree(root, rootProjectDirectory(), rpps, m_parser->scannedFiles());
+ createTree(root, project()->rootProjectDirectory(), rpps, m_parser->scannedFiles());
root->addNode(std::make_unique<FileNode>(projectFilePath(), FileType::Project));
@@ -389,43 +427,26 @@ void CompilationDatabaseProject::buildTreeAndProjectParts()
root->addNode(std::make_unique<FileNode>(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<CppTools::CppProjectUpdater>())
- , 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<CompilationDatabaseProject *>(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 <projectexplorer/buildconfiguration.h>
+#include <projectexplorer/buildsystem.h>
#include <projectexplorer/project.h>
+
#include <texteditor/texteditor.h>
+
#include <utils/filesystemwatcher.h>
#include <QFutureWatcher>
@@ -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<ProjectExplorer::Kit> 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<void> m_parserWatcher;
std::unique_ptr<CppTools::CppProjectUpdater> m_cppCodeModelUpdater;
- std::unique_ptr<ProjectExplorer::Kit> 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 <projectexplorer/project.h>
+#include <projectexplorer/buildsystem.h>
#include <utils/fileutils.h>
@@ -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
diff --git a/src/plugins/designer/codemodelhelpers.cpp b/src/plugins/designer/codemodelhelpers.cpp
index 5f3422e412..f57f1081d2 100644
--- a/src/plugins/designer/codemodelhelpers.cpp
+++ b/src/plugins/designer/codemodelhelpers.cpp
@@ -27,15 +27,19 @@
#include <cpptools/cppmodelmanager.h>
+#include <projectexplorer/buildsystem.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/session.h>
+#include <projectexplorer/target.h>
#include <QCoreApplication>
#include <QDebug>
// Debug helpers for code model. @todo: Move to some CppTools library?
+using namespace ProjectExplorer;
+
typedef QMap<QString, QStringList> DependencyMap;
typedef CPlusPlus::Document::Ptr DocumentPtr;
typedef QList<CPlusPlus::Symbol *> SymbolList;
@@ -46,11 +50,15 @@ static const char setupUiC[] = "setupUi";
// Find the generated "ui_form.h" header of the form via project.
static QString generatedHeaderOf(const QString &uiFileName)
{
- if (const ProjectExplorer::Project *uiProject =
- ProjectExplorer::SessionManager::projectForFile(Utils::FilePath::fromString(uiFileName))) {
- QStringList files = uiProject->filesGeneratedFrom(uiFileName);
- if (!files.isEmpty()) // There should be at most one header generated from a .ui
- return files.front();
+ if (const Project *uiProject =
+ SessionManager::projectForFile(Utils::FilePath::fromString(uiFileName))) {
+ if (Target *t = uiProject->activeTarget()) {
+ if (BuildSystem *bs = t->buildSystem()) {
+ QStringList files = bs->filesGeneratedFrom(uiFileName);
+ if (!files.isEmpty()) // There should be at most one header generated from a .ui
+ return files.front();
+ }
+ }
}
return QString();
}
diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp
index 312a9cfb1e..7a7e7c56e9 100644
--- a/src/plugins/genericprojectmanager/genericproject.cpp
+++ b/src/plugins/genericprojectmanager/genericproject.cpp
@@ -120,9 +120,11 @@ private:
class GenericBuildSystem : public BuildSystem
{
public:
- explicit GenericBuildSystem(Project *project);
+ explicit GenericBuildSystem(Target *target);
~GenericBuildSystem();
+ void triggerParsing() final;
+
bool supportsAction(Node *, ProjectAction action, const Node *) const final
{
return action == AddNewFile
@@ -136,8 +138,6 @@ public:
bool renameFile(Node *, const QString &filePath, const QString &newFilePath) final;
bool addFiles(Node *, const QStringList &filePaths, QStringList *) final;
- GenericProject *project() const { return static_cast<GenericProject *>(BuildSystem::project()); }
-
FilePath filesFilePath() const { return ::FilePath::fromString(m_filesFileName); }
void refresh(RefreshOptions options);
@@ -172,7 +172,9 @@ private:
CppTools::CppProjectUpdaterInterface *m_cppCodeModelUpdater = nullptr;
- Utils::FileSystemWatcher * const m_deployFileWatcher = nullptr;
+ Utils::FileSystemWatcher m_deployFileWatcher;
+
+ ParseGuard m_guard;
};
@@ -194,11 +196,11 @@ GenericProject::GenericProject(const Utils::FilePath &fileName)
setId(Constants::GENERICPROJECT_ID);
setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
setDisplayName(fileName.toFileInfo().completeBaseName());
- setBuildSystemCreator([](Project *p) { return new GenericBuildSystem(p); });
+ setBuildSystemCreator([](Target *t) { return new GenericBuildSystem(t); });
}
-GenericBuildSystem::GenericBuildSystem(Project *project)
- : BuildSystem(project)
+GenericBuildSystem::GenericBuildSystem(Target *target)
+ : BuildSystem(target)
{
QObject *projectUpdaterFactory = ExtensionSystem::PluginManager::getObjectByName(
"CppProjectUpdaterFactory");
@@ -211,7 +213,7 @@ GenericBuildSystem::GenericBuildSystem(Project *project)
QTC_CHECK(successFullyCreatedProjectUpdater);
}
- connect(project, &Project::projectFileIsDirty, this, [this](const FilePath &p) {
+ connect(target->project(), &Project::projectFileIsDirty, this, [this](const FilePath &p) {
if (p.endsWith(".files"))
refresh(Files);
else if (p.endsWith(".includes") || p.endsWith(".config") || p.endsWith(".cxxflags")
@@ -242,18 +244,16 @@ GenericBuildSystem::GenericBuildSystem(Project *project)
QTC_CHECK(writeFile(m_cflagsFileName, Constants::GENERICPROJECT_CFLAGS_FILE_TEMPLATE));
}
- project->setExtraProjectFiles({FilePath::fromString(m_filesFileName),
- FilePath::fromString(m_includesFileName),
- FilePath::fromString(m_configFileName),
- FilePath::fromString(m_cxxflagsFileName),
- FilePath::fromString(m_cflagsFileName)});
+ project()->setExtraProjectFiles({FilePath::fromString(m_filesFileName),
+ FilePath::fromString(m_includesFileName),
+ FilePath::fromString(m_configFileName),
+ FilePath::fromString(m_cxxflagsFileName),
+ FilePath::fromString(m_cflagsFileName)});
- connect(m_deployFileWatcher, &FileSystemWatcher::fileChanged,
+ connect(&m_deployFileWatcher, &FileSystemWatcher::fileChanged,
this, &GenericBuildSystem::updateDeploymentData);
- connect(project, &Project::activeTargetChanged, this, [this] { refresh(Everything); });
-
- connect(project, &Project::activeBuildConfigurationChanged, this, [this] { refresh(Everything); });
+ connect(target, &Target::activeBuildConfigurationChanged, this, [this] { refresh(Everything); });
}
GenericBuildSystem::~GenericBuildSystem()
@@ -261,6 +261,12 @@ GenericBuildSystem::~GenericBuildSystem()
delete m_cppCodeModelUpdater;
}
+void GenericBuildSystem::triggerParsing()
+{
+ m_guard = guardParsingRun();
+ refresh(Everything);
+}
+
static QStringList readLines(const QString &absoluteFileName)
{
QStringList lines;
@@ -455,7 +461,7 @@ FilePath GenericBuildSystem::findCommonSourceRoot()
void GenericBuildSystem::refresh(RefreshOptions options)
{
- Project::ParseGuard guard = project()->guardParsingRun();
+ ParseGuard guard = guardParsingRun();
parse(options);
if (options & Files) {
@@ -504,9 +510,7 @@ void GenericBuildSystem::refresh(RefreshOptions options)
QStringList GenericBuildSystem::processEntries(const QStringList &paths,
QHash<QString, QString> *map) const
{
- Target *target = project()->activeTarget();
- const BuildConfiguration *const buildConfig = target ? target->activeBuildConfiguration()
- : nullptr;
+ const BuildConfiguration *const buildConfig = target()->activeBuildConfiguration();
const Utils::Environment buildEnv = buildConfig ? buildConfig->environment()
: Utils::Environment::systemEnvironment();
@@ -514,8 +518,8 @@ QStringList GenericBuildSystem::processEntries(const QStringList &paths,
const Utils::MacroExpander *expander = project()->macroExpander();
if (buildConfig)
expander = buildConfig->macroExpander();
- else if (target)
- expander = target->macroExpander();
+ else
+ expander = target()->macroExpander();
const QDir projectDir(projectDirectory().toString());
@@ -560,7 +564,7 @@ void GenericBuildSystem::refreshCppCodeModel()
rpp.setFlagsForC({nullptr, m_cflags});
rpp.setFiles(m_files);
- m_cppCodeModelUpdater->update({project(), kitInfo, project()->activeParseEnvironment(), {rpp}});
+ m_cppCodeModelUpdater->update({project(), kitInfo, activeParseEnvironment(), {rpp}});
}
void GenericBuildSystem::updateDeploymentData()
@@ -581,11 +585,11 @@ void GenericBuildSystem::updateDeploymentData()
DeploymentData deploymentData;
deploymentData.addFilesFromDeploymentFile(deploymentFilePath.toString(),
projectDirectory().toString());
- project()->activeTarget()->setDeploymentData(deploymentData);
- if (m_deployFileWatcher->files() != QStringList(deploymentFilePath.toString())) {
- m_deployFileWatcher->removeFiles(m_deployFileWatcher->files());
- m_deployFileWatcher->addFile(deploymentFilePath.toString(),
- FileSystemWatcher::WatchModifiedDate);
+ setDeploymentData(deploymentData);
+ if (m_deployFileWatcher.files() != QStringList(deploymentFilePath.toString())) {
+ m_deployFileWatcher.removeFiles(m_deployFileWatcher.files());
+ m_deployFileWatcher.addFile(deploymentFilePath.toString(),
+ FileSystemWatcher::WatchModifiedDate);
}
}
}
@@ -622,7 +626,9 @@ Project::RestoreResult GenericProject::fromMap(const QVariantMap &map, QString *
t->addRunConfiguration(new CustomExecutableRunConfiguration(t));
}
- static_cast<GenericBuildSystem *>(buildSystem())->refresh(Everything);
+ if (Target *t = activeTarget())
+ static_cast<GenericBuildSystem *>(t->buildSystem())->refresh(Everything);
+
return RestoreResult::Ok;
}
@@ -637,7 +643,10 @@ bool GenericProjectFile::reload(QString *errorString, IDocument::ReloadFlag flag
Q_UNUSED(flag)
if (type == TypePermissions)
return true;
- static_cast<GenericBuildSystem *>(m_project->buildSystem())->refresh(m_options);
+
+ if (Target *t = m_project->activeTarget())
+ static_cast<GenericBuildSystem *>(t->buildSystem())->refresh(m_options);
+
return true;
}
@@ -646,14 +655,18 @@ void GenericProject::editFilesTriggered()
SelectableFilesDialogEditFiles sfd(projectDirectory(),
files(Project::AllFiles),
ICore::mainWindow());
- if (sfd.exec() == QDialog::Accepted)
- static_cast<GenericBuildSystem *>(buildSystem())
- ->setFiles(transform(sfd.selectedFiles(), &FilePath::toString));
+ if (sfd.exec() == QDialog::Accepted) {
+ if (Target *t = activeTarget()) {
+ auto bs = static_cast<GenericBuildSystem *>(t->buildSystem());
+ bs->setFiles(transform(sfd.selectedFiles(), &FilePath::toString));
+ }
+ }
}
void GenericProject::removeFilesTriggered(const QStringList &filesToRemove)
{
- static_cast<GenericBuildSystem *>(buildSystem())->removeFiles(filesToRemove);
+ if (Target *t = activeTarget())
+ static_cast<GenericBuildSystem *>(t->buildSystem())->removeFiles(filesToRemove);
}
} // namespace Internal
diff --git a/src/plugins/ios/iosrunconfiguration.cpp b/src/plugins/ios/iosrunconfiguration.cpp
index fb1389b969..96b6d17bc1 100644
--- a/src/plugins/ios/iosrunconfiguration.cpp
+++ b/src/plugins/ios/iosrunconfiguration.cpp
@@ -139,19 +139,17 @@ void IosRunConfiguration::updateDisplayNames()
aspect<ExecutableAspect>()->setExecutable(localExecutable());
}
-void IosRunConfiguration::updateEnabledState()
+bool IosRunConfiguration::isEnabled() const
{
Core::Id devType = DeviceTypeKitAspect::deviceTypeId(target()->kit());
- if (devType != Constants::IOS_DEVICE_TYPE && devType != Constants::IOS_SIMULATOR_TYPE) {
- setEnabled(false);
- return;
- }
+ if (devType != Constants::IOS_DEVICE_TYPE && devType != Constants::IOS_SIMULATOR_TYPE)
+ return false;
+
IDevice::ConstPtr dev = DeviceKitAspect::device(target()->kit());
- if (dev.isNull() || dev->deviceState() != IDevice::DeviceReadyToUse) {
- setEnabled(false);
- return;
- }
- return RunConfiguration::updateEnabledState();
+ if (dev.isNull() || dev->deviceState() != IDevice::DeviceReadyToUse)
+ return false;
+
+ return true;
}
QString IosRunConfiguration::applicationName() const
diff --git a/src/plugins/ios/iosrunconfiguration.h b/src/plugins/ios/iosrunconfiguration.h
index b9b44ecf5c..11746fd316 100644
--- a/src/plugins/ios/iosrunconfiguration.h
+++ b/src/plugins/ios/iosrunconfiguration.h
@@ -55,7 +55,7 @@ public:
private:
friend class IosDeviceTypeAspect;
void updateDisplayNames();
- void updateEnabledState() final;
+ bool isEnabled() const final;
IosDeviceTypeAspect *m_deviceTypeAspect = nullptr;
};
diff --git a/src/plugins/nim/nimconstants.h b/src/plugins/nim/nimconstants.h
index 61b281fbc7..a8c3863ca8 100644
--- a/src/plugins/nim/nimconstants.h
+++ b/src/plugins/nim/nimconstants.h
@@ -40,10 +40,6 @@ const char C_EDITOR_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("OpenWith::Editors", "Nim
const char C_NIMTOOLCHAIN_TYPEID[] = "Nim.NimToolChain";
const char C_NIMTOOLCHAIN_COMPILER_COMMAND_KEY[] = "Nim.NimToolChain.CompilerCommand";
-// NimbleProject
-const char C_NIMBLEPROJECT_TASKS[] = "Nim.NimbleProject.Tasks";
-const char C_NIMBLEPROJECT_METADATA[] = "Nim.NimbleProject.Metadata";
-
// NimProject
const char C_NIMPROJECT_EXCLUDEDFILES[] = "Nim.NimProjectExcludedFiles";
diff --git a/src/plugins/nim/project/nimblebuildconfiguration.cpp b/src/plugins/nim/project/nimblebuildconfiguration.cpp
index 8b947ce3cc..14e134672f 100644
--- a/src/plugins/nim/project/nimblebuildconfiguration.cpp
+++ b/src/plugins/nim/project/nimblebuildconfiguration.cpp
@@ -24,9 +24,11 @@
****************************************************************************/
#include "nimblebuildconfiguration.h"
+
#include "nimconstants.h"
#include "nimblebuildstep.h"
#include "nimbleproject.h"
+#include "nimblebuildsystem.h"
#include <projectexplorer/buildinfo.h>
#include <projectexplorer/buildstep.h>
@@ -52,10 +54,8 @@ NimbleBuildConfiguration::NimbleBuildConfiguration(Target *target, Core::Id id)
setConfigWidgetHasFrame(true);
setBuildDirectorySettingsKey("Nim.NimbleBuildConfiguration.BuildDirectory");
- m_nimbleProject = dynamic_cast<NimbleProject*>(project());
- QTC_ASSERT(m_nimbleProject, return);
- QObject::connect(m_nimbleProject, &NimbleProject::metadataChanged, this, &NimbleBuildConfiguration::updateApplicationTargets);
- updateApplicationTargets();
+ m_nimbleBuildSystem = dynamic_cast<NimbleBuildSystem *>(buildSystem());
+ QTC_ASSERT(m_nimbleBuildSystem, return);
}
BuildConfiguration::BuildType NimbleBuildConfiguration::buildType() const
@@ -72,35 +72,13 @@ void NimbleBuildConfiguration::initialize()
setBuildDirectory(project()->projectDirectory());
// Don't add a nimble build step when the package has no binaries (i.e a library package)
- if (!m_nimbleProject->metadata().bin.empty())
+ if (!m_nimbleBuildSystem->metadata().bin.empty())
{
BuildStepList *buildSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
buildSteps->appendStep(new NimbleBuildStep(buildSteps));
}
}
-void NimbleBuildConfiguration::updateApplicationTargets()
-{
- QTC_ASSERT(m_nimbleProject, return);
-
- const NimbleMetadata &metaData = m_nimbleProject->metadata();
- const FilePath &projectDir = project()->projectDirectory();
- const FilePath binDir = projectDir.pathAppended(metaData.binDir);
- const FilePath srcDir = projectDir.pathAppended("src");
-
- QList<BuildTargetInfo> targets = Utils::transform(metaData.bin, [&](const QString &bin){
- BuildTargetInfo info = {};
- info.displayName = bin;
- info.targetFilePath = binDir.pathAppended(HostOsInfo::withExecutableSuffix(bin));
- info.projectFilePath = srcDir.pathAppended(bin).stringAppended(".nim");
- info.workingDirectory = binDir;
- info.buildKey = bin;
- return info;
- });
-
- target()->setApplicationTargets(std::move(targets));
-}
-
bool NimbleBuildConfiguration::fromMap(const QVariantMap &map)
{
m_buildType = static_cast<BuildType>(map[Constants::C_NIMBLEBUILDCONFIGURATION_BUILDTYPE].toInt());
diff --git a/src/plugins/nim/project/nimblebuildconfiguration.h b/src/plugins/nim/project/nimblebuildconfiguration.h
index 5ba6b5c218..f7e7dc4dc7 100644
--- a/src/plugins/nim/project/nimblebuildconfiguration.h
+++ b/src/plugins/nim/project/nimblebuildconfiguration.h
@@ -30,7 +30,7 @@
namespace Nim {
-class NimbleProject;
+class NimbleBuildSystem;
class NimbleBuildConfiguration : public ProjectExplorer::BuildConfiguration
{
@@ -49,10 +49,8 @@ class NimbleBuildConfiguration : public ProjectExplorer::BuildConfiguration
protected:
void initialize() override;
- void updateApplicationTargets();
-
private:
- NimbleProject *m_nimbleProject = nullptr;
+ NimbleBuildSystem *m_nimbleBuildSystem = nullptr;
BuildType m_buildType;
};
diff --git a/src/plugins/nim/project/nimblebuildsystem.cpp b/src/plugins/nim/project/nimblebuildsystem.cpp
index d968b50391..2ec092bd56 100644
--- a/src/plugins/nim/project/nimblebuildsystem.cpp
+++ b/src/plugins/nim/project/nimblebuildsystem.cpp
@@ -26,6 +26,8 @@
#include "nimblebuildsystem.h"
#include "nimbleproject.h"
+#include <projectexplorer/target.h>
+
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
@@ -38,6 +40,9 @@ using namespace Utils;
namespace {
+const char C_NIMBLEPROJECT_TASKS[] = "Nim.NimbleProject.Tasks";
+const char C_NIMBLEPROJECT_METADATA[] = "Nim.NimbleProject.Metadata";
+
std::vector<NimbleTask> parseTasks(const QString &nimblePath, const QString &workingDirectory)
{
QProcess process;
@@ -102,28 +107,25 @@ NimbleMetadata parseMetadata(const QString &nimblePath, const QString &workingDi
}
-NimbleBuildSystem::NimbleBuildSystem(Project *project)
- : NimBuildSystem(project)
+NimbleBuildSystem::NimbleBuildSystem(Target *target)
+ : NimBuildSystem(target)
{
// Not called in parseProject due to nimble behavior to create temporary
// files in project directory. This creation in turn stimulate the fs watcher
// that in turn causes project parsing (thus a loop if invoke in parseProject).
// For this reason we call this function manually during project creation
// See https://github.com/nim-lang/nimble/issues/720
- m_directoryWatcher.addFile(this->project()->projectFilePath().toString(),
- FileSystemWatcher::WatchModifiedDate);
+ m_directoryWatcher.addFile(projectFilePath().toString(), FileSystemWatcher::WatchModifiedDate);
+
connect(&m_directoryWatcher, &FileSystemWatcher::fileChanged, this, [this](const QString &path) {
- if (path == this->project()->projectFilePath().toString()) {
+ if (path == project()->projectFilePath().toString()) {
updateProject();
}
});
+
updateProject();
}
-void NimbleBuildSystem::parseProject(BuildSystem::ParsingContext &&ctx)
-{
- NimBuildSystem::parseProject(std::move(ctx));
-}
void NimbleBuildSystem::updateProject()
{
@@ -133,14 +135,82 @@ void NimbleBuildSystem::updateProject()
void NimbleBuildSystem::updateProjectTasks()
{
- auto prj = dynamic_cast<NimbleProject*>(project());
- QTC_ASSERT(prj, return);
- prj->setTasks(parseTasks(QStandardPaths::findExecutable("nimble"), project()->projectDirectory().toString()));
+ setTasks(parseTasks(QStandardPaths::findExecutable("nimble"), projectDirectory().toString()));
}
void NimbleBuildSystem::updateProjectMetaData()
{
- auto prj = dynamic_cast<NimbleProject*>(project());
- QTC_ASSERT(prj, return);
- prj->setMetadata(parseMetadata(QStandardPaths::findExecutable("nimble"), project()->projectDirectory().toString()));
+ setMetadata(parseMetadata(QStandardPaths::findExecutable("nimble"), projectDirectory().toString()));
+}
+
+void NimbleBuildSystem::updateApplicationTargets()
+{
+ const NimbleMetadata &metaData = metadata();
+ const FilePath &projectDir = project()->projectDirectory();
+ const FilePath binDir = projectDir.pathAppended(metaData.binDir);
+ const FilePath srcDir = projectDir.pathAppended("src");
+
+ QList<BuildTargetInfo> targets = Utils::transform(metaData.bin, [&](const QString &bin){
+ BuildTargetInfo info = {};
+ info.displayName = bin;
+ info.targetFilePath = binDir.pathAppended(HostOsInfo::withExecutableSuffix(bin));
+ info.projectFilePath = srcDir.pathAppended(bin).stringAppended(".nim");
+ info.workingDirectory = binDir;
+ info.buildKey = bin;
+ return info;
+ });
+
+ setApplicationTargets(std::move(targets));
+}
+
+std::vector<NimbleTask> NimbleBuildSystem::tasks() const
+{
+ return m_tasks;
+}
+
+NimbleMetadata NimbleBuildSystem::metadata() const
+{
+ return m_metadata;
+}
+
+void NimbleBuildSystem::setTasks(std::vector<NimbleTask> tasks)
+{
+ if (tasks == m_tasks)
+ return;
+ m_tasks = std::move(tasks);
+ emit tasksChanged();
+ emit target()->targetPropertiesChanged();
+}
+
+void NimbleBuildSystem::setMetadata(NimbleMetadata metadata)
+{
+ if (m_metadata == metadata)
+ return;
+ m_metadata = std::move(metadata);
+
+ updateApplicationTargets();
+}
+
+void NimbleBuildSystem::saveSettings()
+{
+ QStringList result;
+ for (const NimbleTask &task : m_tasks) {
+ result.push_back(task.name);
+ result.push_back(task.description);
+ }
+
+ project()->setNamedSettings(C_NIMBLEPROJECT_TASKS, result);
+}
+
+void NimbleBuildSystem::loadSettings()
+{
+ QStringList list = project()->namedSettings(C_NIMBLEPROJECT_TASKS).toStringList();
+
+ m_tasks.clear();
+ if (list.size() % 2 != 0)
+ return;
+
+ std::vector<NimbleTask> result;
+ for (int i = 0; i < list.size(); i += 2)
+ result.push_back({list[i], list[i + 1]});
}
diff --git a/src/plugins/nim/project/nimblebuildsystem.h b/src/plugins/nim/project/nimblebuildsystem.h
index 45c540598e..36beb27e91 100644
--- a/src/plugins/nim/project/nimblebuildsystem.h
+++ b/src/plugins/nim/project/nimblebuildsystem.h
@@ -29,19 +29,55 @@
namespace Nim {
+struct NimbleTask
+{
+ QString name;
+ QString description;
+
+ bool operator==(const NimbleTask &o) const {
+ return name == o.name && description == o.description;
+ }
+};
+
+struct NimbleMetadata
+{
+ QStringList bin;
+ QString binDir;
+ QString srcDir;
+
+ bool operator==(const NimbleMetadata &o) const {
+ return bin == o.bin && binDir == o.binDir && srcDir == o.srcDir;
+ }
+};
+
class NimbleBuildSystem : public NimBuildSystem
{
Q_OBJECT
public:
- NimbleBuildSystem(ProjectExplorer::Project *project);
+ NimbleBuildSystem(ProjectExplorer::Target *target);
+
+ std::vector<NimbleTask> tasks() const;
+
+ NimbleMetadata metadata() const;
-protected:
- void parseProject(ParsingContext &&ctx) override;
+ void setTasks(std::vector<NimbleTask> tasks);
+ void setMetadata(NimbleMetadata metadata);
+
+signals:
+ void tasksChanged();
+
+private:
+ void loadSettings() override;
+ void saveSettings() override;
void updateProject();
void updateProjectTasks();
void updateProjectMetaData();
+ void updateApplicationTargets();
+
+ NimbleMetadata m_metadata;
+ std::vector<NimbleTask> m_tasks;
};
}
diff --git a/src/plugins/nim/project/nimbleproject.cpp b/src/plugins/nim/project/nimbleproject.cpp
index 9003e55a93..cc77d94f36 100644
--- a/src/plugins/nim/project/nimbleproject.cpp
+++ b/src/plugins/nim/project/nimbleproject.cpp
@@ -41,70 +41,7 @@ NimbleProject::NimbleProject(const Utils::FilePath &fileName)
setDisplayName(fileName.toFileInfo().completeBaseName());
// ensure debugging is enabled (Nim plugin translates nim code to C code)
setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
- setBuildSystemCreator([] (Project *p) { return new NimbleBuildSystem(p); });
+ setBuildSystemCreator([] (Target *t) { return new NimbleBuildSystem(t); });
}
-std::vector<NimbleTask> NimbleProject::tasks() const
-{
- return m_tasks;
-}
-
-NimbleMetadata NimbleProject::metadata() const
-{
- return m_metadata;
-}
-
-void NimbleProject::setTasks(std::vector<NimbleTask> tasks)
-{
- if (tasks == m_tasks)
- return;
- m_tasks = std::move(tasks);
- emit tasksChanged(m_tasks);
-}
-
-void NimbleProject::setMetadata(NimbleMetadata metadata)
-{
- if (m_metadata == metadata)
- return;
- m_metadata = std::move(metadata);
- emit metadataChanged(m_metadata);
-}
-QVariantMap NimbleProject::toMap() const
-{
- QVariantMap result = Project::toMap();
- result[Constants::C_NIMPROJECT_EXCLUDEDFILES] = static_cast<NimBuildSystem *>(buildSystem())
- ->excludedFiles();
- result[Constants::C_NIMBLEPROJECT_TASKS] = toStringList(m_tasks);
- return result;
-}
-
-Project::RestoreResult NimbleProject::fromMap(const QVariantMap &map, QString *errorMessage)
-{
- static_cast<NimBuildSystem *>(buildSystem())
- ->setExcludedFiles(map.value(Constants::C_NIMPROJECT_EXCLUDEDFILES).toStringList());
- Project::RestoreResult result = Project::RestoreResult::Error;
- std::tie(result, m_tasks) = fromStringList(map.value(Constants::C_NIMBLEPROJECT_TASKS).toStringList());
- return result == Project::RestoreResult::Ok ? Project::fromMap(map, errorMessage) : result;
-}
-
-QStringList NimbleProject::toStringList(const std::vector<NimbleTask> &tasks)
-{
- QStringList result;
- for (const NimbleTask &task : tasks) {
- result.push_back(task.name);
- result.push_back(task.description);
- }
- return result;
-}
-
-std::tuple<Project::RestoreResult, std::vector<NimbleTask>> NimbleProject::fromStringList(const QStringList &list)
-{
- if (list.size() % 2 != 0)
- return std::make_tuple(Project::RestoreResult::Error, std::vector<NimbleTask>());
-
- std::vector<NimbleTask> result;
- for (int i = 0; i < list.size(); i += 2)
- result.push_back({list[i], list[i + 1]});
- return std::make_tuple(Project::RestoreResult::Ok, result);
-}
diff --git a/src/plugins/nim/project/nimbleproject.h b/src/plugins/nim/project/nimbleproject.h
index e3c7cf9358..5ace87a47f 100644
--- a/src/plugins/nim/project/nimbleproject.h
+++ b/src/plugins/nim/project/nimbleproject.h
@@ -25,64 +25,17 @@
#pragma once
+#include <projectexplorer/buildsystem.h>
#include <projectexplorer/project.h>
namespace Nim {
-struct NimbleTask
-{
- QString name;
- QString description;
-
- bool operator==(const NimbleTask &o) const {
- return name == o.name && description == o.description;
- }
-};
-
-struct NimbleMetadata
-{
- QStringList bin;
- QString binDir;
- QString srcDir;
-
- bool operator==(const NimbleMetadata &o) const {
- return bin == o.bin && binDir == o.binDir && srcDir == o.srcDir;
- }
-};
-
class NimbleProject : public ProjectExplorer::Project
{
Q_OBJECT
public:
NimbleProject(const Utils::FilePath &filename);
-
- std::vector<NimbleTask> tasks() const;
-
- NimbleMetadata metadata() const;
-
- void setTasks(std::vector<NimbleTask> tasks);
-
- void setMetadata(NimbleMetadata metadata);
-
- // Keep for compatibility with Qt Creator 4.10
- QVariantMap toMap() const final;
-
-signals:
- void tasksChanged(std::vector<NimbleTask>);
- void metadataChanged(NimbleMetadata);
-
-protected:
- // Keep for compatibility with Qt Creator 4.10
- RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) final;
-
-private:
- static QStringList toStringList(const std::vector<NimbleTask> &tasks);
-
- static std::tuple<RestoreResult, std::vector<NimbleTask>> fromStringList(const QStringList &list);
-
- NimbleMetadata m_metadata;
- std::vector<NimbleTask> m_tasks;
};
}
diff --git a/src/plugins/nim/project/nimblerunconfiguration.cpp b/src/plugins/nim/project/nimblerunconfiguration.cpp
index 867f22469b..b9f8015238 100644
--- a/src/plugins/nim/project/nimblerunconfiguration.cpp
+++ b/src/plugins/nim/project/nimblerunconfiguration.cpp
@@ -43,20 +43,15 @@ using namespace ProjectExplorer;
NimbleRunConfiguration::NimbleRunConfiguration(ProjectExplorer::Target *target, Core::Id id)
: RunConfiguration(target, id)
{
- auto project = dynamic_cast<NimbleProject*>(target->project());
- QTC_ASSERT(project, return);
-
addAspect<LocalEnvironmentAspect>(target);
addAspect<ExecutableAspect>();
addAspect<ArgumentsAspect>();
addAspect<WorkingDirectoryAspect>();
addAspect<TerminalAspect>();
- connect(project, &Project::parsingFinished,
- this, &NimbleRunConfiguration::updateTargetInformation);
- connect(project, &NimbleProject::metadataChanged,
+ connect(target, &Target::parsingFinished,
this, &NimbleRunConfiguration::updateTargetInformation);
- connect(project, &NimbleProject::tasksChanged,
+ connect(target, &Target::targetPropertiesChanged,
this, &NimbleRunConfiguration::updateTargetInformation);
updateTargetInformation();
@@ -85,14 +80,6 @@ QString NimbleRunConfiguration::disabledReason() const
return RunConfiguration::disabledReason();
}
-void NimbleRunConfiguration::updateEnabledState()
-{
- if (!isBuildTargetValid())
- setEnabled(false);
- else
- RunConfiguration::updateEnabledState();
-}
-
NimbleRunConfigurationFactory::NimbleRunConfigurationFactory()
: RunConfigurationFactory()
{
diff --git a/src/plugins/nim/project/nimblerunconfiguration.h b/src/plugins/nim/project/nimblerunconfiguration.h
index 8e370d32cc..1daa5e2284 100644
--- a/src/plugins/nim/project/nimblerunconfiguration.h
+++ b/src/plugins/nim/project/nimblerunconfiguration.h
@@ -38,9 +38,6 @@ public:
QString disabledReason() const override;
-protected:
- void updateEnabledState() override;
-
private:
void updateTargetInformation();
diff --git a/src/plugins/nim/project/nimbletaskstep.cpp b/src/plugins/nim/project/nimbletaskstep.cpp
index 8a6ce49de9..0608be5915 100644
--- a/src/plugins/nim/project/nimbletaskstep.cpp
+++ b/src/plugins/nim/project/nimbletaskstep.cpp
@@ -104,10 +104,10 @@ bool NimbleTaskStep::validate()
if (m_taskName.isEmpty())
return true;
- auto nimbleProject = dynamic_cast<NimbleProject*>(project());
- QTC_ASSERT(nimbleProject, return false);
+ auto nimbleBuildSystem = dynamic_cast<NimbleBuildSystem*>(buildSystem());
+ QTC_ASSERT(nimbleBuildSystem, return false);
- if (!Utils::contains(nimbleProject->tasks(), [this](const NimbleTask &task){ return task.name == m_taskName; })) {
+ if (!Utils::contains(nimbleBuildSystem->tasks(), [this](const NimbleTask &task){ return task.name == m_taskName; })) {
emit addTask(Task(Task::Error,
tr("Nimble task %1 not found").arg(m_taskName),
Utils::FilePath(), -1,
diff --git a/src/plugins/nim/project/nimbletaskstepwidget.cpp b/src/plugins/nim/project/nimbletaskstepwidget.cpp
index 6d33fdcbe6..0b44cddc9a 100644
--- a/src/plugins/nim/project/nimbletaskstepwidget.cpp
+++ b/src/plugins/nim/project/nimbletaskstepwidget.cpp
@@ -40,14 +40,14 @@ NimbleTaskStepWidget::NimbleTaskStepWidget(NimbleTaskStep *bs)
{
ui->setupUi(this);
- auto project = dynamic_cast<NimbleProject*>(bs->project());
- QTC_ASSERT(project, return);
+ auto buildSystem = dynamic_cast<NimbleBuildSystem *>(bs->buildSystem());
+ QTC_ASSERT(buildSystem, return);
ui->taskList->setModel(&m_tasks);
QObject::connect(&m_tasks, &QAbstractItemModel::dataChanged, this, &NimbleTaskStepWidget::onDataChanged);
- updateTaskList(project->tasks());
- QObject::connect(project, &NimbleProject::tasksChanged, this, &NimbleTaskStepWidget::updateTaskList);
+ updateTaskList();
+ QObject::connect(buildSystem, &NimbleBuildSystem::tasksChanged, this, &NimbleTaskStepWidget::updateTaskList);
selectTask(bs->taskName());
QObject::connect(bs, &NimbleTaskStep::taskNameChanged, this, &NimbleTaskStepWidget::selectTask);
@@ -73,8 +73,12 @@ NimbleTaskStepWidget::~NimbleTaskStepWidget()
delete ui;
}
-void NimbleTaskStepWidget::updateTaskList(const std::vector<NimbleTask> &tasks)
+void NimbleTaskStepWidget::updateTaskList()
{
+ auto buildSystem = dynamic_cast<NimbleBuildSystem *>(step()->buildSystem());
+ QTC_ASSERT(buildSystem, return);
+ const std::vector<NimbleTask> &tasks = buildSystem->tasks();
+
QSet<QString> newTasks;
for (const NimbleTask &t : tasks)
newTasks.insert(t.name);
diff --git a/src/plugins/nim/project/nimbletaskstepwidget.h b/src/plugins/nim/project/nimbletaskstepwidget.h
index 73e15dcd05..a8eed55618 100644
--- a/src/plugins/nim/project/nimbletaskstepwidget.h
+++ b/src/plugins/nim/project/nimbletaskstepwidget.h
@@ -28,6 +28,7 @@
#include <projectexplorer/buildstep.h>
#include <nim/project/nimbleproject.h>
+#include <nim/project/nimblebuildsystem.h>
#include <QStandardItemModel>
@@ -50,7 +51,7 @@ signals:
void selectedTaskChanged(const QString &name);
private:
- void updateTaskList(const std::vector<NimbleTask> &tasks);
+ void updateTaskList();
void selectTask(const QString &name);
diff --git a/src/plugins/nim/project/nimbuildconfiguration.cpp b/src/plugins/nim/project/nimbuildconfiguration.cpp
index c6c745f9e6..e082f2e7e9 100644
--- a/src/plugins/nim/project/nimbuildconfiguration.cpp
+++ b/src/plugins/nim/project/nimbuildconfiguration.cpp
@@ -78,7 +78,7 @@ void NimBuildConfiguration::initialize()
{
BuildConfiguration::initialize();
- auto bs = qobject_cast<NimBuildSystem *>(project()->buildSystem());
+ auto bs = qobject_cast<NimBuildSystem *>(buildSystem());
QTC_ASSERT(bs, return );
// Create the build configuration and initialize it from build info
diff --git a/src/plugins/nim/project/nimbuildsystem.cpp b/src/plugins/nim/project/nimbuildsystem.cpp
index 2c7d97041f..f342a742c8 100644
--- a/src/plugins/nim/project/nimbuildsystem.cpp
+++ b/src/plugins/nim/project/nimbuildsystem.cpp
@@ -25,9 +25,12 @@
#include "nimbuildsystem.h"
+#include "nimproject.h"
#include "nimbleproject.h"
#include "nimprojectnode.h"
+#include <projectexplorer/target.h>
+
#include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <utils/qtcassert.h>
@@ -42,11 +45,11 @@ namespace Nim {
const char SETTINGS_KEY[] = "Nim.BuildSystem";
const char EXCLUDED_FILES_KEY[] = "ExcludedFiles";
-NimBuildSystem::NimBuildSystem(Project *project)
- : BuildSystem(project)
+NimBuildSystem::NimBuildSystem(Target *target)
+ : BuildSystem(target)
{
- connect(project, &Project::settingsLoaded, this, &NimBuildSystem::loadSettings);
- connect(project, &Project::aboutToSaveSettings, this, &NimBuildSystem::saveSettings);
+ connect(target->project(), &Project::settingsLoaded, this, &NimBuildSystem::loadSettings);
+ connect(target->project(), &Project::aboutToSaveSettings, this, &NimBuildSystem::saveSettings);
connect(&m_scanner, &TreeScanner::finished, this, &NimBuildSystem::updateProject);
m_scanner.setFilter([this](const Utils::MimeType &, const Utils::FilePath &fp) {
@@ -64,17 +67,16 @@ NimBuildSystem::NimBuildSystem(Project *project)
bool NimBuildSystem::addFiles(const QStringList &filePaths)
{
- m_excludedFiles = Utils::filtered(m_excludedFiles, [&](const QString & f) {
+ setExcludedFiles(Utils::filtered(excludedFiles(), [&](const QString & f) {
return !filePaths.contains(f);
- });
+ }));
requestParse();
return true;
}
bool NimBuildSystem::removeFiles(const QStringList &filePaths)
{
- m_excludedFiles.append(filePaths);
- m_excludedFiles = Utils::filteredUnique(m_excludedFiles);
+ setExcludedFiles(Utils::filteredUnique(excludedFiles() + filePaths));
requestParse();
return true;
}
@@ -82,27 +84,27 @@ bool NimBuildSystem::removeFiles(const QStringList &filePaths)
bool NimBuildSystem::renameFile(const QString &filePath, const QString &newFilePath)
{
Q_UNUSED(filePath)
- m_excludedFiles.removeOne(newFilePath);
+ QStringList files = excludedFiles();
+ files.removeOne(newFilePath);
+ setExcludedFiles(files);
requestParse();
return true;
}
void NimBuildSystem::setExcludedFiles(const QStringList &list)
{
- m_excludedFiles = list;
+ static_cast<NimProject *>(project())->setExcludedFiles(list);
}
QStringList NimBuildSystem::excludedFiles()
{
- return m_excludedFiles;
+ return static_cast<NimProject *>(project())->excludedFiles();
}
-void NimBuildSystem::parseProject(BuildSystem::ParsingContext &&ctx)
+void NimBuildSystem::triggerParsing()
{
- QTC_ASSERT(!m_currentContext.project, return );
- m_currentContext = std::move(ctx);
- QTC_CHECK(m_currentContext.project);
- m_scanner.asyncScanForFiles(m_currentContext.project->projectDirectory());
+ m_guard = guardParsingRun();
+ m_scanner.asyncScanForFiles(projectDirectory());
}
const FilePathList NimBuildSystem::nimFiles() const
@@ -116,7 +118,7 @@ void NimBuildSystem::loadSettings()
{
QVariantMap settings = project()->namedSettings(SETTINGS_KEY).toMap();
if (settings.contains(EXCLUDED_FILES_KEY))
- m_excludedFiles = settings.value(EXCLUDED_FILES_KEY, m_excludedFiles).toStringList();
+ setExcludedFiles(settings.value(EXCLUDED_FILES_KEY, excludedFiles()).toStringList());
requestParse();
}
@@ -124,7 +126,7 @@ void NimBuildSystem::loadSettings()
void NimBuildSystem::saveSettings()
{
QVariantMap settings;
- settings.insert(EXCLUDED_FILES_KEY, m_excludedFiles);
+ settings.insert(EXCLUDED_FILES_KEY, excludedFiles());
project()->setNamedSettings(SETTINGS_KEY, settings);
}
@@ -156,8 +158,8 @@ void NimBuildSystem::updateProject()
}
// Complete scan
- m_currentContext.guard.markAsSuccess();
- m_currentContext = {};
+ m_guard.markAsSuccess();
+ m_guard = {}; // Trigger destructor of previous object, emitting parsingFinished()
}
bool NimBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
diff --git a/src/plugins/nim/project/nimbuildsystem.h b/src/plugins/nim/project/nimbuildsystem.h
index 686bab3aca..9ea9a337c4 100644
--- a/src/plugins/nim/project/nimbuildsystem.h
+++ b/src/plugins/nim/project/nimbuildsystem.h
@@ -37,7 +37,7 @@ class NimBuildSystem : public ProjectExplorer::BuildSystem
Q_OBJECT
public:
- explicit NimBuildSystem(ProjectExplorer::Project *project);
+ explicit NimBuildSystem(ProjectExplorer::Target *target);
bool addFiles(const QStringList &filePaths);
bool removeFiles(const QStringList &filePaths);
@@ -58,22 +58,20 @@ public:
void setExcludedFiles(const QStringList &list); // Keep for compatibility with Qt Creator 4.10
QStringList excludedFiles(); // Make private when no longer supporting Qt Creator 4.10
- void parseProject(ParsingContext &&ctx) override;
+ void triggerParsing();
const Utils::FilePathList nimFiles() const;
protected:
- void loadSettings();
- void saveSettings();
+ virtual void loadSettings();
+ virtual void saveSettings();
void collectProjectFiles();
void updateProject();
- QStringList m_excludedFiles;
-
ProjectExplorer::TreeScanner m_scanner;
- ParsingContext m_currentContext;
+ ParseGuard m_guard;
Utils::FileSystemWatcher m_directoryWatcher;
};
diff --git a/src/plugins/nim/project/nimcompilerbuildstep.cpp b/src/plugins/nim/project/nimcompilerbuildstep.cpp
index d9cd7599b2..389d6b80d2 100644
--- a/src/plugins/nim/project/nimcompilerbuildstep.cpp
+++ b/src/plugins/nim/project/nimcompilerbuildstep.cpp
@@ -271,8 +271,8 @@ void NimCompilerBuildStep::updateTargetNimFile()
{
if (!m_targetNimFile.isEmpty())
return;
- const Utils::FilePathList nimFiles = static_cast<NimBuildSystem *>(project()->buildSystem())
- ->nimFiles();
+ const Utils::FilePathList nimFiles =
+ static_cast<NimBuildSystem *>(buildConfiguration()->buildSystem())->nimFiles();
if (!nimFiles.isEmpty())
setTargetNimFile(nimFiles.at(0));
}
diff --git a/src/plugins/nim/project/nimcompilerbuildstepconfigwidget.cpp b/src/plugins/nim/project/nimcompilerbuildstepconfigwidget.cpp
index 01e9e23ca6..1e69022628 100644
--- a/src/plugins/nim/project/nimcompilerbuildstepconfigwidget.cpp
+++ b/src/plugins/nim/project/nimcompilerbuildstepconfigwidget.cpp
@@ -116,7 +116,7 @@ void NimCompilerBuildStepConfigWidget::updateTargetComboBox()
{
QTC_ASSERT(m_buildStep, return );
- const auto bs = qobject_cast<NimBuildSystem *>(m_buildStep->project()->buildSystem());
+ const auto bs = qobject_cast<NimBuildSystem *>(m_buildStep->buildConfiguration()->buildSystem());
QTC_ASSERT(bs, return );
// Re enter the files
diff --git a/src/plugins/nim/project/nimproject.cpp b/src/plugins/nim/project/nimproject.cpp
index 7fb17f2c36..1c17b250c1 100644
--- a/src/plugins/nim/project/nimproject.cpp
+++ b/src/plugins/nim/project/nimproject.cpp
@@ -45,7 +45,7 @@ NimProject::NimProject(const FilePath &fileName) : Project(Constants::C_NIM_MIME
// ensure debugging is enabled (Nim plugin translates nim code to C code)
setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
- setBuildSystemCreator([](Project *p) { return new NimBuildSystem(p); });
+ setBuildSystemCreator([](Target *t) { return new NimBuildSystem(t); });
}
Tasks NimProject::projectIssues(const Kit *k) const
@@ -65,17 +65,25 @@ Tasks NimProject::projectIssues(const Kit *k) const
QVariantMap NimProject::toMap() const
{
QVariantMap result = Project::toMap();
- result[Constants::C_NIMPROJECT_EXCLUDEDFILES] = static_cast<NimBuildSystem *>(buildSystem())
- ->excludedFiles();
+ result[Constants::C_NIMPROJECT_EXCLUDEDFILES] = m_excludedFiles;
return result;
}
Project::RestoreResult NimProject::fromMap(const QVariantMap &map, QString *errorMessage)
{
auto result = Project::fromMap(map, errorMessage);
- static_cast<NimBuildSystem *>(buildSystem())
- ->setExcludedFiles(map.value(Constants::C_NIMPROJECT_EXCLUDEDFILES).toStringList());
+ m_excludedFiles = map.value(Constants::C_NIMPROJECT_EXCLUDEDFILES).toStringList();
return result;
}
+QStringList NimProject::excludedFiles() const
+{
+ return m_excludedFiles;
+}
+
+void NimProject::setExcludedFiles(const QStringList &excludedFiles)
+{
+ m_excludedFiles = excludedFiles;
+}
+
} // namespace Nim
diff --git a/src/plugins/nim/project/nimproject.h b/src/plugins/nim/project/nimproject.h
index afe33cf940..540d2129bb 100644
--- a/src/plugins/nim/project/nimproject.h
+++ b/src/plugins/nim/project/nimproject.h
@@ -48,9 +48,14 @@ public:
// Keep for compatibility with Qt Creator 4.10
QVariantMap toMap() const final;
+ QStringList excludedFiles() const;
+ void setExcludedFiles(const QStringList &excludedFiles);
+
protected:
// Keep for compatibility with Qt Creator 4.10
RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) final;
+
+ QStringList m_excludedFiles;
};
} // namespace Nim
diff --git a/src/plugins/projectexplorer/buildconfiguration.cpp b/src/plugins/projectexplorer/buildconfiguration.cpp
index d1e6225b98..b312e0fb7e 100644
--- a/src/plugins/projectexplorer/buildconfiguration.cpp
+++ b/src/plugins/projectexplorer/buildconfiguration.cpp
@@ -28,6 +28,8 @@
#include "buildenvironmentwidget.h"
#include "buildinfo.h"
#include "buildsteplist.h"
+#include "buildstepspage.h"
+#include "buildsystem.h"
#include "namedwidget.h"
#include "kit.h"
#include "kitinformation.h"
@@ -89,6 +91,7 @@ BuildConfiguration::BuildConfiguration(Target *target, Core::Id id)
: ProjectConfiguration(target, id), d(new Internal::BuildConfigurationPrivate)
{
QTC_CHECK(target && target == this->target());
+
Utils::MacroExpander *expander = macroExpander();
expander->setDisplayName(tr("Build Settings"));
expander->setAccumulating(true);
@@ -128,8 +131,8 @@ BuildConfiguration::BuildConfiguration(Target *target, Core::Id id)
this->target()->buildEnvironmentChanged(this);
});
- connect(project(), &Project::parsingStarted, this, &BuildConfiguration::enabledChanged);
- connect(project(), &Project::parsingFinished, this, &BuildConfiguration::enabledChanged);
+ connect(target, &Target::parsingStarted, this, &BuildConfiguration::enabledChanged);
+ connect(target, &Target::parsingFinished, this, &BuildConfiguration::enabledChanged);
connect(this, &BuildConfiguration::enabledChanged, this, [this] {
if (isActive() && project() == SessionManager::startupProject()) {
@@ -164,6 +167,19 @@ void BuildConfiguration::setBuildDirectory(const Utils::FilePath &dir)
emitBuildDirectoryChanged();
}
+void BuildConfiguration::addConfigWidgets(const std::function<void(NamedWidget *)> &adder)
+{
+ if (NamedWidget *generalConfigWidget = createConfigWidget())
+ adder(generalConfigWidget);
+
+ adder(new Internal::BuildStepListWidget(stepList(Constants::BUILDSTEPS_BUILD)));
+ adder(new Internal::BuildStepListWidget(stepList(Constants::BUILDSTEPS_CLEAN)));
+
+ QList<NamedWidget *> subConfigWidgets = createSubConfigWidgets();
+ foreach (NamedWidget *subConfigWidget, subConfigWidgets)
+ adder(subConfigWidget);
+}
+
NamedWidget *BuildConfiguration::createConfigWidget()
{
NamedWidget *named = new NamedWidget(d->m_configWidgetDisplayName);
@@ -203,6 +219,12 @@ QList<NamedWidget *> BuildConfiguration::createSubConfigWidgets()
return {new BuildEnvironmentWidget(this)};
}
+BuildSystem *BuildConfiguration::buildSystem() const
+{
+ QTC_CHECK(target()->fallbackBuildSystem());
+ return target()->fallbackBuildSystem();
+}
+
QList<Core::Id> BuildConfiguration::knownStepLists() const
{
return Utils::transform(d->m_stepLists, &BuildStepList::id);
@@ -368,14 +390,14 @@ void BuildConfiguration::setUserEnvironmentChanges(const Utils::EnvironmentItems
bool BuildConfiguration::isEnabled() const
{
- return !project()->isParsing() && project()->hasParsingData();
+ return !buildSystem()->isParsing() && buildSystem()->hasParsingData();
}
QString BuildConfiguration::disabledReason() const
{
- if (project()->isParsing())
+ if (buildSystem()->isParsing())
return (tr("The project is currently being parsed."));
- if (!project()->hasParsingData())
+ if (!buildSystem()->hasParsingData())
return (tr("The project was not parsed successfully."));
return QString();
}
diff --git a/src/plugins/projectexplorer/buildconfiguration.h b/src/plugins/projectexplorer/buildconfiguration.h
index 6160e3b6a4..2a57fb5858 100644
--- a/src/plugins/projectexplorer/buildconfiguration.h
+++ b/src/plugins/projectexplorer/buildconfiguration.h
@@ -38,6 +38,7 @@ namespace Internal { class BuildConfigurationPrivate; }
class BaseStringAspect;
class BuildInfo;
+class BuildSystem;
class BuildStepList;
class Kit;
class NamedWidget;
@@ -59,6 +60,8 @@ public:
Utils::FilePath rawBuildDirectory() const;
void setBuildDirectory(const Utils::FilePath &dir);
+ virtual BuildSystem *buildSystem() const;
+
virtual NamedWidget *createConfigWidget();
virtual QList<NamedWidget *> createSubConfigWidgets();
@@ -110,6 +113,8 @@ public:
void setConfigWidgetHasFrame(bool configWidgetHasFrame);
void setBuildDirectorySettingsKey(const QString &key);
+ void addConfigWidgets(const std::function<void (NamedWidget *)> &adder);
+
signals:
void environmentChanged();
void buildDirectoryChanged();
diff --git a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
index 468d4751ac..f5d33a7b4e 100644
--- a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
+++ b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
@@ -139,6 +139,7 @@ BuildSettingsWidget::BuildSettingsWidget(Target *target) :
void BuildSettingsWidget::addSubWidget(NamedWidget *widget)
{
+ widget->setParent(this);
widget->setContentsMargins(0, 10, 0, 0);
auto label = new QLabel(this);
@@ -192,23 +193,8 @@ void BuildSettingsWidget::updateBuildSettings()
m_renameButton->setEnabled(!bcs.isEmpty());
m_cloneButton->setEnabled(!bcs.isEmpty());
- if (!m_buildConfiguration)
- return;
-
- // Add pages
- NamedWidget *generalConfigWidget = m_buildConfiguration->createConfigWidget();
- if (generalConfigWidget)
- addSubWidget(generalConfigWidget);
-
- BuildStepList *buildSteps = m_buildConfiguration->stepList(Constants::BUILDSTEPS_BUILD);
- addSubWidget(new BuildStepListWidget(buildSteps, this));
-
- BuildStepList *cleanSteps = m_buildConfiguration->stepList(Constants::BUILDSTEPS_CLEAN);
- addSubWidget(new BuildStepListWidget(cleanSteps, this));
-
- QList<NamedWidget *> subConfigWidgets = m_buildConfiguration->createSubConfigWidgets();
- foreach (NamedWidget *subConfigWidget, subConfigWidgets)
- addSubWidget(subConfigWidget);
+ if (m_buildConfiguration)
+ m_buildConfiguration->addConfigWidgets([this](NamedWidget *w) { addSubWidget(w); });
}
void BuildSettingsWidget::currentIndexChanged(int index)
diff --git a/src/plugins/projectexplorer/buildstep.cpp b/src/plugins/projectexplorer/buildstep.cpp
index fb8c1f3848..ba0bfa221a 100644
--- a/src/plugins/projectexplorer/buildstep.cpp
+++ b/src/plugins/projectexplorer/buildstep.cpp
@@ -204,6 +204,13 @@ ProjectConfiguration *BuildStep::projectConfiguration() const
return static_cast<ProjectConfiguration *>(parent()->parent());
}
+BuildSystem *BuildStep::buildSystem() const
+{
+ if (auto bc = buildConfiguration())
+ return bc->buildSystem();
+ return target()->buildSystem();
+}
+
void BuildStep::reportRunResult(QFutureInterface<bool> &fi, bool success)
{
fi.reportResult(success);
diff --git a/src/plugins/projectexplorer/buildstep.h b/src/plugins/projectexplorer/buildstep.h
index f9fb6fbec6..0c9a85e9b3 100644
--- a/src/plugins/projectexplorer/buildstep.h
+++ b/src/plugins/projectexplorer/buildstep.h
@@ -44,6 +44,7 @@ class BuildConfiguration;
class BuildStepConfigWidget;
class BuildStepFactory;
class BuildStepList;
+class BuildSystem;
class DeployConfiguration;
class Target;
class Task;
@@ -75,6 +76,8 @@ public:
DeployConfiguration *deployConfiguration() const;
ProjectConfiguration *projectConfiguration() const;
+ BuildSystem *buildSystem() const;
+
enum class OutputFormat {
Stdout, Stderr, // These are for forwarded output from external tools
NormalMessage, ErrorMessage // These are for messages from Creator itself
diff --git a/src/plugins/projectexplorer/buildstepspage.cpp b/src/plugins/projectexplorer/buildstepspage.cpp
index 76fadceb68..ea795fec1a 100644
--- a/src/plugins/projectexplorer/buildstepspage.cpp
+++ b/src/plugins/projectexplorer/buildstepspage.cpp
@@ -191,9 +191,9 @@ BuildStepsWidgetData::~BuildStepsWidgetData()
// We do not own the step
}
-BuildStepListWidget::BuildStepListWidget(BuildStepList *bsl, QWidget *parent)
+BuildStepListWidget::BuildStepListWidget(BuildStepList *bsl)
//: %1 is the name returned by BuildStepList::displayName
- : NamedWidget(tr("%1 Steps").arg(bsl->displayName()), parent), m_buildStepList(bsl)
+ : NamedWidget(tr("%1 Steps").arg(bsl->displayName())), m_buildStepList(bsl)
{
setupUi();
diff --git a/src/plugins/projectexplorer/buildstepspage.h b/src/plugins/projectexplorer/buildstepspage.h
index 7eade2d663..9fef567a1f 100644
--- a/src/plugins/projectexplorer/buildstepspage.h
+++ b/src/plugins/projectexplorer/buildstepspage.h
@@ -97,7 +97,7 @@ class BuildStepListWidget : public NamedWidget
Q_OBJECT
public:
- BuildStepListWidget(BuildStepList *bsl, QWidget *parent = nullptr);
+ explicit BuildStepListWidget(BuildStepList *bsl);
~BuildStepListWidget() override;
private:
diff --git a/src/plugins/projectexplorer/buildsystem.cpp b/src/plugins/projectexplorer/buildsystem.cpp
index 496f9cc9f4..e6e6ad9677 100644
--- a/src/plugins/projectexplorer/buildsystem.cpp
+++ b/src/plugins/projectexplorer/buildsystem.cpp
@@ -26,10 +26,14 @@
#include "buildsystem.h"
#include "buildconfiguration.h"
+#include "runconfiguration.h"
+#include "runcontrol.h"
#include "target.h"
#include <utils/qtcassert.h>
+#include <QTimer>
+
using namespace Utils;
namespace ProjectExplorer {
@@ -38,77 +42,129 @@ namespace ProjectExplorer {
// BuildSystem:
// --------------------------------------------------------------------
-BuildSystem::BuildSystem(Project *project)
- : m_project(project)
+class BuildSystemPrivate
+{
+public:
+ Target *m_target = nullptr;
+ BuildConfiguration *m_buildConfiguration = nullptr;
+
+ QTimer m_delayedParsingTimer;
+
+ bool m_isParsing = false;
+ bool m_hasParsingData = false;
+
+ DeploymentData m_deploymentData;
+ QList<BuildTargetInfo> m_appTargets;
+};
+
+BuildSystem::BuildSystem(BuildConfiguration *bc)
+ : BuildSystem(bc->target())
+{
+ d->m_buildConfiguration = bc;
+}
+
+BuildSystem::BuildSystem(Target *target)
+ : d(new BuildSystemPrivate)
{
- QTC_CHECK(project);
+ QTC_CHECK(target);
+ d->m_target = target;
// Timer:
- m_delayedParsingTimer.setSingleShot(true);
+ d->m_delayedParsingTimer.setSingleShot(true);
- connect(&m_delayedParsingTimer, &QTimer::timeout, this, &BuildSystem::triggerParsing);
+ connect(&d->m_delayedParsingTimer, &QTimer::timeout, this, &BuildSystem::triggerParsing);
+}
+
+BuildSystem::~BuildSystem()
+{
+ delete d;
}
Project *BuildSystem::project() const
{
- return m_project;
+ return d->m_target->project();
+}
+
+Target *BuildSystem::target() const
+{
+ return d->m_target;
+}
+
+void BuildSystem::emitParsingStarted()
+{
+ QTC_ASSERT(!d->m_isParsing, return);
+
+ d->m_isParsing = true;
+ d->m_hasParsingData = false;
+ emit d->m_target->parsingStarted();
+}
+
+void BuildSystem::emitParsingFinished(bool success)
+{
+ // Intentionally no return, as we currently get start - start - end - end
+ // sequences when switching qmake targets quickly.
+ QTC_CHECK(d->m_isParsing);
+
+ d->m_isParsing = false;
+ d->m_hasParsingData = success;
+ emit d->m_target->parsingFinished(success);
}
FilePath BuildSystem::projectFilePath() const
{
- return m_project->projectFilePath();
+ return d->m_target->project()->projectFilePath();
}
FilePath BuildSystem::projectDirectory() const
{
- return m_project->projectDirectory();
+ return d->m_target->project()->projectDirectory();
}
bool BuildSystem::isWaitingForParse() const
{
- return m_delayedParsingTimer.isActive();
+ return d->m_delayedParsingTimer.isActive();
}
void BuildSystem::requestParse()
{
- requestParse(0);
+ requestParseHelper(0);
}
void BuildSystem::requestDelayedParse()
{
- requestParse(1000);
+ requestParseHelper(1000);
}
-void BuildSystem::requestParse(int delay)
+bool BuildSystem::isParsing() const
{
- m_delayedParsingTimer.setInterval(delay);
- m_delayedParsingTimer.start();
+ return d->m_isParsing;
}
-void BuildSystem::triggerParsing()
+bool BuildSystem::hasParsingData() const
{
- QTC_ASSERT(!project()->isParsing(), return );
-
- Project *p = project();
- Target *t = p->activeTarget();
- BuildConfiguration *bc = t ? t->activeBuildConfiguration() : nullptr;
+ return d->m_hasParsingData;
+}
- MacroExpander *e = nullptr;
+Environment BuildSystem::activeParseEnvironment() const
+{
+ const BuildConfiguration *const bc = d->m_target->activeBuildConfiguration();
if (bc)
- e = bc->macroExpander();
- else if (t)
- e = t->macroExpander();
- else
- e = p->macroExpander();
+ return bc->environment();
- Utils::Environment env = p->activeParseEnvironment();
+ const RunConfiguration *const rc = d->m_target->activeRunConfiguration();
+ if (rc)
+ return rc->runnable().environment;
- ParsingContext ctx(p->guardParsingRun(), p, bc, e, env);
+ Environment result = Utils::Environment::systemEnvironment();
+ d->m_target->kit()->addToEnvironment(result);
- QTC_ASSERT(ctx.guard.guardsProject(), return );
+ return result;
+}
- if (validateParsingContext(ctx))
- parseProject(std::move(ctx));
+void BuildSystem::requestParseHelper(int delay)
+{
+ d->m_delayedParsingTimer.setInterval(delay);
+ d->m_delayedParsingTimer.start();
}
bool BuildSystem::addFiles(Node *, const QStringList &filePaths, QStringList *notAdded)
@@ -157,4 +213,103 @@ bool BuildSystem::supportsAction(Node *, ProjectAction, const Node *) const
return false;
}
+QStringList BuildSystem::filesGeneratedFrom(const QString &sourceFile) const
+{
+ Q_UNUSED(sourceFile)
+ return {};
+}
+
+QVariant BuildSystem::additionalData(Core::Id id) const
+{
+ Q_UNUSED(id)
+ return {};
+}
+
+// ParseGuard
+
+BuildSystem::ParseGuard::ParseGuard(BuildSystem::ParseGuard &&other)
+ : m_buildSystem{std::move(other.m_buildSystem)}
+ , m_success{std::move(other.m_success)}
+{
+ // No need to release this as this is invalid anyway:-)
+ other.m_buildSystem = nullptr;
+}
+
+BuildSystem::ParseGuard::ParseGuard(BuildSystem *p)
+ : m_buildSystem(p)
+{
+ if (m_buildSystem && !m_buildSystem->isParsing())
+ m_buildSystem->emitParsingStarted();
+ else
+ m_buildSystem = nullptr;
+}
+
+void BuildSystem::ParseGuard::release()
+{
+ if (m_buildSystem)
+ m_buildSystem->emitParsingFinished(m_success);
+ m_buildSystem = nullptr;
+}
+
+BuildSystem::ParseGuard &BuildSystem::ParseGuard::operator=(BuildSystem::ParseGuard &&other)
+{
+ release();
+
+ m_buildSystem = std::move(other.m_buildSystem);
+ m_success = std::move(other.m_success);
+
+ other.m_buildSystem = nullptr;
+ return *this;
+}
+
+void BuildSystem::setDeploymentData(const DeploymentData &deploymentData)
+{
+ if (d->m_deploymentData != deploymentData) {
+ d->m_deploymentData = deploymentData;
+ emit deploymentDataChanged();
+ emit applicationTargetsChanged();
+ emit target()->deploymentDataChanged();
+ emit target()->applicationTargetsChanged();
+ }
+}
+
+DeploymentData BuildSystem::deploymentData() const
+{
+ return d->m_deploymentData;
+}
+
+void BuildSystem::setApplicationTargets(const QList<BuildTargetInfo> &appTargets)
+{
+ if (Utils::toSet(appTargets) != Utils::toSet(d->m_appTargets)) {
+ d->m_appTargets = appTargets;
+ emit applicationTargetsChanged();
+ emit target()->applicationTargetsChanged();
+ }
+}
+
+const QList<BuildTargetInfo> BuildSystem::applicationTargets() const
+{
+ return d->m_appTargets;
+}
+
+BuildTargetInfo BuildSystem::buildTarget(const QString &buildKey) const
+{
+ return Utils::findOrDefault(d->m_appTargets, [&buildKey](const BuildTargetInfo &ti) {
+ return ti.buildKey == buildKey;
+ });
+}
+
+QString BuildSystem::disabledReason(const QString &buildKey) const
+{
+ if (hasParsingData()) {
+ QString msg = isParsing() ? tr("The project is currently being parsed.")
+ : tr("The project could not be fully parsed.");
+ const FilePath projectFilePath = buildTarget(buildKey).projectFilePath;
+ if (!projectFilePath.isEmpty() && !projectFilePath.exists())
+ msg += '\n' + tr("The project file \"%1\" does not exist.").arg(projectFilePath.toString());
+ return msg;
+ }
+ return {};
+}
+
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/buildsystem.h b/src/plugins/projectexplorer/buildsystem.h
index 9bd5de6639..b73b459b7b 100644
--- a/src/plugins/projectexplorer/buildsystem.h
+++ b/src/plugins/projectexplorer/buildsystem.h
@@ -27,15 +27,15 @@
#include "projectexplorer_export.h"
+#include "buildtargetinfo.h"
#include "project.h"
#include "treescanner.h"
-#include <QTimer>
+#include <QObject>
namespace ProjectExplorer {
class BuildConfiguration;
-class ExtraCompiler;
class Node;
// --------------------------------------------------------------------
@@ -47,11 +47,13 @@ class PROJECTEXPLORER_EXPORT BuildSystem : public QObject
Q_OBJECT
public:
- explicit BuildSystem(Project *project);
-
- BuildSystem(const BuildSystem &other) = delete;
+ explicit BuildSystem(Target *target);
+ explicit BuildSystem(BuildConfiguration *bc);
+ ~BuildSystem() override;
Project *project() const;
+ Target *target() const;
+
Utils::FilePath projectFilePath() const;
Utils::FilePath projectDirectory() const;
@@ -60,6 +62,11 @@ public:
void requestParse();
void requestDelayedParse();
+ bool isParsing() const;
+ bool hasParsingData() const;
+
+ Utils::Environment activeParseEnvironment() const;
+
virtual bool addFiles(Node *context, const QStringList &filePaths, QStringList *notAdded = nullptr);
virtual RemovedFilesFromProject removeFiles(Node *context, const QStringList &filePaths,
QStringList *notRemoved = nullptr);
@@ -69,69 +76,64 @@ public:
virtual bool addDependencies(Node *context, const QStringList &dependencies);
virtual bool supportsAction(Node *context, ProjectAction action, const Node *node) const;
-protected:
- class ParsingContext
+ virtual QStringList filesGeneratedFrom(const QString &sourceFile) const;
+ virtual QVariant additionalData(Core::Id id) const;
+
+ void setDeploymentData(const DeploymentData &deploymentData);
+ DeploymentData deploymentData() const;
+
+ void setApplicationTargets(const QList<BuildTargetInfo> &appTargets);
+ const QList<BuildTargetInfo> applicationTargets() const;
+ BuildTargetInfo buildTarget(const QString &buildKey) const;
+
+ class ParseGuard
{
+ friend class BuildSystem;
+ explicit ParseGuard(BuildSystem *p);
+
+ void release();
+
public:
- ParsingContext() = default;
-
- ParsingContext(const ParsingContext &other) = delete;
- ParsingContext &operator=(const ParsingContext &other) = delete;
- ParsingContext(ParsingContext &&other)
- : guard{std::move(other.guard)}
- , project{std::move(other.project)}
- , buildConfiguration{std::move(other.buildConfiguration)}
- , expander{std::move(other.expander)}
- , environment{std::move(other.environment)}
- {}
- ParsingContext &operator=(ParsingContext &&other)
- {
- guard = std::move(other.guard);
- project = std::move(other.project);
- buildConfiguration = std::move(other.buildConfiguration);
- expander = std::move(other.expander);
- environment = std::move(other.environment);
- return *this;
- }
-
- Project::ParseGuard guard;
-
- Project *project = nullptr;
- BuildConfiguration *buildConfiguration = nullptr;
- Utils::MacroExpander *expander = nullptr;
- Utils::Environment environment;
+ ParseGuard() = default;
+ ~ParseGuard() { release(); }
- 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)
- {}
+ void markAsSuccess() const { m_success = true; }
+ bool isSuccess() const { return m_success; }
+ bool guardsProject() const { return m_buildSystem; }
- friend class BuildSystem;
+ ParseGuard(const ParseGuard &other) = delete;
+ ParseGuard &operator=(const ParseGuard &other) = delete;
+ ParseGuard(ParseGuard &&other);
+ ParseGuard &operator=(ParseGuard &&other);
+
+ private:
+ BuildSystem *m_buildSystem = nullptr;
+ mutable bool m_success = false;
};
- virtual bool validateParsingContext(const ParsingContext &ctx)
- {
- Q_UNUSED(ctx)
- return true;
- }
+public:
+ // FIXME: Make this private and the BuildSystem a friend
+ ParseGuard guardParsingRun() { return ParseGuard(this); }
- virtual void parseProject(ParsingContext &&) {} // actual code to parse project
+ QString disabledReason(const QString &buildKey) const;
-private:
- void requestParse(int delay); // request a (delayed!) parser run.
- void triggerParsing();
+ virtual void triggerParsing() = 0;
+
+signals:
+ void deploymentDataChanged();
+ void applicationTargetsChanged();
- QTimer m_delayedParsingTimer;
+protected:
+ // Helper methods to manage parsing state and signalling
+ // Call in GUI thread before the actual parsing starts
+ void emitParsingStarted();
+ // Call in GUI thread right after the actual parsing is done
+ void emitParsingFinished(bool success);
+
+private:
+ void requestParseHelper(int delay); // request a (delayed!) parser run.
- Project *m_project;
+ class BuildSystemPrivate *d = nullptr;
};
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
index ef198bea92..62ba2eace5 100644
--- a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
+++ b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
@@ -246,6 +246,11 @@ bool CustomExecutableRunConfiguration::isConfigured() const
return !rawExecutable().isEmpty();
}
+bool CustomExecutableRunConfiguration::isEnabled() const
+{
+ return true;
+}
+
Runnable CustomExecutableRunConfiguration::runnable() const
{
FilePath workingDirectory =
diff --git a/src/plugins/projectexplorer/customexecutablerunconfiguration.h b/src/plugins/projectexplorer/customexecutablerunconfiguration.h
index 6abd0f3185..bcd7b3b9ba 100644
--- a/src/plugins/projectexplorer/customexecutablerunconfiguration.h
+++ b/src/plugins/projectexplorer/customexecutablerunconfiguration.h
@@ -45,6 +45,7 @@ public:
/** Returns whether this runconfiguration ever was configured with an executable
*/
bool isConfigured() const override;
+ bool isEnabled() const override;
ConfigurationState ensureConfigured(QString *errorMessage) override;
QString defaultDisplayName() const;
diff --git a/src/plugins/projectexplorer/deploymentdataview.cpp b/src/plugins/projectexplorer/deploymentdataview.cpp
index f620cf4a5b..8796c897db 100644
--- a/src/plugins/projectexplorer/deploymentdataview.cpp
+++ b/src/plugins/projectexplorer/deploymentdataview.cpp
@@ -25,9 +25,11 @@
#include "deploymentdataview.h"
+#include "buildsystem.h"
#include "deploymentdata.h"
#include "target.h"
+#include <utils/qtcassert.h>
#include <utils/treemodel.h>
#include <QAbstractTableModel>
@@ -78,7 +80,8 @@ DeploymentDataView::DeploymentDataView(Target *target)
auto updatModel = [this, target, model, view] {
model->clear();
- for (const DeployableFile &file : target->deploymentData().allFiles())
+ QTC_ASSERT(target->buildSystem(), return);
+ for (const DeployableFile &file : target->buildSystem()->deploymentData().allFiles())
model->rootItem()->appendChild(new DeploymentDataItem(file));
QHeaderView *header = view->header();
diff --git a/src/plugins/projectexplorer/desktoprunconfiguration.cpp b/src/plugins/projectexplorer/desktoprunconfiguration.cpp
index a3f1f735ac..616bf19f70 100644
--- a/src/plugins/projectexplorer/desktoprunconfiguration.cpp
+++ b/src/plugins/projectexplorer/desktoprunconfiguration.cpp
@@ -78,7 +78,7 @@ DesktopRunConfiguration::DesktopRunConfiguration(Target *target, Core::Id id, Ki
if (kind == Qbs) {
- connect(project(), &Project::parsingFinished,
+ connect(target, &Target::parsingFinished,
envAspect, &EnvironmentAspect::environmentChanged);
connect(target, &Target::deploymentDataChanged,
@@ -95,12 +95,15 @@ DesktopRunConfiguration::DesktopRunConfiguration(Target *target, Core::Id id, Ki
}
- connect(target->project(), &Project::parsingFinished,
+ connect(target, &Target::parsingFinished,
this, &DesktopRunConfiguration::updateTargetInformation);
}
void DesktopRunConfiguration::updateTargetInformation()
{
+ if (!activeBuildSystem())
+ return;
+
BuildTargetInfo bti = buildTargetInfo();
auto terminalAspect = aspect<TerminalAspect>();
@@ -184,28 +187,6 @@ Utils::FilePath DesktopRunConfiguration::executableToRun(const BuildTargetInfo &
return appInLocalInstallDir.exists() ? appInLocalInstallDir : appInBuildDir;
}
-bool DesktopRunConfiguration::isBuildTargetValid() const
-{
- return Utils::anyOf(target()->applicationTargets(), [this](const BuildTargetInfo &bti) {
- return bti.buildKey == buildKey();
- });
-}
-
-void DesktopRunConfiguration::updateEnabledState()
-{
- if (m_kind == CMake && !isBuildTargetValid())
- setEnabled(false);
- else
- RunConfiguration::updateEnabledState();
-}
-
-QString DesktopRunConfiguration::disabledReason() const
-{
- if (m_kind == CMake && !isBuildTargetValid())
- return tr("The project no longer builds the target associated with this run configuration.");
- return RunConfiguration::disabledReason();
-}
-
// Factory
class DesktopQmakeRunConfiguration : public DesktopRunConfiguration
diff --git a/src/plugins/projectexplorer/desktoprunconfiguration.h b/src/plugins/projectexplorer/desktoprunconfiguration.h
index 4063337ef1..065014edf7 100644
--- a/src/plugins/projectexplorer/desktoprunconfiguration.h
+++ b/src/plugins/projectexplorer/desktoprunconfiguration.h
@@ -43,14 +43,10 @@ protected:
private:
void doAdditionalSetup(const RunConfigurationCreationInfo &info) final;
bool fromMap(const QVariantMap &map) final;
- void updateEnabledState() final;
void updateTargetInformation();
Utils::FilePath executableToRun(const BuildTargetInfo &targetInfo) const;
- QString disabledReason() const override;
-
- bool isBuildTargetValid() const;
const Kind m_kind;
};
diff --git a/src/plugins/projectexplorer/makestep.cpp b/src/plugins/projectexplorer/makestep.cpp
index 64834f190b..8358ea4df3 100644
--- a/src/plugins/projectexplorer/makestep.cpp
+++ b/src/plugins/projectexplorer/makestep.cpp
@@ -443,7 +443,7 @@ MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep)
this, &MakeStepConfigWidget::updateDetails);
connect(m_makeStep->buildConfiguration(), &BuildConfiguration::buildDirectoryChanged,
this, &MakeStepConfigWidget::updateDetails);
- connect(m_makeStep->project(), &Project::parsingFinished,
+ connect(m_makeStep->target(), &Target::parsingFinished,
this, &MakeStepConfigWidget::updateDetails);
Core::VariableChooser::addSupportForChildWidgets(this, m_makeStep->macroExpander());
diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp
index 2e75cd3caf..4f084bc7fa 100644
--- a/src/plugins/projectexplorer/project.cpp
+++ b/src/plugins/projectexplorer/project.cpp
@@ -176,14 +176,15 @@ public:
~ProjectPrivate();
Core::Id m_id;
- bool m_isParsing = false;
- bool m_hasParsingData = false;
bool m_needsInitialExpansion = false;
bool m_canBuildProducts = false;
bool m_knowsAllBuildExecutables = true;
bool m_hasMakeInstallEquivalent = false;
bool m_needsBuildConfigurations = true;
- std::unique_ptr<BuildSystem> m_buildSystem;
+ bool m_needsDeployConfigurations = true;
+
+ std::function<BuildSystem *(Target *)> m_buildSystemCreator;
+
std::unique_ptr<Core::IDocument> m_document;
std::vector<std::unique_ptr<Core::IDocument>> m_extraProjectDocuments;
std::unique_ptr<ProjectNode> m_rootProjectNode;
@@ -255,9 +256,9 @@ bool Project::canBuildProducts() const
return d->m_canBuildProducts;
}
-BuildSystem *Project::buildSystem() const
+BuildSystem *Project::createBuildSystem(Target *target) const
{
- return d->m_buildSystem.get();
+ return d->m_buildSystemCreator ? d->m_buildSystemCreator(target) : nullptr;
}
Utils::FilePath Project::projectFilePath() const
@@ -341,8 +342,6 @@ void Project::setActiveTarget(Target *target)
(target && Utils::contains(d->m_targets, target))) {
d->m_activeTarget = target;
emit activeTargetChanged(d->m_activeTarget);
- emit activeBuildConfigurationChanged(
- d->m_activeTarget ? d->m_activeTarget->activeBuildConfiguration() : nullptr);
}
}
@@ -506,33 +505,14 @@ bool Project::copySteps(Target *sourceTarget, Target *newTarget)
bool Project::setupTarget(Target *t)
{
- if (needsBuildConfigurations())
+ if (d->m_needsBuildConfigurations)
t->updateDefaultBuildConfigurations();
- t->updateDefaultDeployConfigurations();
+ if (d->m_needsDeployConfigurations)
+ t->updateDefaultDeployConfigurations();
t->updateDefaultRunConfigurations();
return true;
}
-void Project::emitParsingStarted()
-{
- QTC_ASSERT(!d->m_isParsing, return);
-
- d->m_isParsing = true;
- d->m_hasParsingData = false;
- emit parsingStarted();
-}
-
-void Project::emitParsingFinished(bool success)
-{
- // Intentionally no return, as we currently get start - start - end - end
- // sequences when switching qmake targets quickly.
- QTC_CHECK(d->m_isParsing);
-
- d->m_isParsing = false;
- d->m_hasParsingData = success;
- emit parsingFinished(success);
-}
-
void Project::setDisplayName(const QString &name)
{
if (name == d->m_displayName)
@@ -596,9 +576,6 @@ void Project::saveSettings()
Project::RestoreResult Project::restoreSettings(QString *errorMessage)
{
- BuildConfiguration *oldBc = activeTarget() ? activeTarget()->activeBuildConfiguration()
- : nullptr;
-
if (!d->m_accessor)
d->m_accessor = std::make_unique<Internal::UserFileAccessor>(this);
QVariantMap map(d->m_accessor->restoreSettings(Core::ICore::mainWindow()));
@@ -606,10 +583,6 @@ Project::RestoreResult Project::restoreSettings(QString *errorMessage)
if (result == RestoreResult::Ok)
emit settingsLoaded();
- BuildConfiguration *bc = activeTarget() ? activeTarget()->activeBuildConfiguration() : nullptr;
- if (bc != oldBc)
- emit activeBuildConfigurationChanged(bc);
-
return result;
}
@@ -798,12 +771,6 @@ EditorConfiguration *Project::editorConfiguration() const
return &d->m_editorConfiguration;
}
-QStringList Project::filesGeneratedFrom(const QString &file) const
-{
- Q_UNUSED(file)
- return QStringList();
-}
-
bool Project::isKnownFile(const Utils::FilePath &filename) const
{
if (d->m_sortedNodeList.empty())
@@ -852,10 +819,6 @@ void Project::setHasMakeInstallEquivalent(bool enabled)
d->m_hasMakeInstallEquivalent = enabled;
}
-void Project::projectLoaded()
-{
-}
-
void Project::setKnowsAllBuildExecutables(bool value)
{
d->m_knowsAllBuildExecutables = value;
@@ -866,31 +829,19 @@ void Project::setNeedsBuildConfigurations(bool value)
d->m_needsBuildConfigurations = value;
}
-Task Project::createProjectTask(Task::TaskType type, const QString &description)
+void Project::setNeedsDeployConfigurations(bool value)
{
- return Task(type, description, Utils::FilePath(), -1, Core::Id());
+ d->m_needsDeployConfigurations = value;
}
-Utils::Environment Project::activeParseEnvironment() const
+Task Project::createProjectTask(Task::TaskType type, const QString &description)
{
- const Target *const t = activeTarget();
- const BuildConfiguration *const bc = t ? t->activeBuildConfiguration() : nullptr;
- if (bc)
- return bc->environment();
-
- const RunConfiguration *const rc = t ? t->activeRunConfiguration() : nullptr;
- if (rc)
- return rc->runnable().environment;
-
- Utils::Environment result = Utils::Environment::systemEnvironment();
- if (t)
- t->kit()->addToEnvironment(result);
- return result;
+ return Task(type, description, Utils::FilePath(), -1, Core::Id());
}
-void Project::setBuildSystemCreator(const std::function<BuildSystem *(Project *)> &creator)
+void Project::setBuildSystemCreator(const std::function<BuildSystem *(Target *)> &creator)
{
- d->m_buildSystem.reset(creator(this));
+ d->m_buildSystemCreator = creator;
}
Core::Context Project::projectContext() const
@@ -988,23 +939,6 @@ Utils::MacroExpander *Project::macroExpander() const
return &d->m_macroExpander;
}
-QVariant Project::additionalData(Core::Id id, const Target *target) const
-{
- Q_UNUSED(id)
- Q_UNUSED(target)
- return QVariant();
-}
-
-bool Project::isParsing() const
-{
- return d->m_isParsing;
-}
-
-bool Project::hasParsingData() const
-{
- return d->m_hasParsingData;
-}
-
ProjectNode *Project::findNodeForBuildKey(const QString &buildKey) const
{
if (!d->m_rootProjectNode)
@@ -1072,6 +1006,14 @@ const QString TEST_PROJECT_MIMETYPE = "application/vnd.test.qmakeprofile";
const QString TEST_PROJECT_DISPLAYNAME = "testProjectFoo";
const char TEST_PROJECT_ID[] = "Test.Project.Id";
+class TestBuildSystem : public BuildSystem
+{
+public:
+ using BuildSystem::BuildSystem;
+
+ void triggerParsing() {}
+};
+
class TestProject : public Project
{
public:
@@ -1079,9 +1021,17 @@ public:
{
setId(TEST_PROJECT_ID);
setDisplayName(TEST_PROJECT_DISPLAYNAME);
+ setBuildSystemCreator([](Target *t) { return new TestBuildSystem(t); });
+ setNeedsBuildConfigurations(false);
+ setNeedsDeployConfigurations(false);
+
+ target = addTargetForKit(&testKit);
}
bool needsConfiguration() const final { return false; }
+
+ Kit testKit;
+ Target *target = nullptr;
};
void ProjectExplorerPlugin::testProject_setup()
@@ -1108,8 +1058,8 @@ void ProjectExplorerPlugin::testProject_setup()
QCOMPARE(project.id(), Core::Id(TEST_PROJECT_ID));
- QVERIFY(!project.isParsing());
- QVERIFY(!project.hasParsingData());
+ QVERIFY(!project.target->buildSystem()->isParsing());
+ QVERIFY(!project.target->buildSystem()->hasParsingData());
}
void ProjectExplorerPlugin::testProject_changeDisplayName()
@@ -1132,16 +1082,16 @@ void ProjectExplorerPlugin::testProject_parsingSuccess()
{
TestProject project;
- QSignalSpy startSpy(&project, &Project::parsingStarted);
- QSignalSpy stopSpy(&project, &Project::parsingFinished);
+ QSignalSpy startSpy(project.target, &Target::parsingStarted);
+ QSignalSpy stopSpy(project.target, &Target::parsingFinished);
{
- Project::ParseGuard guard = project.guardParsingRun();
+ BuildSystem::ParseGuard guard = project.target->buildSystem()->guardParsingRun();
QCOMPARE(startSpy.count(), 1);
QCOMPARE(stopSpy.count(), 0);
- QVERIFY(project.isParsing());
- QVERIFY(!project.hasParsingData());
+ QVERIFY(project.target->buildSystem()->isParsing());
+ QVERIFY(!project.target->buildSystem()->hasParsingData());
guard.markAsSuccess();
}
@@ -1150,32 +1100,32 @@ void ProjectExplorerPlugin::testProject_parsingSuccess()
QCOMPARE(stopSpy.count(), 1);
QCOMPARE(stopSpy.at(0), {QVariant(true)});
- QVERIFY(!project.isParsing());
- QVERIFY(project.hasParsingData());
+ QVERIFY(!project.target->buildSystem()->isParsing());
+ QVERIFY(project.target->buildSystem()->hasParsingData());
}
void ProjectExplorerPlugin::testProject_parsingFail()
{
TestProject project;
- QSignalSpy startSpy(&project, &Project::parsingStarted);
- QSignalSpy stopSpy(&project, &Project::parsingFinished);
+ QSignalSpy startSpy(project.target, &Target::parsingStarted);
+ QSignalSpy stopSpy(project.target, &Target::parsingFinished);
{
- Project::ParseGuard guard = project.guardParsingRun();
+ BuildSystem::ParseGuard guard = project.target->buildSystem()->guardParsingRun();
QCOMPARE(startSpy.count(), 1);
QCOMPARE(stopSpy.count(), 0);
- QVERIFY(project.isParsing());
- QVERIFY(!project.hasParsingData());
+ QVERIFY(project.target->buildSystem()->isParsing());
+ QVERIFY(!project.target->buildSystem()->hasParsingData());
}
QCOMPARE(startSpy.count(), 1);
QCOMPARE(stopSpy.count(), 1);
QCOMPARE(stopSpy.at(0), {QVariant(false)});
- QVERIFY(!project.isParsing());
- QVERIFY(!project.hasParsingData());
+ QVERIFY(!project.target->buildSystem()->isParsing());
+ QVERIFY(!project.target->buildSystem()->hasParsingData());
}
std::unique_ptr<ProjectNode> createFileTree(Project *project)
diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h
index 326763bf8c..243d9a079f 100644
--- a/src/plugins/projectexplorer/project.h
+++ b/src/plugins/projectexplorer/project.h
@@ -50,6 +50,7 @@ namespace ProjectExplorer {
class BuildInfo;
class BuildSystem;
+class BuildConfiguration;
class ContainerNode;
class EditorConfiguration;
class FolderNode;
@@ -64,7 +65,6 @@ class Target;
class PROJECTEXPLORER_EXPORT Project : public QObject
{
friend class SessionManager; // for setActiveTarget
- friend class ProjectExplorerPlugin; // for projectLoaded
Q_OBJECT
public:
@@ -84,7 +84,7 @@ public:
QString mimeType() const;
bool canBuildProducts() const;
- BuildSystem *buildSystem() const;
+ BuildSystem *createBuildSystem(Target *target) const;
Utils::FilePath projectFilePath() const;
Utils::FilePath projectDirectory() const;
@@ -124,7 +124,6 @@ public:
static const NodeMatcher GeneratedFiles;
Utils::FilePathList files(const NodeMatcher &matcher) const;
- virtual QStringList filesGeneratedFrom(const QString &sourceFile) const;
bool isKnownFile(const Utils::FilePath &filename) const;
virtual QVariantMap toMap() const;
@@ -155,81 +154,20 @@ public:
void setup(const QList<BuildInfo> &infoList);
Utils::MacroExpander *macroExpander() const;
- virtual QVariant additionalData(Core::Id id, const Target *target) const;
-
- bool isParsing() const;
- bool hasParsingData() const;
-
ProjectNode *findNodeForBuildKey(const QString &buildKey) const;
bool needsInitialExpansion() const;
void setNeedsInitialExpansion(bool needsInitialExpansion);
- class ParseGuard
- {
- public:
- ParseGuard()
- : ParseGuard(nullptr)
- {}
-
- ~ParseGuard() { release(); }
-
- void markAsSuccess() const { m_success = true; }
- bool isSuccess() const { return m_success; }
- bool guardsProject() const { return m_project; }
-
- ParseGuard(const ParseGuard &other) = delete;
- ParseGuard &operator=(const ParseGuard &other) = delete;
- ParseGuard(ParseGuard &&other)
- : m_project{std::move(other.m_project)}
- , m_success{std::move(other.m_success)}
- {
- // No need to release this as this is invalid anyway:-)
- other.m_project = nullptr;
- }
- ParseGuard &operator=(ParseGuard &&other)
- {
- release();
-
- m_project = std::move(other.m_project);
- m_success = std::move(other.m_success);
-
- other.m_project = nullptr;
- return *this;
- }
-
- private:
- ParseGuard(Project *p)
- : m_project(p)
- {
- if (m_project && !m_project->isParsing())
- m_project->emitParsingStarted();
- else
- m_project = nullptr;
- }
-
- void release()
- {
- if (m_project)
- m_project->emitParsingFinished(m_success);
- m_project = nullptr;
- }
-
- Project *m_project = nullptr;
- mutable bool m_success = false;
-
- friend class Project;
- };
-
- // FIXME: Make this private and the BuildSystem a friend
- ParseGuard guardParsingRun() { return ParseGuard(this); }
void setRootProjectNode(std::unique_ptr<ProjectNode> &&root);
// Set project files that will be watched and trigger the same callback
// as the main project file.
void setExtraProjectFiles(const QVector<Utils::FilePath> &projectDocumentPaths);
- Utils::Environment activeParseEnvironment() const;
+ void setDisplayName(const QString &name);
+ void setProjectLanguage(Core::Id id, bool enabled);
+ void addProjectLanguage(Core::Id id);
signals:
void projectFileIsDirty(const Utils::FilePath &path);
@@ -243,11 +181,6 @@ signals:
void removedProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
void addedProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
- // *ANY* active build configuration changed somewhere in the tree. This might not be
- // the one that would get started right now, since some part of the tree in between might
- // not be active.
- void activeBuildConfigurationChanged(ProjectExplorer::ProjectConfiguration *bc);
-
void aboutToRemoveTarget(ProjectExplorer::Target *target);
void removedTarget(ProjectExplorer::Target *target);
void addedTarget(ProjectExplorer::Target *target);
@@ -257,8 +190,8 @@ signals:
void projectLanguagesUpdated();
- void parsingStarted();
- void parsingFinished(bool success);
+ void anyParsingStarted(Target *target);
+ void anyParsingFinished(Target *target, bool success);
void rootProjectDirectoryChanged();
@@ -267,7 +200,6 @@ protected:
void createTargetFromMap(const QVariantMap &map, int index);
virtual bool setupTarget(Target *t);
- void setDisplayName(const QString &name);
// Used to pre-check kits in the TargetSetupPage. RequiredKitPredicate
// is used to select kits available in the TargetSetupPage
void setPreferredKitPredicate(const Kit::Predicate &predicate);
@@ -278,35 +210,26 @@ protected:
void setId(Core::Id id);
void setProjectLanguages(Core::Context language);
- void addProjectLanguage(Core::Id id);
void removeProjectLanguage(Core::Id id);
- void setProjectLanguage(Core::Id id, bool enabled);
void setHasMakeInstallEquivalent(bool enabled);
- virtual void projectLoaded(); // Called when the project is fully loaded.
void setKnowsAllBuildExecutables(bool value);
void setNeedsBuildConfigurations(bool value);
+ void setNeedsDeployConfigurations(bool value);
static ProjectExplorer::Task createProjectTask(ProjectExplorer::Task::TaskType type,
const QString &description);
- void setBuildSystemCreator(const std::function<BuildSystem *(Project *)> &creator);
+ void setBuildSystemCreator(const std::function<BuildSystem *(Target *)> &creator);
private:
- // Helper methods to manage parsing state and signalling
- // Call in GUI thread before the actual parsing starts
- void emitParsingStarted();
- // Call in GUI thread right after the actual parsing is done
- void emitParsingFinished(bool success);
-
void addTarget(std::unique_ptr<Target> &&target);
void handleSubTreeChanged(FolderNode *node);
void setActiveTarget(Target *target);
- ProjectPrivate *d;
-
friend class ContainerNode;
+ ProjectPrivate *d;
};
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index 4d7aee5fc8..93f003b7b2 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -2046,7 +2046,6 @@ ProjectExplorerPlugin::OpenProjectResult ProjectExplorerPlugin::openProject(cons
return result;
dd->addToRecentProjects(fileName, project->displayName());
SessionManager::setStartupProject(project);
- project->projectLoaded();
return result;
}
@@ -2113,9 +2112,6 @@ ProjectExplorerPlugin::OpenProjectResult ProjectExplorerPlugin::openProjects(con
appendError(errorString,
tr("Failed opening project \"%1\": Project is not a file.").arg(fileName));
} else if (Project *pro = ProjectManager::openProject(mt, filePath)) {
- QObject::connect(pro, &Project::parsingFinished, [pro]() {
- emit SessionManager::instance()->projectFinishedParsing(pro);
- });
QString restoreError;
Project::RestoreResult restoreResult = pro->restoreSettings(&restoreError);
if (restoreResult == Project::RestoreResult::Ok) {
diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp
index 76fe5ed9dc..007fe38e21 100644
--- a/src/plugins/projectexplorer/projectmodels.cpp
+++ b/src/plugins/projectexplorer/projectmodels.cpp
@@ -25,6 +25,7 @@
#include "projectmodels.h"
+#include "buildsystem.h"
#include "project.h"
#include "projectnodes.h"
#include "projectexplorer.h"
@@ -119,6 +120,8 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
const FolderNode * const folderNode = node->asFolderNode();
const ContainerNode * const containerNode = node->asContainerNode();
const Project * const project = containerNode ? containerNode->project() : nullptr;
+ const Target * const target = project ? project->activeTarget() : nullptr;
+ const BuildSystem * const bs = target ? target->buildSystem() : nullptr;
switch (role) {
case Qt::DisplayRole:
@@ -128,7 +131,7 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
case Qt::ToolTipRole: {
QString tooltip = node->tooltip();
if (project) {
- if (project->activeTarget()) {
+ if (target) {
QString projectIssues = toHtml(project->projectIssues(project->activeTarget()->kit()));
if (!projectIssues.isEmpty())
tooltip += "<p>" + projectIssues;
@@ -148,10 +151,9 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
static QIcon emptyIcon = Utils::Icons::EMPTY16.icon();
if (project->needsConfiguration())
return warnIcon;
- if (project->isParsing())
+ if (bs && bs->isParsing())
return emptyIcon;
- if (!project->activeTarget()
- || !project->projectIssues(project->activeTarget()->kit()).isEmpty())
+ if (!target || !project->projectIssues(target->kit()).isEmpty())
return warnIcon;
return containerNode->rootProjectNode() ? containerNode->rootProjectNode()->icon()
: folderNode->icon();
@@ -167,7 +169,7 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
case Project::FilePathRole:
return node->filePath().toString();
case Project::isParsingRole:
- return project ? project->isParsing() && !project->needsConfiguration() : false;
+ return project && bs ? bs->isParsing() && !project->needsConfiguration() : false;
}
return QVariant();
@@ -359,12 +361,12 @@ void FlatModel::handleProjectAdded(Project *project)
{
QTC_ASSERT(project, return);
- connect(project, &Project::parsingStarted,
+ connect(project, &Project::anyParsingStarted,
this, [this, project]() {
if (nodeForProject(project))
parsingStateChanged(project);
});
- connect(project, &Project::parsingFinished,
+ connect(project, &Project::anyParsingFinished,
this, [this, project]() {
if (nodeForProject(project))
parsingStateChanged(project);
diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp
index dd3783ebe0..09fb24520d 100644
--- a/src/plugins/projectexplorer/projectnodes.cpp
+++ b/src/plugins/projectexplorer/projectnodes.cpp
@@ -25,10 +25,12 @@
#include "projectnodes.h"
+#include "buildconfiguration.h"
#include "buildsystem.h"
#include "project.h"
#include "projectexplorerconstants.h"
#include "projecttree.h"
+#include "target.h"
#include <coreplugin/fileiconprovider.h>
#include <coreplugin/icore.h>
@@ -988,7 +990,8 @@ void ProjectNode::setFallbackData(Core::Id key, const QVariant &value)
BuildSystem *ProjectNode::buildSystem() const
{
Project *p = getProject();
- return p ? p->buildSystem() : nullptr;
+ Target *t = p ? p->activeTarget() : nullptr;
+ return t ? t->buildSystem() : nullptr;
}
bool FolderNode::isEmpty() const
diff --git a/src/plugins/projectexplorer/projecttree.cpp b/src/plugins/projectexplorer/projecttree.cpp
index 8fda8340d7..b42da7ad66 100644
--- a/src/plugins/projectexplorer/projecttree.cpp
+++ b/src/plugins/projectexplorer/projecttree.cpp
@@ -30,6 +30,7 @@
#include "projectnodes.h"
#include "projecttreewidget.h"
#include "session.h"
+#include "target.h"
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
@@ -104,6 +105,18 @@ Project *ProjectTree::currentProject()
return s_instance->m_currentProject;
}
+Target *ProjectTree::currentTarget()
+{
+ Project *p = currentProject();
+ return p ? p->activeTarget() : nullptr;
+}
+
+BuildSystem *ProjectTree::currentBuildSystem()
+{
+ Target *t = currentTarget();
+ return t ? t->buildSystem() : nullptr;
+}
+
Node *ProjectTree::currentNode()
{
s_instance->update();
diff --git a/src/plugins/projectexplorer/projecttree.h b/src/plugins/projectexplorer/projecttree.h
index 4adcaa7571..bf1335e5be 100644
--- a/src/plugins/projectexplorer/projecttree.h
+++ b/src/plugins/projectexplorer/projecttree.h
@@ -34,12 +34,14 @@
namespace Utils { class FilePath; }
namespace ProjectExplorer {
+class BuildSystem;
class FileNode;
class FolderNode;
class Node;
class Project;
class ProjectNode;
class SessionNode;
+class Target;
namespace Internal { class ProjectTreeWidget; }
@@ -53,6 +55,8 @@ public:
static ProjectTree *instance();
static Project *currentProject();
+ static Target *currentTarget();
+ static BuildSystem *currentBuildSystem();
static Node *currentNode();
static Utils::FilePath currentFilePath();
diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp
index 4629e0bc22..7c40d8bc41 100644
--- a/src/plugins/projectexplorer/runconfiguration.cpp
+++ b/src/plugins/projectexplorer/runconfiguration.cpp
@@ -27,6 +27,7 @@
#include "abi.h"
#include "buildconfiguration.h"
+#include "buildsystem.h"
#include "environmentaspect.h"
#include "kitinformation.h"
#include "kitinformation.h"
@@ -168,8 +169,7 @@ RunConfiguration::RunConfiguration(Target *target, Core::Id id)
: ProjectConfiguration(target, id)
{
QTC_CHECK(target && target == this->target());
- connect(target->project(), &Project::parsingFinished,
- this, [this]() { updateEnabledState(); });
+ connect(target, &Target::parsingFinished, this, [this] { updateEnabledState(); });
connect(target, &Target::addedRunConfiguration,
this, [this](const RunConfiguration *rc) {
@@ -224,25 +224,16 @@ bool RunConfiguration::isActive() const
return target()->isActive() && target()->activeRunConfiguration() == this;
}
-void RunConfiguration::setEnabled(bool enabled)
+QString RunConfiguration::disabledReason() const
{
- if (enabled == m_isEnabled)
- return;
- m_isEnabled = enabled;
- emit enabledChanged();
+ BuildSystem *bs = activeBuildSystem();
+ return bs ? bs->disabledReason(m_buildKey) : tr("No build system active");
}
-QString RunConfiguration::disabledReason() const
+bool RunConfiguration::isEnabled() const
{
- if (!project()->hasParsingData()) {
- QString msg = project()->isParsing() ? tr("The project is currently being parsed.")
- : tr("The project could not be fully parsed.");
- const FilePath projectFilePath = buildTargetInfo().projectFilePath;
- if (!projectFilePath.isEmpty() && !projectFilePath.exists())
- msg += '\n' + tr("The project file \"%1\" does not exist.").arg(projectFilePath.toString());
- return msg;
- }
- return QString();
+ BuildSystem *bs = activeBuildSystem();
+ return bs && bs->hasParsingData();
}
QWidget *RunConfiguration::createConfigurationWidget()
@@ -266,7 +257,7 @@ QWidget *RunConfiguration::createConfigurationWidget()
void RunConfiguration::updateEnabledState()
{
- setEnabled(project()->hasParsingData());
+ emit enabledChanged();
}
void RunConfiguration::addAspectFactory(const AspectFactory &aspectFactory)
@@ -312,11 +303,14 @@ RunConfiguration::ConfigurationState RunConfiguration::ensureConfigured(QString
BuildConfiguration *RunConfiguration::activeBuildConfiguration() const
{
- if (!target())
- return nullptr;
return target()->activeBuildConfiguration();
}
+BuildSystem *RunConfiguration::activeBuildSystem() const
+{
+ return target()->buildSystem();
+}
+
QVariantMap RunConfiguration::toMap() const
{
QVariantMap map = ProjectConfiguration::toMap();
@@ -344,7 +338,9 @@ CommandLine RunConfiguration::commandLine() const
BuildTargetInfo RunConfiguration::buildTargetInfo() const
{
- return target()->buildTarget(m_buildKey);
+ BuildSystem *bs = target()->buildSystem();
+ QTC_ASSERT(bs, return {});
+ return bs->buildTarget(m_buildKey);
}
bool RunConfiguration::fromMap(const QVariantMap &map)
diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h
index 78175e6156..ae6ad9e2d6 100644
--- a/src/plugins/projectexplorer/runconfiguration.h
+++ b/src/plugins/projectexplorer/runconfiguration.h
@@ -43,6 +43,7 @@ namespace Utils { class OutputFormatter; }
namespace ProjectExplorer {
class BuildConfiguration;
+class BuildSystem;
class GlobalOrProjectAspect;
class Runnable;
class RunConfigurationFactory;
@@ -126,10 +127,8 @@ public:
bool isActive() const override;
- bool isEnabled() const { return m_isEnabled; }
- void setEnabled(bool enabled);
-
virtual QString disabledReason() const;
+ virtual bool isEnabled() const;
virtual QWidget *createConfigurationWidget();
@@ -182,6 +181,7 @@ protected:
/// convenience function to get current build configuration.
BuildConfiguration *activeBuildConfiguration() const;
+ BuildSystem *activeBuildSystem() const;
virtual void updateEnabledState();
virtual void doAdditionalSetup(const RunConfigurationCreationInfo &) {}
@@ -193,7 +193,6 @@ private:
friend class RunConfigurationFactory;
QString m_buildKey;
- bool m_isEnabled = false;
CommandLineGetter m_commandLineGetter;
};
diff --git a/src/plugins/projectexplorer/runcontrol.cpp b/src/plugins/projectexplorer/runcontrol.cpp
index b4a50d0099..ec775c72df 100644
--- a/src/plugins/projectexplorer/runcontrol.cpp
+++ b/src/plugins/projectexplorer/runcontrol.cpp
@@ -376,7 +376,7 @@ void RunControl::setTarget(Target *target)
QTC_CHECK(!d->target);
d->target = target;
- if (!d->buildKey.isEmpty())
+ if (!d->buildKey.isEmpty() && target->buildSystem())
d->buildTargetInfo = target->buildTarget(d->buildKey);
if (auto bc = target->activeBuildConfiguration()) {
diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp
index f224bce49e..858ceb815c 100644
--- a/src/plugins/projectexplorer/session.cpp
+++ b/src/plugins/projectexplorer/session.cpp
@@ -381,6 +381,17 @@ Project *SessionManager::startupProject()
return d->m_startupProject;
}
+Target *SessionManager::startupTarget()
+{
+ return d->m_startupProject ? d->m_startupProject->activeTarget() : nullptr;
+}
+
+BuildSystem *SessionManager::startupBuildSystem()
+{
+ Target *t = startupTarget();
+ return t ? t->buildSystem() : nullptr;
+}
+
void SessionManager::addProject(Project *pro)
{
QTC_ASSERT(pro, return);
diff --git a/src/plugins/projectexplorer/session.h b/src/plugins/projectexplorer/session.h
index 782079f9d7..dfc403bc42 100644
--- a/src/plugins/projectexplorer/session.h
+++ b/src/plugins/projectexplorer/session.h
@@ -42,7 +42,9 @@ namespace ProjectExplorer {
class Project;
class Target;
class BuildConfiguration;
+class BuildSystem;
class DeployConfiguration;
+
enum class SetActive { Cascade, NoCascade };
class PROJECTEXPLORER_EXPORT SessionManager : public QObject
@@ -96,6 +98,8 @@ public:
static Utils::FilePath sessionNameToFileName(const QString &session);
static Project *startupProject();
+ static Target *startupTarget();
+ static BuildSystem *startupBuildSystem();
static const QList<Project *> projects();
static bool hasProjects();
@@ -119,6 +123,8 @@ public:
static bool loadingSession();
signals:
+ void targetAdded(ProjectExplorer::Target *target);
+ void targetRemoved(ProjectExplorer::Target *target);
void projectAdded(ProjectExplorer::Project *project);
void aboutToRemoveProject(ProjectExplorer::Project *project);
void projectDisplayNameChanged(ProjectExplorer::Project *project);
diff --git a/src/plugins/projectexplorer/target.cpp b/src/plugins/projectexplorer/target.cpp
index f8a0da25e7..dd9d98fd82 100644
--- a/src/plugins/projectexplorer/target.cpp
+++ b/src/plugins/projectexplorer/target.cpp
@@ -29,6 +29,7 @@
#include "buildconfiguration.h"
#include "buildinfo.h"
#include "buildmanager.h"
+#include "buildsystem.h"
#include "buildtargetinfo.h"
#include "deployconfiguration.h"
#include "deploymentdata.h"
@@ -98,20 +99,24 @@ public:
m_runConfigurationModel(t)
{ }
+ ~TargetPrivate()
+ {
+ delete m_buildSystem;
+ }
+
QIcon m_overlayIcon;
QList<BuildConfiguration *> m_buildConfigurations;
- BuildConfiguration *m_activeBuildConfiguration = nullptr;
+ QPointer<BuildConfiguration> m_activeBuildConfiguration;
QList<DeployConfiguration *> m_deployConfigurations;
DeployConfiguration *m_activeDeployConfiguration = nullptr;
QList<RunConfiguration *> m_runConfigurations;
RunConfiguration* m_activeRunConfiguration = nullptr;
- DeploymentData m_deploymentData;
- QList<BuildTargetInfo> m_appTargets;
QVariantMap m_pluginSettings;
Kit *const m_kit;
MacroExpander m_macroExpander;
+ BuildSystem *m_buildSystem = nullptr;
ProjectConfigurationModel m_buildConfigurationModel;
ProjectConfigurationModel m_deployConfigurationModel;
@@ -123,13 +128,24 @@ Target::Target(Project *project, Kit *k, _constructor_tag) :
QObject(project),
d(std::make_unique<TargetPrivate>(this, k))
{
+ // Note: nullptr is a valid state for the per-buildConfig systems.
+ d->m_buildSystem = project->createBuildSystem(this);
+
QTC_CHECK(d->m_kit);
connect(DeviceManager::instance(), &DeviceManager::updated, this, &Target::updateDeviceState);
- connect(project, &Project::parsingFinished, this, [this](bool success) {
- if (success && this->project() == SessionManager::startupProject()
- && this == this->project()->activeTarget()) {
+
+ connect(this, &Target::parsingStarted, this, [this, project] {
+ project->anyParsingStarted(this);
+ });
+
+ connect(this, &Target::parsingFinished, this, [this, project](bool success) {
+ if (success && project == SessionManager::startupProject()
+ && this == project->activeTarget()) {
updateDefaultRunConfigurations();
}
+ // For testing.
+ emit SessionManager::instance()->projectFinishedParsing(project);
+ project->anyParsingFinished(this, success);
}, Qt::QueuedConnection); // Must wait for run configs to change their enabled state.
KitManager *km = KitManager::instance();
@@ -193,6 +209,37 @@ Kit *Target::kit() const
return d->m_kit;
}
+BuildSystem *Target::buildSystem() const
+{
+ if (d->m_activeBuildConfiguration)
+ return d->m_activeBuildConfiguration->buildSystem();
+
+ return d->m_buildSystem;
+}
+
+BuildSystem *Target::fallbackBuildSystem() const
+{
+ return d->m_buildSystem;
+}
+
+DeploymentData Target::deploymentData() const
+{
+ QTC_ASSERT(buildSystem(), return {});
+ return buildSystem()->deploymentData();
+}
+
+const QList<BuildTargetInfo> Target::applicationTargets() const
+{
+ QTC_ASSERT(buildSystem(), return {});
+ return buildSystem()->applicationTargets();
+}
+
+BuildTargetInfo Target::buildTarget(const QString &buildKey) const
+{
+ QTC_ASSERT(buildSystem(), return {});
+ return buildSystem()->buildTarget(buildKey);
+}
+
Core::Id Target::id() const
{
return d->m_kit->id();
@@ -277,7 +324,6 @@ void Target::setActiveBuildConfiguration(BuildConfiguration *bc)
(bc && d->m_buildConfigurations.contains(bc) &&
bc != d->m_activeBuildConfiguration)) {
d->m_activeBuildConfiguration = bc;
- project()->activeBuildConfigurationChanged(d->m_activeBuildConfiguration);
emit activeBuildConfigurationChanged(d->m_activeBuildConfiguration);
}
}
@@ -353,49 +399,6 @@ void Target::setActiveDeployConfiguration(DeployConfiguration *dc)
updateDeviceState();
}
-void Target::setDeploymentData(const DeploymentData &deploymentData)
-{
- if (d->m_deploymentData != deploymentData) {
- d->m_deploymentData = deploymentData;
- emit deploymentDataChanged();
- emit applicationTargetsChanged();
- }
-}
-
-DeploymentData Target::deploymentData() const
-{
- return d->m_deploymentData;
-}
-
-void Target::setApplicationTargets(const QList<BuildTargetInfo> &appTargets)
-{
- if (Utils::toSet(appTargets) != Utils::toSet(d->m_appTargets)) {
- d->m_appTargets = appTargets;
- emit applicationTargetsChanged();
- }
-}
-
-const QList<BuildTargetInfo> Target::applicationTargets() const
-{
- return d->m_appTargets;
-}
-
-BuildTargetInfo Target::buildTarget(const QString &buildKey) const
-{
- return Utils::findOrDefault(d->m_appTargets, [&buildKey](const BuildTargetInfo &ti) {
- return ti.buildKey == buildKey;
- });
-}
-
-QList<ProjectConfiguration *> Target::projectConfigurations() const
-{
- QList<ProjectConfiguration *> result;
- result.append(Utils::static_container_cast<ProjectConfiguration *>(buildConfigurations()));
- result.append(Utils::static_container_cast<ProjectConfiguration *>(deployConfigurations()));
- result.append(Utils::static_container_cast<ProjectConfiguration *>(runConfigurations()));
- return result;
-}
-
QList<RunConfiguration *> Target::runConfigurations() const
{
return d->m_runConfigurations;
@@ -716,7 +719,7 @@ void Target::setNamedSettings(const QString &name, const QVariant &value)
QVariant Target::additionalData(Core::Id id) const
{
- return project()->additionalData(id, this);
+ return buildSystem()->additionalData(id);
}
MakeInstallCommand Target::makeInstallCommand(const QString &installRoot) const
diff --git a/src/plugins/projectexplorer/target.h b/src/plugins/projectexplorer/target.h
index 612adcef75..247b0e0425 100644
--- a/src/plugins/projectexplorer/target.h
+++ b/src/plugins/projectexplorer/target.h
@@ -35,6 +35,7 @@ QT_FORWARD_DECLARE_CLASS(QIcon)
namespace ProjectExplorer {
class BuildConfiguration;
class BuildTargetInfo;
+class BuildSystem;
class DeployConfiguration;
class DeploymentData;
class Kit;
@@ -60,6 +61,7 @@ public:
Project *project() const;
Kit *kit() const;
+ BuildSystem *buildSystem() const;
Core::Id id() const;
QString displayName() const;
@@ -79,15 +81,6 @@ public:
QList<DeployConfiguration *> deployConfigurations() const;
DeployConfiguration *activeDeployConfiguration() const;
- void setDeploymentData(const DeploymentData &deploymentData);
- DeploymentData deploymentData() const;
-
- void setApplicationTargets(const QList<BuildTargetInfo> &appTargets);
- const QList<BuildTargetInfo> applicationTargets() const;
- BuildTargetInfo buildTarget(const QString &buildKey) const;
-
- QList<ProjectConfiguration *> projectConfigurations() const;
-
// Running
QList<RunConfiguration *> runConfigurations() const;
void addRunConfiguration(RunConfiguration *rc);
@@ -119,12 +112,20 @@ public:
ProjectConfigurationModel *deployConfigurationModel() const;
ProjectConfigurationModel *runConfigurationModel() const;
+ BuildSystem *fallbackBuildSystem() const;
+
+ DeploymentData deploymentData() const;
+ const QList<BuildTargetInfo> applicationTargets() const;
+ BuildTargetInfo buildTarget(const QString &buildKey) const;
+
signals:
void targetEnabled(bool);
void iconChanged();
void overlayIconChanged();
void kitChanged();
+ void parsingStarted();
+ void parsingFinished(bool);
// TODO clean up signal names
// might be better to also have aboutToRemove signals
@@ -143,6 +144,7 @@ signals:
void deploymentDataChanged();
void applicationTargetsChanged();
+ void targetPropertiesChanged();
private:
bool fromMap(const QVariantMap &map);
diff --git a/src/plugins/python/pythonproject.cpp b/src/plugins/python/pythonproject.cpp
index 892b9f144f..357438dbb8 100644
--- a/src/plugins/python/pythonproject.cpp
+++ b/src/plugins/python/pythonproject.cpp
@@ -39,6 +39,7 @@
#include <QJsonObject>
#include <QProcessEnvironment>
#include <QRegularExpression>
+#include <QTimer>
#include <coreplugin/documentmanager.h>
#include <coreplugin/icontext.h>
@@ -57,7 +58,7 @@ namespace Internal {
class PythonBuildSystem : public BuildSystem
{
public:
- explicit PythonBuildSystem(Project *project);
+ explicit PythonBuildSystem(Target *target);
bool supportsAction(Node *context, ProjectAction action, const Node *node) const override;
bool addFiles(Node *, const QStringList &filePaths, QStringList *) override;
@@ -74,11 +75,9 @@ public:
bool writePyProjectFile(const QString &fileName, QString &content,
const QStringList &rawList, QString *errorMessage);
- void refresh();
+ void triggerParsing() final;
private:
- PythonProject *project() const;
-
QStringList m_rawFileList;
QStringList m_files;
QHash<QString, QString> m_rawListEntries;
@@ -191,12 +190,12 @@ PythonProject::PythonProject(const FilePath &fileName)
setDisplayName(fileName.toFileInfo().completeBaseName());
setNeedsBuildConfigurations(false);
- setBuildSystemCreator([](Project *p) { return new PythonBuildSystem(p); });
+ setBuildSystemCreator([](Target *t) { return new PythonBuildSystem(t); });
}
-void PythonBuildSystem::refresh()
+void PythonBuildSystem::triggerParsing()
{
- Project::ParseGuard guard = project()->guardParsingRun();
+ ParseGuard guard = guardParsingRun();
parse();
const QDir baseDir(projectDirectory().toString());
@@ -225,8 +224,7 @@ void PythonBuildSystem::refresh()
}
project()->setRootProjectNode(std::move(newRoot));
- if (Target *target = project()->activeTarget())
- target->setApplicationTargets(appTargets);
+ setApplicationTargets(appTargets);
guard.markAsSuccess();
}
@@ -423,27 +421,16 @@ Project::RestoreResult PythonProject::fromMap(const QVariantMap &map, QString *e
if (res == RestoreResult::Ok) {
if (!activeTarget())
addTargetForDefaultKit();
-
- if (auto bs = dynamic_cast<PythonBuildSystem *>(buildSystem()))
- bs->refresh();
}
return res;
}
-bool PythonProject::setupTarget(Target *t)
+PythonBuildSystem::PythonBuildSystem(Target *target)
+ : BuildSystem(target)
{
- bool res = Project::setupTarget(t);
- if (auto bs = dynamic_cast<PythonBuildSystem *>(buildSystem()))
- QTimer::singleShot(0, bs, &PythonBuildSystem::refresh);
- return res;
-}
-
-PythonBuildSystem::PythonBuildSystem(Project *project)
- : BuildSystem(project)
-{
- connect(project, &Project::projectFileIsDirty, this, [this]() { refresh(); });
- QTimer::singleShot(0, this, &PythonBuildSystem::refresh);
+ connect(target->project(), &Project::projectFileIsDirty, this, [this]() { triggerParsing(); });
+ QTimer::singleShot(0, this, &PythonBuildSystem::triggerParsing);
}
bool PythonBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
@@ -460,10 +447,5 @@ bool PythonBuildSystem::supportsAction(Node *context, ProjectAction action, cons
return BuildSystem::supportsAction(context, action, node);
}
-PythonProject *PythonBuildSystem::project() const
-{
- return static_cast<PythonProject *>(BuildSystem::project());
-}
-
} // namespace Internal
} // namespace Python
diff --git a/src/plugins/python/pythonproject.h b/src/plugins/python/pythonproject.h
index d030c92dcd..38b7dc2791 100644
--- a/src/plugins/python/pythonproject.h
+++ b/src/plugins/python/pythonproject.h
@@ -43,7 +43,6 @@ public:
bool needsConfiguration() const final { return false; }
private:
RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override;
- bool setupTarget(ProjectExplorer::Target *t) override;
};
} // namespace Internal
diff --git a/src/plugins/python/pythonrunconfiguration.cpp b/src/plugins/python/pythonrunconfiguration.cpp
index 8af7e2f1b2..eca2d7e7ef 100644
--- a/src/plugins/python/pythonrunconfiguration.cpp
+++ b/src/plugins/python/pythonrunconfiguration.cpp
@@ -279,7 +279,7 @@ PythonRunConfiguration::PythonRunConfiguration(Target *target, Core::Id id)
connect(target, &Target::applicationTargetsChanged,
this, &PythonRunConfiguration::updateTargetInformation);
- connect(target->project(), &Project::parsingFinished,
+ connect(target, &Target::parsingFinished,
this, &PythonRunConfiguration::updateTargetInformation);
}
diff --git a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp
index 93cbde2eb1..eeab2c51f7 100644
--- a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp
+++ b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp
@@ -52,6 +52,7 @@
#include <utils/qtcprocess.h>
#include <QCoreApplication>
+#include <QCryptographicHash>
using namespace ProjectExplorer;
using namespace Utils;
@@ -92,6 +93,18 @@ QbsBuildConfiguration::QbsBuildConfiguration(Target *target, Core::Id id)
this, &QbsBuildConfiguration::triggerReparseIfActive);
connect(this, &QbsBuildConfiguration::qbsConfigurationChanged,
this, &QbsBuildConfiguration::triggerReparseIfActive);
+
+ m_buildSystem = new QbsBuildSystem(this);
+}
+
+QbsBuildConfiguration::~QbsBuildConfiguration()
+{
+ delete m_buildSystem;
+}
+
+BuildSystem *QbsBuildConfiguration::buildSystem() const
+{
+ return m_buildSystem;
}
void QbsBuildConfiguration::initialize()
@@ -119,7 +132,15 @@ void QbsBuildConfiguration::initialize()
+ Utils::FileUtils::fileSystemFriendlyName(initialDisplayName());
}
- m_configurationName->setValue(configName);
+ const Kit *kit = target()->kit();
+ const QString kitName = kit->displayName();
+ const QByteArray kitHash = QCryptographicHash::hash(kitName.toUtf8(), QCryptographicHash::Sha1);
+
+ const QString uniqueConfigName = configName
+ + '_' + kit->fileSystemFriendlyName().left(8)
+ + '_' + kitHash.toHex().left(16);
+
+ m_configurationName->setValue(uniqueConfigName);
BuildStepList *buildSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
auto bs = new QbsBuildStep(buildSteps);
@@ -137,7 +158,7 @@ void QbsBuildConfiguration::initialize()
void QbsBuildConfiguration::triggerReparseIfActive()
{
if (isActive())
- qbsProject()->delayParsing();
+ m_buildSystem->delayParsing();
}
bool QbsBuildConfiguration::fromMap(const QVariantMap &map)
@@ -169,11 +190,6 @@ QVariantMap QbsBuildConfiguration::qbsConfiguration() const
return config;
}
-Internal::QbsProject *QbsBuildConfiguration::qbsProject() const
-{
- return qobject_cast<Internal::QbsProject *>(project());
-}
-
BuildConfiguration::BuildType QbsBuildConfiguration::buildType() const
{
QString variant;
diff --git a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h
index 0dbd442efb..a19c52fd99 100644
--- a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h
+++ b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h
@@ -46,15 +46,15 @@ class QbsBuildConfiguration : public ProjectExplorer::BuildConfiguration
friend class ProjectExplorer::BuildConfigurationFactory;
QbsBuildConfiguration(ProjectExplorer::Target *target, Core::Id id);
+ ~QbsBuildConfiguration() final;
public:
- void initialize() override;
+ ProjectExplorer::BuildSystem *buildSystem() const final;
+ void initialize() final;
QbsBuildStep *qbsStep() const;
QVariantMap qbsConfiguration() const;
- Internal::QbsProject *qbsProject() const;
-
BuildType buildType() const override;
void setChangedFiles(const QStringList &files);
@@ -67,7 +67,6 @@ public:
QStringList products() const;
QString configurationName() const;
-
QString equivalentCommandLine(const ProjectExplorer::BuildStep *buildStep) const;
signals:
@@ -80,7 +79,8 @@ private:
QStringList m_changedFiles;
QStringList m_activeFileTags;
QStringList m_products;
- ProjectExplorer::BaseStringAspect *m_configurationName;
+ ProjectExplorer::BaseStringAspect *m_configurationName = nullptr;
+ QbsBuildSystem *m_buildSystem = nullptr;
};
class QbsBuildConfigurationFactory : public ProjectExplorer::BuildConfigurationFactory
diff --git a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp
index 25d16c08ad..f58f63207e 100644
--- a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp
+++ b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp
@@ -170,7 +170,7 @@ QbsBuildStep::~QbsBuildStep()
bool QbsBuildStep::init()
{
- if (project()->isParsing() || m_job)
+ if (qbsBuildSystem()->isParsing() || m_job)
return false;
auto bc = static_cast<QbsBuildConfiguration *>(buildConfiguration());
@@ -212,7 +212,7 @@ ProjectExplorer::BuildStepConfigWidget *QbsBuildStep::createConfigWidget()
void QbsBuildStep::doCancel()
{
if (m_parsingProject)
- qbsProject()->cancelParsing();
+ qbsBuildSystem()->cancelParsing();
else if (m_job)
m_job->cancel();
}
@@ -238,10 +238,8 @@ QVariantMap QbsBuildStep::qbsConfiguration(VariableHandling variableHandling) co
void QbsBuildStep::setQbsConfiguration(const QVariantMap &config)
{
- auto pro = static_cast<QbsProject *>(project());
-
QVariantMap tmp = config;
- tmp.insert(Constants::QBS_CONFIG_PROFILE_KEY, pro->profileForTarget(target()));
+ tmp.insert(Constants::QBS_CONFIG_PROFILE_KEY, qbsBuildSystem()->profile());
if (!tmp.contains(Constants::QBS_CONFIG_VARIANT_KEY))
tmp.insert(Constants::QBS_CONFIG_VARIANT_KEY,
QString::fromLatin1(Constants::QBS_VARIANT_DEBUG));
@@ -347,14 +345,12 @@ void QbsBuildStep::buildingDone(bool success)
createTaskAndOutput(ProjectExplorer::Task::Error, item.description(),
item.codeLocation().filePath(), item.codeLocation().line());
- auto pro = static_cast<QbsProject *>(project());
-
// Building can uncover additional target artifacts.
- pro->updateAfterBuild();
+ qbsBuildSystem()->updateAfterBuild();
// The reparsing, if it is necessary, has to be done before finished() is emitted, as
// otherwise a potential additional build step could conflict with the parsing step.
- if (pro->parsingScheduled())
+ if (qbsBuildSystem()->parsingScheduled())
parseProject();
else
finish();
@@ -362,7 +358,7 @@ void QbsBuildStep::buildingDone(bool success)
void QbsBuildStep::reparsingDone(bool success)
{
- disconnect(project(), &Project::parsingFinished, this, &QbsBuildStep::reparsingDone);
+ disconnect(target(), &Target::parsingFinished, this, &QbsBuildStep::reparsingDone);
m_parsingProject = false;
if (m_job) { // This was a scheduled reparsing after building.
finish();
@@ -431,6 +427,11 @@ QString QbsBuildStep::buildVariant() const
return qbsConfiguration(PreserveVariables).value(Constants::QBS_CONFIG_VARIANT_KEY).toString();
}
+QbsBuildSystem *QbsBuildStep::qbsBuildSystem() const
+{
+ return static_cast<QbsBuildSystem *>(buildConfiguration()->buildSystem());
+}
+
void QbsBuildStep::setBuildVariant(const QString &variant)
{
if (m_qbsConfiguration.value(Constants::QBS_CONFIG_VARIANT_KEY).toString() == variant)
@@ -490,8 +491,8 @@ void QbsBuildStep::setCleanInstallRoot(bool clean)
void QbsBuildStep::parseProject()
{
m_parsingProject = true;
- connect(project(), &Project::parsingFinished, this, &QbsBuildStep::reparsingDone);
- qbsProject()->parseCurrentBuildConfiguration();
+ connect(target(), &Target::parsingFinished, this, &QbsBuildStep::reparsingDone);
+ qbsBuildSystem()->parseCurrentBuildConfiguration();
}
void QbsBuildStep::build()
@@ -503,7 +504,7 @@ void QbsBuildStep::build()
options.setLogElapsedTime(!qEnvironmentVariableIsEmpty(Constants::QBS_PROFILING_ENV));
QString error;
- m_job = qbsProject()->build(options, m_products, error);
+ m_job = qbsBuildSystem()->build(options, m_products, error);
if (!m_job) {
emit addOutput(error, OutputFormat::ErrorMessage);
emit finished(false);
diff --git a/src/plugins/qbsprojectmanager/qbsbuildstep.h b/src/plugins/qbsprojectmanager/qbsbuildstep.h
index 913bf61268..7258b6347c 100644
--- a/src/plugins/qbsprojectmanager/qbsbuildstep.h
+++ b/src/plugins/qbsprojectmanager/qbsbuildstep.h
@@ -79,6 +79,8 @@ public:
}
bool isQmlDebuggingEnabled() const { return m_enableQmlDebugging; }
+ QbsBuildSystem *qbsBuildSystem() const;
+
signals:
void qbsConfigurationChanged();
void qbsBuildOptionsChanged();
diff --git a/src/plugins/qbsprojectmanager/qbscleanstep.cpp b/src/plugins/qbsprojectmanager/qbscleanstep.cpp
index 7b64b888ce..5e46e166e9 100644
--- a/src/plugins/qbsprojectmanager/qbscleanstep.cpp
+++ b/src/plugins/qbsprojectmanager/qbscleanstep.cpp
@@ -81,7 +81,7 @@ QbsCleanStep::~QbsCleanStep()
bool QbsCleanStep::init()
{
- if (project()->isParsing() || m_job)
+ if (buildSystem()->isParsing() || m_job)
return false;
auto bc = static_cast<QbsBuildConfiguration *>(buildConfiguration());
@@ -95,13 +95,12 @@ bool QbsCleanStep::init()
void QbsCleanStep::doRun()
{
- auto pro = static_cast<QbsProject *>(project());
qbs::CleanOptions options;
options.setDryRun(m_dryRunAspect->value());
options.setKeepGoing(m_keepGoingAspect->value());
QString error;
- m_job = pro->clean(options, m_products, error);
+ m_job = qbsBuildSystem()->clean(options, m_products, error);
if (!m_job) {
emit addOutput(error, OutputFormat::ErrorMessage);
emit finished(false);
@@ -157,6 +156,11 @@ void QbsCleanStep::createTaskAndOutput(ProjectExplorer::Task::TaskType type, con
emit addOutput(message, OutputFormat::Stdout);
}
+QbsBuildSystem *QbsCleanStep::qbsBuildSystem() const
+{
+ return static_cast<QbsBuildSystem *>(buildSystem());
+}
+
// --------------------------------------------------------------------
// QbsCleanStepFactory:
// --------------------------------------------------------------------
diff --git a/src/plugins/qbsprojectmanager/qbscleanstep.h b/src/plugins/qbsprojectmanager/qbscleanstep.h
index fa07d35292..df2dccbf13 100644
--- a/src/plugins/qbsprojectmanager/qbscleanstep.h
+++ b/src/plugins/qbsprojectmanager/qbscleanstep.h
@@ -62,6 +62,8 @@ private:
ProjectExplorer::BaseBoolAspect *m_dryRunAspect = nullptr;
ProjectExplorer::BaseBoolAspect *m_keepGoingAspect = nullptr;
+ QbsBuildSystem *qbsBuildSystem() const;
+
QStringList m_products;
qbs::CleanJob *m_job = nullptr;
diff --git a/src/plugins/qbsprojectmanager/qbsinstallstep.cpp b/src/plugins/qbsprojectmanager/qbsinstallstep.cpp
index 648d4c3e8e..49ce7c8484 100644
--- a/src/plugins/qbsprojectmanager/qbsinstallstep.cpp
+++ b/src/plugins/qbsprojectmanager/qbsinstallstep.cpp
@@ -109,14 +109,14 @@ QbsInstallStep::~QbsInstallStep()
bool QbsInstallStep::init()
{
- QTC_ASSERT(!project()->isParsing() && !m_job, return false);
+ QTC_ASSERT(!buildConfiguration()->buildSystem()->isParsing() && !m_job, return false);
return true;
}
void QbsInstallStep::doRun()
{
- auto pro = static_cast<QbsProject *>(project());
- m_job = pro->install(m_qbsInstallOptions);
+ auto bs = static_cast<QbsBuildSystem *>(buildSystem());
+ m_job = bs->install(m_qbsInstallOptions);
if (!m_job) {
emit finished(false);
@@ -336,7 +336,7 @@ QbsInstallStepConfigWidget::QbsInstallStepConfigWidget(QbsInstallStep *step) :
connect(m_keepGoingCheckBox, &QAbstractButton::toggled,
this, &QbsInstallStepConfigWidget::changeKeepGoing);
- connect(m_step->project(), &Project::parsingFinished,
+ connect(m_step->target(), &Target::parsingFinished,
this, &QbsInstallStepConfigWidget::updateState);
updateState();
diff --git a/src/plugins/qbsprojectmanager/qbsnodes.cpp b/src/plugins/qbsprojectmanager/qbsnodes.cpp
index 002ebe77fb..8ec0669cd3 100644
--- a/src/plugins/qbsprojectmanager/qbsnodes.cpp
+++ b/src/plugins/qbsprojectmanager/qbsnodes.cpp
@@ -54,35 +54,6 @@ using namespace ProjectExplorer;
namespace QbsProjectManager {
namespace Internal {
-static const QbsProjectNode *parentQbsProjectNode(const ProjectExplorer::Node *node)
-{
- for (const ProjectExplorer::FolderNode *pn = node->managingProject(); pn; pn = pn->parentProjectNode()) {
- const auto prjNode = dynamic_cast<const QbsProjectNode *>(pn);
- if (prjNode)
- return prjNode;
- }
- return nullptr;
-}
-
-static const QbsProductNode *parentQbsProductNode(const ProjectExplorer::Node *node)
-{
- for (; node; node = node->parentFolderNode()) {
- const auto prdNode = dynamic_cast<const QbsProductNode *>(node);
- if (prdNode)
- return prdNode;
- }
- return nullptr;
-}
-
-static qbs::GroupData findMainQbsGroup(const qbs::ProductData &productData)
-{
- foreach (const qbs::GroupData &grp, productData.groups()) {
- if (grp.name() == productData.name() && grp.location() == productData.location())
- return grp;
- }
- return qbs::GroupData();
-}
-
class FileTreeNode {
public:
explicit FileTreeNode(const QString &n = QString(), FileTreeNode *p = nullptr, bool f = false) :
@@ -212,16 +183,6 @@ public:
};
-static bool supportsNodeAction(ProjectAction action, const Node *node)
-{
- const QbsProject * const project = parentQbsProjectNode(node)->project();
- if (!project->isProjectEditable())
- return false;
- if (action == RemoveFile || action == Rename)
- return node->asFileNode();
- return false;
-}
-
// --------------------------------------------------------------------
// QbsGroupNode:
// --------------------------------------------------------------------
@@ -337,16 +298,11 @@ QbsProjectNode::QbsProjectNode(const Utils::FilePath &projectDirectory) :
setIcon(projectIcon);
}
-QbsProject *QbsProjectNode::project() const
+Project *QbsProjectNode::project() const
{
return static_cast<QbsProjectNode *>(parentFolderNode())->project();
}
-const qbs::Project QbsProjectNode::qbsProject() const
-{
- return project()->qbsProject();
-}
-
void QbsProjectNode::setProjectData(const qbs::ProjectData &data)
{
m_projectData = data;
@@ -356,156 +312,11 @@ void QbsProjectNode::setProjectData(const qbs::ProjectData &data)
// QbsRootProjectNode:
// --------------------------------------------------------------------
-QbsRootProjectNode::QbsRootProjectNode(QbsProject *project) :
+QbsRootProjectNode::QbsRootProjectNode(Project *project) :
QbsProjectNode(project->projectDirectory()),
m_project(project)
{ }
-// --------------------------------------------------------------------
-// QbsBuildSystem:
-// --------------------------------------------------------------------
-
-QbsBuildSystem::QbsBuildSystem(Project *project)
- : BuildSystem(project)
-{
-}
-
-bool QbsBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
-{
- if (dynamic_cast<QbsGroupNode *>(context)) {
- if (action == AddNewFile || action == AddExistingFile)
- return true;
- }
-
- if (dynamic_cast<QbsProductNode *>(context)) {
- if (action == AddNewFile || action == AddExistingFile)
- return true;
- }
-
- return supportsNodeAction(action, node);
-}
-
-bool QbsBuildSystem::addFiles(Node *context, const QStringList &filePaths, QStringList *notAdded)
-{
- if (auto n = dynamic_cast<QbsGroupNode *>(context)) {
- QStringList notAddedDummy;
- if (!notAdded)
- notAdded = &notAddedDummy;
-
- const QbsProjectNode *prjNode = parentQbsProjectNode(n);
- if (!prjNode || !prjNode->qbsProject().isValid()) {
- *notAdded += filePaths;
- return false;
- }
-
- const QbsProductNode *prdNode = parentQbsProductNode(n);
- if (!prdNode || !prdNode->qbsProductData().isValid()) {
- *notAdded += filePaths;
- return false;
- }
-
- return prjNode->project()->addFilesToProduct(filePaths, prdNode->qbsProductData(),
- n->m_qbsGroupData, notAdded);
- }
-
- if (auto n = dynamic_cast<QbsProductNode *>(context)) {
- QStringList notAddedDummy;
- if (!notAdded)
- notAdded = &notAddedDummy;
-
- const QbsProjectNode *prjNode = parentQbsProjectNode(n);
- if (!prjNode || !prjNode->qbsProject().isValid()) {
- *notAdded += filePaths;
- return false;
- }
-
- qbs::GroupData grp = findMainQbsGroup(n->qbsProductData());
- if (grp.isValid())
- return prjNode->project()->addFilesToProduct(filePaths, n->qbsProductData(), grp, notAdded);
-
- QTC_ASSERT(false, return false);
- }
-
- return BuildSystem::addFiles(context, filePaths, notAdded);
-}
-
-RemovedFilesFromProject QbsBuildSystem::removeFiles(Node *context, const QStringList &filePaths,
- QStringList *notRemoved)
-{
- if (auto n = dynamic_cast<QbsGroupNode *>(context)) {
- QStringList notRemovedDummy;
- if (!notRemoved)
- notRemoved = &notRemovedDummy;
-
- const QbsProjectNode *prjNode = parentQbsProjectNode(n);
- if (!prjNode || !prjNode->qbsProject().isValid()) {
- *notRemoved += filePaths;
- return RemovedFilesFromProject::Error;
- }
-
- const QbsProductNode *prdNode = parentQbsProductNode(n);
- if (!prdNode || !prdNode->qbsProductData().isValid()) {
- *notRemoved += filePaths;
- return RemovedFilesFromProject::Error;
- }
-
- return project()->removeFilesFromProduct(filePaths, prdNode->qbsProductData(),
- n->m_qbsGroupData, notRemoved);
- }
-
- if (auto n = dynamic_cast<QbsProductNode *>(context)) {
- QStringList notRemovedDummy;
- if (!notRemoved)
- notRemoved = &notRemovedDummy;
-
- const QbsProjectNode *prjNode = parentQbsProjectNode(n);
- if (!prjNode || !prjNode->qbsProject().isValid()) {
- *notRemoved += filePaths;
- return RemovedFilesFromProject::Error;
- }
-
- qbs::GroupData grp = findMainQbsGroup(n->qbsProductData());
- if (grp.isValid()) {
- return prjNode->project()->removeFilesFromProduct(filePaths, n->qbsProductData(), grp,
- notRemoved);
- }
-
- QTC_ASSERT(false, return RemovedFilesFromProject::Error);
- }
-
- return BuildSystem::removeFiles(context, filePaths, notRemoved);
-}
-
-bool QbsBuildSystem::renameFile(Node *context, const QString &filePath, const QString &newFilePath)
-{
- if (auto *n = dynamic_cast<QbsGroupNode *>(context)) {
- const QbsProjectNode *prjNode = parentQbsProjectNode(n);
- if (!prjNode || !prjNode->qbsProject().isValid())
- return false;
- const QbsProductNode *prdNode = parentQbsProductNode(n);
- if (!prdNode || !prdNode->qbsProductData().isValid())
- return false;
-
- return project()->renameFileInProduct(filePath, newFilePath,
- prdNode->qbsProductData(), n->m_qbsGroupData);
- }
-
- if (auto *n = dynamic_cast<QbsProductNode *>(context)) {
- const QbsProjectNode * prjNode = parentQbsProjectNode(n);
- if (!prjNode || !prjNode->qbsProject().isValid())
- return false;
- const qbs::GroupData grp = findMainQbsGroup(n->qbsProductData());
- QTC_ASSERT(grp.isValid(), return false);
- return prjNode->project()->renameFileInProduct(filePath, newFilePath, n->qbsProductData(), grp);
- }
-
- return BuildSystem::renameFile(context, filePath, newFilePath);
-}
-
-QbsProject *QbsBuildSystem::project() const
-{
- return static_cast<QbsProject *>(BuildSystem::project());
-}
} // namespace Internal
} // namespace QbsProjectManager
diff --git a/src/plugins/qbsprojectmanager/qbsnodes.h b/src/plugins/qbsprojectmanager/qbsnodes.h
index a2439dcdb6..74a571bac6 100644
--- a/src/plugins/qbsprojectmanager/qbsnodes.h
+++ b/src/plugins/qbsprojectmanager/qbsnodes.h
@@ -35,26 +35,7 @@ namespace Internal {
class QbsNodeTreeBuilder;
class QbsProject;
-
-class QbsBuildSystem : public ProjectExplorer::BuildSystem
-{
-public:
- explicit QbsBuildSystem(ProjectExplorer::Project *project);
-
- bool supportsAction(ProjectExplorer::Node *context,
- ProjectExplorer::ProjectAction action,
- const ProjectExplorer::Node *node) const final;
- bool addFiles(ProjectExplorer::Node *context,
- const QStringList &filePaths,
- QStringList *notAdded = nullptr) override;
- ProjectExplorer::RemovedFilesFromProject removeFiles(ProjectExplorer::Node *context,
- const QStringList &filePaths,
- QStringList *notRemoved = nullptr) override;
- bool renameFile(ProjectExplorer::Node *context,
- const QString &filePath, const QString &newFilePath) override;
-
- QbsProject *project() const;
-};
+class QbsBuildSystem;
// --------------------------------------------------------------------
// QbsGroupNode:
@@ -106,8 +87,7 @@ class QbsProjectNode : public ProjectExplorer::ProjectNode
public:
explicit QbsProjectNode(const Utils::FilePath &projectDirectory);
- virtual QbsProject *project() const;
- const qbs::Project qbsProject() const;
+ virtual ProjectExplorer::Project *project() const;
const qbs::ProjectData qbsProjectData() const { return m_projectData; }
void setProjectData(const qbs::ProjectData &data); // FIXME: Needed?
@@ -125,12 +105,12 @@ private:
class QbsRootProjectNode : public QbsProjectNode
{
public:
- explicit QbsRootProjectNode(QbsProject *project);
+ explicit QbsRootProjectNode(ProjectExplorer::Project *project);
- QbsProject *project() const override { return m_project; }
+ ProjectExplorer::Project *project() const override { return m_project; }
private:
- QbsProject *const m_project;
+ ProjectExplorer::Project *const m_project;
};
diff --git a/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp b/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp
index f7bbde2a13..cc6e7e54db 100644
--- a/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp
+++ b/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp
@@ -203,19 +203,19 @@ QStringList unreferencedBuildSystemFiles(const qbs::Project &p)
} // namespace
-std::unique_ptr<QbsRootProjectNode> QbsNodeTreeBuilder::buildTree(QbsProject *project)
+std::unique_ptr<QbsRootProjectNode> QbsNodeTreeBuilder::buildTree(QbsBuildSystem *buildSystem)
{
- if (!project->qbsProjectData().isValid())
+ if (!buildSystem->qbsProjectData().isValid())
return {};
- auto root = std::make_unique<QbsRootProjectNode>(project);
- setupProjectNode(root.get(), project->qbsProjectData(), project->qbsProject());
+ auto root = std::make_unique<QbsRootProjectNode>(buildSystem->project());
+ setupProjectNode(root.get(), buildSystem->qbsProjectData(), buildSystem->qbsProject());
- auto buildSystemFiles = std::make_unique<FolderNode>(project->projectDirectory());
+ auto buildSystemFiles = std::make_unique<FolderNode>(buildSystem->projectDirectory());
buildSystemFiles->setDisplayName(QCoreApplication::translate("QbsRootProjectNode", "Qbs files"));
- const FilePath base = project->projectDirectory();
- const QStringList files = unreferencedBuildSystemFiles(project->qbsProject());
+ const FilePath base = buildSystem->projectDirectory();
+ const QStringList files = unreferencedBuildSystemFiles(buildSystem->qbsProject());
for (const QString &f : files) {
const FilePath filePath = FilePath::fromString(f);
if (filePath.isChildOf(base))
diff --git a/src/plugins/qbsprojectmanager/qbsnodetreebuilder.h b/src/plugins/qbsprojectmanager/qbsnodetreebuilder.h
index 4834dd00d1..3568cda7c6 100644
--- a/src/plugins/qbsprojectmanager/qbsnodetreebuilder.h
+++ b/src/plugins/qbsprojectmanager/qbsnodetreebuilder.h
@@ -39,7 +39,7 @@ namespace Internal {
class QbsNodeTreeBuilder
{
public:
- static std::unique_ptr<QbsRootProjectNode> buildTree(QbsProject *project);
+ static std::unique_ptr<QbsRootProjectNode> buildTree(QbsBuildSystem *project);
};
} // namespace Internal
diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp
index ade70195c9..381bb9ce6e 100644
--- a/src/plugins/qbsprojectmanager/qbsproject.cpp
+++ b/src/plugins/qbsprojectmanager/qbsproject.cpp
@@ -127,45 +127,98 @@ private:
QbsProject::QbsProject(const FilePath &fileName)
: Project(Constants::MIME_TYPE, fileName)
- , m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
{
- m_parsingDelay.setInterval(1000); // delay parsing by 1s.
-
setId(Constants::PROJECT_ID);
setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
setCanBuildProducts();
+ setDisplayName(fileName.toFileInfo().completeBaseName());
+}
- setBuildSystemCreator([](Project *p) { return new QbsBuildSystem(p); });
+QbsProject::~QbsProject()
+{
+ delete m_importer;
+}
- rebuildProjectTree();
+ProjectImporter *QbsProject::projectImporter() const
+{
+ if (!m_importer)
+ m_importer = new QbsProjectImporter(projectFilePath());
+ return m_importer;
+}
- connect(this, &Project::activeTargetChanged, this, &QbsProject::changeActiveTarget);
- connect(this, &Project::addedTarget, this, [this](Target *t) {
- m_qbsProjects.insert(t, qbs::Project());
- });
- connect(this, &Project::removedTarget, this, [this](Target *t) {
- const auto it = m_qbsProjects.find(t);
- QTC_ASSERT(it != m_qbsProjects.end(), return);
- if (it.value() == m_qbsProject) {
- m_qbsProject = qbs::Project();
- m_projectData = qbs::ProjectData();
- }
- m_qbsProjects.erase(it);
- });
+// --------------------------------------------------------------------
+// QbsBuildSystem:
+// --------------------------------------------------------------------
+
+static const QbsProjectNode *parentQbsProjectNode(const ProjectExplorer::Node *node)
+{
+ for (const ProjectExplorer::FolderNode *pn = node->managingProject(); pn; pn = pn->parentProjectNode()) {
+ const auto prjNode = dynamic_cast<const QbsProjectNode *>(pn);
+ if (prjNode)
+ return prjNode;
+ }
+ return nullptr;
+}
- connect(this, &Project::activeBuildConfigurationChanged,
- this, &QbsProject::delayParsing);
+static const QbsProductNode *parentQbsProductNode(const ProjectExplorer::Node *node)
+{
+ for (; node; node = node->parentFolderNode()) {
+ const auto prdNode = dynamic_cast<const QbsProductNode *>(node);
+ if (prdNode)
+ return prdNode;
+ }
+ return nullptr;
+}
- connect(&m_parsingDelay, &QTimer::timeout, this, &QbsProject::startParsing);
+static bool supportsNodeAction(ProjectAction action, const Node *node)
+{
+ const Project * const project = parentQbsProjectNode(node)->project();
+ Target *t = project ? project->activeTarget() : nullptr;
+ QbsBuildSystem *bs = t ? static_cast<QbsBuildSystem *>(t->buildSystem()) : nullptr;
+ if (!bs)
+ return false;
+ if (!bs->isProjectEditable())
+ return false;
+ if (action == RemoveFile || action == Rename)
+ return node->asFileNode();
+ return false;
+}
- connect(this, &QbsProject::projectFileIsDirty, this, &QbsProject::delayParsing);
+static qbs::GroupData findMainQbsGroup(const qbs::ProductData &productData)
+{
+ foreach (const qbs::GroupData &grp, productData.groups()) {
+ if (grp.name() == productData.name() && grp.location() == productData.location())
+ return grp;
+ }
+ return qbs::GroupData();
}
-QbsProject::~QbsProject()
+QbsBuildSystem::QbsBuildSystem(QbsBuildConfiguration *bc)
+ : BuildSystem(bc->target()),
+ m_cppCodeModelUpdater(new CppTools::CppProjectUpdater),
+ m_buildConfiguration(bc)
+
+{
+ m_parsingDelay.setInterval(1000); // delay parsing by 1s.
+ delayParsing();
+
+ connect(bc->project(), &Project::activeTargetChanged,
+ this, &QbsBuildSystem::changeActiveTarget);
+
+ connect(bc->target(), &Target::activeBuildConfigurationChanged,
+ this, &QbsBuildSystem::delayParsing);
+
+ connect(&m_parsingDelay, &QTimer::timeout, this, &QbsBuildSystem::triggerParsing);
+
+ connect(bc->project(), &Project::projectFileIsDirty, this, &QbsBuildSystem::delayParsing);
+
+ rebuildProjectTree();
+}
+
+QbsBuildSystem::~QbsBuildSystem()
{
delete m_cppCodeModelUpdater;
delete m_qbsProjectParser;
- delete m_importer;
if (m_qbsUpdateFutureInterface) {
m_qbsUpdateFutureInterface->reportCanceled();
m_qbsUpdateFutureInterface->reportFinished();
@@ -175,24 +228,141 @@ QbsProject::~QbsProject()
qDeleteAll(m_extraCompilers);
}
-void QbsProject::projectLoaded()
+bool QbsBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
{
- m_parsingDelay.start(0);
+ if (dynamic_cast<QbsGroupNode *>(context)) {
+ if (action == AddNewFile || action == AddExistingFile)
+ return true;
+ }
+
+ if (dynamic_cast<QbsProductNode *>(context)) {
+ if (action == AddNewFile || action == AddExistingFile)
+ return true;
+ }
+
+ return supportsNodeAction(action, node);
}
-ProjectImporter *QbsProject::projectImporter() const
+bool QbsBuildSystem::addFiles(Node *context, const QStringList &filePaths, QStringList *notAdded)
{
- if (!m_importer)
- m_importer = new QbsProjectImporter(projectFilePath());
- return m_importer;
+ if (auto n = dynamic_cast<QbsGroupNode *>(context)) {
+ QStringList notAddedDummy;
+ if (!notAdded)
+ notAdded = &notAddedDummy;
+
+ const QbsProjectNode *prjNode = parentQbsProjectNode(n);
+ if (!prjNode || !qbsProject().isValid()) {
+ *notAdded += filePaths;
+ return false;
+ }
+
+ const QbsProductNode *prdNode = parentQbsProductNode(n);
+ if (!prdNode || !prdNode->qbsProductData().isValid()) {
+ *notAdded += filePaths;
+ return false;
+ }
+
+ return addFilesToProduct(filePaths, prdNode->qbsProductData(), n->m_qbsGroupData, notAdded);
+ }
+
+ if (auto n = dynamic_cast<QbsProductNode *>(context)) {
+ QStringList notAddedDummy;
+ if (!notAdded)
+ notAdded = &notAddedDummy;
+
+ const QbsProjectNode *prjNode = parentQbsProjectNode(n);
+ if (!prjNode || !qbsProject().isValid()) {
+ *notAdded += filePaths;
+ return false;
+ }
+
+ qbs::GroupData grp = findMainQbsGroup(n->qbsProductData());
+ if (grp.isValid())
+ return addFilesToProduct(filePaths, n->qbsProductData(), grp, notAdded);
+
+ QTC_ASSERT(false, return false);
+ }
+
+ return BuildSystem::addFiles(context, filePaths, notAdded);
}
-QVariant QbsProject::additionalData(Id id, const Target *target) const
+RemovedFilesFromProject QbsBuildSystem::removeFiles(Node *context, const QStringList &filePaths,
+ QStringList *notRemoved)
+{
+ if (auto n = dynamic_cast<QbsGroupNode *>(context)) {
+ QStringList notRemovedDummy;
+ if (!notRemoved)
+ notRemoved = &notRemovedDummy;
+
+ const QbsProjectNode *prjNode = parentQbsProjectNode(n);
+ if (!prjNode || !qbsProject().isValid()) {
+ *notRemoved += filePaths;
+ return RemovedFilesFromProject::Error;
+ }
+
+ const QbsProductNode *prdNode = parentQbsProductNode(n);
+ if (!prdNode || !prdNode->qbsProductData().isValid()) {
+ *notRemoved += filePaths;
+ return RemovedFilesFromProject::Error;
+ }
+
+ return removeFilesFromProduct(filePaths, prdNode->qbsProductData(),
+ n->m_qbsGroupData, notRemoved);
+ }
+
+ if (auto n = dynamic_cast<QbsProductNode *>(context)) {
+ QStringList notRemovedDummy;
+ if (!notRemoved)
+ notRemoved = &notRemovedDummy;
+
+ const QbsProjectNode *prjNode = parentQbsProjectNode(n);
+ if (!prjNode || !qbsProject().isValid()) {
+ *notRemoved += filePaths;
+ return RemovedFilesFromProject::Error;
+ }
+
+ qbs::GroupData grp = findMainQbsGroup(n->qbsProductData());
+ if (grp.isValid()) {
+ return removeFilesFromProduct(filePaths, n->qbsProductData(), grp, notRemoved);
+ }
+
+ QTC_ASSERT(false, return RemovedFilesFromProject::Error);
+ }
+
+ return BuildSystem::removeFiles(context, filePaths, notRemoved);
+}
+
+bool QbsBuildSystem::renameFile(Node *context, const QString &filePath, const QString &newFilePath)
+{
+ if (auto *n = dynamic_cast<QbsGroupNode *>(context)) {
+ const QbsProjectNode *prjNode = parentQbsProjectNode(n);
+ if (!prjNode || !qbsProject().isValid())
+ return false;
+ const QbsProductNode *prdNode = parentQbsProductNode(n);
+ if (!prdNode || !prdNode->qbsProductData().isValid())
+ return false;
+
+ return renameFileInProduct(filePath, newFilePath,
+ prdNode->qbsProductData(), n->m_qbsGroupData);
+ }
+
+ if (auto *n = dynamic_cast<QbsProductNode *>(context)) {
+ const QbsProjectNode * prjNode = parentQbsProjectNode(n);
+ if (!prjNode || !qbsProject().isValid())
+ return false;
+ const qbs::GroupData grp = findMainQbsGroup(n->qbsProductData());
+ QTC_ASSERT(grp.isValid(), return false);
+ return renameFileInProduct(filePath, newFilePath, n->qbsProductData(), grp);
+ }
+
+ return BuildSystem::renameFile(context, filePath, newFilePath);
+}
+
+QVariant QbsBuildSystem::additionalData(Id id) const
{
if (id == "QmlDesignerImportPath") {
- const qbs::Project qbsProject = m_qbsProjects.value(const_cast<Target *>(target));
- const qbs::ProjectData projectData = qbsProject.isValid()
- ? qbsProject.projectData() : qbs::ProjectData();
+ const qbs::ProjectData projectData = m_qbsProject.isValid()
+ ? m_qbsProject.projectData() : qbs::ProjectData();
QStringList designerImportPaths;
foreach (const qbs::ProductData &product, projectData.allProducts()) {
designerImportPaths << product.properties()
@@ -200,7 +370,7 @@ QVariant QbsProject::additionalData(Id id, const Target *target) const
}
return designerImportPaths;
}
- return Project::additionalData(id, target);
+ return BuildSystem::additionalData(id);
}
ProjectExplorer::DeploymentKnowledge QbsProject::deploymentKnowledge() const
@@ -208,7 +378,7 @@ ProjectExplorer::DeploymentKnowledge QbsProject::deploymentKnowledge() const
return DeploymentKnowledge::Perfect;
}
-QStringList QbsProject::filesGeneratedFrom(const QString &sourceFile) const
+QStringList QbsBuildSystem::filesGeneratedFrom(const QString &sourceFile) const
{
QStringList generated;
foreach (const qbs::ProductData &data, m_projectData.allProducts())
@@ -216,12 +386,12 @@ QStringList QbsProject::filesGeneratedFrom(const QString &sourceFile) const
return generated;
}
-bool QbsProject::isProjectEditable() const
+bool QbsBuildSystem::isProjectEditable() const
{
return m_qbsProject.isValid() && !isParsing() && !BuildManager::isBuilding();
}
-bool QbsProject::ensureWriteableQbsFile(const QString &file)
+bool QbsBuildSystem::ensureWriteableQbsFile(const QString &file)
{
// Ensure that the file is not read only
QFileInfo fi(file);
@@ -242,9 +412,9 @@ bool QbsProject::ensureWriteableQbsFile(const QString &file)
return true;
}
-bool QbsProject::addFilesToProduct(const QStringList &filePaths,
- const qbs::ProductData productData,
- const qbs::GroupData groupData, QStringList *notAdded)
+bool QbsBuildSystem::addFilesToProduct(const QStringList &filePaths,
+ const qbs::ProductData productData,
+ const qbs::GroupData groupData, QStringList *notAdded)
{
QTC_ASSERT(m_qbsProject.isValid(), return false);
QStringList allPaths = groupData.allFilePaths();
@@ -267,10 +437,10 @@ bool QbsProject::addFilesToProduct(const QStringList &filePaths,
return notAdded->isEmpty();
}
-RemovedFilesFromProject QbsProject::removeFilesFromProduct(const QStringList &filePaths,
- const qbs::ProductData &productData,
- const qbs::GroupData &groupData,
- QStringList *notRemoved)
+RemovedFilesFromProject QbsBuildSystem::removeFilesFromProduct(const QStringList &filePaths,
+ const qbs::ProductData &productData,
+ const qbs::GroupData &groupData,
+ QStringList *notRemoved)
{
QTC_ASSERT(m_qbsProject.isValid(), return RemovedFilesFromProject::Error);
@@ -313,9 +483,9 @@ RemovedFilesFromProject QbsProject::removeFilesFromProduct(const QStringList &fi
return RemovedFilesFromProject::Ok;
}
-bool QbsProject::renameFileInProduct(const QString &oldPath, const QString &newPath,
- const qbs::ProductData productData,
- const qbs::GroupData groupData)
+bool QbsBuildSystem::renameFileInProduct(const QString &oldPath, const QString &newPath,
+ const qbs::ProductData productData,
+ const qbs::GroupData groupData)
{
if (newPath.isEmpty())
return false;
@@ -326,7 +496,7 @@ bool QbsProject::renameFileInProduct(const QString &oldPath, const QString &newP
}
qbs::ProductData newProductData;
foreach (const qbs::ProductData &p, m_projectData.allProducts()) {
- if (uniqueProductName(p) == uniqueProductName(productData)) {
+ if (QbsProject::uniqueProductName(p) == QbsProject::uniqueProductName(productData)) {
newProductData = p;
break;
}
@@ -365,8 +535,8 @@ static qbs::AbstractJob *doBuildOrClean(const qbs::Project &project,
}
template<typename Options>
-qbs::AbstractJob *QbsProject::buildOrClean(const Options &opts, const QStringList &productNames,
- QString &error)
+qbs::AbstractJob *QbsBuildSystem::buildOrClean(const Options &opts, const QStringList &productNames,
+ QString &error)
{
QTC_ASSERT(qbsProject().isValid(), return nullptr);
QTC_ASSERT(!isParsing(), return nullptr);
@@ -375,7 +545,7 @@ qbs::AbstractJob *QbsProject::buildOrClean(const Options &opts, const QStringLis
foreach (const QString &productName, productNames) {
bool found = false;
foreach (const qbs::ProductData &data, qbsProjectData().allProducts()) {
- if (uniqueProductName(data) == productName) {
+ if (QbsProject::uniqueProductName(data) == productName) {
found = true;
products.append(data);
break;
@@ -391,41 +561,41 @@ qbs::AbstractJob *QbsProject::buildOrClean(const Options &opts, const QStringLis
return doBuildOrClean(qbsProject(), products, opts);
}
-qbs::BuildJob *QbsProject::build(const qbs::BuildOptions &opts, QStringList productNames,
- QString &error)
+qbs::BuildJob *QbsBuildSystem::build(const qbs::BuildOptions &opts, QStringList productNames,
+ QString &error)
{
return static_cast<qbs::BuildJob *>(buildOrClean(opts, productNames, error));
}
-qbs::CleanJob *QbsProject::clean(const qbs::CleanOptions &opts, const QStringList &productNames,
- QString &error)
+qbs::CleanJob *QbsBuildSystem::clean(const qbs::CleanOptions &opts, const QStringList &productNames,
+ QString &error)
{
return static_cast<qbs::CleanJob *>(buildOrClean(opts, productNames, error));
}
-qbs::InstallJob *QbsProject::install(const qbs::InstallOptions &opts)
+qbs::InstallJob *QbsBuildSystem::install(const qbs::InstallOptions &opts)
{
if (!qbsProject().isValid())
return nullptr;
return qbsProject().installAllProducts(opts);
}
-QString QbsProject::profileForTarget(const Target *t) const
+QString QbsBuildSystem::profile() const
{
- return QbsManager::profileForKit(t->kit());
+ return QbsManager::profileForKit(target()->kit());
}
-qbs::Project QbsProject::qbsProject() const
+qbs::Project QbsBuildSystem::qbsProject() const
{
return m_qbsProject;
}
-qbs::ProjectData QbsProject::qbsProjectData() const
+qbs::ProjectData QbsBuildSystem::qbsProjectData() const
{
return m_projectData;
}
-bool QbsProject::checkCancelStatus()
+bool QbsBuildSystem::checkCancelStatus()
{
const CancelStatus cancelStatus = m_cancelStatus;
m_cancelStatus = CancelStatusNone;
@@ -439,7 +609,7 @@ bool QbsProject::checkCancelStatus()
return true;
}
-void QbsProject::updateAfterParse()
+void QbsBuildSystem::updateAfterParse()
{
qCDebug(qbsPmLog) << "Updating data after parse";
OpTimer opTimer("updateAfterParse");
@@ -448,27 +618,24 @@ void QbsProject::updateAfterParse()
updateBuildTargetData();
updateCppCodeModel();
updateQmlJsCodeModel();
- emit fileListChanged();
+ emit project()->fileListChanged();
m_envCache.clear();
- emit dataChanged();
}
-void QbsProject::delayedUpdateAfterParse()
+void QbsBuildSystem::delayedUpdateAfterParse()
{
- QTimer::singleShot(0, this, &QbsProject::updateAfterParse);
+ QTimer::singleShot(0, this, &QbsBuildSystem::updateAfterParse);
}
-void QbsProject::updateProjectNodes()
+void QbsBuildSystem::updateProjectNodes()
{
OpTimer opTimer("updateProjectNodes");
rebuildProjectTree();
}
-FilePath QbsProject::installRoot()
+FilePath QbsBuildSystem::installRoot()
{
- if (!activeTarget())
- return FilePath();
- const auto dc = activeTarget()->activeDeployConfiguration();
+ const auto dc = target()->activeDeployConfiguration();
if (dc) {
const QList<BuildStep *> steps = dc->stepList()->steps();
for (const BuildStep * const step : steps) {
@@ -478,15 +645,11 @@ FilePath QbsProject::installRoot()
return FilePath::fromString(qbsInstallStep->installRoot());
}
}
- const auto * const bc
- = qobject_cast<QbsBuildConfiguration *>(activeTarget()->activeBuildConfiguration());
- if (!bc)
- return FilePath();
- const QbsBuildStep * const buildStep = bc->qbsStep();
+ const QbsBuildStep * const buildStep = m_buildConfiguration->qbsStep();
return buildStep && buildStep->install() ? buildStep->installRoot() : FilePath();
}
-void QbsProject::handleQbsParsingDone(bool success)
+void QbsBuildSystem::handleQbsParsingDone(bool success)
{
QTC_ASSERT(m_qbsProjectParser, return);
QTC_ASSERT(m_qbsUpdateFutureInterface, return);
@@ -499,7 +662,6 @@ void QbsProject::handleQbsParsingDone(bool success)
generateErrors(m_qbsProjectParser->error());
m_qbsProject = m_qbsProjectParser->qbsProject();
- m_qbsProjects.insert(activeTarget(), m_qbsProject);
bool dataChanged = false;
bool envChanged = m_lastParseEnv != m_qbsProjectParser->environment();
m_lastParseEnv = m_qbsProjectParser->environment();
@@ -528,14 +690,14 @@ void QbsProject::handleQbsParsingDone(bool success)
m_guard = {};
}
-void QbsProject::rebuildProjectTree()
+void QbsBuildSystem::rebuildProjectTree()
{
std::unique_ptr<QbsRootProjectNode> newRoot = Internal::QbsNodeTreeBuilder::buildTree(this);
- setDisplayName(newRoot ? newRoot->displayName() : projectFilePath().toFileInfo().completeBaseName());
- setRootProjectNode(std::move(newRoot));
+ project()->setDisplayName(newRoot ? newRoot->displayName() : projectFilePath().toFileInfo().completeBaseName());
+ project()->setRootProjectNode(std::move(newRoot));
}
-void QbsProject::handleRuleExecutionDone()
+void QbsBuildSystem::handleRuleExecutionDone()
{
qCDebug(qbsPmLog) << "Rule execution done";
@@ -553,28 +715,17 @@ void QbsProject::handleRuleExecutionDone()
updateAfterParse();
}
-void QbsProject::changeActiveTarget(Target *t)
+void QbsBuildSystem::changeActiveTarget(Target *t)
{
- bool targetFound = false;
- for (auto it = m_qbsProjects.begin(); it != m_qbsProjects.end(); ++it) {
- qbs::Project &qbsProjectForTarget = it.value();
- if (it.key() == t) {
- m_qbsProject = qbsProjectForTarget;
- targetFound = true;
- } else if (qbsProjectForTarget.isValid() && !BuildManager::isBuilding(it.key())) {
- qbsProjectForTarget = qbs::Project();
- }
- }
- QTC_ASSERT(targetFound || !t, m_qbsProject = qbs::Project());
- if (t && t->isActive())
+ if (t)
delayParsing();
}
-void QbsProject::startParsing()
+void QbsBuildSystem::triggerParsing()
{
// Qbs does update the build graph during the build. So we cannot
// start to parse while a build is running or we will lose information.
- if (BuildManager::isBuilding(this)) {
+ if (BuildManager::isBuilding(project())) {
scheduleParsing();
return;
}
@@ -582,12 +733,13 @@ void QbsProject::startParsing()
parseCurrentBuildConfiguration();
}
-void QbsProject::delayParsing()
+void QbsBuildSystem::delayParsing()
{
- m_parsingDelay.start();
+ if (m_buildConfiguration->isActive())
+ m_parsingDelay.start();
}
-void QbsProject::parseCurrentBuildConfiguration()
+void QbsBuildSystem::parseCurrentBuildConfiguration()
{
m_parsingScheduled = false;
if (m_cancelStatus == CancelStatusCancelingForReparse)
@@ -598,12 +750,6 @@ void QbsProject::parseCurrentBuildConfiguration()
// but of course not while canceling is in progress).
QTC_ASSERT(m_cancelStatus == CancelStatusNone, return);
- if (!activeTarget())
- return;
- auto bc = qobject_cast<QbsBuildConfiguration *>(activeTarget()->activeBuildConfiguration());
- if (!bc)
- return;
-
// New parse requests override old ones.
// NOTE: We need to wait for the current operation to finish, since otherwise there could
// be a conflict. Consider the case where the old qbs::ProjectSetupJob is writing
@@ -616,28 +762,44 @@ void QbsProject::parseCurrentBuildConfiguration()
return;
}
- parse(bc->qbsConfiguration(), bc->environment(), bc->buildDirectory().toString(),
- bc->configurationName());
+ QVariantMap config = m_buildConfiguration->qbsConfiguration();
+ Environment env = m_buildConfiguration->environment();
+ QString dir = m_buildConfiguration->buildDirectory().toString();
+
+ m_guard = guardParsingRun();
+
+ prepareForParsing();
+
+ m_parsingDelay.stop();
+
+ QTC_ASSERT(!m_qbsProjectParser, return);
+ m_qbsProjectParser = new QbsProjectParser(this, m_qbsUpdateFutureInterface);
+
+ connect(m_qbsProjectParser, &QbsProjectParser::ruleExecutionDone,
+ this, &QbsBuildSystem::handleRuleExecutionDone);
+ connect(m_qbsProjectParser, &QbsProjectParser::done,
+ this, &QbsBuildSystem::handleQbsParsingDone);
+
+ QbsManager::updateProfileIfNecessary(target()->kit());
+ m_qbsProjectParser->parse(config, env, dir, m_buildConfiguration->configurationName());
}
-void QbsProject::cancelParsing()
+void QbsBuildSystem::cancelParsing()
{
QTC_ASSERT(m_qbsProjectParser, return);
m_cancelStatus = CancelStatusCancelingAltoghether;
m_qbsProjectParser->cancel();
}
-void QbsProject::updateAfterBuild()
+void QbsBuildSystem::updateAfterBuild()
{
OpTimer opTimer("updateAfterBuild");
QTC_ASSERT(m_qbsProject.isValid(), return);
const qbs::ProjectData &projectData = m_qbsProject.projectData();
if (projectData == m_projectData) {
- if (activeTarget()) {
- DeploymentData deploymentData = activeTarget()->deploymentData();
- deploymentData.setLocalInstallRoot(installRoot());
- activeTarget()->setDeploymentData(deploymentData);
- }
+ DeploymentData deploymentDataTmp = deploymentData();
+ deploymentDataTmp.setLocalInstallRoot(installRoot());
+ setDeploymentData(deploymentDataTmp);
return;
}
qCDebug(qbsPmLog) << "Updating data after build";
@@ -649,29 +811,9 @@ void QbsProject::updateAfterBuild()
updateCppCodeModel();
}
m_envCache.clear();
- emit dataChanged();
}
-void QbsProject::registerQbsProjectParser(QbsProjectParser *p)
-{
- m_parsingDelay.stop();
-
- if (m_qbsProjectParser) {
- m_qbsProjectParser->disconnect(this);
- m_qbsProjectParser->deleteLater();
- }
-
- m_qbsProjectParser = p;
-
- if (p) {
- connect(m_qbsProjectParser, &QbsProjectParser::ruleExecutionDone,
- this, &QbsProject::handleRuleExecutionDone);
- connect(m_qbsProjectParser, &QbsProjectParser::done,
- this, &QbsProject::handleQbsParsingDone);
- }
-}
-
-void QbsProject::generateErrors(const qbs::ErrorInfo &e)
+void QbsBuildSystem::generateErrors(const qbs::ErrorInfo &e)
{
foreach (const qbs::ErrorItem &item, e.items())
TaskHub::addTask(Task::Error, item.description(),
@@ -697,24 +839,11 @@ void QbsProject::configureAsExampleProject()
}
}
setup(infoList);
- prepareForParsing();
-}
-
-void QbsProject::parse(const QVariantMap &config, const Environment &env, const QString &dir,
- const QString &configName)
-{
- m_guard = guardParsingRun();
-
- prepareForParsing();
- QTC_ASSERT(!m_qbsProjectParser, return);
-
- registerQbsProjectParser(new QbsProjectParser(this, m_qbsUpdateFutureInterface));
-
- QbsManager::updateProfileIfNecessary(activeTarget()->kit());
- m_qbsProjectParser->parse(config, env, dir, configName);
+ if (activeTarget())
+ static_cast<QbsBuildSystem *>(activeTarget()->buildSystem())->prepareForParsing();
}
-void QbsProject::prepareForParsing()
+void QbsBuildSystem::prepareForParsing()
{
TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
if (m_qbsUpdateFutureInterface) {
@@ -727,11 +856,11 @@ void QbsProject::prepareForParsing()
m_qbsUpdateFutureInterface = new QFutureInterface<bool>();
m_qbsUpdateFutureInterface->setProgressRange(0, 0);
ProgressManager::addTask(m_qbsUpdateFutureInterface->future(),
- tr("Reading Project \"%1\"").arg(displayName()), "Qbs.QbsEvaluate");
+ tr("Reading Project \"%1\"").arg(project()->displayName()), "Qbs.QbsEvaluate");
m_qbsUpdateFutureInterface->reportStarted();
}
-void QbsProject::updateDocuments(const std::set<QString> &files)
+void QbsBuildSystem::updateDocuments(const std::set<QString> &files)
{
OpTimer opTimer("updateDocuments");
@@ -742,7 +871,7 @@ void QbsProject::updateDocuments(const std::set<QString> &files)
[buildDir](const FilePath &p) {
return !p.isChildOf(buildDir);
});
- setExtraProjectFiles(nonBuildDirFilePaths);
+ project()->setExtraProjectFiles(nonBuildDirFilePaths);
}
static QString getMimeType(const qbs::ArtifactData &sourceFile)
@@ -870,21 +999,20 @@ static void getExpandedCompilerFlags(QStringList &cFlags, QStringList &cxxFlags,
}
}
-void QbsProject::updateCppCodeModel()
+void QbsBuildSystem::updateCppCodeModel()
{
OpTimer optimer("updateCppCodeModel");
if (!m_projectData.isValid())
return;
- QList<ProjectExplorer::ExtraCompilerFactory *> factories =
- ProjectExplorer::ExtraCompilerFactory::extraCompilerFactories();
+ const QList<ExtraCompilerFactory *> factories = ExtraCompilerFactory::extraCompilerFactories();
const auto factoriesBegin = factories.constBegin();
const auto factoriesEnd = factories.constEnd();
qDeleteAll(m_extraCompilers);
m_extraCompilers.clear();
- QtSupport::CppKitInfo kitInfo(this);
+ QtSupport::CppKitInfo kitInfo(project());
QTC_ASSERT(kitInfo.isValid(), return);
RawProjectParts rpps;
@@ -959,7 +1087,7 @@ void QbsProject::updateCppCodeModel()
rpp.setDisplayName(grp.name());
rpp.setProjectFileLocation(grp.location().filePath(),
grp.location().line(), grp.location().column());
- rpp.setBuildSystemTarget(uniqueProductName(prd));
+ rpp.setBuildSystemTarget(QbsProject::uniqueProductName(prd));
rpp.setBuildTargetType(prd.isRunnable() ? ProjectExplorer::BuildTargetType::Executable
: ProjectExplorer::BuildTargetType::Library);
@@ -996,7 +1124,7 @@ void QbsProject::updateCppCodeModel()
return Utils::FilePath::fromString(s);
});
m_extraCompilers.append((*i)->create(
- this, FilePath::fromString(source.filePath()), fileNames));
+ project(), FilePath::fromString(source.filePath()), fileNames));
}
}
}
@@ -1038,10 +1166,10 @@ void QbsProject::updateCppCodeModel()
}
CppTools::GeneratedCodeModelSupport::update(m_extraCompilers);
- m_cppCodeModelUpdater->update({this, kitInfo, activeParseEnvironment(), rpps});
+ m_cppCodeModelUpdater->update({project(), kitInfo, activeParseEnvironment(), rpps});
}
-void QbsProject::updateQmlJsCodeModel()
+void QbsBuildSystem::updateQmlJsCodeModel()
{
OpTimer optimer("updateQmlJsCodeModel");
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
@@ -1049,7 +1177,7 @@ void QbsProject::updateQmlJsCodeModel()
return;
QmlJS::ModelManagerInterface::ProjectInfo projectInfo =
- modelManager->defaultProjectInfoForProject(this);
+ modelManager->defaultProjectInfoForProject(project());
foreach (const qbs::ProductData &product, m_projectData.allProducts()) {
static const QString propertyName = QLatin1String("qmlImportPaths");
foreach (const QString &path, product.properties().value(propertyName).toStringList()) {
@@ -1058,12 +1186,12 @@ void QbsProject::updateQmlJsCodeModel()
}
}
- setProjectLanguage(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID,
+ project()->setProjectLanguage(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID,
!projectInfo.sourceFiles.isEmpty());
- modelManager->updateProjectInfo(projectInfo, this);
+ modelManager->updateProjectInfo(projectInfo, project());
}
-void QbsProject::updateApplicationTargets()
+void QbsBuildSystem::updateApplicationTargets()
{
QList<BuildTargetInfo> applications;
foreach (const qbs::ProductData &productData, m_projectData.allProducts()) {
@@ -1125,11 +1253,10 @@ void QbsProject::updateApplicationTargets()
applications.append(bti);
}
- if (activeTarget())
- activeTarget()->setApplicationTargets(applications);
+ setApplicationTargets(applications);
}
-void QbsProject::updateDeploymentInfo()
+void QbsBuildSystem::updateDeploymentInfo()
{
DeploymentData deploymentData;
if (m_qbsProject.isValid()) {
@@ -1139,11 +1266,10 @@ void QbsProject::updateDeploymentInfo()
}
}
deploymentData.setLocalInstallRoot(installRoot());
- if (activeTarget())
- activeTarget()->setDeploymentData(deploymentData);
+ setDeploymentData(deploymentData);
}
-void QbsProject::updateBuildTargetData()
+void QbsBuildSystem::updateBuildTargetData()
{
OpTimer optimer("updateBuildTargetData");
updateApplicationTargets();
diff --git a/src/plugins/qbsprojectmanager/qbsproject.h b/src/plugins/qbsprojectmanager/qbsproject.h
index 56798792bf..69d79c89ca 100644
--- a/src/plugins/qbsprojectmanager/qbsproject.h
+++ b/src/plugins/qbsprojectmanager/qbsproject.h
@@ -41,12 +41,12 @@
#include <QHash>
#include <QTimer>
-namespace Core { class IDocument; }
namespace CppTools { class CppProjectUpdater; }
namespace QbsProjectManager {
namespace Internal {
+class QbsBuildConfiguration;
class QbsProjectParser;
class QbsProject : public ProjectExplorer::Project
@@ -55,9 +55,43 @@ class QbsProject : public ProjectExplorer::Project
public:
explicit QbsProject(const Utils::FilePath &filename);
- ~QbsProject() override;
+ ~QbsProject();
- QStringList filesGeneratedFrom(const QString &sourceFile) const override;
+ ProjectExplorer::ProjectImporter *projectImporter() const override;
+
+ ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override;
+
+ void configureAsExampleProject() final;
+
+ static QString uniqueProductName(const qbs::ProductData &product);
+
+private:
+ mutable ProjectExplorer::ProjectImporter *m_importer = nullptr;
+};
+
+class QbsBuildSystem : public ProjectExplorer::BuildSystem
+{
+ Q_OBJECT
+
+public:
+ explicit QbsBuildSystem(QbsBuildConfiguration *bc);
+ ~QbsBuildSystem() final;
+
+ void triggerParsing() final;
+ bool supportsAction(ProjectExplorer::Node *context,
+ ProjectExplorer::ProjectAction action,
+ const ProjectExplorer::Node *node) const final;
+ bool addFiles(ProjectExplorer::Node *context,
+ const QStringList &filePaths,
+ QStringList *notAdded = nullptr) final;
+ ProjectExplorer::RemovedFilesFromProject removeFiles(ProjectExplorer::Node *context,
+ const QStringList &filePaths,
+ QStringList *notRemoved = nullptr) final;
+ bool renameFile(ProjectExplorer::Node *context,
+ const QString &filePath, const QString &newFilePath) final;
+
+ QStringList filesGeneratedFrom(const QString &sourceFile) const final;
+ QVariant additionalData(Core::Id id) const final;
bool isProjectEditable() const;
// qbs::ProductData and qbs::GroupData are held by the nodes in the project tree.
@@ -81,39 +115,27 @@ public:
static ProjectExplorer::FileType fileTypeFor(const QSet<QString> &tags);
- QString profileForTarget(const ProjectExplorer::Target *t) const;
+ QString profile() const;
void parseCurrentBuildConfiguration();
void scheduleParsing() { m_parsingScheduled = true; }
bool parsingScheduled() const { return m_parsingScheduled; }
void cancelParsing();
void updateAfterBuild();
- void registerQbsProjectParser(QbsProjectParser *p);
-
qbs::Project qbsProject() const;
qbs::ProjectData qbsProjectData() const;
void generateErrors(const qbs::ErrorInfo &e);
- static QString uniqueProductName(const qbs::ProductData &product);
-
- void configureAsExampleProject() final;
-
void delayParsing();
-signals:
- void dataChanged();
-
private:
+ friend class QbsProject;
void handleQbsParsingDone(bool success);
void rebuildProjectTree();
void changeActiveTarget(ProjectExplorer::Target *t);
- void startParsing();
-
- void parse(const QVariantMap &config, const Utils::Environment &env, const QString &dir,
- const QString &configName);
void prepareForParsing();
void updateDocuments(const std::set<QString> &files);
@@ -129,19 +151,12 @@ private:
void updateProjectNodes();
Utils::FilePath installRoot();
- void projectLoaded() override;
- ProjectExplorer::ProjectImporter *projectImporter() const override;
- QVariant additionalData(Core::Id id, const ProjectExplorer::Target *target) const final;
-
- ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override;
-
static bool ensureWriteableQbsFile(const QString &file);
template<typename Options> qbs::AbstractJob *buildOrClean(const Options &opts,
const QStringList &productNames, QString &error);
- QHash<ProjectExplorer::Target *, qbs::Project> m_qbsProjects;
- qbs::Project m_qbsProject; // for activeTarget()
+ qbs::Project m_qbsProject;
qbs::ProjectData m_projectData; // Cached m_qbsProject.projectData()
Utils::Environment m_lastParseEnv;
@@ -158,15 +173,14 @@ private:
CppTools::CppProjectUpdater *m_cppCodeModelUpdater = nullptr;
- mutable ProjectExplorer::ProjectImporter *m_importer = nullptr;
-
QTimer m_parsingDelay;
QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers;
bool m_extraCompilersPending = false;
QHash<QString, Utils::Environment> m_envCache;
- ParseGuard m_guard;
+ ProjectExplorer::BuildSystem::ParseGuard m_guard;
+ QbsBuildConfiguration *m_buildConfiguration = nullptr;
};
} // namespace Internal
diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp
index bc123b09c7..d7f860ec17 100644
--- a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp
+++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp
@@ -246,9 +246,9 @@ bool QbsProjectManagerPlugin::initialize(const QStringList &arguments, QString *
connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged,
this, &QbsProjectManagerPlugin::updateBuildActions);
- connect(SessionManager::instance(), &SessionManager::projectAdded,
- this, &QbsProjectManagerPlugin::projectWasAdded);
- connect(SessionManager::instance(), &SessionManager::projectRemoved,
+ connect(SessionManager::instance(), &SessionManager::targetAdded,
+ this, &QbsProjectManagerPlugin::targetWasAdded);
+ connect(SessionManager::instance(), &SessionManager::targetRemoved,
this, &QbsProjectManagerPlugin::updateBuildActions);
connect(SessionManager::instance(), &SessionManager::startupProjectChanged,
this, &QbsProjectManagerPlugin::updateReparseQbsAction);
@@ -264,16 +264,14 @@ bool QbsProjectManagerPlugin::initialize(const QStringList &arguments, QString *
void QbsProjectManagerPlugin::extensionsInitialized()
{ }
-void QbsProjectManagerPlugin::projectWasAdded(Project *project)
+void QbsProjectManagerPlugin::targetWasAdded(Target *target)
{
- auto qbsProject = qobject_cast<QbsProject *>(project);
-
- if (!qbsProject)
+ if (!qobject_cast<QbsProject *>(target->project()))
return;
- connect(qbsProject, &Project::parsingStarted,
+ connect(target, &Target::parsingStarted,
this, &QbsProjectManagerPlugin::projectChanged);
- connect(qbsProject, &Project::parsingFinished,
+ connect(target, &Target::parsingFinished,
this, &QbsProjectManagerPlugin::projectChanged);
}
@@ -282,7 +280,8 @@ void QbsProjectManagerPlugin::updateContextActions()
auto project = qobject_cast<Internal::QbsProject *>(ProjectTree::currentProject());
const Node *node = ProjectTree::currentNode();
bool isEnabled = !BuildManager::isBuilding(project)
- && project && !project->isParsing()
+ && project && project->activeTarget()
+ && !project->activeTarget()->buildSystem()->isParsing()
&& node && node->isEnabled();
const bool isFile = project && node && node->asFileNode();
@@ -305,7 +304,8 @@ void QbsProjectManagerPlugin::updateReparseQbsAction()
auto project = qobject_cast<QbsProject *>(SessionManager::startupProject());
m_reparseQbs->setEnabled(project
&& !BuildManager::isBuilding(project)
- && !project->isParsing());
+ && project && project->activeTarget()
+ && !project->activeTarget()->buildSystem()->isParsing());
}
void QbsProjectManagerPlugin::updateBuildActions()
@@ -334,7 +334,9 @@ void QbsProjectManagerPlugin::updateBuildActions()
}
if (QbsProject *editorProject = currentEditorProject()) {
- enabled = !BuildManager::isBuilding(editorProject) && !editorProject->isParsing();
+ enabled = !BuildManager::isBuilding(editorProject)
+ && editorProject->activeTarget()
+ && !editorProject->activeTarget()->buildSystem()->isParsing();
fileVisible = productNode
|| dynamic_cast<QbsProjectNode *>(parentProjectNode)
|| dynamic_cast<QbsGroupNode *>(parentProjectNode);
@@ -567,12 +569,20 @@ void QbsProjectManagerPlugin::reparseProject(QbsProject *project)
if (!project)
return;
+ Target *t = project->activeTarget();
+ if (!t)
+ return;
+
+ QbsBuildSystem *bs = static_cast<QbsBuildSystem *>(t->buildSystem());
+ if (!bs)
+ return;
+
// Qbs does update the build graph during the build. So we cannot
// start to parse while a build is running or we will lose information.
if (BuildManager::isBuilding(project))
- project->scheduleParsing();
+ bs->scheduleParsing();
else
- project->parseCurrentBuildConfiguration();
+ bs->parseCurrentBuildConfiguration();
}
void QbsProjectManagerPlugin::buildNamedProduct(QbsProject *project, const QString &product)
diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h
index 267b7777ae..d237e82d82 100644
--- a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h
+++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h
@@ -29,7 +29,7 @@
#include <extensionsystem/iplugin.h>
#include <utils/parameteraction.h>
-namespace ProjectExplorer { class Project; }
+namespace ProjectExplorer { class Target; }
namespace QbsProjectManager {
namespace Internal {
@@ -51,7 +51,7 @@ private:
bool initialize(const QStringList &arguments, QString *errorMessage) final;
void extensionsInitialized() final;
- void projectWasAdded(ProjectExplorer::Project *project);
+ void targetWasAdded(ProjectExplorer::Target *target);
void projectChanged();
void buildFileContextMenu();
diff --git a/src/plugins/qbsprojectmanager/qbsprojectparser.cpp b/src/plugins/qbsprojectmanager/qbsprojectparser.cpp
index 10196cbd37..6e2c9f3936 100644
--- a/src/plugins/qbsprojectmanager/qbsprojectparser.cpp
+++ b/src/plugins/qbsprojectmanager/qbsprojectparser.cpp
@@ -48,11 +48,11 @@ namespace Internal {
// QbsProjectParser:
// --------------------------------------------------------------------
-QbsProjectParser::QbsProjectParser(QbsProject *project, QFutureInterface<bool> *fi) :
+QbsProjectParser::QbsProjectParser(QbsBuildSystem *buildSystem, QFutureInterface<bool> *fi) :
m_fi(fi)
{
- m_project = project->qbsProject();
- m_projectFilePath = project->projectFilePath().toString();
+ m_project = buildSystem->qbsProject();
+ m_projectFilePath = buildSystem->projectFilePath().toString();
auto * const watcher = new QFutureWatcher<bool>(this);
connect(watcher, &QFutureWatcher<bool>::canceled, this, &QbsProjectParser::cancel);
watcher->setFuture(fi->future());
diff --git a/src/plugins/qbsprojectmanager/qbsprojectparser.h b/src/plugins/qbsprojectmanager/qbsprojectparser.h
index 37b9e5f6d2..c6353d3df4 100644
--- a/src/plugins/qbsprojectmanager/qbsprojectparser.h
+++ b/src/plugins/qbsprojectmanager/qbsprojectparser.h
@@ -35,15 +35,14 @@
namespace QbsProjectManager {
namespace Internal {
-class QbsProject;
+class QbsBuildSystem;
class QbsProjectParser : public QObject
{
Q_OBJECT
public:
- QbsProjectParser(QbsProjectManager::Internal::QbsProject *project,
- QFutureInterface<bool> *fi);
+ QbsProjectParser(QbsBuildSystem *buildSystem, QFutureInterface<bool> *fi);
~QbsProjectParser() override;
void parse(const QVariantMap &config, const Utils::Environment &env, const QString &dir,
diff --git a/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp b/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp
index 1f7a96eee5..0d15283227 100644
--- a/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp
+++ b/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp
@@ -1018,8 +1018,12 @@ void InternalLibraryDetailsController::updateProFile()
m_rootProjectPath = project->projectDirectory().toString();
+ auto t = project->activeTarget();
+ auto bs = dynamic_cast<QmakeBuildSystem *>(t ? t->buildSystem() : nullptr);
+ QTC_ASSERT(bs, return);
+
QDir rootDir(m_rootProjectPath);
- foreach (QmakeProFile *proFile, project->rootProFile()->allProFiles()) {
+ foreach (QmakeProFile *proFile, bs->rootProFile()->allProFiles()) {
QmakeProjectManager::ProjectType type = proFile->projectType();
if (type != ProjectType::SharedLibraryTemplate && type != ProjectType::StaticLibraryTemplate)
continue;
diff --git a/src/plugins/qmakeprojectmanager/profileeditor.cpp b/src/plugins/qmakeprojectmanager/profileeditor.cpp
index 346f119782..3d14ff3d50 100644
--- a/src/plugins/qmakeprojectmanager/profileeditor.cpp
+++ b/src/plugins/qmakeprojectmanager/profileeditor.cpp
@@ -38,6 +38,7 @@
#include <extensionsystem/pluginmanager.h>
#include <qtsupport/qtsupportconstants.h>
#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/target.h>
#include <projectexplorer/session.h>
#include <texteditor/texteditoractionhandler.h>
#include <texteditor/textdocument.h>
@@ -85,8 +86,10 @@ QString ProFileEditorWidget::checkForPrfFile(const QString &baseName) const
const FilePath projectFile = textDocument()->filePath();
const QmakePriFileNode *projectNode = nullptr;
for (const Project * const project : SessionManager::projects()) {
- if (project->isParsing())
- continue;
+ if (Target *t = project->activeTarget()) {
+ if (t->buildSystem()->isParsing())
+ continue;
+ }
projectNode = dynamic_cast<const QmakePriFileNode *>(project->rootProjectNode()
->findProjectNode([&projectFile](const ProjectNode *pn) {
return pn->filePath() == projectFile;
diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp
index 7e90562c54..193df6477a 100644
--- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp
@@ -108,6 +108,8 @@ enum { debug = 0 };
QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target, Core::Id id)
: BuildConfiguration(target, id)
{
+ m_buildSystem = new QmakeBuildSystem(this);
+
connect(this, &BuildConfiguration::buildDirectoryChanged,
this, &QmakeBuildConfiguration::emitProFileEvaluateNeeded);
connect(this, &BuildConfiguration::environmentChanged,
@@ -175,7 +177,10 @@ void QmakeBuildConfiguration::initialize()
updateCacheAndEmitEnvironmentChanged();
}
-QmakeBuildConfiguration::~QmakeBuildConfiguration() = default;
+QmakeBuildConfiguration::~QmakeBuildConfiguration()
+{
+ delete m_buildSystem;
+}
QVariantMap QmakeBuildConfiguration::toMap() const
{
@@ -219,6 +224,11 @@ void QmakeBuildConfiguration::qtVersionsChanged(const QList<int> &,const QList<i
emitProFileEvaluateNeeded();
}
+BuildSystem *QmakeBuildConfiguration::buildSystem() const
+{
+ return m_buildSystem;
+}
+
NamedWidget *QmakeBuildConfiguration::createConfigWidget()
{
return new QmakeProjectConfigWidget(this);
@@ -255,8 +265,7 @@ void QmakeBuildConfiguration::setFileNodeBuild(FileNode *node)
QString QmakeBuildConfiguration::makefile() const
{
- auto rootNode = dynamic_cast<QmakeProFileNode *>(target()->project()->rootProjectNode());
- return rootNode ? rootNode->makefile() : QString();
+ return m_buildSystem->rootProFile()->singleVariableValue(Variable::Makefile);
}
BaseQtVersion::QmakeBuildConfigs QmakeBuildConfiguration::qmakeBuildConfiguration() const
@@ -277,10 +286,7 @@ void QmakeBuildConfiguration::setQMakeBuildConfiguration(BaseQtVersion::QmakeBui
void QmakeBuildConfiguration::emitProFileEvaluateNeeded()
{
- Target *t = target();
- Project *p = t->project();
- if (t->activeBuildConfiguration() == this && p->activeTarget() == t)
- static_cast<QmakeProject *>(p)->scheduleAsyncUpdate();
+ m_buildSystem->scheduleUpdateAllNowOrLater();
}
QString QmakeBuildConfiguration::unalignedBuildDirWarning()
@@ -341,6 +347,11 @@ QmakeMakeStep *QmakeBuildConfiguration::makeStep() const
return nullptr;
}
+QmakeBuildSystem *QmakeBuildConfiguration::qmakeBuildSystem() const
+{
+ return m_buildSystem;
+}
+
// Returns true if both are equal.
QmakeBuildConfiguration::MakefileState QmakeBuildConfiguration::compareToImportFrom(const QString &makefile, QString *errorString)
{
diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h
index 7fd4c7dfeb..5445c9ebc9 100644
--- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h
+++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h
@@ -35,6 +35,7 @@ namespace ProjectExplorer { class FileNode; }
namespace QmakeProjectManager {
class QMakeStep;
+class QmakeBuildSystem;
class QmakeMakeStep;
class QmakeProFileNode;
@@ -46,6 +47,8 @@ public:
QmakeBuildConfiguration(ProjectExplorer::Target *target, Core::Id id);
~QmakeBuildConfiguration() override;
+ ProjectExplorer::BuildSystem *buildSystem() const final;
+
void initialize() override;
ProjectExplorer::NamedWidget *createConfigWidget() override;
@@ -72,6 +75,8 @@ public:
QMakeStep *qmakeStep() const;
QmakeMakeStep *makeStep() const;
+ QmakeBuildSystem *qmakeBuildSystem() const;
+
QString makefile() const;
enum MakefileState { MakefileMatches, MakefileForWrongProject, MakefileIncompatible, MakefileMissing };
@@ -125,6 +130,7 @@ private:
QtSupport::BaseQtVersion::QmakeBuildConfigs m_qmakeBuildConfiguration;
QmakeProFileNode *m_subNodeBuild = nullptr;
ProjectExplorer::FileNode *m_fileNodeBuild = nullptr;
+ QmakeBuildSystem *m_buildSystem = nullptr;
};
class QMAKEPROJECTMANAGER_EXPORT QmakeBuildConfigurationFactory : public ProjectExplorer::BuildConfigurationFactory
diff --git a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp
index 77aec206cf..3de706a50f 100644
--- a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp
@@ -48,7 +48,6 @@
#include <QDir>
#include <QFileInfo>
-using ExtensionSystem::PluginManager;
using namespace ProjectExplorer;
using namespace QmakeProjectManager;
using namespace QmakeProjectManager::Internal;
@@ -85,12 +84,12 @@ bool QmakeMakeStep::init()
ProcessParameters *pp = processParameters();
pp->setMacroExpander(bc->macroExpander());
- QString workingDirectory;
+ Utils::FilePath workingDirectory;
if (bc->subNodeBuild())
- workingDirectory = bc->subNodeBuild()->buildDir();
+ workingDirectory = bc->subNodeBuild()->buildDir(bc);
else
- workingDirectory = bc->buildDirectory().toString();
- pp->setWorkingDirectory(Utils::FilePath::fromString(workingDirectory));
+ workingDirectory = bc->buildDirectory();
+ pp->setWorkingDirectory(workingDirectory);
// If we are cleaning, then make can fail with a error code, but that doesn't mean
// we should stop the clean queue
@@ -117,13 +116,14 @@ bool QmakeMakeStep::init()
if (makefile != "Makefile")
makeCmd.addArgs({"-f", makefile});
- m_makeFileToCheck = QDir(workingDirectory).filePath(makefile);
+ m_makeFileToCheck = QDir(workingDirectory.toString()).filePath(makefile);
} else {
- if (!bc->makefile().isEmpty()) {
- makeCmd.addArgs({"-f", bc->makefile()});
- m_makeFileToCheck = QDir(workingDirectory).filePath(bc->makefile());
+ QString makefile = bc->makefile();
+ if (!makefile.isEmpty()) {
+ makeCmd.addArgs({"-f", makefile});
+ m_makeFileToCheck = QDir(workingDirectory.toString()).filePath(makefile);
} else {
- m_makeFileToCheck = QDir(workingDirectory).filePath("Makefile");
+ m_makeFileToCheck = QDir(workingDirectory.toString()).filePath("Makefile");
}
}
@@ -168,7 +168,9 @@ bool QmakeMakeStep::init()
appendOutputParser(new QMakeParser); // make may cause qmake to be run, add last to make sure
// it has a low priority.
- m_scriptTarget = (static_cast<QmakeProject *>(bc->target()->project())->rootProjectNode()->projectType() == ProjectType::ScriptTemplate);
+ auto rootNode = dynamic_cast<QmakeProFileNode *>(bc->project()->rootProjectNode());
+ QTC_ASSERT(rootNode, return false);
+ m_scriptTarget = rootNode->projectType() == ProjectType::ScriptTemplate;
m_unalignedBuildDir = !bc->isBuildDirAtSafeLocation();
// A user doing "make clean" indicates they want a proper rebuild, so make sure to really
diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp
index 59c650e675..08cd2bc573 100644
--- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp
@@ -47,6 +47,8 @@
using namespace ProjectExplorer;
using namespace Utils;
+using namespace QmakeProjectManager::Internal;
+
namespace QmakeProjectManager {
/*!
@@ -54,21 +56,26 @@ namespace QmakeProjectManager {
Implements abstract ProjectNode class
*/
-QmakePriFileNode::QmakePriFileNode(QmakeProject *project, QmakeProFileNode *qmakeProFileNode,
+QmakePriFileNode::QmakePriFileNode(QmakeBuildSystem *buildSystem, QmakeProFileNode *qmakeProFileNode,
const FilePath &filePath, QmakePriFile *pf) :
ProjectNode(filePath),
- m_project(project),
+ m_buildSystem(buildSystem),
m_qmakeProFileNode(qmakeProFileNode),
m_qmakePriFile(pf)
{ }
QmakePriFile *QmakePriFileNode::priFile() const
{
- if (!m_project->isParsing())
+ if (!m_buildSystem)
+ return nullptr;
+
+ if (!m_buildSystem->isParsing())
return m_qmakePriFile;
+
// During a parsing run the qmakePriFile tree will change, so search for the PriFile and
// do not depend on the cached value.
- return m_project->rootProFile()->findPriFile(filePath());
+ // NOTE: This would go away if the node tree would be per-buildsystem
+ return m_buildSystem->rootProFile()->findPriFile(filePath());
}
bool QmakePriFileNode::deploysFolder(const QString &folder) const
@@ -91,16 +98,21 @@ bool QmakeBuildSystem::supportsAction(Node *context, ProjectAction action, const
|| dynamic_cast<const ResourceEditor::ResourceTopLevelNode *>(node);
}
- const FolderNode *folderNode = n;
- const QmakeProFileNode *proFileNode;
- while (!(proFileNode = dynamic_cast<const QmakeProFileNode*>(folderNode))) {
- folderNode = folderNode->parentFolderNode();
- QTC_ASSERT(folderNode, return false);
+ ProjectType t = ProjectType::Invalid;
+ const QmakeProFile *pro = nullptr;
+ if (hasParsingData()) {
+ const FolderNode *folderNode = n;
+ const QmakeProFileNode *proFileNode;
+ while (!(proFileNode = dynamic_cast<const QmakeProFileNode*>(folderNode))) {
+ folderNode = folderNode->parentFolderNode();
+ QTC_ASSERT(folderNode, return false);
+ }
+ QTC_ASSERT(proFileNode, return false);
+ pro = proFileNode->proFile();
+ t = pro->projectType();
}
- QTC_ASSERT(proFileNode, return false);
- const QmakeProFile *pro = proFileNode->proFile();
- switch (pro ? pro->projectType() : ProjectType::Invalid) {
+ switch (t) {
case ProjectType::ApplicationTemplate:
case ProjectType::StaticLibraryTemplate:
case ProjectType::SharedLibraryTemplate:
@@ -287,8 +299,8 @@ FolderNode::AddNewInformation QmakePriFileNode::addNewInformation(const QStringL
\class QmakeProFileNode
Implements abstract ProjectNode class
*/
-QmakeProFileNode::QmakeProFileNode(QmakeProject *project, const FilePath &filePath, QmakeProFile *pf) :
- QmakePriFileNode(project, this, filePath, pf)
+QmakeProFileNode::QmakeProFileNode(QmakeBuildSystem *buildSystem, const FilePath &filePath, QmakeProFile *pf) :
+ QmakePriFileNode(buildSystem, this, filePath, pf)
{
if (projectType() == ProjectType::ApplicationTemplate) {
setProductType(ProductType::App);
@@ -302,7 +314,7 @@ QmakeProFileNode::QmakeProFileNode(QmakeProject *project, const FilePath &filePa
bool QmakeProFileNode::showInSimpleTree() const
{
- return showInSimpleTree(projectType()) || m_project->rootProjectNode() == this;
+ return showInSimpleTree(projectType()) || m_buildSystem->project()->rootProjectNode() == this;
}
QString QmakeProFileNode::buildKey() const
@@ -407,7 +419,7 @@ bool QmakeProFileNode::setData(Core::Id role, const QVariant &value) const
QmakeProFile *QmakeProFileNode::proFile() const
{
- return static_cast<QmakeProFile*>(QmakePriFileNode::priFile());
+ return dynamic_cast<QmakeProFile*>(QmakePriFileNode::priFile());
}
QString QmakeProFileNode::makefile() const
@@ -469,19 +481,7 @@ QString QmakeProFileNode::singleVariableValue(const Variable var) const
return values.isEmpty() ? QString() : values.first();
}
-QString QmakeProFileNode::buildDir() const
-{
- if (Target *target = m_project->activeTarget()) {
- if (BuildConfiguration *bc = target->activeBuildConfiguration()) {
- const QDir srcDirRoot(m_project->projectDirectory().toString());
- const QString relativeDir = srcDirRoot.relativeFilePath(filePath().parentDir().toString());
- return QDir::cleanPath(QDir(bc->buildDirectory().toString()).absoluteFilePath(relativeDir));
- }
- }
- return QString();
-}
-
-FilePath QmakeProFileNode::buildDir(QmakeBuildConfiguration *bc) const
+FilePath QmakeProFileNode::buildDir(BuildConfiguration *bc) const
{
const QmakeProFile *pro = proFile();
return pro ? pro->buildDir(bc) : FilePath();
@@ -500,9 +500,4 @@ TargetInformation QmakeProFileNode::targetInformation() const
return proFile() ? proFile()->targetInformation() : TargetInformation();
}
-QmakeBuildSystem::QmakeBuildSystem(Project *project)
- : BuildSystem(project)
-{
-}
-
} // namespace QmakeProjectManager
diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.h b/src/plugins/qmakeprojectmanager/qmakenodes.h
index 473f400620..1332574bdb 100644
--- a/src/plugins/qmakeprojectmanager/qmakenodes.h
+++ b/src/plugins/qmakeprojectmanager/qmakenodes.h
@@ -37,36 +37,11 @@ namespace QmakeProjectManager {
class QmakeProFileNode;
class QmakeProject;
-class QmakeBuildSystem : public ProjectExplorer::BuildSystem
-{
-public:
- explicit QmakeBuildSystem(ProjectExplorer::Project *project);
-
- bool supportsAction(ProjectExplorer::Node *context,
- ProjectExplorer::ProjectAction action,
- const ProjectExplorer::Node *node) const override;
-
- bool addFiles(ProjectExplorer::Node *context,
- const QStringList &filePaths,
- QStringList *notAdded = nullptr) override;
- ProjectExplorer::RemovedFilesFromProject removeFiles(ProjectExplorer::Node *context,
- const QStringList &filePaths,
- QStringList *notRemoved = nullptr) override;
- bool deleteFiles(ProjectExplorer::Node *context,
- const QStringList &filePaths) override;
- bool canRenameFile(ProjectExplorer::Node *context,
- const QString &filePath, const QString &newFilePath) override;
- bool renameFile(ProjectExplorer::Node *context,
- const QString &filePath, const QString &newFilePath) override;
- bool addDependencies(ProjectExplorer::Node *context,
- const QStringList &dependencies) override;
-};
-
// Implements ProjectNode for qmake .pri files
class QMAKEPROJECTMANAGER_EXPORT QmakePriFileNode : public ProjectExplorer::ProjectNode
{
public:
- QmakePriFileNode(QmakeProject *project, QmakeProFileNode *qmakeProFileNode,
+ QmakePriFileNode(QmakeBuildSystem *buildSystem, QmakeProFileNode *qmakeProFileNode,
const Utils::FilePath &filePath, QmakePriFile *pf);
QmakePriFile *priFile() const;
@@ -85,7 +60,7 @@ public:
QmakeProFileNode *proFileNode() const;
protected:
- QmakeProject *m_project = nullptr;
+ QPointer<QmakeBuildSystem> m_buildSystem;
private:
QmakeProFileNode *m_qmakeProFileNode = nullptr;
@@ -96,7 +71,7 @@ private:
class QMAKEPROJECTMANAGER_EXPORT QmakeProFileNode : public QmakePriFileNode
{
public:
- QmakeProFileNode(QmakeProject *project, const Utils::FilePath &filePath, QmakeProFile *pf);
+ QmakeProFileNode(QmakeBuildSystem *buildSystem, const Utils::FilePath &filePath, QmakeProFile *pf);
QmakeProFile *proFile() const;
@@ -122,8 +97,7 @@ public:
bool setData(Core::Id role, const QVariant &value) const override;
QmakeProjectManager::ProjectType projectType() const;
- QString buildDir() const;
- Utils::FilePath buildDir(QmakeBuildConfiguration *bc) const;
+ Utils::FilePath buildDir(ProjectExplorer::BuildConfiguration *bc) const;
QStringList variableValue(const Variable var) const;
QString singleVariableValue(const Variable var) const;
diff --git a/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp b/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp
index e02c037aa1..18a73f768f 100644
--- a/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp
@@ -42,6 +42,8 @@ using namespace ProjectExplorer;
using namespace QtSupport;
using namespace Utils;
+using namespace QmakeProjectManager::Internal;
+
namespace {
// Static cached data in struct QmakeStaticData providing information and icons
@@ -128,7 +130,10 @@ void clearQmakeStaticData()
namespace QmakeProjectManager {
-static void createTree(const QmakePriFile *pri, QmakePriFileNode *node, const FilePathList &toExclude)
+static void createTree(QmakeBuildSystem *buildSystem,
+ const QmakePriFile *pri,
+ QmakePriFileNode *node,
+ const FilePathList &toExclude)
{
QTC_ASSERT(pri, return);
QTC_ASSERT(node, return);
@@ -166,7 +171,7 @@ static void createTree(const QmakePriFile *pri, QmakePriFileNode *node, const Fi
if (type == FileType::Resource) {
for (const auto &file : newFilePaths) {
- auto vfs = pri->project()->qmakeVfs();
+ auto vfs = buildSystem->qmakeVfs();
QString contents;
QString errorMessage;
// Prefer the cumulative file if it's non-empty, based on the assumption
@@ -223,26 +228,26 @@ static void createTree(const QmakePriFile *pri, QmakePriFileNode *node, const Fi
for (QmakePriFile *c : pri->children()) {
std::unique_ptr<QmakePriFileNode> newNode;
if (auto pf = dynamic_cast<QmakeProFile *>(c))
- newNode = std::make_unique<QmakeProFileNode>(c->project(), c->filePath(), pf);
+ newNode = std::make_unique<QmakeProFileNode>(c->buildSystem(), c->filePath(), pf);
else
- newNode = std::make_unique<QmakePriFileNode>(c->project(), node->proFileNode(), c->filePath(), c);
- createTree(c, newNode.get(), toExclude);
+ newNode = std::make_unique<QmakePriFileNode>(c->buildSystem(), node->proFileNode(), c->filePath(), c);
+ createTree(buildSystem, c, newNode.get(), toExclude);
node->addNode(std::move(newNode));
}
}
-std::unique_ptr<QmakeProFileNode> QmakeNodeTreeBuilder::buildTree(QmakeProject *project)
+std::unique_ptr<QmakeProFileNode> QmakeNodeTreeBuilder::buildTree(QmakeBuildSystem *buildSystem)
{
// Remove qmake implementation details that litter up the project data:
- Target *t = project->activeTarget();
- Kit *k = t ? t->kit() : KitManager::defaultKit();
- BaseQtVersion *qt = k ? QtKitAspect::qtVersion(k) : nullptr;
+ Target *t = buildSystem->target();
+ BaseQtVersion *qt = QtKitAspect::qtVersion(t->kit());
const FilePathList toExclude = qt ? qt->directoriesToIgnoreInProjectTree() : FilePathList();
- auto root = std::make_unique<QmakeProFileNode>(project, project->projectFilePath(),
- project->rootProFile());
- createTree(project->rootProFile(), root.get(), toExclude);
+ auto root = std::make_unique<QmakeProFileNode>(buildSystem,
+ buildSystem->projectFilePath(),
+ buildSystem->rootProFile());
+ createTree(buildSystem, buildSystem->rootProFile(), root.get(), toExclude);
return root;
}
diff --git a/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.h b/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.h
index be3240da3c..267331d574 100644
--- a/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.h
+++ b/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.h
@@ -28,16 +28,14 @@
#include "qmakeprojectmanager_global.h"
#include "qmakeparsernodes.h"
#include "qmakenodes.h"
-
-namespace Utils { class FilePath; }
-namespace ProjectExplorer { class RunConfiguration; }
+#include "qmakeproject.h"
namespace QmakeProjectManager {
class QmakeNodeTreeBuilder
{
public:
- static std::unique_ptr<QmakeProFileNode> buildTree(QmakeProject *project);
+ static std::unique_ptr<QmakeProFileNode> buildTree(QmakeBuildSystem *buildSystem);
};
} // namespace QmakeProjectManager
diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp
index 0ae1c3ae1a..945ba7a940 100644
--- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp
@@ -162,12 +162,12 @@ public:
} // namespace Internal
-QmakePriFile::QmakePriFile(QmakeProject *project, QmakeProFile *qmakeProFile,
+QmakePriFile::QmakePriFile(QmakeBuildSystem *buildSystem, QmakeProFile *qmakeProFile,
const FilePath &filePath) :
- m_project(project),
+ m_buildSystem(buildSystem),
m_qmakeProFile(qmakeProFile)
{
- Q_ASSERT(project);
+ Q_ASSERT(buildSystem);
m_priFileDocument = std::make_unique<QmakePriFileDocument>(this, filePath);
Core::DocumentManager::addDocument(m_priFileDocument.get());
}
@@ -194,7 +194,7 @@ QmakePriFile *QmakePriFile::parent() const
QmakeProject *QmakePriFile::project() const
{
- return m_project;
+ return static_cast<QmakeProject *>(m_buildSystem->project());
}
QVector<QmakePriFile *> QmakePriFile::children() const
@@ -255,7 +255,7 @@ QmakePriFile::~QmakePriFile()
void QmakePriFile::scheduleUpdate()
{
QtSupport::ProFileCacheManager::instance()->discardFile(
- filePath().toString(), m_project->qmakeVfs());
+ filePath().toString(), m_buildSystem->qmakeVfs());
m_qmakeProFile->scheduleUpdate(QmakeProFile::ParseLater);
}
@@ -399,8 +399,8 @@ void QmakePriFile::watchFolders(const QSet<FilePath> &folders)
QSet<QString> toWatch = folderStrings;
toWatch.subtract(m_watchedFolders);
- m_project->unwatchFolders(Utils::toList(toUnwatch), this);
- m_project->watchFolders(Utils::toList(toWatch), this);
+ m_buildSystem->unwatchFolders(Utils::toList(toUnwatch), this);
+ m_buildSystem->watchFolders(Utils::toList(toWatch), this);
m_watchedFolders = folderStrings;
}
@@ -418,6 +418,11 @@ QString QmakePriFile::continuationIndent() const
return QString(tabSettings.m_indentSize, ' ');
}
+QmakeBuildSystem *QmakePriFile::buildSystem() const
+{
+ return m_buildSystem;
+}
+
bool QmakePriFile::knowsFile(const FilePath &filePath) const
{
return m_recursiveEnumerateFiles.contains(filePath);
@@ -710,8 +715,9 @@ bool QmakePriFile::saveModifiedEditors()
// force instant reload of ourselves
QtSupport::ProFileCacheManager::instance()->discardFile(
- filePath().toString(), m_project->qmakeVfs());
- QmakeProject::notifyChanged(filePath());
+ filePath().toString(), m_buildSystem->qmakeVfs());
+
+ m_buildSystem->notifyChanged(filePath());
return true;
}
@@ -784,7 +790,7 @@ QPair<ProFile *, QStringList> QmakePriFile::readProFile()
&contents,
&m_textFormat,
&errorMsg) != TextFileFormat::ReadSuccess) {
- QmakeProject::proFileParseError(errorMsg);
+ QmakeBuildSystem::proFileParseError(errorMsg);
return qMakePair(includeFile, lines);
}
lines = contents.split('\n');
@@ -1171,8 +1177,8 @@ QByteArray QmakeProFile::cxxDefines() const
\class QmakeProFile
Implements abstract ProjectNode class
*/
-QmakeProFile::QmakeProFile(QmakeProject *project, const FilePath &filePath) :
- QmakePriFile(project, this, filePath)
+QmakeProFile::QmakeProFile(QmakeBuildSystem *buildSystem, const FilePath &filePath) :
+ QmakePriFile(buildSystem, this, filePath)
{
// The lifetime of the m_parserFutureWatcher is shorter
// than of this, so this is all safe
@@ -1245,10 +1251,7 @@ void QmakeProFile::setParseInProgressRecursive(bool b)
void QmakeProFile::setParseInProgress(bool b)
{
- if (m_parseInProgress == b)
- return;
m_parseInProgress = b;
- emit m_project->proFileUpdated(this, m_validParse, m_parseInProgress);
}
// Do note the absence of signal emission, always set validParse
@@ -1275,12 +1278,12 @@ bool QmakeProFile::parseInProgress() const
void QmakeProFile::scheduleUpdate(QmakeProFile::AsyncUpdateDelay delay)
{
setParseInProgressRecursive(true);
- m_project->scheduleAsyncUpdate(this, delay);
+ m_buildSystem->scheduleAsyncUpdateFile(this, delay);
}
void QmakeProFile::asyncUpdate()
{
- m_project->incrementPendingEvaluateFutures();
+ m_buildSystem->incrementPendingEvaluateFutures();
setupReader();
if (!includedInExactParse())
m_readerExact->setExact(false);
@@ -1307,11 +1310,11 @@ QmakeEvalInput QmakeProFile::evalInput() const
input.projectDir = directoryPath().toString();
input.projectFilePath = filePath();
input.buildDirectory = buildDir();
- input.sysroot = FilePath::fromString(m_project->qmakeSysroot());
+ input.sysroot = FilePath::fromString(m_buildSystem->qmakeSysroot());
input.readerExact = m_readerExact;
input.readerCumulative = m_readerCumulative;
- input.qmakeGlobals = m_project->qmakeGlobals();
- input.qmakeVfs = m_project->qmakeVfs();
+ input.qmakeGlobals = m_buildSystem->qmakeGlobals();
+ input.qmakeVfs = m_buildSystem->qmakeVfs();
return input;
}
@@ -1320,9 +1323,9 @@ void QmakeProFile::setupReader()
Q_ASSERT(!m_readerExact);
Q_ASSERT(!m_readerCumulative);
- m_readerExact = m_project->createProFileReader(this);
+ m_readerExact = m_buildSystem->createProFileReader(this);
- m_readerCumulative = m_project->createProFileReader(this);
+ m_readerCumulative = m_buildSystem->createProFileReader(this);
m_readerCumulative->setCumulative(true);
}
@@ -1588,7 +1591,7 @@ void QmakeProFile::applyAsyncEvaluate()
{
if (m_parseFutureWatcher.isFinished())
applyEvaluate(m_parseFutureWatcher.result());
- m_project->decrementPendingEvaluateFutures();
+ m_buildSystem->decrementPendingEvaluateFutures();
}
bool sortByParserNodes(Node *a, Node *b)
@@ -1602,23 +1605,24 @@ void QmakeProFile::applyEvaluate(QmakeEvalResult *evalResult)
if (!m_readerExact)
return;
- if (m_project->asyncUpdateState() == QmakeProject::ShuttingDown) {
+ if (m_buildSystem->asyncUpdateState() == QmakeBuildSystem::ShuttingDown) {
cleanupProFileReaders();
return;
}
foreach (const QString &error, evalResult->errors)
- QmakeProject::proFileParseError(error);
+ QmakeBuildSystem::proFileParseError(error);
// we are changing what is executed in that case
- if (result->state == QmakeEvalResult::EvalFail || m_project->wasEvaluateCanceled()) {
+ if (result->state == QmakeEvalResult::EvalFail || m_buildSystem->wasEvaluateCanceled()) {
m_validParse = false;
cleanupProFileReaders();
setValidParseRecursive(false);
setParseInProgressRecursive(false);
if (result->state == QmakeEvalResult::EvalFail) {
- QmakeProject::proFileParseError(QCoreApplication::translate("QmakeProFile", "Error while parsing file %1. Giving up.")
+ QmakeBuildSystem::proFileParseError(
+ QCoreApplication::translate("QmakeProFile", "Error while parsing file %1. Giving up.")
.arg(filePath().toUserOutput()));
if (m_projectType == ProjectType::Invalid)
return;
@@ -1678,14 +1682,14 @@ void QmakeProFile::applyEvaluate(QmakeEvalResult *evalResult)
continue; // Do nothing
if (priFile->proFile) {
- auto *qmakePriFileNode = new QmakePriFile(m_project, this, priFile->name);
+ auto *qmakePriFileNode = new QmakePriFile(m_buildSystem, this, priFile->name);
pn->addChild(qmakePriFileNode);
qmakePriFileNode->setIncludedInExactParse(
(result->state == QmakeEvalResult::EvalOk) && pn->includedInExactParse());
qmakePriFileNode->update(priFile->result);
toCompare.append(qMakePair(qmakePriFileNode, priFile));
} else {
- auto *qmakeProFileNode = new QmakeProFile(m_project, priFile->name);
+ auto *qmakeProFileNode = new QmakeProFile(m_buildSystem, priFile->name);
pn->addChild(qmakeProFileNode);
qmakeProFileNode->setIncludedInExactParse(
result->exactSubdirs.contains(qmakeProFileNode->filePath())
@@ -1765,9 +1769,9 @@ void QmakeProFile::applyEvaluate(QmakeEvalResult *evalResult)
void QmakeProFile::cleanupProFileReaders()
{
if (m_readerExact)
- m_project->destroyProFileReader(m_readerExact);
+ m_buildSystem->destroyProFileReader(m_readerExact);
if (m_readerCumulative)
- m_project->destroyProFileReader(m_readerCumulative);
+ m_buildSystem->destroyProFileReader(m_readerCumulative);
m_readerExact = nullptr;
m_readerCumulative = nullptr;
@@ -2017,15 +2021,16 @@ FilePath QmakeProFile::sourceDir() const
return directoryPath();
}
-FilePath QmakeProFile::buildDir(QmakeBuildConfiguration *bc) const
+FilePath QmakeProFile::buildDir(BuildConfiguration *bc) const
{
- const QDir srcDirRoot = QDir(m_project->projectDirectory().toString());
+ if (!bc)
+ bc = m_buildSystem->target()->activeBuildConfiguration();
+
+ const QDir srcDirRoot = QDir(m_buildSystem->projectDirectory().toString());
const QString relativeDir = srcDirRoot.relativeFilePath(directoryPath().toString());
- if (!bc && m_project->activeTarget())
- bc = static_cast<QmakeBuildConfiguration *>(m_project->activeTarget()->activeBuildConfiguration());
const QString buildConfigBuildDir = bc ? bc->buildDirectory().toString() : QString();
const QString buildDir = buildConfigBuildDir.isEmpty()
- ? m_project->projectDirectory().toString()
+ ? m_buildSystem->projectDirectory().toString()
: buildConfigBuildDir;
return FilePath::fromString(QDir::cleanPath(QDir(buildDir).absoluteFilePath(relativeDir)));
}
@@ -2075,7 +2080,7 @@ void QmakeProFile::setupExtraCompiler(const FilePath &buildDir,
for (const FilePath &fn : collectFiles(fileType)) {
const FilePathList generated = generatedFiles(buildDir, fn, fileType);
if (!generated.isEmpty())
- m_extraCompilers.append(factory->create(m_project, fn, generated));
+ m_extraCompilers.append(factory->create(m_buildSystem->project(), fn, generated));
}
}
diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h
index 538d1a65e9..25dc5c5acf 100644
--- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h
+++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h
@@ -47,10 +47,10 @@ class FileSystemWatcher;
} // namespace Utils;
namespace QtSupport { class ProFileReader; }
-namespace ProjectExplorer { class RunConfiguration; }
namespace QmakeProjectManager {
class QmakeBuildConfiguration;
+class QmakeBuildSystem;
class QmakeProFile;
class QmakeProject;
@@ -122,7 +122,7 @@ using SourceFiles = QSet<SourceFile>;
class QMAKEPROJECTMANAGER_EXPORT QmakePriFile
{
public:
- QmakePriFile(QmakeProject *project, QmakeProFile *qmakeProFile, const Utils::FilePath &filePath);
+ QmakePriFile(QmakeBuildSystem *buildSystem, QmakeProFile *qmakeProFile, const Utils::FilePath &filePath);
virtual ~QmakePriFile();
Utils::FilePath filePath() const;
@@ -178,6 +178,8 @@ public:
void scheduleUpdate();
+ QmakeBuildSystem *buildSystem() const;
+
protected:
void setIncludedInExactParse(bool b);
static QStringList varNames(ProjectExplorer::FileType type, QtSupport::ProFileReader *readerExact);
@@ -225,7 +227,7 @@ private:
QString continuationIndent() const;
- QmakeProject *m_project = nullptr;
+ QPointer<QmakeBuildSystem> m_buildSystem;
QmakeProFile *m_qmakeProFile = nullptr;
QmakePriFile *m_parent = nullptr;
QVector<QmakePriFile *> m_children;
@@ -289,7 +291,7 @@ public:
class QMAKEPROJECTMANAGER_EXPORT QmakeProFile : public QmakePriFile
{
public:
- QmakeProFile(QmakeProject *project, const Utils::FilePath &filePath);
+ QmakeProFile(QmakeBuildSystem *buildSystem, const Utils::FilePath &filePath);
~QmakeProFile() override;
bool isParent(QmakeProFile *node);
@@ -309,7 +311,7 @@ public:
}
Utils::FilePath sourceDir() const;
- Utils::FilePath buildDir(QmakeBuildConfiguration *bc = nullptr) const;
+ Utils::FilePath buildDir(ProjectExplorer::BuildConfiguration *bc = nullptr) const;
Utils::FilePathList generatedFiles(const Utils::FilePath &buildDirectory,
const Utils::FilePath &sourceFile,
diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
index 01916251c7..d0c03864c8 100644
--- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
@@ -90,7 +90,7 @@ class CentralizedFolderWatcher : public QObject
{
Q_OBJECT
public:
- CentralizedFolderWatcher(QmakeProject *parent);
+ CentralizedFolderWatcher(QmakeBuildSystem *BuildSystem);
void watchFolders(const QList<QString> &folders, QmakePriFile *file);
void unwatchFolders(const QList<QString> &folders, QmakePriFile *file);
@@ -100,7 +100,7 @@ private:
void onTimer();
void delayedFolderChanged(const QString &folder);
- QmakeProject *m_project;
+ QmakeBuildSystem *m_buildSystem;
QSet<QString> recursiveDirs(const QString &folder);
QFileSystemWatcher m_watcher;
QMultiMap<QString, QmakePriFile *> m_map;
@@ -110,8 +110,6 @@ private:
QSet<QString> m_changedFolders;
};
-static QList<QmakeProject *> s_projects;
-
} // namespace Internal
/*!
@@ -120,61 +118,35 @@ static QList<QmakeProject *> s_projects;
QmakeProject manages information about an individual Qt 4 (.pro) project file.
*/
+static bool matchesKit(const Project *p, const Kit *kit)
+{
+ FilePath filePath = p->projectFilePath();
+ QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(kit);
+
+ return QtSupport::QtVersionManager::version([&filePath, version](const QtSupport::BaseQtVersion *v) {
+ return v->isValid() && v->isSubProject(filePath) && v == version;
+ });
+}
+
QmakeProject::QmakeProject(const FilePath &fileName) :
- Project(QmakeProjectManager::Constants::PROFILE_MIMETYPE, fileName),
- m_qmakeVfs(new QMakeVfs),
- m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
+ Project(QmakeProjectManager::Constants::PROFILE_MIMETYPE, fileName)
{
- s_projects.append(this);
setId(Constants::QMAKEPROJECT_ID);
setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
setDisplayName(fileName.toFileInfo().completeBaseName());
setCanBuildProducts();
setHasMakeInstallEquivalent(true);
- const QTextCodec *codec = Core::EditorManager::defaultTextCodec();
- m_qmakeVfs->setTextCodec(codec);
-
- m_asyncUpdateTimer.setSingleShot(true);
- m_asyncUpdateTimer.setInterval(UPDATE_INTERVAL);
- connect(&m_asyncUpdateTimer, &QTimer::timeout, this, &QmakeProject::asyncUpdate);
-
- m_rootProFile = std::make_unique<QmakeProFile>(this, projectFilePath());
-
- connect(BuildManager::instance(), &BuildManager::buildQueueFinished,
- this, &QmakeProject::buildFinished);
-
- setPreferredKitPredicate([this](const Kit *kit) -> bool { return matchesKit(kit); });
- setBuildSystemCreator([](Project *p) { return new QmakeBuildSystem(p); });
+ setPreferredKitPredicate([this](const Kit *kit) -> bool { return matchesKit(this, kit); });
}
QmakeProject::~QmakeProject()
{
- s_projects.removeOne(this);
delete m_projectImporter;
m_projectImporter = nullptr;
- delete m_cppCodeModelUpdater;
- m_cppCodeModelUpdater = nullptr;
- m_asyncUpdateState = ShuttingDown;
// Make sure root node (and associated readers) are shut hown before proceeding
setRootProjectNode(nullptr);
- m_rootProFile.reset();
-
- m_cancelEvaluate = true;
- Q_ASSERT(m_qmakeGlobalsRefCnt == 0);
- delete m_qmakeVfs;
-
- if (m_asyncUpdateFutureInterface) {
- m_asyncUpdateFutureInterface->reportCanceled();
- m_asyncUpdateFutureInterface->reportFinished();
- delete m_asyncUpdateFutureInterface;
- }
-}
-
-QmakeProFile *QmakeProject::rootProFile() const
-{
- return m_rootProFile.get();
}
Project::RestoreResult QmakeProject::fromMap(const QVariantMap &map, QString *errorMessage)
@@ -193,17 +165,6 @@ Project::RestoreResult QmakeProject::fromMap(const QVariantMap &map, QString *er
}
}
- // On active buildconfiguration changes, reevaluate the .pro files
- m_activeTarget = activeTarget();
- if (m_activeTarget) {
- connect(m_activeTarget, &Target::activeBuildConfigurationChanged,
- this, &QmakeProject::scheduleAsyncUpdateLater);
- scheduleAsyncUpdate(QmakeProFile::ParseNow);
- }
-
- connect(this, &Project::activeTargetChanged,
- this, &QmakeProject::activeTargetWasChanged);
-
return RestoreResult::Ok;
}
@@ -212,20 +173,78 @@ DeploymentKnowledge QmakeProject::deploymentKnowledge() const
return DeploymentKnowledge::Approximative; // E.g. QTCREATORBUG-21855
}
-void QmakeProject::updateCodeModels()
+//
+// QmakeBuildSystem
+//
+
+QmakeBuildSystem::QmakeBuildSystem(QmakeBuildConfiguration *bc)
+ : BuildSystem(bc),
+ m_qmakeVfs(new QMakeVfs),
+ m_cppCodeModelUpdater(new CppTools::CppProjectUpdater),
+ m_buildConfiguration(bc)
+{
+ const QTextCodec *codec = Core::EditorManager::defaultTextCodec();
+ m_qmakeVfs->setTextCodec(codec);
+
+ m_asyncUpdateTimer.setSingleShot(true);
+ m_asyncUpdateTimer.setInterval(UPDATE_INTERVAL);
+ connect(&m_asyncUpdateTimer, &QTimer::timeout, this, &QmakeBuildSystem::asyncUpdate);
+
+ m_rootProFile = std::make_unique<QmakeProFile>(this, projectFilePath());
+
+ connect(BuildManager::instance(), &BuildManager::buildQueueFinished,
+ this, &QmakeBuildSystem::buildFinished);
+
+ connect(bc->target(), &Target::activeBuildConfigurationChanged,
+ this, [this](BuildConfiguration *bc) {
+ if (bc == m_buildConfiguration)
+ scheduleUpdateAllNowOrLater();
+// FIXME: This is too eager in the presence of not handling updates
+// when the build configuration is not active, see startAsyncTimer
+// below.
+// else
+// m_cancelEvaluate = true;
+ });
+
+ connect(bc->project(), &Project::activeTargetChanged,
+ this, &QmakeBuildSystem::activeTargetWasChanged);
+
+ connect(bc->project(), &Project::projectFileIsDirty,
+ this, &QmakeBuildSystem::scheduleUpdateAllLater);
+}
+
+QmakeBuildSystem::~QmakeBuildSystem()
+{
+ delete m_cppCodeModelUpdater;
+ m_cppCodeModelUpdater = nullptr;
+ m_asyncUpdateState = ShuttingDown;
+
+ // Make sure root node (and associated readers) are shut hown before proceeding
+ m_rootProFile.reset();
+
+ m_cancelEvaluate = true;
+ QTC_CHECK(m_qmakeGlobalsRefCnt == 0);
+ delete m_qmakeVfs;
+ m_qmakeVfs = nullptr;
+
+ m_asyncUpdateFutureInterface.reportCanceled();
+ m_asyncUpdateFutureInterface.reportFinished();
+}
+
+void QmakeBuildSystem::updateCodeModels()
{
- if (activeTarget() && !activeTarget()->activeBuildConfiguration())
+ if (!m_buildConfiguration->isActive())
return;
updateCppCodeModel();
updateQmlJSCodeModel();
}
-void QmakeProject::updateCppCodeModel()
+void QmakeBuildSystem::updateCppCodeModel()
{
m_toolChainWarnings.clear();
- QtSupport::CppKitInfo kitInfo(this);
+ QtSupport::CppKitInfo kitInfo(project());
QTC_ASSERT(kitInfo.isValid(), return);
QList<ProjectExplorer::ExtraCompiler *> generators;
@@ -286,17 +305,17 @@ void QmakeProject::updateCppCodeModel()
}
CppTools::GeneratedCodeModelSupport::update(generators);
- m_cppCodeModelUpdater->update({this, kitInfo, activeParseEnvironment(), rpps});
+ m_cppCodeModelUpdater->update({project(), kitInfo, activeParseEnvironment(), rpps});
}
-void QmakeProject::updateQmlJSCodeModel()
+void QmakeBuildSystem::updateQmlJSCodeModel()
{
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
if (!modelManager)
return;
QmlJS::ModelManagerInterface::ProjectInfo projectInfo =
- modelManager->defaultProjectInfoForProject(this);
+ modelManager->defaultProjectInfoForProject(project());
const QList<QmakeProFile *> proFiles = rootProFile()->allProFiles();
@@ -339,15 +358,15 @@ void QmakeProject::updateQmlJSCodeModel()
// This assumption fails when there are no QDeclarativeEngine/QDeclarativeView (QtQuick 1)
// or QQmlEngine/QQuickView (QtQuick 2) instances.
if (hasQmlLib)
- addProjectLanguage(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID);
+ project()->addProjectLanguage(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID);
projectInfo.activeResourceFiles.removeDuplicates();
projectInfo.allResourceFiles.removeDuplicates();
- modelManager->updateProjectInfo(projectInfo, this);
+ modelManager->updateProjectInfo(projectInfo, project());
}
-void QmakeProject::scheduleAsyncUpdate(QmakeProFile *file, QmakeProFile::AsyncUpdateDelay delay)
+void QmakeBuildSystem::scheduleAsyncUpdateFile(QmakeProFile *file, QmakeProFile::AsyncUpdateDelay delay)
{
if (m_asyncUpdateState == ShuttingDown)
return;
@@ -400,11 +419,21 @@ void QmakeProject::scheduleAsyncUpdate(QmakeProFile *file, QmakeProFile::AsyncUp
// change a partial update gets in progress and then another
// batch of changes come in, which triggers a full update
// even if that's not really needed
- scheduleAsyncUpdate(delay);
+ scheduleUpdateAll(delay);
}
}
-void QmakeProject::scheduleAsyncUpdate(QmakeProFile::AsyncUpdateDelay delay)
+void QmakeBuildSystem::scheduleUpdateAllNowOrLater()
+{
+ if (m_firstParseNeeded) {
+ m_firstParseNeeded = false;
+ scheduleUpdateAll(QmakeProFile::ParseNow);
+ } else {
+ scheduleUpdateAll(QmakeProFile::ParseLater);
+ }
+}
+
+void QmakeBuildSystem::scheduleUpdateAll(QmakeProFile::AsyncUpdateDelay delay)
{
if (m_asyncUpdateState == ShuttingDown)
return;
@@ -430,8 +459,11 @@ void QmakeProject::scheduleAsyncUpdate(QmakeProFile::AsyncUpdateDelay delay)
startAsyncTimer(delay);
}
-void QmakeProject::startAsyncTimer(QmakeProFile::AsyncUpdateDelay delay)
+void QmakeBuildSystem::startAsyncTimer(QmakeProFile::AsyncUpdateDelay delay)
{
+ if (!m_buildConfiguration->isActive())
+ return;
+
m_asyncUpdateTimer.stop();
m_asyncUpdateTimer.setInterval(qMin(m_asyncUpdateTimer.interval(),
delay == QmakeProFile::ParseLater ? UPDATE_INTERVAL : 0));
@@ -439,33 +471,31 @@ void QmakeProject::startAsyncTimer(QmakeProFile::AsyncUpdateDelay delay)
m_asyncUpdateTimer.start();
}
-void QmakeProject::incrementPendingEvaluateFutures()
+void QmakeBuildSystem::incrementPendingEvaluateFutures()
{
if (m_pendingEvaluateFuturesCount == 0)
m_guard = guardParsingRun();
++m_pendingEvaluateFuturesCount;
- m_asyncUpdateFutureInterface->setProgressRange(m_asyncUpdateFutureInterface->progressMinimum(),
- m_asyncUpdateFutureInterface->progressMaximum() + 1);
+ m_asyncUpdateFutureInterface.setProgressRange(m_asyncUpdateFutureInterface.progressMinimum(),
+ m_asyncUpdateFutureInterface.progressMaximum() + 1);
}
-void QmakeProject::decrementPendingEvaluateFutures()
+void QmakeBuildSystem::decrementPendingEvaluateFutures()
{
--m_pendingEvaluateFuturesCount;
if (!rootProFile())
return; // We are closing the project!
- m_asyncUpdateFutureInterface->setProgressValue(m_asyncUpdateFutureInterface->progressValue() + 1);
+ m_asyncUpdateFutureInterface.setProgressValue(m_asyncUpdateFutureInterface.progressValue() + 1);
if (m_pendingEvaluateFuturesCount == 0) {
// We are done!
- setRootProjectNode(QmakeNodeTreeBuilder::buildTree(this));
+ project()->setRootProjectNode(QmakeNodeTreeBuilder::buildTree(this));
if (!m_rootProFile->validParse())
- m_asyncUpdateFutureInterface->reportCanceled();
+ m_asyncUpdateFutureInterface.reportCanceled();
- m_asyncUpdateFutureInterface->reportFinished();
- delete m_asyncUpdateFutureInterface;
- m_asyncUpdateFutureInterface = nullptr;
+ m_asyncUpdateFutureInterface.reportFinished();
m_cancelEvaluate = false;
// TODO clear the profile cache ?
@@ -479,20 +509,19 @@ void QmakeProject::decrementPendingEvaluateFutures()
m_asyncUpdateState = Base;
updateBuildSystemData();
updateCodeModels();
- if (activeTarget())
- activeTarget()->updateDefaultDeployConfigurations();
+ target()->updateDefaultDeployConfigurations();
m_guard.markAsSuccess(); // Qmake always returns (some) data, even when it failed:-)
- m_guard = {};
+ m_guard = {}; // This triggers emitParsingFinished by destroying the previous guard.
}
}
}
-bool QmakeProject::wasEvaluateCanceled()
+bool QmakeBuildSystem::wasEvaluateCanceled()
{
return m_cancelEvaluate;
}
-void QmakeProject::asyncUpdate()
+void QmakeBuildSystem::asyncUpdate()
{
m_asyncUpdateTimer.setInterval(UPDATE_INTERVAL);
@@ -503,28 +532,23 @@ void QmakeProject::asyncUpdate()
m_qmakeVfs->invalidateCache();
}
- Q_ASSERT(!m_asyncUpdateFutureInterface);
- m_asyncUpdateFutureInterface = new QFutureInterface<void>();
-
- m_asyncUpdateFutureInterface->setProgressRange(0, 0);
- Core::ProgressManager::addTask(m_asyncUpdateFutureInterface->future(),
- tr("Reading Project \"%1\"").arg(displayName()),
+ m_asyncUpdateFutureInterface.setProgressRange(0, 0);
+ Core::ProgressManager::addTask(m_asyncUpdateFutureInterface.future(),
+ tr("Reading Project \"%1\"").arg(project()->displayName()),
Constants::PROFILE_EVALUATE);
- m_asyncUpdateFutureInterface->reportStarted();
+ m_asyncUpdateFutureInterface.reportStarted();
- const Kit * const kit = activeTarget() ? activeTarget()->kit() : nullptr;
+ const Kit * const kit = target()->kit();
QtSupport::BaseQtVersion * const qtVersion = QtSupport::QtKitAspect::qtVersion(kit);
if (!qtVersion || !qtVersion->isValid()) {
const QString errorMessage = kit
? tr("Cannot parse project \"%1\": The currently selected kit \"%2\" does not "
- "have a valid Qt.").arg(displayName(), kit->displayName())
- : tr("Cannot parse project \"%1\": No kit selected.").arg(displayName());
+ "have a valid Qt.").arg(project()->displayName(), kit->displayName())
+ : tr("Cannot parse project \"%1\": No kit selected.").arg(project()->displayName());
proFileParseError(errorMessage);
- m_asyncUpdateFutureInterface->reportCanceled();
- m_asyncUpdateFutureInterface->reportFinished();
- delete m_asyncUpdateFutureInterface;
- m_asyncUpdateFutureInterface = nullptr;
+ m_asyncUpdateFutureInterface.reportCanceled();
+ m_asyncUpdateFutureInterface.reportFinished();
return;
}
@@ -539,7 +563,7 @@ void QmakeProject::asyncUpdate()
m_asyncUpdateState = AsyncUpdateInProgress;
}
-void QmakeProject::buildFinished(bool success)
+void QmakeBuildSystem::buildFinished(bool success)
{
if (success)
m_invalidateQmakeVfsContents = true;
@@ -584,51 +608,28 @@ static FileNode *fileNodeOf(FolderNode *in, const FilePath &fileName)
return nullptr;
}
-QStringList QmakeProject::filesGeneratedFrom(const QString &input) const
-{
- if (!rootProjectNode())
- return { };
-
- if (const FileNode *file = fileNodeOf(rootProjectNode(), FilePath::fromString(input))) {
- const QmakeProFileNode *pro = static_cast<QmakeProFileNode *>(file->parentFolderNode());
- QTC_ASSERT(pro, return {});
- if (const QmakeProFile *proFile = pro->proFile())
- return Utils::transform(proFile->generatedFiles(FilePath::fromString(pro->buildDir()),
- file->filePath(), file->fileType()),
- &FilePath::toString);
- }
- return { };
-}
-
-void QmakeProject::proFileParseError(const QString &errorMessage)
+void QmakeBuildSystem::proFileParseError(const QString &errorMessage)
{
Core::MessageManager::write(errorMessage);
}
-QtSupport::ProFileReader *QmakeProject::createProFileReader(const QmakeProFile *qmakeProFile)
+QtSupport::ProFileReader *QmakeBuildSystem::createProFileReader(const QmakeProFile *qmakeProFile)
{
if (!m_qmakeGlobals) {
m_qmakeGlobals = std::make_unique<QMakeGlobals>();
m_qmakeGlobalsRefCnt = 0;
- Kit *k = KitManager::defaultKit();
Environment env = Environment::systemEnvironment();
QStringList qmakeArgs;
- if (Target *t = activeTarget()) {
- k = t->kit();
- if (auto bc = static_cast<QmakeBuildConfiguration *>(t->activeBuildConfiguration())) {
- env = bc->environment();
- if (QMakeStep *qs = bc->qmakeStep())
- qmakeArgs = qs->parserArguments();
- else
- qmakeArgs = bc->configCommandLineArguments();
- }
- } else {
- // Set up a better default environment without using a build configuration:
- QmakeBuildConfiguration::setupBuildEnvironment(k, env);
- if (k)
- k->addToEnvironment(env);
+ Target *t = target();
+ Kit *k = t->kit();
+ if (auto bc = static_cast<QmakeBuildConfiguration *>(t->activeBuildConfiguration())) {
+ env = bc->environment();
+ if (QMakeStep *qs = bc->qmakeStep())
+ qmakeArgs = qs->parserArguments();
+ else
+ qmakeArgs = bc->configCommandLineArguments();
}
QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(k);
@@ -672,22 +673,22 @@ QtSupport::ProFileReader *QmakeProject::createProFileReader(const QmakeProFile *
return reader;
}
-QMakeGlobals *QmakeProject::qmakeGlobals()
+QMakeGlobals *QmakeBuildSystem::qmakeGlobals()
{
return m_qmakeGlobals.get();
}
-QMakeVfs *QmakeProject::qmakeVfs()
+QMakeVfs *QmakeBuildSystem::qmakeVfs()
{
return m_qmakeVfs;
}
-QString QmakeProject::qmakeSysroot()
+QString QmakeBuildSystem::qmakeSysroot()
{
return m_qmakeSysroot;
}
-void QmakeProject::destroyProFileReader(QtSupport::ProFileReader *reader)
+void QmakeBuildSystem::destroyProFileReader(QtSupport::ProFileReader *reader)
{
delete reader;
if (!--m_qmakeGlobalsRefCnt) {
@@ -701,36 +702,21 @@ void QmakeProject::destroyProFileReader(QtSupport::ProFileReader *reader)
}
}
-QmakeProFileNode *QmakeProject::rootProjectNode() const
-{
- return static_cast<QmakeProFileNode *>(Project::rootProjectNode());
-}
-
-void QmakeProject::activeTargetWasChanged()
+void QmakeBuildSystem::activeTargetWasChanged(Target *t)
{
- const bool hadActiveTarget = m_activeTarget;
- if (hadActiveTarget) {
- disconnect(m_activeTarget, &Target::activeBuildConfigurationChanged,
- this, &QmakeProject::scheduleAsyncUpdateLater);
- }
-
- m_activeTarget = activeTarget();
- m_invalidateQmakeVfsContents = true;
-
- if (!m_activeTarget)
+ // We are only interested in our own target.
+ if (t != m_buildConfiguration->target())
return;
- connect(m_activeTarget, &Target::activeBuildConfigurationChanged,
- this, &QmakeProject::scheduleAsyncUpdateLater);
-
- scheduleAsyncUpdate(hadActiveTarget ? QmakeProFile::ParseLater : QmakeProFile::ParseNow);
+ m_invalidateQmakeVfsContents = true;
+ scheduleUpdateAll(QmakeProFile::ParseLater);
}
static void notifyChangedHelper(const FilePath &fileName, QmakeProFile *file)
{
if (file->filePath() == fileName) {
QtSupport::ProFileCacheManager::instance()->discardFile(
- fileName.toString(), file->project()->qmakeVfs());
+ fileName.toString(), file->buildSystem()->qmakeVfs());
file->scheduleUpdate(QmakeProFile::ParseNow);
}
@@ -740,19 +726,19 @@ static void notifyChangedHelper(const FilePath &fileName, QmakeProFile *file)
}
}
-void QmakeProject::notifyChanged(const FilePath &name)
+void QmakeBuildSystem::notifyChanged(const FilePath &name)
{
- for (QmakeProject *project : s_projects) {
- if (!project
- ->files([&name](const ProjectExplorer::Node *n) {
- return Project::SourceFiles(n) && n->filePath() == name;
- })
- .isEmpty())
- notifyChangedHelper(name, project->rootProFile());
- }
+ FilePathList files = project()->files([&name](const Node *n) {
+ return Project::SourceFiles(n) && n->filePath() == name;
+ });
+
+ if (files.isEmpty())
+ return;
+
+ notifyChangedHelper(name, m_rootProFile.get());
}
-void QmakeProject::watchFolders(const QStringList &l, QmakePriFile *file)
+void QmakeBuildSystem::watchFolders(const QStringList &l, QmakePriFile *file)
{
if (l.isEmpty())
return;
@@ -761,7 +747,7 @@ void QmakeProject::watchFolders(const QStringList &l, QmakePriFile *file)
m_centralizedFolderWatcher->watchFolders(l, file);
}
-void QmakeProject::unwatchFolders(const QStringList &l, QmakePriFile *file)
+void QmakeBuildSystem::unwatchFolders(const QStringList &l, QmakePriFile *file)
{
if (m_centralizedFolderWatcher && !l.isEmpty())
m_centralizedFolderWatcher->unwatchFolders(l, file);
@@ -772,8 +758,8 @@ void QmakeProject::unwatchFolders(const QStringList &l, QmakePriFile *file)
////////////
// All the folder have a trailing slash!
-CentralizedFolderWatcher::CentralizedFolderWatcher(QmakeProject *parent)
- : QObject(parent), m_project(parent)
+CentralizedFolderWatcher::CentralizedFolderWatcher(QmakeBuildSystem *parent)
+ : QObject(parent), m_buildSystem(parent)
{
m_compressTimer.setSingleShot(true);
m_compressTimer.setInterval(200);
@@ -914,7 +900,7 @@ void CentralizedFolderWatcher::delayedFolderChanged(const QString &folder)
}
if (newOrRemovedFiles)
- m_project->updateCodeModels();
+ m_buildSystem->updateCodeModels();
}
void QmakeProject::configureAsExampleProject()
@@ -930,22 +916,19 @@ void QmakeProject::configureAsExampleProject()
setup(infoList);
}
-void QmakeProject::updateBuildSystemData()
+void QmakeBuildSystem::updateBuildSystemData()
{
- Target *const target = activeTarget();
- if (!target)
- return;
const QmakeProFile *const file = rootProFile();
if (!file || file->parseInProgress())
return;
DeploymentData deploymentData;
collectData(file, deploymentData);
- target->setDeploymentData(deploymentData);
+ setDeploymentData(deploymentData);
QList<BuildTargetInfo> appTargetList;
- rootProjectNode()->forEachProjectNode([this, target, &appTargetList](const ProjectNode *pn) {
+ project()->rootProjectNode()->forEachProjectNode([this, &appTargetList](const ProjectNode *pn) {
auto node = dynamic_cast<const QmakeProFileNode *>(pn);
if (!node || !node->includedInExactParse())
return;
@@ -1017,7 +1000,7 @@ void QmakeProject::updateBuildSystemData()
libraryPaths.append(dir);
}
}
- QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(target->kit());
+ QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(target()->kit());
if (qtVersion)
libraryPaths.append(qtVersion->librarySearchPath().toString());
@@ -1030,10 +1013,10 @@ void QmakeProject::updateBuildSystemData()
appTargetList.append(bti);
});
- target->setApplicationTargets(appTargetList);
+ setApplicationTargets(appTargetList);
}
-void QmakeProject::collectData(const QmakeProFile *file, DeploymentData &deploymentData)
+void QmakeBuildSystem::collectData(const QmakeProFile *file, DeploymentData &deploymentData)
{
if (!file->isSubProjectDeployable(file->filePath()))
return;
@@ -1069,7 +1052,7 @@ void QmakeProject::collectData(const QmakeProFile *file, DeploymentData &deploym
}
}
-void QmakeProject::collectApplicationData(const QmakeProFile *file, DeploymentData &deploymentData)
+void QmakeBuildSystem::collectApplicationData(const QmakeProFile *file, DeploymentData &deploymentData)
{
QString executable = executableFor(file);
if (!executable.isEmpty())
@@ -1086,12 +1069,12 @@ static FilePath destDirFor(const TargetInformation &ti)
return ti.destDir;
}
-void QmakeProject::collectLibraryData(const QmakeProFile *file, DeploymentData &deploymentData)
+void QmakeBuildSystem::collectLibraryData(const QmakeProFile *file, DeploymentData &deploymentData)
{
const QString targetPath = file->installsList().targetPath;
if (targetPath.isEmpty())
return;
- const Kit * const kit = activeTarget()->kit();
+ const Kit * const kit = target()->kit();
const ToolChain * const toolchain = ToolChainKitAspect::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID);
if (!toolchain)
return;
@@ -1176,16 +1159,6 @@ void QmakeProject::collectLibraryData(const QmakeProFile *file, DeploymentData &
}
}
-bool QmakeProject::matchesKit(const Kit *kit)
-{
- FilePath filePath = projectFilePath();
- QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(kit);
-
- return QtSupport::QtVersionManager::version([&filePath, version](const QtSupport::BaseQtVersion *v) {
- return v->isValid() && v->isSubProject(filePath) && v == version;
- });
-}
-
static Utils::FilePath getFullPathOf(const QmakeProFile *pro, Variable variable,
const BuildConfiguration *bc)
{
@@ -1205,7 +1178,7 @@ static Utils::FilePath getFullPathOf(const QmakeProFile *pro, Variable variable,
return bc->environment().searchInPath(exe);
}
-void QmakeProject::testToolChain(ToolChain *tc, const Utils::FilePath &path) const
+void QmakeBuildSystem::testToolChain(ToolChain *tc, const FilePath &path) const
{
if (!tc || path.isEmpty())
return;
@@ -1213,15 +1186,14 @@ void QmakeProject::testToolChain(ToolChain *tc, const Utils::FilePath &path) con
const Utils::FilePath expected = tc->compilerCommand();
Environment env = Environment::systemEnvironment();
- Kit *k = nullptr;
- if (Target *t = activeTarget()) {
- k = t->kit();
- if (BuildConfiguration *bc = t->activeBuildConfiguration())
- env = bc->environment();
- else
- k->addToEnvironment(env);
- }
- QTC_ASSERT(k, return);
+ Target *t = target();
+ QTC_ASSERT(t, return);
+
+ Kit *k = t->kit();
+ if (BuildConfiguration *bc = t->activeBuildConfiguration())
+ env = bc->environment();
+ else
+ k->addToEnvironment(env);
if (env.isSameExecutable(path.toString(), expected.toString()))
return;
@@ -1247,9 +1219,9 @@ void QmakeProject::testToolChain(ToolChain *tc, const Utils::FilePath &path) con
m_toolChainWarnings.insert(pair);
}
-void QmakeProject::warnOnToolChainMismatch(const QmakeProFile *pro) const
+void QmakeBuildSystem::warnOnToolChainMismatch(const QmakeProFile *pro) const
{
- const Target *t = activeTarget();
+ const Target *t = target();
const BuildConfiguration *bc = t ? t->activeBuildConfiguration() : nullptr;
if (!bc)
return;
@@ -1260,9 +1232,9 @@ void QmakeProject::warnOnToolChainMismatch(const QmakeProFile *pro) const
getFullPathOf(pro, Variable::QmakeCxx, bc));
}
-QString QmakeProject::executableFor(const QmakeProFile *file)
+QString QmakeBuildSystem::executableFor(const QmakeProFile *file)
{
- const Kit *const kit = activeTarget() ? activeTarget()->kit() : nullptr;
+ const Kit *const kit = target()->kit();
const ToolChain *const tc = ToolChainKitAspect::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID);
if (!tc)
return QString();
@@ -1285,11 +1257,6 @@ QString QmakeProject::executableFor(const QmakeProFile *file)
return QDir(destDirFor(ti).toString()).absoluteFilePath(target);
}
-void QmakeProject::emitBuildDirectoryInitialized()
-{
- emit buildDirectoryInitialized();
-}
-
ProjectImporter *QmakeProject::projectImporter() const
{
if (!m_projectImporter)
@@ -1297,24 +1264,44 @@ ProjectImporter *QmakeProject::projectImporter() const
return m_projectImporter;
}
-QmakeProject::AsyncUpdateState QmakeProject::asyncUpdateState() const
+QmakeBuildSystem::AsyncUpdateState QmakeBuildSystem::asyncUpdateState() const
{
return m_asyncUpdateState;
}
-QString QmakeProject::mapProFilePathToTarget(const FilePath &proFilePath)
+QmakeProFile *QmakeBuildSystem::rootProFile() const
+{
+ return m_rootProFile.get();
+}
+
+void QmakeBuildSystem::triggerParsing()
+{
+ asyncUpdate();
+}
+
+QStringList QmakeBuildSystem::filesGeneratedFrom(const QString &input) const
{
- const QmakeProFile *pro = rootProFile()->findProFile(proFilePath);
- return pro ? pro->targetInformation().target : QString();
+ if (!project()->rootProjectNode())
+ return {};
+
+ if (const FileNode *file = fileNodeOf(project()->rootProjectNode(), FilePath::fromString(input))) {
+ const QmakeProFileNode *pro = dynamic_cast<QmakeProFileNode *>(file->parentFolderNode());
+ QTC_ASSERT(pro, return {});
+ if (const QmakeProFile *proFile = pro->proFile())
+ return Utils::transform(proFile->generatedFiles(pro->buildDir(nullptr),
+ file->filePath(), file->fileType()),
+ &FilePath::toString);
+ }
+ return {};
}
-QVariant QmakeProject::additionalData(Core::Id id, const Target *target) const
+QVariant QmakeBuildSystem::additionalData(Core::Id id) const
{
if (id == "QmlDesignerImportPath")
- return rootProjectNode()->variableValue(Variable::QmlDesignerImportPath);
- return Project::additionalData(id, target);
+ return m_rootProFile->variableValue(Variable::QmlDesignerImportPath);
+ return BuildSystem::additionalData(id);
}
-} // namespace QmakeProjectManager
+} // QmakeProjectManager
#include "qmakeproject.moc"
diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.h b/src/plugins/qmakeprojectmanager/qmakeproject.h
index 3c1b4f1ba6..8c138e5499 100644
--- a/src/plugins/qmakeprojectmanager/qmakeproject.h
+++ b/src/plugins/qmakeprojectmanager/qmakeproject.h
@@ -59,15 +59,75 @@ public:
explicit QmakeProject(const Utils::FilePath &proFile);
~QmakeProject() final;
- QmakeProFile *rootProFile() const;
-
ProjectExplorer::Tasks projectIssues(const ProjectExplorer::Kit *k) const final;
- QmakeProFileNode *rootProjectNode() const final;
+ void configureAsExampleProject() final;
+
+ ProjectExplorer::ProjectImporter *projectImporter() const final;
+
+protected:
+ RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) final;
+
+private:
+ ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override;
+
+ mutable ProjectExplorer::ProjectImporter *m_projectImporter = nullptr;
+};
+
+// FIXME: This export here is only there to appease the current version
+// of the appman plugin. This _will_ go away, one way or the other.
+class QMAKEPROJECTMANAGER_EXPORT QmakeBuildSystem : public ProjectExplorer::BuildSystem
+{
+ Q_OBJECT
+
+public:
+ explicit QmakeBuildSystem(QmakeBuildConfiguration *bc);
+ ~QmakeBuildSystem();
+
+ bool supportsAction(ProjectExplorer::Node *context,
+ ProjectExplorer::ProjectAction action,
+ const ProjectExplorer::Node *node) const override;
+
+ bool addFiles(ProjectExplorer::Node *context,
+ const QStringList &filePaths,
+ QStringList *notAdded = nullptr) override;
+ ProjectExplorer::RemovedFilesFromProject removeFiles(ProjectExplorer::Node *context,
+ const QStringList &filePaths,
+ QStringList *notRemoved = nullptr) override;
+ bool deleteFiles(ProjectExplorer::Node *context,
+ const QStringList &filePaths) override;
+ bool canRenameFile(ProjectExplorer::Node *context,
+ const QString &filePath, const QString &newFilePath) override;
+ bool renameFile(ProjectExplorer::Node *context,
+ const QString &filePath, const QString &newFilePath) override;
+ bool addDependencies(ProjectExplorer::Node *context,
+ const QStringList &dependencies) override;
+ void triggerParsing() final;
QStringList filesGeneratedFrom(const QString &file) const final;
+ QVariant additionalData(Core::Id id) const final;
+
+ void asyncUpdate();
+ void buildFinished(bool success);
+ void activeTargetWasChanged(ProjectExplorer::Target *);
+
+ QString executableFor(const QmakeProFile *file);
+
+ void updateCppCodeModel();
+ void updateQmlJSCodeModel();
+
+ static bool equalFileList(const QStringList &a, const QStringList &b);
+
+ void updateBuildSystemData();
+ void collectData(const QmakeProFile *file, ProjectExplorer::DeploymentData &deploymentData);
+ void collectApplicationData(const QmakeProFile *file,
+ ProjectExplorer::DeploymentData &deploymentData);
+ void collectLibraryData(const QmakeProFile *file,
+ ProjectExplorer::DeploymentData &deploymentData);
+ void startAsyncTimer(QmakeProFile::AsyncUpdateDelay delay);
- static void notifyChanged(const Utils::FilePath &name);
+ void warnOnToolChainMismatch(const QmakeProFile *pro) const;
+ void testToolChain(ProjectExplorer::ToolChain *tc, const Utils::FilePath &path) const;
/// \internal
QtSupport::ProFileReader *createProFileReader(const QmakeProFile *qmakeProFile);
@@ -81,8 +141,8 @@ public:
void destroyProFileReader(QtSupport::ProFileReader *reader);
/// \internal
- void scheduleAsyncUpdate(QmakeProFile *file,
- QmakeProFile::AsyncUpdateDelay delay = QmakeProFile::ParseLater);
+ void scheduleAsyncUpdateFile(QmakeProFile *file,
+ QmakeProFile::AsyncUpdateDelay delay = QmakeProFile::ParseLater);
/// \internal
void incrementPendingEvaluateFutures();
/// \internal
@@ -95,56 +155,19 @@ public:
void watchFolders(const QStringList &l, QmakePriFile *file);
void unwatchFolders(const QStringList &l, QmakePriFile *file);
- void configureAsExampleProject() final;
-
- void emitBuildDirectoryInitialized();
static void proFileParseError(const QString &errorMessage);
- ProjectExplorer::ProjectImporter *projectImporter() const final;
-
enum AsyncUpdateState { Base, AsyncFullUpdatePending, AsyncPartialUpdatePending, AsyncUpdateInProgress, ShuttingDown };
AsyncUpdateState asyncUpdateState() const;
- QString mapProFilePathToTarget(const Utils::FilePath &proFilePath);
-
- QVariant additionalData(Core::Id id, const ProjectExplorer::Target *target) const final;
+ QmakeProFile *rootProFile() const;
-signals:
- void proFileUpdated(QmakeProjectManager::QmakeProFile *pro, bool, bool);
- void buildDirectoryInitialized();
+ void notifyChanged(const Utils::FilePath &name);
public:
- void scheduleAsyncUpdate(QmakeProFile::AsyncUpdateDelay delay = QmakeProFile::ParseLater);
- void scheduleAsyncUpdateLater() { scheduleAsyncUpdate(); }
-
-protected:
- RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) final;
-
-private:
- ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override;
-
- void asyncUpdate();
- void buildFinished(bool success);
- void activeTargetWasChanged();
-
- QString executableFor(const QmakeProFile *file);
-
- void updateCppCodeModel();
- void updateQmlJSCodeModel();
-
- static bool equalFileList(const QStringList &a, const QStringList &b);
-
- void updateBuildSystemData();
- void collectData(const QmakeProFile *file, ProjectExplorer::DeploymentData &deploymentData);
- void collectApplicationData(const QmakeProFile *file,
- ProjectExplorer::DeploymentData &deploymentData);
- void collectLibraryData(const QmakeProFile *file,
- ProjectExplorer::DeploymentData &deploymentData);
- void startAsyncTimer(QmakeProFile::AsyncUpdateDelay delay);
- bool matchesKit(const ProjectExplorer::Kit *kit);
-
- void warnOnToolChainMismatch(const QmakeProFile *pro) const;
- void testToolChain(ProjectExplorer::ToolChain *tc, const Utils::FilePath &path) const;
+ void scheduleUpdateAll(QmakeProFile::AsyncUpdateDelay delay);
+ void scheduleUpdateAllLater() { scheduleUpdateAll(QmakeProFile::ParseLater); }
+ void scheduleUpdateAllNowOrLater();
mutable QSet<const QPair<Utils::FilePath, Utils::FilePath>> m_toolChainWarnings;
@@ -164,7 +187,7 @@ private:
QString m_qmakeSysroot;
QTimer m_asyncUpdateTimer;
- QFutureInterface<void> *m_asyncUpdateFutureInterface = nullptr;
+ QFutureInterface<void> m_asyncUpdateFutureInterface;
int m_pendingEvaluateFuturesCount = 0;
AsyncUpdateState m_asyncUpdateState = Base;
bool m_cancelEvaluate = false;
@@ -174,10 +197,9 @@ private:
Internal::CentralizedFolderWatcher *m_centralizedFolderWatcher = nullptr;
- ProjectExplorer::Target *m_activeTarget = nullptr;
- mutable ProjectExplorer::ProjectImporter *m_projectImporter = nullptr;
-
- ParseGuard m_guard;
+ ProjectExplorer::BuildSystem::ParseGuard m_guard;
+ QmakeBuildConfiguration *m_buildConfiguration = nullptr;
+ bool m_firstParseNeeded = true;
};
} // namespace QmakeProjectManager
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp
index 7949d21f72..04286333e3 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp
@@ -149,10 +149,7 @@ QmakeProjectConfigWidget::QmakeProjectConfigWidget(QmakeBuildConfiguration *bc)
connect(bc, &BuildConfiguration::enabledChanged,
this, &QmakeProjectConfigWidget::environmentChanged);
- auto qmakeProject = static_cast<QmakeProject *>(bc->target()->project());
- connect(qmakeProject, &QmakeProject::buildDirectoryInitialized,
- this, &QmakeProjectConfigWidget::updateProblemLabel);
- connect(qmakeProject, &Project::parsingFinished,
+ connect(bc->target(), &Target::parsingFinished,
this, &QmakeProjectConfigWidget::updateProblemLabel);
connect(&QmakeSettings::instance(), &QmakeSettings::settingsChanged,
this, &QmakeProjectConfigWidget::updateProblemLabel);
@@ -254,8 +251,8 @@ void QmakeProjectConfigWidget::updateProblemLabel()
return;
}
- auto *p = static_cast<QmakeProject *>(m_buildConfiguration->target()->project());
- if (p->rootProFile()->parseInProgress() || !p->rootProFile()->validParse()) {
+ auto bs = m_buildConfiguration->qmakeBuildSystem();
+ if (bs->rootProFile()->parseInProgress() || !bs->rootProFile()->validParse()) {
setProblemLabel(QString());
return;
}
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp
index f7068873cc..c8bd5614df 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp
@@ -319,8 +319,6 @@ void QmakeProjectManagerPluginPrivate::projectChanged()
if (m_previousStartupProject) {
connect(m_previousStartupProject, &Project::activeTargetChanged,
this, &QmakeProjectManagerPluginPrivate::activeTargetChanged);
- connect(m_previousStartupProject, &Project::parsingFinished,
- this, &QmakeProjectManagerPluginPrivate::updateActions);
}
activeTargetChanged();
@@ -334,9 +332,12 @@ void QmakeProjectManagerPluginPrivate::activeTargetChanged()
m_previousTarget = m_previousStartupProject ? m_previousStartupProject->activeTarget() : nullptr;
- if (m_previousTarget)
+ if (m_previousTarget) {
connect(m_previousTarget, &Target::activeBuildConfigurationChanged,
this, &QmakeProjectManagerPluginPrivate::updateRunQMakeAction);
+ connect(m_previousTarget, &Target::parsingFinished,
+ this, &QmakeProjectManagerPluginPrivate::updateActions);
+ }
updateRunQMakeAction();
}
diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp
index 671a7ee375..d212caa10d 100644
--- a/src/plugins/qmakeprojectmanager/qmakestep.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp
@@ -81,7 +81,7 @@ QMakeStep::QMakeStep(BuildStepList *bsl) : AbstractProcessStep(bsl, Constants::Q
QmakeBuildConfiguration *QMakeStep::qmakeBuildConfiguration() const
{
- return static_cast<QmakeBuildConfiguration *>(buildConfiguration());
+ return qobject_cast<QmakeBuildConfiguration *>(buildConfiguration());
}
///
@@ -174,17 +174,17 @@ bool QMakeStep::init()
return false;
}
- QString workingDirectory;
+ FilePath workingDirectory;
if (qmakeBc->subNodeBuild())
- workingDirectory = qmakeBc->subNodeBuild()->buildDir();
+ workingDirectory = qmakeBc->subNodeBuild()->buildDir(qmakeBc);
else
- workingDirectory = qmakeBc->buildDirectory().toString();
+ workingDirectory = qmakeBc->buildDirectory();
m_qmakeCommand = CommandLine{qtVersion->qmakeCommand(), allArguments(qtVersion), CommandLine::Raw};
m_runMakeQmake = (qtVersion->qtVersion() >= QtVersionNumber(5, 0 ,0));
- QString makefile = workingDirectory + '/';
+ QString makefile = workingDirectory.toString() + '/';
if (qmakeBc->subNodeBuild()) {
QmakeProFileNode *pro = qmakeBc->subNodeBuild();
@@ -220,18 +220,18 @@ bool QMakeStep::init()
ProcessParameters *pp = processParameters();
pp->setMacroExpander(qmakeBc->macroExpander());
- pp->setWorkingDirectory(Utils::FilePath::fromString(workingDirectory));
+ pp->setWorkingDirectory(workingDirectory);
pp->setEnvironment(qmakeBc->environment());
setOutputParser(new QMakeParser);
- QmakeProFileNode *node = static_cast<QmakeProject *>(qmakeBc->target()->project())->rootProjectNode();
+ QmakeProFileNode *node = static_cast<QmakeProFileNode *>(qmakeBc->project()->rootProjectNode());
if (qmakeBc->subNodeBuild())
node = qmakeBc->subNodeBuild();
QTC_ASSERT(node, return false);
QString proFile = node->filePath().toString();
- Tasks tasks = qtVersion->reportIssues(proFile, workingDirectory);
+ Tasks tasks = qtVersion->reportIssues(proFile, workingDirectory.toString());
Utils::sort(tasks);
if (!tasks.isEmpty()) {
@@ -292,8 +292,7 @@ bool QMakeStep::processSucceeded(int exitCode, QProcess::ExitStatus status)
bool result = AbstractProcessStep::processSucceeded(exitCode, status);
if (!result)
m_needToRunQMake = true;
- auto *project = static_cast<QmakeProject *>(qmakeBuildConfiguration()->target()->project());
- project->emitBuildDirectoryInitialized();
+ emit buildConfiguration()->buildDirectoryChanged();
return result;
}
@@ -591,7 +590,7 @@ QMakeStepConfigWidget::QMakeStepConfigWidget(QMakeStep *step)
this, &QMakeStepConfigWidget::linkQmlDebuggingLibraryChanged);
connect(step->project(), &Project::projectLanguagesUpdated,
this, &QMakeStepConfigWidget::linkQmlDebuggingLibraryChanged);
- connect(step->project(), &Project::parsingFinished,
+ connect(step->target(), &Target::parsingFinished,
this, &QMakeStepConfigWidget::updateEffectiveQMakeCall);
connect(step, &QMakeStep::useQtQuickCompilerChanged,
this, &QMakeStepConfigWidget::useQtQuickCompilerChanged);
@@ -866,7 +865,7 @@ void QMakeStepConfigWidget::updateEffectiveQMakeCall()
void QMakeStepConfigWidget::recompileMessageBoxFinished(int button)
{
if (button == QMessageBox::Yes) {
- QmakeBuildConfiguration *bc = m_step->qmakeBuildConfiguration();
+ BuildConfiguration *bc = m_step->buildConfiguration();
if (!bc)
return;
diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp
index d227db6fe5..afe577487a 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.cpp
+++ b/src/plugins/qmlprojectmanager/qmlproject.cpp
@@ -24,6 +24,7 @@
****************************************************************************/
#include "qmlproject.h"
+
#include "fileformat/qmlprojectfileformat.h"
#include "fileformat/qmlprojectitem.h"
#include "qmlprojectrunconfiguration.h"
@@ -31,6 +32,9 @@
#include "qmlprojectmanagerconstants.h"
#include "qmlprojectnodes.h"
+#include <coreplugin/documentmanager.h>
+#include <coreplugin/editormanager/documentmodel.h>
+#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
@@ -46,66 +50,84 @@
#include <qmljs/qmljsmodelmanagerinterface.h>
+#include <texteditor/textdocument.h>
+
#include <utils/algorithm.h>
#include <QDebug>
+#include <QRegularExpression>
+#include <QTextCodec>
using namespace Core;
using namespace ProjectExplorer;
+using namespace QmlProjectManager::Internal;
namespace QmlProjectManager {
QmlProject::QmlProject(const Utils::FilePath &fileName)
: Project(QString::fromLatin1(Constants::QMLPROJECT_MIMETYPE), fileName)
{
- const QString normalized
- = Utils::FileUtils::normalizePathName(fileName.toFileInfo().canonicalFilePath());
- m_canonicalProjectDir = Utils::FilePath::fromString(normalized).parentDir();
-
setId(QmlProjectManager::Constants::QML_PROJECT_ID);
setProjectLanguages(Context(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID));
setDisplayName(fileName.toFileInfo().completeBaseName());
setNeedsBuildConfigurations(false);
- setBuildSystemCreator([](Project *p) { return new Internal::QmlBuildSystem(p); });
+ setBuildSystemCreator([](Target *t) { return new QmlBuildSystem(t); });
+}
+
+QmlBuildSystem::QmlBuildSystem(Target *target)
+ : BuildSystem(target)
+{
+ const QString normalized
+ = Utils::FileUtils::normalizePathName(target->project()
+ ->projectFilePath().toFileInfo().canonicalFilePath());
+ m_canonicalProjectDir = Utils::FilePath::fromString(normalized).parentDir();
+
+ connect(target->project(), &Project::projectFileIsDirty,
+ this, &QmlBuildSystem::refreshProjectFile);
- connect(this, &QmlProject::projectFileIsDirty, this, &QmlProject::refreshProjectFile);
+ // refresh first - project information is used e.g. to decide the default RC's
+ refresh(Everything);
+
+// FIXME: Check. Probably bogus after the BuildSystem move.
+// // addedTarget calls updateEnabled on the runconfigurations
+// // which needs to happen after refresh
+// foreach (Target *t, targets())
+// addedTarget(t);
+
+ connect(target->project(), &Project::activeTargetChanged,
+ this, &QmlBuildSystem::onActiveTargetChanged);
+ updateDeploymentData();
}
-QmlProject::~QmlProject()
+QmlBuildSystem::~QmlBuildSystem()
{
delete m_projectItem.data();
}
-void QmlProject::addedTarget(Target *target)
+void QmlBuildSystem::triggerParsing()
{
- updateDeploymentData(target);
+ refresh(Everything);
}
-void QmlProject::onActiveTargetChanged(Target *target)
+void QmlBuildSystem::onActiveTargetChanged(Target *)
{
- if (m_activeTarget)
- disconnect(m_activeTarget, &Target::kitChanged, this, &QmlProject::onKitChanged);
- m_activeTarget = target;
- if (m_activeTarget)
- connect(target, &Target::kitChanged, this, &QmlProject::onKitChanged);
-
// make sure e.g. the default qml imports are adapted
refresh(Configuration);
}
-void QmlProject::onKitChanged()
+void QmlBuildSystem::onKitChanged()
{
// make sure e.g. the default qml imports are adapted
refresh(Configuration);
}
-Utils::FilePath QmlProject::canonicalProjectDir() const
+Utils::FilePath QmlBuildSystem::canonicalProjectDir() const
{
return m_canonicalProjectDir;
}
-void QmlProject::parseProject(RefreshOptions options)
+void QmlBuildSystem::parseProject(RefreshOptions options)
{
if (options & Files) {
if (options & ProjectFile)
@@ -115,7 +137,7 @@ void QmlProject::parseProject(RefreshOptions options)
m_projectItem = QmlProjectFileFormat::parseProjectFile(projectFilePath(), &errorMessage);
if (m_projectItem) {
connect(m_projectItem.data(), &QmlProjectItem::qmlFilesChanged,
- this, &QmlProject::refreshFiles);
+ this, &QmlBuildSystem::refreshFiles);
} else {
MessageManager::write(tr("Error while loading project file %1.")
@@ -153,7 +175,7 @@ void QmlProject::parseProject(RefreshOptions options)
}
}
-void QmlProject::refresh(RefreshOptions options)
+void QmlBuildSystem::refresh(RefreshOptions options)
{
ParseGuard guard = guardParsingRun();
parseProject(options);
@@ -166,32 +188,32 @@ void QmlProject::refresh(RefreshOptions options)
return;
QmlJS::ModelManagerInterface::ProjectInfo projectInfo =
- modelManager->defaultProjectInfoForProject(this);
+ modelManager->defaultProjectInfoForProject(project());
foreach (const QString &searchPath, makeAbsolute(canonicalProjectDir(), customImportPaths()))
projectInfo.importPaths.maybeInsert(Utils::FilePath::fromString(searchPath),
QmlJS::Dialect::Qml);
- modelManager->updateProjectInfo(projectInfo, this);
+ modelManager->updateProjectInfo(projectInfo, project());
guard.markAsSuccess();
}
-QString QmlProject::mainFile() const
+QString QmlBuildSystem::mainFile() const
{
if (m_projectItem)
return m_projectItem.data()->mainFile();
return QString();
}
-void QmlProject::setMainFile(const QString &mainFilePath)
+void QmlBuildSystem::setMainFile(const QString &mainFilePath)
{
if (m_projectItem)
m_projectItem.data()->setMainFile(mainFilePath);
}
-Utils::FilePath QmlProject::targetDirectory(const Target *target) const
+Utils::FilePath QmlBuildSystem::targetDirectory() const
{
- if (DeviceTypeKitAspect::deviceTypeId(target->kit())
+ if (DeviceTypeKitAspect::deviceTypeId(target()->kit())
== ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
return canonicalProjectDir();
@@ -199,53 +221,42 @@ Utils::FilePath QmlProject::targetDirectory(const Target *target) const
: Utils::FilePath();
}
-Utils::FilePath QmlProject::targetFile(const Utils::FilePath &sourceFile,
- const Target *target) const
+Utils::FilePath QmlBuildSystem::targetFile(const Utils::FilePath &sourceFile) const
{
const QDir sourceDir(m_projectItem ? m_projectItem->sourceDirectory()
: canonicalProjectDir().toString());
- const QDir targetDir(targetDirectory(target).toString());
+ const QDir targetDir(targetDirectory().toString());
const QString relative = sourceDir.relativeFilePath(sourceFile.toString());
return Utils::FilePath::fromString(QDir::cleanPath(targetDir.absoluteFilePath(relative)));
}
-Utils::EnvironmentItems QmlProject::environment() const
+Utils::EnvironmentItems QmlBuildSystem::environment() const
{
if (m_projectItem)
return m_projectItem.data()->environment();
return {};
}
-QStringList QmlProject::customImportPaths() const
+QStringList QmlBuildSystem::customImportPaths() const
{
if (m_projectItem)
return m_projectItem.data()->importPaths();
return {};
}
-QStringList QmlProject::customFileSelectors() const
+QStringList QmlBuildSystem::customFileSelectors() const
{
if (m_projectItem)
return m_projectItem.data()->fileSelectors();
return {};
}
-bool QmlProject::addFiles(const QStringList &filePaths)
-{
- QStringList toAdd;
- foreach (const QString &filePath, filePaths) {
- if (!m_projectItem.data()->matchesFile(filePath))
- toAdd << filePaths;
- }
- return toAdd.isEmpty();
-}
-
-void QmlProject::refreshProjectFile()
+void QmlBuildSystem::refreshProjectFile()
{
- refresh(QmlProject::ProjectFile | Files);
+ refresh(QmlBuildSystem::ProjectFile | Files);
}
-QStringList QmlProject::makeAbsolute(const Utils::FilePath &path, const QStringList &relativePaths)
+QStringList QmlBuildSystem::makeAbsolute(const Utils::FilePath &path, const QStringList &relativePaths)
{
if (path.isEmpty())
return relativePaths;
@@ -256,14 +267,7 @@ QStringList QmlProject::makeAbsolute(const Utils::FilePath &path, const QStringL
});
}
-QVariant QmlProject::additionalData(Id id, const Target *) const
-{
- if (id == Constants::customFileSelectorsData)
- return customFileSelectors();
- return {};
-}
-
-void QmlProject::refreshFiles(const QSet<QString> &/*added*/, const QSet<QString> &removed)
+void QmlBuildSystem::refreshFiles(const QSet<QString> &/*added*/, const QSet<QString> &removed)
{
refresh(Files);
if (!removed.isEmpty()) {
@@ -273,11 +277,9 @@ void QmlProject::refreshFiles(const QSet<QString> &/*added*/, const QSet<QString
refreshTargetDirectory();
}
-void QmlProject::refreshTargetDirectory()
+void QmlBuildSystem::refreshTargetDirectory()
{
- const QList<Target *> targetList = targets();
- for (Target *target : targetList)
- updateDeploymentData(target);
+ updateDeploymentData();
}
Tasks QmlProject::projectIssues(const Kit *k) const
@@ -324,9 +326,6 @@ Project::RestoreResult QmlProject::fromMap(const QVariantMap &map, QString *erro
if (result != RestoreResult::Ok)
return result;
- // refresh first - project information is used e.g. to decide the default RC's
- refresh(Everything);
-
if (!activeTarget()) {
// find a kit that matches prerequisites (prefer default one)
const QList<Kit*> kits = Utils::filtered(KitManager::kits(), [this](const Kit *k) {
@@ -341,18 +340,6 @@ Project::RestoreResult QmlProject::fromMap(const QVariantMap &map, QString *erro
}
}
- // addedTarget calls updateEnabled on the runconfigurations
- // which needs to happen after refresh
- foreach (Target *t, targets())
- addedTarget(t);
-
- connect(this, &ProjectExplorer::Project::addedTarget, this, &QmlProject::addedTarget);
-
- connect(this, &ProjectExplorer::Project::activeTargetChanged,
- this, &QmlProject::onActiveTargetChanged);
-
- onActiveTargetChanged(activeTarget());
-
return RestoreResult::Ok;
}
@@ -361,12 +348,12 @@ ProjectExplorer::DeploymentKnowledge QmlProject::deploymentKnowledge() const
return DeploymentKnowledge::Perfect;
}
-void QmlProject::generateProjectTree()
+void QmlBuildSystem::generateProjectTree()
{
if (!m_projectItem)
return;
- auto newRoot = std::make_unique<Internal::QmlProjectNode>(this);
+ auto newRoot = std::make_unique<QmlProjectNode>(project());
for (const QString &f : m_projectItem.data()->files()) {
const Utils::FilePath fileName = Utils::FilePath::fromString(f);
@@ -376,16 +363,16 @@ void QmlProject::generateProjectTree()
}
newRoot->addNestedNode(std::make_unique<FileNode>(projectFilePath(), FileType::Project));
- setRootProjectNode(std::move(newRoot));
+ project()->setRootProjectNode(std::move(newRoot));
refreshTargetDirectory();
}
-void QmlProject::updateDeploymentData(ProjectExplorer::Target *target)
+void QmlBuildSystem::updateDeploymentData()
{
if (!m_projectItem)
return;
- if (DeviceTypeKitAspect::deviceTypeId(target->kit())
+ if (DeviceTypeKitAspect::deviceTypeId(target()->kit())
== ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
return;
}
@@ -394,10 +381,109 @@ void QmlProject::updateDeploymentData(ProjectExplorer::Target *target)
for (const QString &file : m_projectItem->files()) {
deploymentData.addFile(
file,
- targetFile(Utils::FilePath::fromString(file), target).parentDir().toString());
+ targetFile(Utils::FilePath::fromString(file)).parentDir().toString());
+ }
+
+ setDeploymentData(deploymentData);
+}
+
+QVariant QmlBuildSystem::additionalData(Id id) const
+{
+ if (id == Constants::customFileSelectorsData)
+ return customFileSelectors();
+ return {};
+}
+
+bool QmlBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
+{
+ if (dynamic_cast<QmlProjectNode *>(context)) {
+ if (action == AddNewFile || action == EraseFile)
+ return true;
+ QTC_ASSERT(node, return false);
+
+ if (action == Rename && node->asFileNode()) {
+ const FileNode *fileNode = node->asFileNode();
+ QTC_ASSERT(fileNode, return false);
+ return fileNode->fileType() != FileType::Project;
+ }
+
+ return false;
+ }
+
+ return BuildSystem::supportsAction(context, action, node);
+}
+
+QmlProject *QmlBuildSystem::qmlProject() const
+{
+ return static_cast<QmlProject *>(BuildSystem::project());
+}
+
+bool QmlBuildSystem::addFiles(Node *context, const QStringList &filePaths, QStringList *)
+{
+ if (!dynamic_cast<QmlProjectNode *>(context))
+ return false;
+
+ QStringList toAdd;
+ foreach (const QString &filePath, filePaths) {
+ if (!m_projectItem.data()->matchesFile(filePath))
+ toAdd << filePaths;
+ }
+ return toAdd.isEmpty();
+}
+
+bool QmlBuildSystem::deleteFiles(Node *context, const QStringList &filePaths)
+{
+ if (dynamic_cast<QmlProjectNode *>(context))
+ return true;
+
+ return BuildSystem::deleteFiles(context, filePaths);
+}
+
+bool QmlBuildSystem::renameFile(Node * context, const QString &filePath, const QString &newFilePath)
+{
+ if (dynamic_cast<QmlProjectNode *>(context)) {
+ if (filePath.endsWith(mainFile())) {
+ setMainFile(newFilePath);
+
+ // make sure to change it also in the qmlproject file
+ const QString qmlProjectFilePath = project()->projectFilePath().toString();
+ Core::FileChangeBlocker fileChangeBlocker(qmlProjectFilePath);
+ const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForFilePath(qmlProjectFilePath);
+ TextEditor::TextDocument *document = nullptr;
+ if (!editors.isEmpty()) {
+ document = qobject_cast<TextEditor::TextDocument*>(editors.first()->document());
+ if (document && document->isModified())
+ if (!Core::DocumentManager::saveDocument(document))
+ return false;
+ }
+
+ QString fileContent;
+ QString error;
+ Utils::TextFileFormat textFileFormat;
+ const QTextCodec *codec = QTextCodec::codecForName("UTF-8"); // qml files are defined to be utf-8
+ if (Utils::TextFileFormat::readFile(qmlProjectFilePath, codec, &fileContent, &textFileFormat, &error)
+ != Utils::TextFileFormat::ReadSuccess) {
+ qWarning() << "Failed to read file" << qmlProjectFilePath << ":" << error;
+ }
+
+ // find the mainFile and do the file name with brackets in a capture group and mask the . with \.
+ QString originalFileName = QFileInfo(filePath).fileName();
+ originalFileName.replace(".", "\\.");
+ const QRegularExpression expression(QString("mainFile:\\s*\"(%1)\"").arg(originalFileName));
+ const QRegularExpressionMatch match = expression.match(fileContent);
+
+ fileContent.replace(match.capturedStart(1), match.capturedLength(1), QFileInfo(newFilePath).fileName());
+
+ if (!textFileFormat.writeFile(qmlProjectFilePath, fileContent, &error))
+ qWarning() << "Failed to write file" << qmlProjectFilePath << ":" << error;
+
+ refresh(Everything);
+ }
+
+ return true;
}
- target->setDeploymentData(deploymentData);
+ return BuildSystem::renameFile(context, filePath, newFilePath);
}
} // namespace QmlProjectManager
diff --git a/src/plugins/qmlprojectmanager/qmlproject.h b/src/plugins/qmlprojectmanager/qmlproject.h
index d911d7946e..2fe1d6dfd7 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.h
+++ b/src/plugins/qmlprojectmanager/qmlproject.h
@@ -35,19 +35,18 @@
#include <QPointer>
-namespace ProjectExplorer { class RunConfiguration; }
-
namespace QmlProjectManager {
class QmlProject;
class QmlProjectItem;
-namespace Internal {
-
class QmlBuildSystem : public ProjectExplorer::BuildSystem
{
public:
- explicit QmlBuildSystem(ProjectExplorer::Project *project) : BuildSystem(project) {}
+ explicit QmlBuildSystem(ProjectExplorer::Target *target);
+ ~QmlBuildSystem();
+
+ void triggerParsing() final;
bool supportsAction(ProjectExplorer::Node *context,
ProjectExplorer::ProjectAction action,
@@ -59,20 +58,9 @@ public:
bool renameFile(ProjectExplorer::Node *context,
const QString &filePath, const QString &newFilePath) override;
- QmlProject *project() const;
-};
-
-} // Internal
+ QmlProject *qmlProject() const;
-class QMLPROJECTMANAGER_EXPORT QmlProject : public ProjectExplorer::Project
-{
- Q_OBJECT
-
-public:
- explicit QmlProject(const Utils::FilePath &filename);
- ~QmlProject() override;
-
- ProjectExplorer::Tasks projectIssues(const ProjectExplorer::Kit *k) const final;
+ QVariant additionalData(Core::Id id) const override;
enum RefreshOption {
ProjectFile = 0x01,
@@ -87,9 +75,8 @@ public:
Utils::FilePath canonicalProjectDir() const;
QString mainFile() const;
void setMainFile(const QString &mainFilePath);
- Utils::FilePath targetDirectory(const ProjectExplorer::Target *target) const;
- Utils::FilePath targetFile(const Utils::FilePath &sourceFile,
- const ProjectExplorer::Target *target) const;
+ Utils::FilePath targetDirectory() const;
+ Utils::FilePath targetFile(const Utils::FilePath &sourceFile) const;
Utils::EnvironmentItems environment() const;
QStringList customImportPaths() const;
@@ -101,31 +88,37 @@ public:
static QStringList makeAbsolute(const Utils::FilePath &path, const QStringList &relativePaths);
- QVariant additionalData(Core::Id id, const ProjectExplorer::Target *target) const override;
-
-protected:
- RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override;
-
-private:
- ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override;
-
void generateProjectTree();
- void updateDeploymentData(ProjectExplorer::Target *target);
+ void updateDeploymentData();
void refreshFiles(const QSet<QString> &added, const QSet<QString> &removed);
void refreshTargetDirectory();
- void addedTarget(ProjectExplorer::Target *target);
void onActiveTargetChanged(ProjectExplorer::Target *target);
void onKitChanged();
// plain format
void parseProject(RefreshOptions options);
- ProjectExplorer::Target *m_activeTarget = nullptr;
-
QPointer<QmlProjectItem> m_projectItem;
Utils::FilePath m_canonicalProjectDir;
};
+class QMLPROJECTMANAGER_EXPORT QmlProject : public ProjectExplorer::Project
+{
+ Q_OBJECT
+
+public:
+ explicit QmlProject(const Utils::FilePath &filename);
+
+ ProjectExplorer::Tasks projectIssues(const ProjectExplorer::Kit *k) const final;
+
+protected:
+ RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override;
+
+private:
+ ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override;
+
+};
+
} // namespace QmlProjectManager
-Q_DECLARE_OPERATORS_FOR_FLAGS(QmlProjectManager::QmlProject::RefreshOptions)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QmlProjectManager::QmlBuildSystem::RefreshOptions)
diff --git a/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
index 2d7a4daddb..cfa6c5e74e 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
@@ -24,28 +24,19 @@
****************************************************************************/
#include "qmlprojectnodes.h"
-#include "qmlproject.h"
-#include <coreplugin/idocument.h>
#include <coreplugin/fileiconprovider.h>
-#include <coreplugin/documentmanager.h>
-#include <coreplugin/editormanager/documentmodel.h>
-#include <coreplugin/editormanager/ieditor.h>
-#include <projectexplorer/projectexplorer.h>
-#include <texteditor/textdocument.h>
-#include <utils/algorithm.h>
-#include <utils/textfileformat.h>
-#include <QRegularExpression>
-#include <QTextCodec>
+#include <projectexplorer/project.h>
+#include <projectexplorer/projectexplorer.h>
using namespace ProjectExplorer;
namespace QmlProjectManager {
namespace Internal {
-QmlProjectNode::QmlProjectNode(QmlProject *project) : ProjectNode(project->projectDirectory()),
- m_project(project)
+QmlProjectNode::QmlProjectNode(Project *project)
+ : ProjectNode(project->projectDirectory())
{
setDisplayName(project->projectFilePath().toFileInfo().completeBaseName());
@@ -53,91 +44,5 @@ QmlProjectNode::QmlProjectNode(QmlProject *project) : ProjectNode(project->proje
setIcon(qmlProjectIcon);
}
-bool QmlBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
-{
- if (dynamic_cast<QmlProjectNode *>(context)) {
- if (action == AddNewFile || action == EraseFile)
- return true;
- QTC_ASSERT(node, return false);
-
- if (action == Rename && node->asFileNode()) {
- const FileNode *fileNode = node->asFileNode();
- QTC_ASSERT(fileNode, return false);
- return fileNode->fileType() != FileType::Project;
- }
-
- return false;
- }
-
- return BuildSystem::supportsAction(context, action, node);
-}
-
-QmlProject *QmlBuildSystem::project() const
-{
- return static_cast<QmlProject *>(BuildSystem::project());
-}
-
-bool QmlBuildSystem::addFiles(Node *context, const QStringList &filePaths, QStringList *notAdded)
-{
- if (dynamic_cast<QmlProjectNode *>(context))
- return project()->addFiles(filePaths);
-
- return BuildSystem::addFiles(context, filePaths, notAdded);
-}
-
-bool QmlBuildSystem::deleteFiles(Node *context, const QStringList &filePaths)
-{
- if (dynamic_cast<QmlProjectNode *>(context))
- return true;
-
- return BuildSystem::deleteFiles(context, filePaths);
-}
-
-bool QmlBuildSystem::renameFile(Node * context, const QString &filePath, const QString &newFilePath)
-{
- if (dynamic_cast<QmlProjectNode *>(context)) {
- if (filePath.endsWith(project()->mainFile())) {
- project()->setMainFile(newFilePath);
-
- // make sure to change it also in the qmlproject file
- const QString qmlProjectFilePath = project()->projectFilePath().toString();
- Core::FileChangeBlocker fileChangeBlocker(qmlProjectFilePath);
- const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForFilePath(qmlProjectFilePath);
- TextEditor::TextDocument *document = nullptr;
- if (!editors.isEmpty()) {
- document = qobject_cast<TextEditor::TextDocument*>(editors.first()->document());
- if (document && document->isModified())
- if (!Core::DocumentManager::saveDocument(document))
- return false;
- }
-
- QString fileContent;
- QString error;
- Utils::TextFileFormat textFileFormat;
- const QTextCodec *codec = QTextCodec::codecForName("UTF-8"); // qml files are defined to be utf-8
- if (Utils::TextFileFormat::readFile(qmlProjectFilePath, codec, &fileContent, &textFileFormat, &error)
- != Utils::TextFileFormat::ReadSuccess) {
- qWarning() << "Failed to read file" << qmlProjectFilePath << ":" << error;
- }
-
- // find the mainFile and do the file name with brackets in a capture group and mask the . with \.
- QString originalFileName = QFileInfo(filePath).fileName();
- originalFileName.replace(".", "\\.");
- const QRegularExpression expression(QString("mainFile:\\s*\"(%1)\"").arg(originalFileName));
- const QRegularExpressionMatch match = expression.match(fileContent);
-
- fileContent.replace(match.capturedStart(1), match.capturedLength(1), QFileInfo(newFilePath).fileName());
-
- if (!textFileFormat.writeFile(qmlProjectFilePath, fileContent, &error))
- qWarning() << "Failed to write file" << qmlProjectFilePath << ":" << error;
- project()->refresh(QmlProject::Everything);
- }
-
- return true;
- }
-
- return BuildSystem::renameFile(context, filePath, newFilePath);
-}
-
} // namespace Internal
} // namespace QmlProjectManager
diff --git a/src/plugins/qmlprojectmanager/qmlprojectnodes.h b/src/plugins/qmlprojectmanager/qmlprojectnodes.h
index 13c25a31a7..b400a21c69 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectnodes.h
+++ b/src/plugins/qmlprojectmanager/qmlprojectnodes.h
@@ -28,18 +28,12 @@
#include <projectexplorer/projectnodes.h>
namespace QmlProjectManager {
-
-class QmlProject;
-
namespace Internal {
class QmlProjectNode : public ProjectExplorer::ProjectNode
{
public:
- QmlProjectNode(QmlProject *project);
-
-private:
- QmlProject *m_project;
+ explicit QmlProjectNode(ProjectExplorer::Project *project);
};
} // namespace Internal
diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
index a10ac4fa57..9979249269 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
@@ -73,7 +73,7 @@ static bool caseInsensitiveLessThan(const QString &s1, const QString &s2)
class MainQmlFileAspect : public ProjectConfigurationAspect
{
public:
- explicit MainQmlFileAspect(QmlProject *project);
+ explicit MainQmlFileAspect(Target *target);
~MainQmlFileAspect() override { delete m_fileListCombo; }
enum MainScriptSource {
@@ -97,7 +97,12 @@ public:
bool isQmlFilePresent();
public:
- QmlProject *m_project;
+ QmlBuildSystem *qmlBuildSystem() const
+ {
+ return static_cast<QmlBuildSystem *>(m_target->buildSystem());
+ }
+
+ Target *m_target = nullptr;
QPointer<QComboBox> m_fileListCombo;
QStandardItemModel m_fileListModel;
QString m_scriptFile;
@@ -107,8 +112,8 @@ public:
QString m_mainScriptFilename;
};
-MainQmlFileAspect::MainQmlFileAspect(QmlProject *project)
- : m_project(project)
+MainQmlFileAspect::MainQmlFileAspect(Target *target)
+ : m_target(target)
, m_scriptFile(M_CURRENT_FILE)
{
connect(EditorManager::instance(), &EditorManager::currentEditorChanged,
@@ -153,7 +158,7 @@ void MainQmlFileAspect::fromMap(const QVariantMap &map)
void MainQmlFileAspect::updateFileComboBox()
{
- QDir projectDir(m_project->projectDirectory().toString());
+ QDir projectDir(m_target->project()->projectDirectory().toString());
if (mainScriptSource() == FileInProjectFile) {
const QString mainScriptInFilePath = projectDir.relativeFilePath(mainScript());
@@ -170,7 +175,7 @@ void MainQmlFileAspect::updateFileComboBox()
m_fileListModel.appendRow(new QStandardItem(QLatin1String(CURRENT_FILE)));
QModelIndex currentIndex;
- QStringList sortedFiles = Utils::transform(m_project->files(Project::SourceFiles),
+ QStringList sortedFiles = Utils::transform(m_target->project()->files(Project::SourceFiles),
&Utils::FilePath::toString);
// make paths relative to project directory
@@ -207,7 +212,7 @@ void MainQmlFileAspect::updateFileComboBox()
MainQmlFileAspect::MainScriptSource MainQmlFileAspect::mainScriptSource() const
{
- if (!m_project->mainFile().isEmpty())
+ if (!qmlBuildSystem()->mainFile().isEmpty())
return FileInProjectFile;
if (!m_mainScriptFilename.isEmpty())
return FileInSettings;
@@ -234,7 +239,7 @@ void MainQmlFileAspect::setScriptSource(MainScriptSource source, const QString &
m_mainScriptFilename.clear();
} else { // FileInSettings
m_scriptFile = settingsPath;
- m_mainScriptFilename = m_project->projectDirectory().toString() + '/' + m_scriptFile;
+ m_mainScriptFilename = m_target->project()->projectDirectory().toString() + '/' + m_scriptFile;
}
emit changed();
@@ -246,12 +251,12 @@ void MainQmlFileAspect::setScriptSource(MainScriptSource source, const QString &
*/
QString MainQmlFileAspect::mainScript() const
{
- if (!m_project->mainFile().isEmpty()) {
- const QString pathInProject = m_project->mainFile();
+ if (!qmlBuildSystem()->mainFile().isEmpty()) {
+ const QString pathInProject = qmlBuildSystem()->mainFile();
if (QFileInfo(pathInProject).isAbsolute())
return pathInProject;
else
- return QDir(m_project->canonicalProjectDir().toString()).absoluteFilePath(pathInProject);
+ return QDir(qmlBuildSystem()->canonicalProjectDir().toString()).absoluteFilePath(pathInProject);
}
if (!m_mainScriptFilename.isEmpty())
@@ -279,9 +284,9 @@ QmlProjectRunConfiguration::QmlProjectRunConfiguration(Target *target, Id id)
{
auto envAspect = addAspect<EnvironmentAspect>();
- auto envModifier = [target](Environment env) {
- if (auto project = qobject_cast<const QmlProject *>(target->project()))
- env.modify(project->environment());
+ auto envModifier = [this](Environment env) {
+ if (auto bs = dynamic_cast<const QmlBuildSystem *>(activeBuildSystem()))
+ env.modify(bs->environment());
return env;
};
@@ -311,9 +316,7 @@ QmlProjectRunConfiguration::QmlProjectRunConfiguration(Target *target, Id id)
CommandLine::Raw);
});
- auto qmlProject = qobject_cast<QmlProject *>(target->project());
- QTC_ASSERT(qmlProject, return);
- m_mainQmlFileAspect = addAspect<MainQmlFileAspect>(qmlProject);
+ m_mainQmlFileAspect = addAspect<MainQmlFileAspect>(target);
connect(m_mainQmlFileAspect, &MainQmlFileAspect::changed,
this, &QmlProjectRunConfiguration::updateEnabledState);
@@ -329,7 +332,8 @@ Runnable QmlProjectRunConfiguration::runnable() const
Runnable r;
r.setCommandLine(commandLine());
r.environment = aspect<EnvironmentAspect>()->environment();
- r.workingDirectory = static_cast<QmlProject *>(project())->targetDirectory(target()).toString();
+ const QmlBuildSystem *bs = static_cast<QmlBuildSystem *>(activeBuildSystem());
+ r.workingDirectory = bs->targetDirectory().toString();
return r;
}
@@ -377,38 +381,35 @@ QString QmlProjectRunConfiguration::commandLineArguments() const
{
// arguments in .user file
QString args = aspect<ArgumentsAspect>()->arguments(macroExpander());
- const Target *currentTarget = target();
- const IDevice::ConstPtr device = DeviceKitAspect::device(currentTarget->kit());
+ const IDevice::ConstPtr device = DeviceKitAspect::device(target()->kit());
const Utils::OsType osType = device ? device->osType() : Utils::HostOsInfo::hostOs();
// arguments from .qmlproject file
- const QmlProject *project = static_cast<QmlProject *>(currentTarget->project());
+ const QmlBuildSystem *bs = static_cast<QmlBuildSystem *>(target()->buildSystem());
foreach (const QString &importPath,
- QmlProject::makeAbsolute(project->targetDirectory(currentTarget), project->customImportPaths())) {
+ QmlBuildSystem::makeAbsolute(bs->targetDirectory(), bs->customImportPaths())) {
Utils::QtcProcess::addArg(&args, QLatin1String("-I"), osType);
Utils::QtcProcess::addArg(&args, importPath, osType);
}
- for (const QString &fileSelector : project->customFileSelectors()) {
+ for (const QString &fileSelector : bs->customFileSelectors()) {
Utils::QtcProcess::addArg(&args, QLatin1String("-S"), osType);
Utils::QtcProcess::addArg(&args, fileSelector, osType);
}
- const QString main = project->targetFile(Utils::FilePath::fromString(mainScript()),
- currentTarget).toString();
+ const QString main = bs->targetFile(FilePath::fromString(mainScript())).toString();
if (!main.isEmpty())
Utils::QtcProcess::addArg(&args, main, osType);
return args;
}
-void QmlProjectRunConfiguration::updateEnabledState()
+bool QmlProjectRunConfiguration::isEnabled() const
{
- bool enabled = false;
if (m_mainQmlFileAspect->isQmlFilePresent() && !commandLine().executable().isEmpty()) {
- Project *p = target()->project();
- enabled = !p->isParsing() && p->hasParsingData();
+ BuildSystem *bs = activeBuildSystem();
+ return !bs->isParsing() && bs->hasParsingData();
}
- setEnabled(enabled);
+ return false;
}
bool MainQmlFileAspect::isQmlFilePresent()
@@ -430,7 +431,7 @@ bool MainQmlFileAspect::isQmlFilePresent()
|| mainScriptMimeType.matchesName(QLatin1String(QmlJSTools::Constants::QMLPROJECT_MIMETYPE))) {
// find a qml file with lowercase filename. This is slow, but only done
// in initialization/other border cases.
- const auto files = m_project->files(Project::SourceFiles);
+ const auto files = m_target->project()->files(Project::SourceFiles);
for (const Utils::FilePath &filename : files) {
const QFileInfo fi = filename.toFileInfo();
diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h
index 8a18fd0ef9..9d810671f1 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h
+++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h
@@ -44,7 +44,7 @@ public:
private:
ProjectExplorer::Runnable runnable() const final;
QString disabledReason() const final;
- void updateEnabledState() final;
+ bool isEnabled() const final;
QString mainScript() const;
QString theExecutable() const;
diff --git a/src/plugins/qnx/qnxrunconfiguration.cpp b/src/plugins/qnx/qnxrunconfiguration.cpp
index d9b3522207..74481cfabd 100644
--- a/src/plugins/qnx/qnxrunconfiguration.cpp
+++ b/src/plugins/qnx/qnxrunconfiguration.cpp
@@ -82,7 +82,7 @@ QnxRunConfiguration::QnxRunConfiguration(Target *target, Core::Id id)
connect(target, &Target::deploymentDataChanged, this, updateTargetInformation);
connect(target, &Target::applicationTargetsChanged, this, updateTargetInformation);
- connect(target->project(), &Project::parsingFinished, this, updateTargetInformation);
+ connect(target, &Target::parsingFinished, this, updateTargetInformation);
connect(target, &Target::kitChanged, this, updateTargetInformation);
}
diff --git a/src/plugins/remotelinux/makeinstallstep.cpp b/src/plugins/remotelinux/makeinstallstep.cpp
index 7ddb4c9083..c902bd2f42 100644
--- a/src/plugins/remotelinux/makeinstallstep.cpp
+++ b/src/plugins/remotelinux/makeinstallstep.cpp
@@ -27,6 +27,7 @@
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/buildsteplist.h>
+#include <projectexplorer/buildsystem.h>
#include <projectexplorer/deployconfiguration.h>
#include <projectexplorer/processparameters.h>
#include <projectexplorer/runconfigurationaspects.h>
@@ -167,7 +168,7 @@ void MakeInstallStep::finish(bool success)
m_deploymentData.addFile(fi.filePath(),
fi.dir().path().mid(installRoot().toString().length()));
}
- target()->setDeploymentData(m_deploymentData);
+ buildSystem()->setDeploymentData(m_deploymentData);
} else if (m_noInstallTarget && m_isCmakeProject) {
emit addTask(Task(Task::Warning, tr("You need to add an install statement to your "
"CMakeLists.txt file for deployment to work."),
diff --git a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp
index 745858dd41..7c1d740367 100644
--- a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp
+++ b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp
@@ -72,7 +72,7 @@ RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *target, Core::I
this, &RemoteLinuxRunConfiguration::updateTargetInformation);
connect(target, &Target::applicationTargetsChanged,
this, &RemoteLinuxRunConfiguration::updateTargetInformation);
- connect(target->project(), &Project::parsingFinished,
+ connect(target, &Target::parsingFinished,
this, &RemoteLinuxRunConfiguration::updateTargetInformation);
connect(target, &Target::kitChanged,
this, &RemoteLinuxRunConfiguration::updateTargetInformation);