forked from qt-creator/qt-creator
ProjectExplorer: Move BuildSystem owership to BuildConfiguration
... or Target. This patch moves build system from conceptually "one per project" to "one per target (i.e. per project-and-kit)" or "per BuildConfigurations" for targets where the builds differ significantly. Building requires usually items from the kit (Qt version, compiler, ...) so a target-agnostic build is practically almost always wrong. Moving the build system to the target also has the potential to solve issues caused by switching targets while parsing, that used Project::activeTarget() regularly, with potentially different results before and after the switch. This patch might create performance/size regressions when several targets are set up per project as the build system implementation's internal data are duplicated in this case. The idea is to fix that by sharing per-project pieces again in the project implementation once these problems occur. Change-Id: I87f640ce418b93175b5029124eaa55f3b8721dca Reviewed-by: Christian Stenger <christian.stenger@qt.io> Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -79,6 +79,8 @@ public:
|
||||
}
|
||||
bool isQmlDebuggingEnabled() const { return m_enableQmlDebugging; }
|
||||
|
||||
QbsBuildSystem *qbsBuildSystem() const;
|
||||
|
||||
signals:
|
||||
void qbsConfigurationChanged();
|
||||
void qbsBuildOptionsChanged();
|
||||
|
||||
@@ -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:
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 = ¬AddedDummy;
|
||||
|
||||
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 = ¬AddedDummy;
|
||||
|
||||
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 = ¬RemovedDummy;
|
||||
|
||||
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 = ¬RemovedDummy;
|
||||
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -127,57 +127,16 @@ 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();
|
||||
|
||||
setBuildSystemCreator([](Project *p) { return new QbsBuildSystem(p); });
|
||||
|
||||
rebuildProjectTree();
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
connect(this, &Project::activeBuildConfigurationChanged,
|
||||
this, &QbsProject::delayParsing);
|
||||
|
||||
connect(&m_parsingDelay, &QTimer::timeout, this, &QbsProject::startParsing);
|
||||
|
||||
connect(this, &QbsProject::projectFileIsDirty, this, &QbsProject::delayParsing);
|
||||
setDisplayName(fileName.toFileInfo().completeBaseName());
|
||||
}
|
||||
|
||||
QbsProject::~QbsProject()
|
||||
{
|
||||
delete m_cppCodeModelUpdater;
|
||||
delete m_qbsProjectParser;
|
||||
delete m_importer;
|
||||
if (m_qbsUpdateFutureInterface) {
|
||||
m_qbsUpdateFutureInterface->reportCanceled();
|
||||
m_qbsUpdateFutureInterface->reportFinished();
|
||||
delete m_qbsUpdateFutureInterface;
|
||||
m_qbsUpdateFutureInterface = nullptr;
|
||||
}
|
||||
qDeleteAll(m_extraCompilers);
|
||||
}
|
||||
|
||||
void QbsProject::projectLoaded()
|
||||
{
|
||||
m_parsingDelay.start(0);
|
||||
}
|
||||
|
||||
ProjectImporter *QbsProject::projectImporter() const
|
||||
@@ -187,12 +146,223 @@ ProjectImporter *QbsProject::projectImporter() const
|
||||
return m_importer;
|
||||
}
|
||||
|
||||
QVariant QbsProject::additionalData(Id id, const Target *target) const
|
||||
// --------------------------------------------------------------------
|
||||
// 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;
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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;
|
||||
if (m_qbsUpdateFutureInterface) {
|
||||
m_qbsUpdateFutureInterface->reportCanceled();
|
||||
m_qbsUpdateFutureInterface->reportFinished();
|
||||
delete m_qbsUpdateFutureInterface;
|
||||
m_qbsUpdateFutureInterface = nullptr;
|
||||
}
|
||||
qDeleteAll(m_extraCompilers);
|
||||
}
|
||||
|
||||
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 = ¬AddedDummy;
|
||||
|
||||
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 = ¬AddedDummy;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
RemovedFilesFromProject QbsBuildSystem::removeFiles(Node *context, const QStringList &filePaths,
|
||||
QStringList *notRemoved)
|
||||
{
|
||||
if (auto n = dynamic_cast<QbsGroupNode *>(context)) {
|
||||
QStringList notRemovedDummy;
|
||||
if (!notRemoved)
|
||||
notRemoved = ¬RemovedDummy;
|
||||
|
||||
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 = ¬RemovedDummy;
|
||||
|
||||
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();
|
||||
if (activeTarget())
|
||||
static_cast<QbsBuildSystem *>(activeTarget()->buildSystem())->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);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user