aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);