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:
@@ -45,11 +45,11 @@ AndroidExtraLibraryListModel::AndroidExtraLibraryListModel(ProjectExplorer::Targ
|
|||||||
{
|
{
|
||||||
updateModel();
|
updateModel();
|
||||||
|
|
||||||
connect(target->project(), &ProjectExplorer::Project::parsingStarted,
|
connect(target, &Target::parsingStarted,
|
||||||
this, &AndroidExtraLibraryListModel::updateModel);
|
this, &AndroidExtraLibraryListModel::updateModel);
|
||||||
connect(target->project(), &ProjectExplorer::Project::parsingFinished,
|
connect(target, &Target::parsingFinished,
|
||||||
this, &AndroidExtraLibraryListModel::updateModel);
|
this, &AndroidExtraLibraryListModel::updateModel);
|
||||||
connect(target, &ProjectExplorer::Target::activeRunConfigurationChanged,
|
connect(target, &Target::activeRunConfigurationChanged,
|
||||||
this, &AndroidExtraLibraryListModel::updateModel);
|
this, &AndroidExtraLibraryListModel::updateModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -132,7 +132,7 @@ AndroidRunConfiguration::AndroidRunConfiguration(Target *target, Core::Id id)
|
|||||||
postStartShellCmdAspect->setSettingsKey("Android.PostStartShellCmdListKey");
|
postStartShellCmdAspect->setSettingsKey("Android.PostStartShellCmdListKey");
|
||||||
postStartShellCmdAspect->setLabel(tr("Shell commands to run on Android device after application quits."));
|
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();
|
updateTargetInformation();
|
||||||
AndroidManager::updateGradleProperties(this->target(), buildKey());
|
AndroidManager::updateGradleProperties(this->target(), buildKey());
|
||||||
});
|
});
|
||||||
|
@@ -42,13 +42,13 @@ using namespace ProjectExplorer;
|
|||||||
namespace AutotoolsProjectManager {
|
namespace AutotoolsProjectManager {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
AutotoolsBuildSystem::AutotoolsBuildSystem(Project *project)
|
AutotoolsBuildSystem::AutotoolsBuildSystem(Target *target)
|
||||||
: BuildSystem(project)
|
: BuildSystem(target)
|
||||||
, m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
|
, 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()
|
AutotoolsBuildSystem::~AutotoolsBuildSystem()
|
||||||
@@ -62,7 +62,7 @@ AutotoolsBuildSystem::~AutotoolsBuildSystem()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutotoolsBuildSystem::parseProject(BuildSystem::ParsingContext &&ctx)
|
void AutotoolsBuildSystem::triggerParsing()
|
||||||
{
|
{
|
||||||
if (m_makefileParserThread) {
|
if (m_makefileParserThread) {
|
||||||
// The thread is still busy parsing a previous configuration.
|
// 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
|
// Parse the makefile asynchronously in a thread
|
||||||
m_makefileParserThread = new MakefileParserThread(project()->projectFilePath().toString(),
|
m_makefileParserThread = new MakefileParserThread(this);
|
||||||
std::move(ctx.guard));
|
|
||||||
|
|
||||||
connect(m_makefileParserThread,
|
connect(m_makefileParserThread,
|
||||||
&MakefileParserThread::finished,
|
&MakefileParserThread::finished,
|
||||||
@@ -114,7 +113,7 @@ void AutotoolsBuildSystem::makefileParsingFinished()
|
|||||||
QVector<Utils::FilePath> filesToWatch;
|
QVector<Utils::FilePath> filesToWatch;
|
||||||
|
|
||||||
// Apply sources to m_files, which are returned at AutotoolsBuildSystem::files()
|
// 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 QDir dir = fileInfo.absoluteDir();
|
||||||
const QStringList files = m_makefileParserThread->sources();
|
const QStringList files = m_makefileParserThread->sources();
|
||||||
foreach (const QString& file, files)
|
foreach (const QString& file, files)
|
||||||
@@ -202,7 +201,7 @@ void AutotoolsBuildSystem::updateCppCodeModel()
|
|||||||
rpp.setMacros(m_makefileParserThread->macros());
|
rpp.setMacros(m_makefileParserThread->macros());
|
||||||
rpp.setFiles(m_files);
|
rpp.setFiles(m_files);
|
||||||
|
|
||||||
m_cppCodeModelUpdater->update({project(), kitInfo, project()->activeParseEnvironment(), {rpp}});
|
m_cppCodeModelUpdater->update({project(), kitInfo, activeParseEnvironment(), {rpp}});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -29,12 +29,9 @@
|
|||||||
|
|
||||||
#include <projectexplorer/buildsystem.h>
|
#include <projectexplorer/buildsystem.h>
|
||||||
|
|
||||||
namespace Utils { class FileSystemWatcher; }
|
|
||||||
|
|
||||||
namespace CppTools { class CppProjectUpdater; }
|
namespace CppTools { class CppProjectUpdater; }
|
||||||
|
|
||||||
namespace AutotoolsProjectManager {
|
namespace AutotoolsProjectManager {
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class MakefileParserThread;
|
class MakefileParserThread;
|
||||||
@@ -44,13 +41,12 @@ class AutotoolsBuildSystem : public ProjectExplorer::BuildSystem
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AutotoolsBuildSystem(ProjectExplorer::Project *project);
|
explicit AutotoolsBuildSystem(ProjectExplorer::Target *target);
|
||||||
~AutotoolsBuildSystem() override;
|
~AutotoolsBuildSystem() override;
|
||||||
|
|
||||||
protected:
|
|
||||||
void parseProject(ParsingContext &&ctx) final;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void triggerParsing() final;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is invoked when the makefile parsing by m_makefileParserThread has
|
* Is invoked when the makefile parsing by m_makefileParserThread has
|
||||||
* been finished. Adds all sources and files into the project tree and
|
* been finished. Adds all sources and files into the project tree and
|
||||||
|
@@ -36,7 +36,9 @@
|
|||||||
#include "makestep.h"
|
#include "makestep.h"
|
||||||
|
|
||||||
#include <coreplugin/icontext.h>
|
#include <coreplugin/icontext.h>
|
||||||
|
|
||||||
#include <projectexplorer/projectmanager.h>
|
#include <projectexplorer/projectmanager.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
|
||||||
namespace AutotoolsProjectManager {
|
namespace AutotoolsProjectManager {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -50,7 +52,7 @@ AutotoolsProject::AutotoolsProject(const Utils::FilePath &fileName)
|
|||||||
|
|
||||||
setHasMakeInstallEquivalent(true);
|
setHasMakeInstallEquivalent(true);
|
||||||
|
|
||||||
setBuildSystemCreator([](Project *p) { return new AutotoolsBuildSystem(p); });
|
setBuildSystemCreator([](ProjectExplorer::Target *t) { return new AutotoolsBuildSystem(t); });
|
||||||
}
|
}
|
||||||
|
|
||||||
class AutotoolsProjectPluginPrivate
|
class AutotoolsProjectPluginPrivate
|
||||||
|
@@ -31,10 +31,9 @@
|
|||||||
|
|
||||||
using namespace AutotoolsProjectManager::Internal;
|
using namespace AutotoolsProjectManager::Internal;
|
||||||
|
|
||||||
MakefileParserThread::MakefileParserThread(const QString &makefile,
|
MakefileParserThread::MakefileParserThread(ProjectExplorer::BuildSystem *bs)
|
||||||
ProjectExplorer::Project::ParseGuard &&guard)
|
: m_parser(bs->projectFilePath().toString()),
|
||||||
: m_parser(makefile)
|
m_guard(bs->guardParsingRun())
|
||||||
, m_guard(std::move(guard))
|
|
||||||
{
|
{
|
||||||
connect(&m_parser, &MakefileParser::status,
|
connect(&m_parser, &MakefileParser::status,
|
||||||
this, &MakefileParserThread::status);
|
this, &MakefileParserThread::status);
|
||||||
|
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "makefileparser.h"
|
#include "makefileparser.h"
|
||||||
|
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/buildsystem.h>
|
||||||
#include <projectexplorer/projectmacro.h>
|
#include <projectexplorer/projectmacro.h>
|
||||||
|
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
@@ -54,7 +54,7 @@ class MakefileParserThread : public QThread
|
|||||||
using Macros = ProjectExplorer::Macros;
|
using Macros = ProjectExplorer::Macros;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MakefileParserThread(const QString &makefile, ProjectExplorer::Project::ParseGuard &&guard);
|
explicit MakefileParserThread(ProjectExplorer::BuildSystem *bs);
|
||||||
|
|
||||||
/** @see QThread::run() */
|
/** @see QThread::run() */
|
||||||
void run() override;
|
void run() override;
|
||||||
@@ -143,7 +143,7 @@ private:
|
|||||||
QStringList m_cflags; ///< Return value for MakefileParserThread::cflags()
|
QStringList m_cflags; ///< Return value for MakefileParserThread::cflags()
|
||||||
QStringList m_cxxflags; ///< Return value for MakefileParserThread::cxxflags()
|
QStringList m_cxxflags; ///< Return value for MakefileParserThread::cxxflags()
|
||||||
|
|
||||||
ProjectExplorer::Project::ParseGuard m_guard;
|
ProjectExplorer::BuildSystem::ParseGuard m_guard;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -55,7 +55,7 @@ BareMetalRunConfiguration::BareMetalRunConfiguration(Target *target, Core::Id id
|
|||||||
this, &BareMetalRunConfiguration::updateTargetInformation);
|
this, &BareMetalRunConfiguration::updateTargetInformation);
|
||||||
connect(target, &Target::kitChanged,
|
connect(target, &Target::kitChanged,
|
||||||
this, &BareMetalRunConfiguration::updateTargetInformation); // Handles device changes, etc.
|
this, &BareMetalRunConfiguration::updateTargetInformation); // Handles device changes, etc.
|
||||||
connect(target->project(), &Project::parsingFinished,
|
connect(target, &Target::parsingFinished,
|
||||||
this, &BareMetalRunConfiguration::updateTargetInformation);
|
this, &BareMetalRunConfiguration::updateTargetInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -91,7 +91,7 @@ QdbRunConfiguration::QdbRunConfiguration(Target *target, Core::Id id)
|
|||||||
this, &QdbRunConfiguration::updateTargetInformation);
|
this, &QdbRunConfiguration::updateTargetInformation);
|
||||||
connect(target, &Target::kitChanged,
|
connect(target, &Target::kitChanged,
|
||||||
this, &QdbRunConfiguration::updateTargetInformation);
|
this, &QdbRunConfiguration::updateTargetInformation);
|
||||||
connect(target->project(), &Project::parsingFinished,
|
connect(target, &Target::parsingFinished,
|
||||||
this, &QdbRunConfiguration::updateTargetInformation);
|
this, &QdbRunConfiguration::updateTargetInformation);
|
||||||
|
|
||||||
setDefaultDisplayName(tr("Run on Boot2Qt Device"));
|
setDefaultDisplayName(tr("Run on Boot2Qt Device"));
|
||||||
|
@@ -65,24 +65,29 @@ Q_LOGGING_CATEGORY(cmakeBuildDirManagerLog, "qtc.cmake.builddirmanager", QtWarni
|
|||||||
// BuildDirManager:
|
// BuildDirManager:
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
BuildDirManager::BuildDirManager(CMakeProject *project) : m_project(project) { assert(project); }
|
BuildDirManager::BuildDirManager(CMakeBuildSystem *buildSystem)
|
||||||
|
: m_buildSystem(buildSystem)
|
||||||
|
{
|
||||||
|
assert(buildSystem);
|
||||||
|
}
|
||||||
|
|
||||||
BuildDirManager::~BuildDirManager() = default;
|
BuildDirManager::~BuildDirManager() = default;
|
||||||
|
|
||||||
Utils::FilePath BuildDirManager::workDirectory(const BuildDirParameters ¶meters) const
|
FilePath BuildDirManager::workDirectory(const BuildDirParameters ¶meters) const
|
||||||
{
|
{
|
||||||
const Utils::FilePath bdir = parameters.buildDirectory;
|
const Utils::FilePath bdir = parameters.buildDirectory;
|
||||||
const CMakeTool *cmake = parameters.cmakeTool();
|
const CMakeTool *cmake = parameters.cmakeTool();
|
||||||
if (bdir.exists()) {
|
if (bdir.exists()) {
|
||||||
m_buildDirToTempDir.erase(bdir);
|
m_buildDirToTempDir.erase(bdir);
|
||||||
return 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);
|
auto tmpDirIt = m_buildDirToTempDir.find(bdir);
|
||||||
if (tmpDirIt == m_buildDirToTempDir.end()) {
|
if (tmpDirIt == m_buildDirToTempDir.end()) {
|
||||||
auto ret = m_buildDirToTempDir.emplace(std::make_pair(bdir, std::make_unique<Utils::TemporaryDirectory>("qtc-cmake-XXXXXXXX")));
|
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(); });
|
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_buildSystem;
|
||||||
return m_parameters.buildConfiguration;
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePath BuildDirManager::buildDirectory() const
|
FilePath BuildDirManager::buildDirectory() const
|
||||||
{
|
{
|
||||||
return buildConfiguration() ? m_parameters.buildDirectory : FilePath();
|
return m_parameters.buildDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildDirManager::becameDirty()
|
void BuildDirManager::becameDirty()
|
||||||
{
|
{
|
||||||
qCDebug(cmakeBuildDirManagerLog) << "BuildDirManager: becameDirty was triggered.";
|
qCDebug(cmakeBuildDirManagerLog) << "BuildDirManager: becameDirty was triggered.";
|
||||||
if (isParsing() || !buildConfiguration())
|
if (isParsing() || !buildSystem())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const CMakeTool *tool = m_parameters.cmakeTool();
|
const CMakeTool *tool = m_parameters.cmakeTool();
|
||||||
@@ -444,7 +447,7 @@ static CMakeBuildTarget utilityTarget(const QString &title, const BuildDirManage
|
|||||||
target.title = title;
|
target.title = title;
|
||||||
target.targetType = UtilityType;
|
target.targetType = UtilityType;
|
||||||
target.workingDirectory = bdm->buildDirectory();
|
target.workingDirectory = bdm->buildDirectory();
|
||||||
target.sourceDirectory = bdm->project()->projectDirectory();
|
target.sourceDirectory = bdm->buildSystem()->project()->projectDirectory();
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
@@ -528,13 +531,10 @@ QString BuildDirManager::flagsString(int reparseFlags)
|
|||||||
|
|
||||||
bool BuildDirManager::checkConfiguration()
|
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!
|
if (m_parameters.workDirectory != m_parameters.buildDirectory) // always throw away changes in the tmpdir!
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const CMakeConfig cache = bc->configurationFromCMake();
|
const CMakeConfig cache = m_buildSystem->cmakeBuildConfiguration()->configurationFromCMake();
|
||||||
if (cache.isEmpty())
|
if (cache.isEmpty())
|
||||||
return false; // No cache file yet.
|
return false; // No cache file yet.
|
||||||
|
|
||||||
@@ -586,8 +586,8 @@ bool BuildDirManager::checkConfiguration()
|
|||||||
box->exec();
|
box->exec();
|
||||||
if (box->clickedButton() == applyButton) {
|
if (box->clickedButton() == applyButton) {
|
||||||
m_parameters.configuration = newConfig;
|
m_parameters.configuration = newConfig;
|
||||||
QSignalBlocker blocker(bc);
|
QSignalBlocker blocker(m_buildSystem->buildConfiguration());
|
||||||
bc->setConfigurationForCMake(newConfig);
|
m_buildSystem->cmakeBuildConfiguration()->setConfigurationForCMake(newConfig);
|
||||||
return false;
|
return false;
|
||||||
} else if (box->clickedButton() == defaultButton)
|
} else if (box->clickedButton() == defaultButton)
|
||||||
return true;
|
return true;
|
||||||
|
@@ -27,7 +27,6 @@
|
|||||||
|
|
||||||
#include "builddirparameters.h"
|
#include "builddirparameters.h"
|
||||||
#include "builddirreader.h"
|
#include "builddirreader.h"
|
||||||
#include "cmakebuildsystem.h"
|
|
||||||
#include "cmakebuildtarget.h"
|
#include "cmakebuildtarget.h"
|
||||||
#include "cmakeconfigitem.h"
|
#include "cmakeconfigitem.h"
|
||||||
|
|
||||||
@@ -46,14 +45,11 @@
|
|||||||
namespace ProjectExplorer { class FileNode; }
|
namespace ProjectExplorer { class FileNode; }
|
||||||
|
|
||||||
namespace CMakeProjectManager {
|
namespace CMakeProjectManager {
|
||||||
|
|
||||||
class CMakeProject;
|
|
||||||
class CMakeTool;
|
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class CMakeProjectNode;
|
|
||||||
class CMakeBuildConfiguration;
|
class CMakeBuildConfiguration;
|
||||||
|
class CMakeBuildSystem;
|
||||||
|
class CMakeProjectNode;
|
||||||
|
|
||||||
class BuildDirManager : public QObject
|
class BuildDirManager : public QObject
|
||||||
{
|
{
|
||||||
@@ -71,7 +67,7 @@ public:
|
|||||||
|
|
||||||
static QString flagsString(int reparseFlags);
|
static QString flagsString(int reparseFlags);
|
||||||
|
|
||||||
BuildDirManager(CMakeProject *project);
|
explicit BuildDirManager(CMakeBuildSystem *buildSystem);
|
||||||
~BuildDirManager() final;
|
~BuildDirManager() final;
|
||||||
|
|
||||||
bool isParsing() const;
|
bool isParsing() const;
|
||||||
@@ -81,8 +77,7 @@ public:
|
|||||||
void setParametersAndRequestParse(const BuildDirParameters ¶meters,
|
void setParametersAndRequestParse(const BuildDirParameters ¶meters,
|
||||||
const int reparseOptions);
|
const int reparseOptions);
|
||||||
// nullptr if the BC is not active anymore!
|
// nullptr if the BC is not active anymore!
|
||||||
CMakeBuildConfiguration *buildConfiguration() const;
|
CMakeBuildSystem *buildSystem() const;
|
||||||
CMakeProject *project() const {return m_project; }
|
|
||||||
Utils::FilePath buildDirectory() const;
|
Utils::FilePath buildDirectory() const;
|
||||||
|
|
||||||
void clearCache();
|
void clearCache();
|
||||||
@@ -133,7 +128,7 @@ private:
|
|||||||
|
|
||||||
BuildDirParameters m_parameters;
|
BuildDirParameters m_parameters;
|
||||||
int m_reparseParameters;
|
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::unordered_map<Utils::FilePath, std::unique_ptr<Utils::TemporaryDirectory>> m_buildDirToTempDir;
|
||||||
mutable std::unique_ptr<BuildDirReader> m_reader;
|
mutable std::unique_ptr<BuildDirReader> m_reader;
|
||||||
mutable bool m_isHandlingError = false;
|
mutable bool m_isHandlingError = false;
|
||||||
|
@@ -45,7 +45,7 @@ BuildDirParameters::BuildDirParameters() = default;
|
|||||||
|
|
||||||
BuildDirParameters::BuildDirParameters(CMakeBuildConfiguration *bc)
|
BuildDirParameters::BuildDirParameters(CMakeBuildConfiguration *bc)
|
||||||
{
|
{
|
||||||
buildConfiguration = bc;
|
initialized = bc != nullptr;
|
||||||
|
|
||||||
const Kit *k = bc->target()->kit();
|
const Kit *k = bc->target()->kit();
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ BuildDirParameters::BuildDirParameters(CMakeBuildConfiguration *bc)
|
|||||||
generatorArguments = CMakeGeneratorKitAspect::generatorArguments(k);
|
generatorArguments = CMakeGeneratorKitAspect::generatorArguments(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BuildDirParameters::isValid() const { return buildConfiguration && cmakeTool(); }
|
bool BuildDirParameters::isValid() const { return initialized && cmakeTool(); }
|
||||||
|
|
||||||
CMakeTool *BuildDirParameters::cmakeTool() const
|
CMakeTool *BuildDirParameters::cmakeTool() const
|
||||||
{
|
{
|
||||||
|
@@ -42,14 +42,14 @@ class CMakeBuildConfiguration;
|
|||||||
class BuildDirParameters {
|
class BuildDirParameters {
|
||||||
public:
|
public:
|
||||||
BuildDirParameters();
|
BuildDirParameters();
|
||||||
BuildDirParameters(CMakeBuildConfiguration *bc);
|
explicit BuildDirParameters(CMakeBuildConfiguration *bc);
|
||||||
BuildDirParameters(const BuildDirParameters &other);
|
BuildDirParameters(const BuildDirParameters &other);
|
||||||
BuildDirParameters &operator=(const BuildDirParameters &other);
|
BuildDirParameters &operator=(const BuildDirParameters &other);
|
||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
CMakeTool *cmakeTool() const;
|
CMakeTool *cmakeTool() const;
|
||||||
|
|
||||||
CMakeBuildConfiguration *buildConfiguration = nullptr;
|
bool initialized = false;
|
||||||
QString projectName;
|
QString projectName;
|
||||||
|
|
||||||
Utils::FilePath sourceDirectory;
|
Utils::FilePath sourceDirectory;
|
||||||
|
@@ -84,101 +84,17 @@ const char CONFIGURATION_KEY[] = "CMake.Configuration";
|
|||||||
|
|
||||||
CMakeBuildConfiguration::CMakeBuildConfiguration(Target *parent, Core::Id id)
|
CMakeBuildConfiguration::CMakeBuildConfiguration(Target *parent, Core::Id id)
|
||||||
: BuildConfiguration(parent, id)
|
: BuildConfiguration(parent, id)
|
||||||
, m_buildDirManager(qobject_cast<CMakeProject *>(parent->project()))
|
|
||||||
{
|
{
|
||||||
|
m_buildSystem = new CMakeBuildSystem(this);
|
||||||
setBuildDirectory(shadowBuildDirectory(project()->projectFilePath(),
|
setBuildDirectory(shadowBuildDirectory(project()->projectFilePath(),
|
||||||
target()->kit(),
|
target()->kit(),
|
||||||
displayName(),
|
displayName(),
|
||||||
BuildConfiguration::Unknown));
|
BuildConfiguration::Unknown));
|
||||||
|
}
|
||||||
|
|
||||||
BuildSystem *bs = qobject_cast<CMakeBuildSystem *>(project()->buildSystem());
|
CMakeBuildConfiguration::~CMakeBuildConfiguration()
|
||||||
|
{
|
||||||
// BuildDirManager:
|
delete m_buildSystem;
|
||||||
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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildConfiguration::initialize()
|
void CMakeBuildConfiguration::initialize()
|
||||||
@@ -284,82 +200,11 @@ bool CMakeBuildConfiguration::fromMap(const QVariantMap &map)
|
|||||||
return true;
|
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,
|
FilePath CMakeBuildConfiguration::shadowBuildDirectory(const FilePath &projectFilePath,
|
||||||
const Kit *k,
|
const Kit *k,
|
||||||
@@ -408,11 +253,6 @@ void CMakeBuildConfiguration::setConfigurationFromCMake(const CMakeConfig &confi
|
|||||||
m_configurationFromCMake = config;
|
m_configurationFromCMake = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildConfiguration::setBuildTargets(const QList<CMakeBuildTarget> &targets)
|
|
||||||
{
|
|
||||||
m_buildTargets = targets;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMakeBuildConfiguration::setConfigurationForCMake(const QList<ConfigModel::DataItem> &items)
|
void CMakeBuildConfiguration::setConfigurationForCMake(const QList<ConfigModel::DataItem> &items)
|
||||||
{
|
{
|
||||||
const CMakeConfig newConfig = Utils::transform(items, [](const ConfigModel::DataItem &i) {
|
const CMakeConfig newConfig = Utils::transform(items, [](const ConfigModel::DataItem &i) {
|
||||||
@@ -548,64 +388,6 @@ void CMakeBuildConfiguration::setWarning(const QString &message)
|
|||||||
emit warningOccured(m_warning);
|
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
|
QString CMakeBuildConfiguration::error() const
|
||||||
{
|
{
|
||||||
@@ -775,5 +557,10 @@ CMakeProject *CMakeBuildConfiguration::project() const
|
|||||||
return qobject_cast<CMakeProject *>(BuildConfiguration::project());
|
return qobject_cast<CMakeProject *>(BuildConfiguration::project());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BuildSystem *CMakeBuildConfiguration::buildSystem() const
|
||||||
|
{
|
||||||
|
return m_buildSystem;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace CMakeProjectManager
|
} // namespace CMakeProjectManager
|
||||||
|
@@ -34,13 +34,12 @@
|
|||||||
#include <projectexplorer/deploymentdata.h>
|
#include <projectexplorer/deploymentdata.h>
|
||||||
|
|
||||||
namespace CMakeProjectManager {
|
namespace CMakeProjectManager {
|
||||||
class CMakeBuildSystem;
|
|
||||||
class CMakeExtraBuildInfo;
|
|
||||||
class CMakeProject;
|
class CMakeProject;
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class BuildDirManager;
|
class BuildDirManager;
|
||||||
|
class CMakeBuildSystem;
|
||||||
class CMakeBuildSettingsWidget;
|
class CMakeBuildSettingsWidget;
|
||||||
|
|
||||||
class CMakeBuildConfiguration : public ProjectExplorer::BuildConfiguration
|
class CMakeBuildConfiguration : public ProjectExplorer::BuildConfiguration
|
||||||
@@ -49,6 +48,7 @@ class CMakeBuildConfiguration : public ProjectExplorer::BuildConfiguration
|
|||||||
|
|
||||||
friend class ProjectExplorer::BuildConfigurationFactory;
|
friend class ProjectExplorer::BuildConfigurationFactory;
|
||||||
CMakeBuildConfiguration(ProjectExplorer::Target *parent, Core::Id id);
|
CMakeBuildConfiguration(ProjectExplorer::Target *parent, Core::Id id);
|
||||||
|
~CMakeBuildConfiguration() final;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void emitBuildTypeChanged();
|
void emitBuildTypeChanged();
|
||||||
@@ -61,17 +61,14 @@ public:
|
|||||||
|
|
||||||
CMakeProject *project() const;
|
CMakeProject *project() const;
|
||||||
|
|
||||||
QStringList buildTargetTitles() const;
|
|
||||||
const QList<CMakeBuildTarget> &buildTargets() const;
|
|
||||||
const QList<ProjectExplorer::BuildTargetInfo> appTargets() const;
|
|
||||||
ProjectExplorer::DeploymentData deploymentData() const;
|
|
||||||
|
|
||||||
static Utils::FilePath
|
static Utils::FilePath
|
||||||
shadowBuildDirectory(const Utils::FilePath &projectFilePath, const ProjectExplorer::Kit *k,
|
shadowBuildDirectory(const Utils::FilePath &projectFilePath, const ProjectExplorer::Kit *k,
|
||||||
const QString &bcName, BuildConfiguration::BuildType buildType);
|
const QString &bcName, BuildConfiguration::BuildType buildType);
|
||||||
|
|
||||||
// Context menu action:
|
// Context menu action:
|
||||||
void buildTarget(const QString &buildTarget);
|
void buildTarget(const QString &buildTarget);
|
||||||
|
ProjectExplorer::BuildSystem *buildSystem() const final;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void errorOccured(const QString &message);
|
void errorOccured(const QString &message);
|
||||||
void warningOccured(const QString &message);
|
void warningOccured(const QString &message);
|
||||||
@@ -92,7 +89,6 @@ private:
|
|||||||
enum ForceEnabledChanged { False, True };
|
enum ForceEnabledChanged { False, True };
|
||||||
void clearError(ForceEnabledChanged fec = ForceEnabledChanged::False);
|
void clearError(ForceEnabledChanged fec = ForceEnabledChanged::False);
|
||||||
|
|
||||||
void setBuildTargets(const QList<CMakeBuildTarget> &targets);
|
|
||||||
void setConfigurationFromCMake(const CMakeConfig &config);
|
void setConfigurationFromCMake(const CMakeConfig &config);
|
||||||
void setConfigurationForCMake(const QList<ConfigModel::DataItem> &items);
|
void setConfigurationForCMake(const QList<ConfigModel::DataItem> &items);
|
||||||
void setConfigurationForCMake(const CMakeConfig &config);
|
void setConfigurationForCMake(const CMakeConfig &config);
|
||||||
@@ -100,27 +96,17 @@ private:
|
|||||||
void setError(const QString &message);
|
void setError(const QString &message);
|
||||||
void setWarning(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_configurationForCMake;
|
||||||
CMakeConfig m_initialConfiguration;
|
CMakeConfig m_initialConfiguration;
|
||||||
QString m_error;
|
QString m_error;
|
||||||
QString m_warning;
|
QString m_warning;
|
||||||
|
|
||||||
CMakeConfig m_configurationFromCMake;
|
CMakeConfig m_configurationFromCMake;
|
||||||
QList<CMakeBuildTarget> m_buildTargets;
|
CMakeBuildSystem *m_buildSystem = nullptr;
|
||||||
|
|
||||||
friend class CMakeBuildSettingsWidget;
|
friend class CMakeBuildSettingsWidget;
|
||||||
friend class CMakeProjectManager::CMakeBuildSystem;
|
friend class CMakeBuildSystem;
|
||||||
friend class CMakeProjectManager::CMakeProject;
|
friend class CMakeProject;
|
||||||
friend class BuildDirManager;
|
friend class BuildDirManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -59,6 +59,8 @@
|
|||||||
#include <QStyledItemDelegate>
|
#include <QStyledItemDelegate>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
|
||||||
|
using namespace ProjectExplorer;
|
||||||
|
|
||||||
namespace CMakeProjectManager {
|
namespace CMakeProjectManager {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -102,7 +104,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
|
|||||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
mainLayout->setColumnStretch(1, 10);
|
mainLayout->setColumnStretch(1, 10);
|
||||||
|
|
||||||
auto project = static_cast<CMakeProject *>(bc->project());
|
auto project = bc->project();
|
||||||
|
|
||||||
auto buildDirChooser = new Utils::PathChooser;
|
auto buildDirChooser = new Utils::PathChooser;
|
||||||
buildDirChooser->setBaseFileName(project->projectDirectory());
|
buildDirChooser->setBaseFileName(project->projectDirectory());
|
||||||
@@ -245,21 +247,20 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
|
|||||||
setError(bc->error());
|
setError(bc->error());
|
||||||
setWarning(bc->warning());
|
setWarning(bc->warning());
|
||||||
|
|
||||||
connect(project, &ProjectExplorer::Project::parsingStarted, this, [this]() {
|
connect(bc->target(), &Target::parsingStarted, this, [this]() {
|
||||||
updateButtonState();
|
updateButtonState();
|
||||||
m_configView->setEnabled(false);
|
m_configView->setEnabled(false);
|
||||||
m_showProgressTimer.start();
|
m_showProgressTimer.start();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (project->isParsing())
|
if (bc->buildSystem()->isParsing())
|
||||||
m_showProgressTimer.start();
|
m_showProgressTimer.start();
|
||||||
else {
|
else {
|
||||||
m_configModel->setConfiguration(m_buildConfiguration->configurationFromCMake());
|
m_configModel->setConfiguration(m_buildConfiguration->configurationFromCMake());
|
||||||
m_configView->expandAll();
|
m_configView->expandAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(project, &ProjectExplorer::Project::parsingFinished,
|
connect(bc->target(), &Target::parsingFinished, this, [this, buildDirChooser, stretcher] {
|
||||||
this, [this, buildDirChooser, stretcher]() {
|
|
||||||
m_configModel->setConfiguration(m_buildConfiguration->configurationFromCMake());
|
m_configModel->setConfiguration(m_buildConfiguration->configurationFromCMake());
|
||||||
m_configView->expandAll();
|
m_configView->expandAll();
|
||||||
m_configView->setEnabled(true);
|
m_configView->setEnabled(true);
|
||||||
@@ -363,7 +364,7 @@ void CMakeBuildSettingsWidget::setWarning(const QString &message)
|
|||||||
|
|
||||||
void CMakeBuildSettingsWidget::updateButtonState()
|
void CMakeBuildSettingsWidget::updateButtonState()
|
||||||
{
|
{
|
||||||
const bool isParsing = m_buildConfiguration->project()->isParsing();
|
const bool isParsing = m_buildConfiguration->buildSystem()->isParsing();
|
||||||
const bool hasChanges = m_configModel->hasChanges();
|
const bool hasChanges = m_configModel->hasChanges();
|
||||||
m_resetButton->setEnabled(hasChanges && !isParsing);
|
m_resetButton->setEnabled(hasChanges && !isParsing);
|
||||||
m_reconfigureButton->setEnabled((hasChanges || m_configModel->hasCMakeChanges()) && !isParsing);
|
m_reconfigureButton->setEnabled((hasChanges || m_configModel->hasCMakeChanges()) && !isParsing);
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#include "cmakebuildstep.h"
|
#include "cmakebuildstep.h"
|
||||||
|
|
||||||
#include "cmakebuildconfiguration.h"
|
#include "cmakebuildconfiguration.h"
|
||||||
|
#include "cmakebuildsystem.h"
|
||||||
#include "cmakekitinformation.h"
|
#include "cmakekitinformation.h"
|
||||||
#include "cmakeparser.h"
|
#include "cmakeparser.h"
|
||||||
#include "cmakeprojectconstants.h"
|
#include "cmakeprojectconstants.h"
|
||||||
@@ -91,7 +92,7 @@ CMakeBuildStep::CMakeBuildStep(BuildStepList *bsl) :
|
|||||||
setLowPriority();
|
setLowPriority();
|
||||||
|
|
||||||
connect(target(), &Target::kitChanged, this, &CMakeBuildStep::cmakeCommandChanged);
|
connect(target(), &Target::kitChanged, this, &CMakeBuildStep::cmakeCommandChanged);
|
||||||
connect(project(), &Project::parsingFinished,
|
connect(target(), &Target::parsingFinished,
|
||||||
this, &CMakeBuildStep::handleBuildTargetChanges);
|
this, &CMakeBuildStep::handleBuildTargetChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,17 +222,17 @@ void CMakeBuildStep::doRun()
|
|||||||
QTC_ASSERT(bc, return);
|
QTC_ASSERT(bc, return);
|
||||||
|
|
||||||
m_waiting = false;
|
m_waiting = false;
|
||||||
auto p = static_cast<CMakeProject *>(bc->project());
|
auto bs = static_cast<CMakeBuildSystem *>(buildConfiguration()->buildSystem());
|
||||||
if (p->persistCMakeState()) {
|
if (bs->persistCMakeState()) {
|
||||||
emit addOutput(tr("Persisting CMake state..."), BuildStep::OutputFormat::NormalMessage);
|
emit addOutput(tr("Persisting CMake state..."), BuildStep::OutputFormat::NormalMessage);
|
||||||
m_waiting = true;
|
m_waiting = true;
|
||||||
} else if (p->mustUpdateCMakeStateBeforeBuild()) {
|
} else if (buildConfiguration()->buildSystem()->isWaitingForParse()) {
|
||||||
emit addOutput(tr("Running CMake in preparation to build..."), BuildStep::OutputFormat::NormalMessage);
|
emit addOutput(tr("Running CMake in preparation to build..."), BuildStep::OutputFormat::NormalMessage);
|
||||||
m_waiting = true;
|
m_waiting = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_waiting) {
|
if (m_waiting) {
|
||||||
m_runTrigger = connect(project(), &Project::parsingFinished,
|
m_runTrigger = connect(target(), &Target::parsingFinished,
|
||||||
this, [this](bool success) { handleProjectWasParsed(success); });
|
this, [this](bool success) { handleProjectWasParsed(success); });
|
||||||
} else {
|
} else {
|
||||||
runImpl();
|
runImpl();
|
||||||
@@ -367,7 +368,7 @@ Utils::CommandLine CMakeBuildStep::cmakeCommand(RunConfiguration *rc) const
|
|||||||
|
|
||||||
QStringList CMakeBuildStep::knownBuildTargets()
|
QStringList CMakeBuildStep::knownBuildTargets()
|
||||||
{
|
{
|
||||||
auto bc = qobject_cast<CMakeBuildConfiguration *>(buildConfiguration());
|
auto bc = qobject_cast<CMakeBuildSystem *>(buildConfiguration()->buildSystem());
|
||||||
return bc ? bc->buildTargetTitles() : QStringList();
|
return bc ? bc->buildTargetTitles() : QStringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -30,13 +30,18 @@
|
|||||||
#include "cmakeprojectconstants.h"
|
#include "cmakeprojectconstants.h"
|
||||||
#include "cmakeprojectnodes.h"
|
#include "cmakeprojectnodes.h"
|
||||||
|
|
||||||
|
#include <android/androidconstants.h>
|
||||||
|
|
||||||
#include <coreplugin/progressmanager/progressmanager.h>
|
#include <coreplugin/progressmanager/progressmanager.h>
|
||||||
#include <cpptools/cppprojectupdater.h>
|
#include <cpptools/cppprojectupdater.h>
|
||||||
#include <cpptools/generatedcodemodelsupport.h>
|
#include <cpptools/generatedcodemodelsupport.h>
|
||||||
|
#include <projectexplorer/kitmanager.h>
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||||
|
|
||||||
#include <qtsupport/qtcppkitinfo.h>
|
#include <qtsupport/qtcppkitinfo.h>
|
||||||
|
#include <qtsupport/qtkitinformation.h>
|
||||||
|
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/mimetypes/mimetype.h>
|
#include <utils/mimetypes/mimetype.h>
|
||||||
@@ -48,8 +53,7 @@ using namespace ProjectExplorer;
|
|||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
namespace CMakeProjectManager {
|
namespace CMakeProjectManager {
|
||||||
|
namespace Internal {
|
||||||
using namespace Internal;
|
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(cmakeBuildSystemLog, "qtc.cmake.buildsystem", QtWarningMsg);
|
Q_LOGGING_CATEGORY(cmakeBuildSystemLog, "qtc.cmake.buildsystem", QtWarningMsg);
|
||||||
|
|
||||||
@@ -57,15 +61,15 @@ Q_LOGGING_CATEGORY(cmakeBuildSystemLog, "qtc.cmake.buildsystem", QtWarningMsg);
|
|||||||
// CMakeBuildSystem:
|
// CMakeBuildSystem:
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
CMakeBuildSystem::CMakeBuildSystem(Project *project)
|
CMakeBuildSystem::CMakeBuildSystem(CMakeBuildConfiguration *bc)
|
||||||
: BuildSystem(project)
|
: BuildSystem(bc)
|
||||||
|
, m_buildConfiguration(bc)
|
||||||
|
, m_buildDirManager(this)
|
||||||
, m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
|
, m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
|
||||||
{
|
{
|
||||||
// TreeScanner:
|
// TreeScanner:
|
||||||
connect(&m_treeScanner,
|
connect(&m_treeScanner, &TreeScanner::finished,
|
||||||
&TreeScanner::finished,
|
this, &CMakeBuildSystem::handleTreeScanningFinished);
|
||||||
this,
|
|
||||||
&CMakeBuildSystem::handleTreeScanningFinished);
|
|
||||||
|
|
||||||
m_treeScanner.setFilter([this](const MimeType &mimeType, const FilePath &fn) {
|
m_treeScanner.setFilter([this](const MimeType &mimeType, const FilePath &fn) {
|
||||||
// Mime checks requires more resources, so keep it last in check list
|
// Mime checks requires more resources, so keep it last in check list
|
||||||
@@ -98,6 +102,109 @@ CMakeBuildSystem::CMakeBuildSystem(Project *project)
|
|||||||
}
|
}
|
||||||
return type;
|
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()
|
CMakeBuildSystem::~CMakeBuildSystem()
|
||||||
@@ -112,36 +219,84 @@ CMakeBuildSystem::~CMakeBuildSystem()
|
|||||||
qDeleteAll(m_allFiles);
|
qDeleteAll(m_allFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMakeBuildSystem::validateParsingContext(const ParsingContext &ctx)
|
void CMakeBuildSystem::triggerParsing()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!m_currentContext.guard.guardsProject(), return false);
|
m_currentGuard = guardParsingRun();
|
||||||
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 );
|
|
||||||
|
|
||||||
if (m_allFiles.isEmpty())
|
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_waitingForParse = true;
|
||||||
m_combinedScanAndParseResult = true;
|
m_combinedScanAndParseResult = true;
|
||||||
|
|
||||||
if (m_waitingForScan) {
|
if (m_waitingForScan) {
|
||||||
QTC_CHECK(m_treeScanner.isFinished());
|
QTC_CHECK(m_treeScanner.isFinished());
|
||||||
m_treeScanner.asyncScanForFiles(m_currentContext.project->projectDirectory());
|
m_treeScanner.asyncScanForFiles(projectDirectory());
|
||||||
Core::ProgressManager::addTask(m_treeScanner.future(),
|
Core::ProgressManager::addTask(m_treeScanner.future(),
|
||||||
tr("Scan \"%1\" project tree")
|
tr("Scan \"%1\" project tree")
|
||||||
.arg(m_currentContext.project->displayName()),
|
.arg(project()->displayName()),
|
||||||
"CMake.Scan.Tree");
|
"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()
|
void CMakeBuildSystem::handleTreeScanningFinished()
|
||||||
@@ -156,11 +311,18 @@ void CMakeBuildSystem::handleTreeScanningFinished()
|
|||||||
combineScanAndParse();
|
combineScanAndParse();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::handleParsingSuccess(CMakeBuildConfiguration *bc)
|
bool CMakeBuildSystem::persistCMakeState()
|
||||||
{
|
{
|
||||||
if (bc != m_currentContext.buildConfiguration)
|
return m_buildDirManager.persistCMakeState();
|
||||||
return; // Not current information, ignore.
|
}
|
||||||
|
|
||||||
|
void CMakeBuildSystem::clearCMakeCache()
|
||||||
|
{
|
||||||
|
m_buildDirManager.clearCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeBuildSystem::handleParsingSuccess()
|
||||||
|
{
|
||||||
QTC_ASSERT(m_waitingForParse, return );
|
QTC_ASSERT(m_waitingForParse, return );
|
||||||
|
|
||||||
m_waitingForParse = false;
|
m_waitingForParse = false;
|
||||||
@@ -168,11 +330,8 @@ void CMakeBuildSystem::handleParsingSuccess(CMakeBuildConfiguration *bc)
|
|||||||
combineScanAndParse();
|
combineScanAndParse();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::handleParsingError(CMakeBuildConfiguration *bc)
|
void CMakeBuildSystem::handleParsingError()
|
||||||
{
|
{
|
||||||
if (bc != m_currentContext.buildConfiguration)
|
|
||||||
return; // Not current information, ignore.
|
|
||||||
|
|
||||||
QTC_CHECK(m_waitingForParse);
|
QTC_CHECK(m_waitingForParse);
|
||||||
|
|
||||||
m_waitingForParse = false;
|
m_waitingForParse = false;
|
||||||
@@ -181,35 +340,51 @@ void CMakeBuildSystem::handleParsingError(CMakeBuildConfiguration *bc)
|
|||||||
combineScanAndParse();
|
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()
|
void CMakeBuildSystem::combineScanAndParse()
|
||||||
{
|
{
|
||||||
auto bc = qobject_cast<CMakeBuildConfiguration *>(m_currentContext.buildConfiguration);
|
if (m_buildConfiguration->isActive()) {
|
||||||
if (bc && bc->isActive()) {
|
|
||||||
if (m_waitingForParse || m_waitingForScan)
|
if (m_waitingForParse || m_waitingForScan)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_combinedScanAndParseResult) {
|
if (m_combinedScanAndParseResult) {
|
||||||
updateProjectData(qobject_cast<CMakeProject *>(m_currentContext.project), bc);
|
updateProjectData();
|
||||||
m_currentContext.guard.markAsSuccess();
|
m_currentGuard.markAsSuccess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_currentContext = BuildSystem::ParsingContext();
|
m_currentGuard = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::updateProjectData(CMakeProject *p, CMakeBuildConfiguration *bc)
|
void CMakeBuildSystem::checkAndReportError(QString &errorMessage)
|
||||||
|
{
|
||||||
|
if (!errorMessage.isEmpty()) {
|
||||||
|
m_buildConfiguration->setError(errorMessage);
|
||||||
|
errorMessage.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeBuildSystem::updateProjectData()
|
||||||
{
|
{
|
||||||
qCDebug(cmakeBuildSystemLog) << "Updating CMake project data";
|
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;
|
CMakeConfigItem settingFileItem;
|
||||||
settingFileItem.key = "ANDROID_DEPLOYMENT_SETTINGS_FILE";
|
settingFileItem.key = "ANDROID_DEPLOYMENT_SETTINGS_FILE";
|
||||||
settingFileItem.value = bc->buildDirectory()
|
settingFileItem.value = m_buildConfiguration->buildDirectory()
|
||||||
.pathAppended("android_deployment_settings.json")
|
.pathAppended("android_deployment_settings.json")
|
||||||
.toString()
|
.toString()
|
||||||
.toUtf8();
|
.toUtf8();
|
||||||
@@ -218,7 +393,7 @@ void CMakeBuildSystem::updateProjectData(CMakeProject *p, CMakeBuildConfiguratio
|
|||||||
{
|
{
|
||||||
QSet<QString> res;
|
QSet<QString> res;
|
||||||
QStringList apps;
|
QStringList apps;
|
||||||
for (const auto &target : bc->buildTargets()) {
|
for (const auto &target : m_buildTargets) {
|
||||||
if (target.targetType == CMakeProjectManager::DynamicLibraryType) {
|
if (target.targetType == CMakeProjectManager::DynamicLibraryType) {
|
||||||
res.insert(target.executable.parentDir().toString());
|
res.insert(target.executable.parentDir().toString());
|
||||||
apps.push_back(target.executable.toUserOutput());
|
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) {
|
if (newRoot) {
|
||||||
p->setRootProjectNode(std::move(newRoot));
|
p->setRootProjectNode(std::move(newRoot));
|
||||||
if (p->rootProjectNode())
|
if (p->rootProjectNode())
|
||||||
p->setDisplayName(p->rootProjectNode()->displayName());
|
p->setDisplayName(p->rootProjectNode()->displayName());
|
||||||
|
|
||||||
for (const CMakeBuildTarget &bt : bc->buildTargets()) {
|
for (const CMakeBuildTarget &bt : m_buildTargets) {
|
||||||
const QString buildKey = bt.title;
|
const QString buildKey = bt.title;
|
||||||
if (ProjectNode *node = p->findNodeForBuildKey(buildKey)) {
|
if (ProjectNode *node = p->findNodeForBuildKey(buildKey)) {
|
||||||
if (auto targetNode = dynamic_cast<CMakeTargetNode *>(node))
|
if (auto targetNode = dynamic_cast<CMakeTargetNode *>(node))
|
||||||
@@ -260,7 +436,7 @@ void CMakeBuildSystem::updateProjectData(CMakeProject *p, CMakeBuildConfiguratio
|
|||||||
|
|
||||||
{
|
{
|
||||||
qDeleteAll(m_extraCompilers);
|
qDeleteAll(m_extraCompilers);
|
||||||
m_extraCompilers = findExtraCompilers(p);
|
m_extraCompilers = findExtraCompilers();
|
||||||
CppTools::GeneratedCodeModelSupport::update(m_extraCompilers);
|
CppTools::GeneratedCodeModelSupport::update(m_extraCompilers);
|
||||||
qCDebug(cmakeBuildSystemLog) << "Extra compilers updated.";
|
qCDebug(cmakeBuildSystemLog) << "Extra compilers updated.";
|
||||||
}
|
}
|
||||||
@@ -270,9 +446,9 @@ void CMakeBuildSystem::updateProjectData(CMakeProject *p, CMakeBuildConfiguratio
|
|||||||
|
|
||||||
{
|
{
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
RawProjectParts rpps = bc->m_buildDirManager.createRawProjectParts(errorMessage);
|
RawProjectParts rpps = m_buildDirManager.createRawProjectParts(errorMessage);
|
||||||
if (!errorMessage.isEmpty())
|
if (!errorMessage.isEmpty())
|
||||||
bc->setError(errorMessage);
|
m_buildConfiguration->setError(errorMessage);
|
||||||
qCDebug(cmakeBuildSystemLog) << "Raw project parts created." << errorMessage;
|
qCDebug(cmakeBuildSystemLog) << "Raw project parts created." << errorMessage;
|
||||||
|
|
||||||
for (RawProjectPart &rpp : rpps) {
|
for (RawProjectPart &rpp : rpps) {
|
||||||
@@ -284,22 +460,147 @@ void CMakeBuildSystem::updateProjectData(CMakeProject *p, CMakeBuildConfiguratio
|
|||||||
rpp.setFlagsForC({kitInfo.cToolChain, rpp.flagsForC.commandLineFlags});
|
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 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.";
|
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.";
|
qCDebug(cmakeBuildSystemLog) << "Finding Extra Compilers: start.";
|
||||||
|
|
||||||
@@ -315,6 +616,7 @@ QList<ProjectExplorer::ExtraCompiler *> CMakeBuildSystem::findExtraCompilers(CMa
|
|||||||
<< fileExtensions;
|
<< fileExtensions;
|
||||||
|
|
||||||
// Find all files generated by any of the extra compilers, in a rather crude way.
|
// 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) {
|
const FilePathList fileList = p->files([&fileExtensions, p](const Node *n) {
|
||||||
if (!p->SourceFiles(n))
|
if (!p->SourceFiles(n))
|
||||||
return false;
|
return false;
|
||||||
@@ -336,7 +638,7 @@ QList<ProjectExplorer::ExtraCompiler *> CMakeBuildSystem::findExtraCompilers(CMa
|
|||||||
});
|
});
|
||||||
QTC_ASSERT(factory, continue);
|
QTC_ASSERT(factory, continue);
|
||||||
|
|
||||||
QStringList generated = p->filesGeneratedFrom(file.toString());
|
QStringList generated = filesGeneratedFrom(file.toString());
|
||||||
qCDebug(cmakeBuildSystemLog)
|
qCDebug(cmakeBuildSystemLog)
|
||||||
<< "Finding Extra Compilers: generated files:" << generated;
|
<< "Finding Extra Compilers: generated files:" << generated;
|
||||||
if (generated.isEmpty())
|
if (generated.isEmpty())
|
||||||
@@ -355,19 +657,20 @@ QList<ProjectExplorer::ExtraCompiler *> CMakeBuildSystem::findExtraCompilers(CMa
|
|||||||
return extraCompilers;
|
return extraCompilers;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::updateQmlJSCodeModel(CMakeProject *p, CMakeBuildConfiguration *bc)
|
void CMakeBuildSystem::updateQmlJSCodeModel()
|
||||||
{
|
{
|
||||||
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
|
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
|
||||||
|
|
||||||
if (!modelManager)
|
if (!modelManager)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Project *p = project();
|
||||||
QmlJS::ModelManagerInterface::ProjectInfo projectInfo = modelManager
|
QmlJS::ModelManagerInterface::ProjectInfo projectInfo = modelManager
|
||||||
->defaultProjectInfoForProject(p);
|
->defaultProjectInfoForProject(p);
|
||||||
|
|
||||||
projectInfo.importPaths.clear();
|
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));
|
const QString cmakeImports = QString::fromUtf8(CMakeConfigItem::valueOf("QML_IMPORT_PATH", cm));
|
||||||
|
|
||||||
foreach (const QString &cmakeImport, CMakeConfigItem::cmakeSplitValue(cmakeImports))
|
foreach (const QString &cmakeImport, CMakeConfigItem::cmakeSplitValue(cmakeImports))
|
||||||
@@ -376,4 +679,5 @@ void CMakeBuildSystem::updateQmlJSCodeModel(CMakeProject *p, CMakeBuildConfigura
|
|||||||
modelManager->updateProjectInfo(projectInfo, p);
|
modelManager->updateProjectInfo(projectInfo, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
} // namespace CMakeProjectManager
|
} // namespace CMakeProjectManager
|
||||||
|
@@ -25,8 +25,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "builddirmanager.h"
|
||||||
|
|
||||||
#include <projectexplorer/buildsystem.h>
|
#include <projectexplorer/buildsystem.h>
|
||||||
|
|
||||||
|
namespace ProjectExplorer { class ExtraCompiler; }
|
||||||
|
|
||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
class CppProjectUpdater;
|
class CppProjectUpdater;
|
||||||
} // namespace CppTools
|
} // namespace CppTools
|
||||||
@@ -37,7 +41,6 @@ class CMakeProject;
|
|||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
class CMakeBuildConfiguration;
|
class CMakeBuildConfiguration;
|
||||||
} // namespace Internal
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
// CMakeBuildSystem:
|
// CMakeBuildSystem:
|
||||||
@@ -48,12 +51,10 @@ class CMakeBuildSystem : public ProjectExplorer::BuildSystem
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CMakeBuildSystem(ProjectExplorer::Project *project);
|
explicit CMakeBuildSystem(CMakeBuildConfiguration *bc);
|
||||||
~CMakeBuildSystem() final;
|
~CMakeBuildSystem() final;
|
||||||
|
|
||||||
protected:
|
void triggerParsing() final;
|
||||||
bool validateParsingContext(const ParsingContext &ctx) final;
|
|
||||||
void parseProject(ParsingContext &&ctx) final;
|
|
||||||
|
|
||||||
bool supportsAction(ProjectExplorer::Node *context,
|
bool supportsAction(ProjectExplorer::Node *context,
|
||||||
ProjectExplorer::ProjectAction action,
|
ProjectExplorer::ProjectAction action,
|
||||||
@@ -62,20 +63,49 @@ protected:
|
|||||||
bool addFiles(ProjectExplorer::Node *context,
|
bool addFiles(ProjectExplorer::Node *context,
|
||||||
const QStringList &filePaths, QStringList *) final;
|
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:
|
// Treescanner states:
|
||||||
void handleTreeScanningFinished();
|
void handleTreeScanningFinished();
|
||||||
|
|
||||||
|
bool persistCMakeState();
|
||||||
|
void clearCMakeCache();
|
||||||
|
|
||||||
// Parser states:
|
// Parser states:
|
||||||
void handleParsingSuccess(Internal::CMakeBuildConfiguration *bc);
|
void handleParsingSuccess();
|
||||||
void handleParsingError(Internal::CMakeBuildConfiguration *bc);
|
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:
|
// Combining Treescanner and Parser states:
|
||||||
void combineScanAndParse();
|
void combineScanAndParse();
|
||||||
|
|
||||||
void updateProjectData(CMakeProject *p, Internal::CMakeBuildConfiguration *bc);
|
void checkAndReportError(QString &errorMessage);
|
||||||
QList<ProjectExplorer::ExtraCompiler *> findExtraCompilers(CMakeProject *p);
|
|
||||||
void updateQmlJSCodeModel(CMakeProject *p, Internal::CMakeBuildConfiguration *bc);
|
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;
|
ProjectExplorer::TreeScanner m_treeScanner;
|
||||||
QHash<QString, bool> m_mimeBinaryCache;
|
QHash<QString, bool> m_mimeBinaryCache;
|
||||||
@@ -85,12 +115,12 @@ private:
|
|||||||
bool m_waitingForParse = false;
|
bool m_waitingForParse = false;
|
||||||
bool m_combinedScanAndParseResult = false;
|
bool m_combinedScanAndParseResult = false;
|
||||||
|
|
||||||
ParsingContext m_currentContext;
|
ParseGuard m_currentGuard;
|
||||||
|
|
||||||
CppTools::CppProjectUpdater *m_cppCodeModelUpdater = nullptr;
|
CppTools::CppProjectUpdater *m_cppCodeModelUpdater = nullptr;
|
||||||
QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers;
|
QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers;
|
||||||
|
QList<CMakeBuildTarget> m_buildTargets;
|
||||||
friend class Internal::CMakeBuildConfiguration; // For handleParsing* callbacks
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
} // namespace CMakeProjectManager
|
} // namespace CMakeProjectManager
|
||||||
|
@@ -66,12 +66,11 @@ void CMakeTargetLocatorFilter::prepareSearch(const QString &entry)
|
|||||||
auto cmakeProject = qobject_cast<const CMakeProject *>(p);
|
auto cmakeProject = qobject_cast<const CMakeProject *>(p);
|
||||||
if (!cmakeProject || !cmakeProject->activeTarget())
|
if (!cmakeProject || !cmakeProject->activeTarget())
|
||||||
continue;
|
continue;
|
||||||
auto bc = qobject_cast<CMakeBuildConfiguration *>(
|
auto bs = qobject_cast<CMakeBuildSystem *>(cmakeProject->activeTarget()->buildSystem());
|
||||||
cmakeProject->activeTarget()->activeBuildConfiguration());
|
if (!bs)
|
||||||
if (!bc)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const QList<CMakeBuildTarget> buildTargets = bc->buildTargets();
|
const QList<CMakeBuildTarget> buildTargets = bs->buildTargets();
|
||||||
for (const CMakeBuildTarget &target : buildTargets) {
|
for (const CMakeBuildTarget &target : buildTargets) {
|
||||||
const int index = target.title.indexOf(entry);
|
const int index = target.title.indexOf(entry);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
|
@@ -68,11 +68,6 @@ namespace CMakeProjectManager {
|
|||||||
|
|
||||||
using namespace Internal;
|
using namespace Internal;
|
||||||
|
|
||||||
static CMakeBuildConfiguration *activeBc(const CMakeProject *p)
|
|
||||||
{
|
|
||||||
return qobject_cast<CMakeBuildConfiguration *>(p->activeTarget() ? p->activeTarget()->activeBuildConfiguration() : nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// QtCreator CMake Generator wishlist:
|
// QtCreator CMake Generator wishlist:
|
||||||
// Which make targets we need to build to get all executables
|
// Which make targets we need to build to get all executables
|
||||||
// What is the actual compiler executable
|
// What is the actual compiler executable
|
||||||
@@ -90,8 +85,6 @@ CMakeProject::CMakeProject(const FilePath &fileName)
|
|||||||
setCanBuildProducts();
|
setCanBuildProducts();
|
||||||
setKnowsAllBuildExecutables(false);
|
setKnowsAllBuildExecutables(false);
|
||||||
setHasMakeInstallEquivalent(true);
|
setHasMakeInstallEquivalent(true);
|
||||||
|
|
||||||
setBuildSystemCreator([](Project *p) { return new CMakeBuildSystem(p); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CMakeProject::~CMakeProject() = default;
|
CMakeProject::~CMakeProject() = default;
|
||||||
@@ -108,38 +101,6 @@ Tasks CMakeProject::projectIssues(const Kit *k) const
|
|||||||
return result;
|
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
|
ProjectImporter *CMakeProject::projectImporter() const
|
||||||
{
|
{
|
||||||
@@ -148,19 +109,6 @@ ProjectImporter *CMakeProject::projectImporter() const
|
|||||||
return m_projectImporter.get();
|
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)
|
bool CMakeProject::setupTarget(Target *t)
|
||||||
{
|
{
|
||||||
t->updateDefaultBuildConfigurations();
|
t->updateDefaultBuildConfigurations();
|
||||||
@@ -170,42 +118,6 @@ bool CMakeProject::setupTarget(Target *t)
|
|||||||
return true;
|
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
|
ProjectExplorer::DeploymentKnowledge CMakeProject::deploymentKnowledge() const
|
||||||
{
|
{
|
||||||
return !files([](const ProjectExplorer::Node *n) {
|
return !files([](const ProjectExplorer::Node *n) {
|
||||||
@@ -232,9 +144,4 @@ MakeInstallCommand CMakeProject::makeInstallCommand(const Target *target,
|
|||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMakeProject::mustUpdateCMakeStateBeforeBuild() const
|
|
||||||
{
|
|
||||||
return buildSystem()->isWaitingForParse();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace CMakeProjectManager
|
} // namespace CMakeProjectManager
|
||||||
|
@@ -49,24 +49,12 @@ public:
|
|||||||
|
|
||||||
ProjectExplorer::Tasks projectIssues(const ProjectExplorer::Kit *k) const final;
|
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;
|
ProjectExplorer::ProjectImporter *projectImporter() const final;
|
||||||
|
|
||||||
bool persistCMakeState();
|
|
||||||
void clearCMakeCache();
|
|
||||||
bool mustUpdateCMakeStateBeforeBuild() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool setupTarget(ProjectExplorer::Target *t) final;
|
bool setupTarget(ProjectExplorer::Target *t) final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStringList filesGeneratedFrom(const QString &sourceFile) const final;
|
|
||||||
|
|
||||||
ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override;
|
ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override;
|
||||||
ProjectExplorer::MakeInstallCommand makeInstallCommand(const ProjectExplorer::Target *target,
|
ProjectExplorer::MakeInstallCommand makeInstallCommand(const ProjectExplorer::Target *target,
|
||||||
const QString &installRoot) override;
|
const QString &installRoot) override;
|
||||||
|
@@ -78,7 +78,7 @@ CMakeManager::CMakeManager() :
|
|||||||
command->setAttribute(Core::Command::CA_Hide);
|
command->setAttribute(Core::Command::CA_Hide);
|
||||||
mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_DEPLOY);
|
mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_DEPLOY);
|
||||||
connect(m_runCMakeAction, &QAction::triggered, [this]() {
|
connect(m_runCMakeAction, &QAction::triggered, [this]() {
|
||||||
runCMake(SessionManager::startupProject());
|
runCMake(SessionManager::startupBuildSystem());
|
||||||
});
|
});
|
||||||
|
|
||||||
command = Core::ActionManager::registerAction(m_clearCMakeCacheAction,
|
command = Core::ActionManager::registerAction(m_clearCMakeCacheAction,
|
||||||
@@ -86,7 +86,7 @@ CMakeManager::CMakeManager() :
|
|||||||
command->setAttribute(Core::Command::CA_Hide);
|
command->setAttribute(Core::Command::CA_Hide);
|
||||||
mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_DEPLOY);
|
mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_DEPLOY);
|
||||||
connect(m_clearCMakeCacheAction, &QAction::triggered, [this]() {
|
connect(m_clearCMakeCacheAction, &QAction::triggered, [this]() {
|
||||||
clearCMakeCache(SessionManager::startupProject());
|
clearCMakeCache(SessionManager::startupBuildSystem());
|
||||||
});
|
});
|
||||||
|
|
||||||
command = Core::ActionManager::registerAction(m_runCMakeActionContextMenu,
|
command = Core::ActionManager::registerAction(m_runCMakeActionContextMenu,
|
||||||
@@ -95,7 +95,7 @@ CMakeManager::CMakeManager() :
|
|||||||
mproject->addAction(command, ProjectExplorer::Constants::G_PROJECT_BUILD);
|
mproject->addAction(command, ProjectExplorer::Constants::G_PROJECT_BUILD);
|
||||||
msubproject->addAction(command, ProjectExplorer::Constants::G_PROJECT_BUILD);
|
msubproject->addAction(command, ProjectExplorer::Constants::G_PROJECT_BUILD);
|
||||||
connect(m_runCMakeActionContextMenu, &QAction::triggered, [this]() {
|
connect(m_runCMakeActionContextMenu, &QAction::triggered, [this]() {
|
||||||
runCMake(ProjectTree::currentProject());
|
runCMake(ProjectTree::currentBuildSystem());
|
||||||
});
|
});
|
||||||
|
|
||||||
m_buildFileContextMenu = new QAction(tr("Build"), this);
|
m_buildFileContextMenu = new QAction(tr("Build"), this);
|
||||||
@@ -111,7 +111,7 @@ CMakeManager::CMakeManager() :
|
|||||||
command->setAttribute(Core::Command::CA_Hide);
|
command->setAttribute(Core::Command::CA_Hide);
|
||||||
mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_DEPLOY);
|
mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_DEPLOY);
|
||||||
connect(m_rescanProjectAction, &QAction::triggered, [this]() {
|
connect(m_rescanProjectAction, &QAction::triggered, [this]() {
|
||||||
rescanProject(ProjectTree::currentProject());
|
rescanProject(ProjectTree::currentBuildSystem());
|
||||||
});
|
});
|
||||||
|
|
||||||
m_buildFileAction = new Utils::ParameterAction(tr("Build File"), tr("Build File \"%1\""),
|
m_buildFileAction = new Utils::ParameterAction(tr("Build File"), tr("Build File \"%1\""),
|
||||||
@@ -146,34 +146,29 @@ void CMakeManager::updateCmakeActions()
|
|||||||
enableBuildFileMenus(ProjectTree::currentNode());
|
enableBuildFileMenus(ProjectTree::currentNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeManager::clearCMakeCache(Project *project)
|
void CMakeManager::clearCMakeCache(BuildSystem *buildSystem)
|
||||||
{
|
{
|
||||||
auto cmakeProject = qobject_cast<CMakeProject *>(project);
|
auto cmakeBuildSystem = dynamic_cast<CMakeBuildSystem *>(buildSystem);
|
||||||
if (!cmakeProject || !cmakeProject->activeTarget() || !cmakeProject->activeTarget()->activeBuildConfiguration())
|
QTC_ASSERT(cmakeBuildSystem, return);
|
||||||
return;
|
|
||||||
|
|
||||||
cmakeProject->clearCMakeCache();
|
cmakeBuildSystem->clearCMakeCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeManager::runCMake(Project *project)
|
void CMakeManager::runCMake(BuildSystem *buildSystem)
|
||||||
{
|
{
|
||||||
auto cmakeProject = qobject_cast<CMakeProject *>(project);
|
auto cmakeBuildSystem = dynamic_cast<CMakeBuildSystem *>(buildSystem);
|
||||||
if (!cmakeProject || !cmakeProject->activeTarget() || !cmakeProject->activeTarget()->activeBuildConfiguration())
|
QTC_ASSERT(cmakeBuildSystem, return);
|
||||||
return;
|
|
||||||
|
|
||||||
if (!ProjectExplorerPlugin::saveModifiedFiles())
|
if (ProjectExplorerPlugin::saveModifiedFiles())
|
||||||
return;
|
cmakeBuildSystem->runCMake();
|
||||||
|
|
||||||
cmakeProject->runCMake();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeManager::rescanProject(Project *project)
|
void CMakeManager::rescanProject(BuildSystem *buildSystem)
|
||||||
{
|
{
|
||||||
auto cmakeProject = qobject_cast<CMakeProject *>(project);
|
auto cmakeBuildSystem = dynamic_cast<CMakeBuildSystem *>(buildSystem);
|
||||||
if (!cmakeProject || !cmakeProject->activeTarget() || !cmakeProject->activeTarget()->activeBuildConfiguration())
|
QTC_ASSERT(cmakeBuildSystem, return);
|
||||||
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()
|
void CMakeManager::updateBuildFileAction()
|
||||||
@@ -235,14 +230,15 @@ void CMakeManager::buildFile(Node *node)
|
|||||||
CMakeTargetNode *targetNode = dynamic_cast<CMakeTargetNode *>(fileNode->parentProjectNode());
|
CMakeTargetNode *targetNode = dynamic_cast<CMakeTargetNode *>(fileNode->parentProjectNode());
|
||||||
if (!targetNode)
|
if (!targetNode)
|
||||||
return;
|
return;
|
||||||
auto cmakeProject = static_cast<CMakeProject *>(project);
|
Target *target = project->activeTarget();
|
||||||
Target *target = cmakeProject->activeTarget();
|
QTC_ASSERT(target, return);
|
||||||
const QString generator = CMakeGeneratorKitAspect::generator(target->kit());
|
const QString generator = CMakeGeneratorKitAspect::generator(target->kit());
|
||||||
const QString relativeSource = fileNode->filePath().relativeChildPath(targetNode->filePath()).toString();
|
const QString relativeSource = fileNode->filePath().relativeChildPath(targetNode->filePath()).toString();
|
||||||
const QString objExtension = Utils::HostOsInfo::isWindowsHost() ? QString(".obj") : QString(".o");
|
const QString objExtension = Utils::HostOsInfo::isWindowsHost() ? QString(".obj") : QString(".o");
|
||||||
Utils::FilePath targetBase;
|
Utils::FilePath targetBase;
|
||||||
|
BuildConfiguration *bc = target->activeBuildConfiguration();
|
||||||
|
QTC_ASSERT(bc, return);
|
||||||
if (generator == "Ninja") {
|
if (generator == "Ninja") {
|
||||||
BuildConfiguration *bc = target->activeBuildConfiguration();
|
|
||||||
const Utils::FilePath relativeBuildDir = targetNode->buildDirectory().relativeChildPath(
|
const Utils::FilePath relativeBuildDir = targetNode->buildDirectory().relativeChildPath(
|
||||||
bc->buildDirectory());
|
bc->buildDirectory());
|
||||||
targetBase = relativeBuildDir
|
targetBase = relativeBuildDir
|
||||||
@@ -253,7 +249,9 @@ void CMakeManager::buildFile(Node *node)
|
|||||||
.arg(generator));
|
.arg(generator));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cmakeProject->buildCMakeTarget(targetBase.pathAppended(relativeSource).toString() + objExtension);
|
|
||||||
|
static_cast<CMakeBuildSystem *>(bc->buildSystem())
|
||||||
|
->buildCMakeTarget(targetBase.pathAppended(relativeSource).toString() + objExtension);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeManager::buildFileContextMenu()
|
void CMakeManager::buildFileContextMenu()
|
||||||
|
@@ -45,9 +45,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void updateCmakeActions();
|
void updateCmakeActions();
|
||||||
void clearCMakeCache(ProjectExplorer::Project *project);
|
void clearCMakeCache(ProjectExplorer::BuildSystem *buildSystem);
|
||||||
void runCMake(ProjectExplorer::Project *project);
|
void runCMake(ProjectExplorer::BuildSystem *buildSystem);
|
||||||
void rescanProject(ProjectExplorer::Project *project);
|
void rescanProject(ProjectExplorer::BuildSystem *buildSystem);
|
||||||
void buildFileContextMenu();
|
void buildFileContextMenu();
|
||||||
void buildFile(ProjectExplorer::Node *node = nullptr);
|
void buildFile(ProjectExplorer::Node *node = nullptr);
|
||||||
void updateBuildFileAction();
|
void updateBuildFileAction();
|
||||||
|
@@ -265,7 +265,10 @@ Utils::optional<Utils::FilePath> CMakeTargetNode::visibleAfterAddFileAction() co
|
|||||||
|
|
||||||
void CMakeTargetNode::build()
|
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,
|
void CMakeTargetNode::setTargetInformation(const QList<Utils::FilePath> &artifacts,
|
||||||
|
@@ -47,6 +47,7 @@
|
|||||||
#include <projectexplorer/projectmanager.h>
|
#include <projectexplorer/projectmanager.h>
|
||||||
#include <projectexplorer/projecttree.h>
|
#include <projectexplorer/projecttree.h>
|
||||||
#include <projectexplorer/runcontrol.h>
|
#include <projectexplorer/runcontrol.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
|
||||||
#include <texteditor/snippets/snippetprovider.h>
|
#include <texteditor/snippets/snippetprovider.h>
|
||||||
|
|
||||||
@@ -70,8 +71,6 @@ public:
|
|||||||
ParameterAction::AlwaysEnabled/*handled manually*/
|
ParameterAction::AlwaysEnabled/*handled manually*/
|
||||||
};
|
};
|
||||||
|
|
||||||
QMetaObject::Connection m_actionConnect;
|
|
||||||
|
|
||||||
CMakeSettingsPage settingsPage;
|
CMakeSettingsPage settingsPage;
|
||||||
CMakeSpecificSettingsPage specificSettings{CMakeProjectPlugin::projectTypeSpecificSettings()};
|
CMakeSpecificSettingsPage specificSettings{CMakeProjectPlugin::projectTypeSpecificSettings()};
|
||||||
|
|
||||||
@@ -129,6 +128,13 @@ bool CMakeProjectPlugin::initialize(const QStringList & /*arguments*/, QString *
|
|||||||
connect(ProjectTree::instance(), &ProjectTree::currentNodeChanged,
|
connect(ProjectTree::instance(), &ProjectTree::currentNodeChanged,
|
||||||
this, &CMakeProjectPlugin::updateContextActions);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,24 +146,13 @@ void CMakeProjectPlugin::extensionsInitialized()
|
|||||||
|
|
||||||
void CMakeProjectPlugin::updateContextActions()
|
void CMakeProjectPlugin::updateContextActions()
|
||||||
{
|
{
|
||||||
Project *project = ProjectTree::currentProject();
|
auto targetNode = dynamic_cast<const CMakeTargetNode *>(ProjectTree::currentNode());
|
||||||
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
|
|
||||||
const QString targetDisplayName = targetNode ? targetNode->displayName() : QString();
|
const QString targetDisplayName = targetNode ? targetNode->displayName() : QString();
|
||||||
auto cmProject = dynamic_cast<CMakeProject *>(project);
|
|
||||||
|
|
||||||
// Build Target:
|
// Build Target:
|
||||||
disconnect(d->m_actionConnect);
|
|
||||||
d->buildTargetContextAction.setParameter(targetDisplayName);
|
d->buildTargetContextAction.setParameter(targetDisplayName);
|
||||||
d->buildTargetContextAction.setEnabled(targetNode);
|
d->buildTargetContextAction.setEnabled(targetNode);
|
||||||
d->buildTargetContextAction.setVisible(targetNode);
|
d->buildTargetContextAction.setVisible(targetNode);
|
||||||
if (cmProject && targetNode) {
|
|
||||||
d->m_actionConnect = connect(&d->buildTargetContextAction, &ParameterAction::triggered,
|
|
||||||
cmProject, [cmProject, targetDisplayName]() {
|
|
||||||
cmProject->buildCMakeTarget(targetDisplayName);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // Internal
|
} // Internal
|
||||||
|
@@ -337,9 +337,46 @@ void createTree(std::unique_ptr<ProjectNode> &root,
|
|||||||
|
|
||||||
} // anonymous namespace
|
} // 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))
|
||||||
{
|
{
|
||||||
ProjectExplorer::KitInfo kitInfo(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(project());
|
||||||
QTC_ASSERT(kitInfo.isValid(), return);
|
QTC_ASSERT(kitInfo.isValid(), return);
|
||||||
// Reset toolchains to pick them based on the database entries.
|
// Reset toolchains to pick them based on the database entries.
|
||||||
kitInfo.cToolChain = nullptr;
|
kitInfo.cToolChain = nullptr;
|
||||||
@@ -349,6 +386,7 @@ void CompilationDatabaseProject::buildTreeAndProjectParts()
|
|||||||
QTC_ASSERT(m_parser, return);
|
QTC_ASSERT(m_parser, return);
|
||||||
const DbContents dbContents = m_parser->dbContents();
|
const DbContents dbContents = m_parser->dbContents();
|
||||||
const DbEntry *prevEntry = nullptr;
|
const DbEntry *prevEntry = nullptr;
|
||||||
|
Kit *kit = static_cast<CompilationDatabaseProject *>(project())->kit();
|
||||||
for (const DbEntry &entry : dbContents.entries) {
|
for (const DbEntry &entry : dbContents.entries) {
|
||||||
if (prevEntry && prevEntry->flags == entry.flags) {
|
if (prevEntry && prevEntry->flags == entry.flags) {
|
||||||
rpps.back().files.append(entry.fileName.toString());
|
rpps.back().files.append(entry.fileName.toString());
|
||||||
@@ -358,7 +396,7 @@ void CompilationDatabaseProject::buildTreeAndProjectParts()
|
|||||||
prevEntry = &entry;
|
prevEntry = &entry;
|
||||||
|
|
||||||
RawProjectPart rpp = makeRawProjectPart(projectFilePath(),
|
RawProjectPart rpp = makeRawProjectPart(projectFilePath(),
|
||||||
m_kit.get(),
|
kit,
|
||||||
kitInfo,
|
kitInfo,
|
||||||
entry.workingDir,
|
entry.workingDir,
|
||||||
entry.fileName,
|
entry.fileName,
|
||||||
@@ -381,7 +419,7 @@ void CompilationDatabaseProject::buildTreeAndProjectParts()
|
|||||||
|
|
||||||
|
|
||||||
auto root = std::make_unique<ProjectNode>(projectDirectory());
|
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));
|
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),
|
root->addNode(std::make_unique<FileNode>(Utils::FilePath::fromString(dbContents.extraFileName),
|
||||||
FileType::Project));
|
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();
|
updateDeploymentData();
|
||||||
}
|
}
|
||||||
|
|
||||||
CompilationDatabaseProject::CompilationDatabaseProject(const Utils::FilePath &projectFile)
|
CompilationDatabaseProject::CompilationDatabaseProject(const Utils::FilePath &projectFile)
|
||||||
: Project(Constants::COMPILATIONDATABASEMIMETYPE, 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);
|
setId(Constants::COMPILATIONDATABASEPROJECT_ID);
|
||||||
setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
|
setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
|
||||||
setDisplayName(projectDirectory().fileName());
|
setDisplayName(projectDirectory().fileName());
|
||||||
|
|
||||||
|
setBuildSystemCreator([](Target *t) { return new CompilationDatabaseBuildSystem(t); });
|
||||||
|
|
||||||
m_kit.reset(KitManager::defaultKit()->clone());
|
m_kit.reset(KitManager::defaultKit()->clone());
|
||||||
addTargetForKit(m_kit.get());
|
addTargetForKit(m_kit.get());
|
||||||
|
|
||||||
connect(this, &CompilationDatabaseProject::rootProjectDirectoryChanged,
|
|
||||||
this, [this] {
|
|
||||||
m_projectFileHash.clear();
|
|
||||||
m_parseDelay->start();
|
|
||||||
});
|
|
||||||
|
|
||||||
setExtraProjectFiles(
|
setExtraProjectFiles(
|
||||||
{projectFile.stringAppended(Constants::COMPILATIONDATABASEPROJECT_FILES_SUFFIX)});
|
{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
|
Utils::FilePath CompilationDatabaseProject::rootPathFromSettings() const
|
||||||
@@ -442,26 +463,19 @@ Project::RestoreResult CompilationDatabaseProject::fromMap(const QVariantMap &ma
|
|||||||
QString *errorMessage)
|
QString *errorMessage)
|
||||||
{
|
{
|
||||||
Project::RestoreResult result = Project::fromMap(map, 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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilationDatabaseProject::reparseProject()
|
void CompilationDatabaseBuildSystem::reparseProject()
|
||||||
{
|
{
|
||||||
if (m_parser) {
|
if (m_parser) {
|
||||||
QTC_CHECK(isParsing());
|
QTC_CHECK(isParsing());
|
||||||
m_parser->stop();
|
m_parser->stop();
|
||||||
}
|
}
|
||||||
m_parser = new CompilationDbParser(displayName(),
|
const FilePath rootPath = static_cast<CompilationDatabaseProject *>(project())->rootPathFromSettings();
|
||||||
|
m_parser = new CompilationDbParser(project()->displayName(),
|
||||||
projectFilePath(),
|
projectFilePath(),
|
||||||
rootPathFromSettings(),
|
rootPath,
|
||||||
m_mimeBinaryCache,
|
m_mimeBinaryCache,
|
||||||
guardParsingRun(),
|
guardParsingRun(),
|
||||||
this);
|
this);
|
||||||
@@ -475,17 +489,14 @@ void CompilationDatabaseProject::reparseProject()
|
|||||||
m_parser->start();
|
m_parser->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilationDatabaseProject::updateDeploymentData()
|
void CompilationDatabaseBuildSystem::updateDeploymentData()
|
||||||
{
|
{
|
||||||
Target * const target = activeTarget();
|
|
||||||
if (!target)
|
|
||||||
return;
|
|
||||||
const Utils::FilePath deploymentFilePath = projectDirectory()
|
const Utils::FilePath deploymentFilePath = projectDirectory()
|
||||||
.pathAppended("QtCreatorDeployment.txt");
|
.pathAppended("QtCreatorDeployment.txt");
|
||||||
DeploymentData deploymentData;
|
DeploymentData deploymentData;
|
||||||
deploymentData.addFilesFromDeploymentFile(deploymentFilePath.toString(),
|
deploymentData.addFilesFromDeploymentFile(deploymentFilePath.toString(),
|
||||||
projectDirectory().toString());
|
projectDirectory().toString());
|
||||||
target->setDeploymentData(deploymentData);
|
setDeploymentData(deploymentData);
|
||||||
if (m_deployFileWatcher->files() != QStringList(deploymentFilePath.toString())) {
|
if (m_deployFileWatcher->files() != QStringList(deploymentFilePath.toString())) {
|
||||||
m_deployFileWatcher->removeFiles(m_deployFileWatcher->files());
|
m_deployFileWatcher->removeFiles(m_deployFileWatcher->files());
|
||||||
m_deployFileWatcher->addFile(deploymentFilePath.toString(),
|
m_deployFileWatcher->addFile(deploymentFilePath.toString(),
|
||||||
@@ -493,12 +504,6 @@ void CompilationDatabaseProject::updateDeploymentData()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CompilationDatabaseProject::~CompilationDatabaseProject()
|
|
||||||
{
|
|
||||||
m_parserWatcher.cancel();
|
|
||||||
m_parserWatcher.waitForFinished();
|
|
||||||
}
|
|
||||||
|
|
||||||
static TextEditor::TextDocument *createCompilationDatabaseDocument()
|
static TextEditor::TextDocument *createCompilationDatabaseDocument()
|
||||||
{
|
{
|
||||||
auto doc = new TextEditor::TextDocument;
|
auto doc = new TextEditor::TextDocument;
|
||||||
|
@@ -28,8 +28,11 @@
|
|||||||
#include "compilationdatabaseutils.h"
|
#include "compilationdatabaseutils.h"
|
||||||
|
|
||||||
#include <projectexplorer/buildconfiguration.h>
|
#include <projectexplorer/buildconfiguration.h>
|
||||||
|
#include <projectexplorer/buildsystem.h>
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
|
|
||||||
#include <texteditor/texteditor.h>
|
#include <texteditor/texteditor.h>
|
||||||
|
|
||||||
#include <utils/filesystemwatcher.h>
|
#include <utils/filesystemwatcher.h>
|
||||||
|
|
||||||
#include <QFutureWatcher>
|
#include <QFutureWatcher>
|
||||||
@@ -52,20 +55,31 @@ class CompilationDatabaseProject : public ProjectExplorer::Project
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CompilationDatabaseProject(const Utils::FilePath &filename);
|
explicit CompilationDatabaseProject(const Utils::FilePath &filename);
|
||||||
~CompilationDatabaseProject() override;
|
|
||||||
bool needsConfiguration() const override { return false; }
|
bool needsConfiguration() const override { return false; }
|
||||||
|
|
||||||
|
Utils::FilePath rootPathFromSettings() const;
|
||||||
|
ProjectExplorer::Kit *kit() const { return m_kit.get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override;
|
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 reparseProject();
|
||||||
void updateDeploymentData();
|
void updateDeploymentData();
|
||||||
void buildTreeAndProjectParts();
|
void buildTreeAndProjectParts();
|
||||||
Utils::FilePath rootPathFromSettings() const;
|
|
||||||
|
|
||||||
QFutureWatcher<void> m_parserWatcher;
|
QFutureWatcher<void> m_parserWatcher;
|
||||||
std::unique_ptr<CppTools::CppProjectUpdater> m_cppCodeModelUpdater;
|
std::unique_ptr<CppTools::CppProjectUpdater> m_cppCodeModelUpdater;
|
||||||
std::unique_ptr<ProjectExplorer::Kit> m_kit;
|
|
||||||
MimeBinaryCache m_mimeBinaryCache;
|
MimeBinaryCache m_mimeBinaryCache;
|
||||||
QByteArray m_projectFileHash;
|
QByteArray m_projectFileHash;
|
||||||
QTimer * const m_parseDelay;
|
QTimer * const m_parseDelay;
|
||||||
|
@@ -48,7 +48,7 @@ CompilationDbParser::CompilationDbParser(const QString &projectName,
|
|||||||
const FilePath &projectPath,
|
const FilePath &projectPath,
|
||||||
const FilePath &rootPath,
|
const FilePath &rootPath,
|
||||||
MimeBinaryCache &mimeBinaryCache,
|
MimeBinaryCache &mimeBinaryCache,
|
||||||
ProjectExplorer::Project::ParseGuard &&guard,
|
BuildSystem::ParseGuard &&guard,
|
||||||
QObject *parent)
|
QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_projectName(projectName)
|
, m_projectName(projectName)
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include "compilationdatabaseutils.h"
|
#include "compilationdatabaseutils.h"
|
||||||
|
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/buildsystem.h>
|
||||||
|
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ public:
|
|||||||
const Utils::FilePath &projectPath,
|
const Utils::FilePath &projectPath,
|
||||||
const Utils::FilePath &rootPath,
|
const Utils::FilePath &rootPath,
|
||||||
MimeBinaryCache &mimeBinaryCache,
|
MimeBinaryCache &mimeBinaryCache,
|
||||||
ProjectExplorer::Project::ParseGuard &&guard,
|
ProjectExplorer::BuildSystem::ParseGuard &&guard,
|
||||||
QObject *parent = nullptr);
|
QObject *parent = nullptr);
|
||||||
|
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ private:
|
|||||||
QByteArray m_projectFileContents;
|
QByteArray m_projectFileContents;
|
||||||
QByteArray m_projectFileHash;
|
QByteArray m_projectFileHash;
|
||||||
|
|
||||||
ProjectExplorer::Project::ParseGuard m_guard;
|
ProjectExplorer::BuildSystem::ParseGuard m_guard;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -27,15 +27,19 @@
|
|||||||
|
|
||||||
#include <cpptools/cppmodelmanager.h>
|
#include <cpptools/cppmodelmanager.h>
|
||||||
|
|
||||||
|
#include <projectexplorer/buildsystem.h>
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
#include <projectexplorer/projectexplorer.h>
|
#include <projectexplorer/projectexplorer.h>
|
||||||
#include <projectexplorer/session.h>
|
#include <projectexplorer/session.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
// Debug helpers for code model. @todo: Move to some CppTools library?
|
// Debug helpers for code model. @todo: Move to some CppTools library?
|
||||||
|
|
||||||
|
using namespace ProjectExplorer;
|
||||||
|
|
||||||
typedef QMap<QString, QStringList> DependencyMap;
|
typedef QMap<QString, QStringList> DependencyMap;
|
||||||
typedef CPlusPlus::Document::Ptr DocumentPtr;
|
typedef CPlusPlus::Document::Ptr DocumentPtr;
|
||||||
typedef QList<CPlusPlus::Symbol *> SymbolList;
|
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.
|
// Find the generated "ui_form.h" header of the form via project.
|
||||||
static QString generatedHeaderOf(const QString &uiFileName)
|
static QString generatedHeaderOf(const QString &uiFileName)
|
||||||
{
|
{
|
||||||
if (const ProjectExplorer::Project *uiProject =
|
if (const Project *uiProject =
|
||||||
ProjectExplorer::SessionManager::projectForFile(Utils::FilePath::fromString(uiFileName))) {
|
SessionManager::projectForFile(Utils::FilePath::fromString(uiFileName))) {
|
||||||
QStringList files = uiProject->filesGeneratedFrom(uiFileName);
|
if (Target *t = uiProject->activeTarget()) {
|
||||||
if (!files.isEmpty()) // There should be at most one header generated from a .ui
|
if (BuildSystem *bs = t->buildSystem()) {
|
||||||
return files.front();
|
QStringList files = bs->filesGeneratedFrom(uiFileName);
|
||||||
|
if (!files.isEmpty()) // There should be at most one header generated from a .ui
|
||||||
|
return files.front();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
@@ -120,9 +120,11 @@ private:
|
|||||||
class GenericBuildSystem : public BuildSystem
|
class GenericBuildSystem : public BuildSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit GenericBuildSystem(Project *project);
|
explicit GenericBuildSystem(Target *target);
|
||||||
~GenericBuildSystem();
|
~GenericBuildSystem();
|
||||||
|
|
||||||
|
void triggerParsing() final;
|
||||||
|
|
||||||
bool supportsAction(Node *, ProjectAction action, const Node *) const final
|
bool supportsAction(Node *, ProjectAction action, const Node *) const final
|
||||||
{
|
{
|
||||||
return action == AddNewFile
|
return action == AddNewFile
|
||||||
@@ -136,8 +138,6 @@ public:
|
|||||||
bool renameFile(Node *, const QString &filePath, const QString &newFilePath) final;
|
bool renameFile(Node *, const QString &filePath, const QString &newFilePath) final;
|
||||||
bool addFiles(Node *, const QStringList &filePaths, QStringList *) 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); }
|
FilePath filesFilePath() const { return ::FilePath::fromString(m_filesFileName); }
|
||||||
|
|
||||||
void refresh(RefreshOptions options);
|
void refresh(RefreshOptions options);
|
||||||
@@ -172,7 +172,9 @@ private:
|
|||||||
|
|
||||||
CppTools::CppProjectUpdaterInterface *m_cppCodeModelUpdater = nullptr;
|
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);
|
setId(Constants::GENERICPROJECT_ID);
|
||||||
setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
|
setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
|
||||||
setDisplayName(fileName.toFileInfo().completeBaseName());
|
setDisplayName(fileName.toFileInfo().completeBaseName());
|
||||||
setBuildSystemCreator([](Project *p) { return new GenericBuildSystem(p); });
|
setBuildSystemCreator([](Target *t) { return new GenericBuildSystem(t); });
|
||||||
}
|
}
|
||||||
|
|
||||||
GenericBuildSystem::GenericBuildSystem(Project *project)
|
GenericBuildSystem::GenericBuildSystem(Target *target)
|
||||||
: BuildSystem(project)
|
: BuildSystem(target)
|
||||||
{
|
{
|
||||||
QObject *projectUpdaterFactory = ExtensionSystem::PluginManager::getObjectByName(
|
QObject *projectUpdaterFactory = ExtensionSystem::PluginManager::getObjectByName(
|
||||||
"CppProjectUpdaterFactory");
|
"CppProjectUpdaterFactory");
|
||||||
@@ -211,7 +213,7 @@ GenericBuildSystem::GenericBuildSystem(Project *project)
|
|||||||
QTC_CHECK(successFullyCreatedProjectUpdater);
|
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"))
|
if (p.endsWith(".files"))
|
||||||
refresh(Files);
|
refresh(Files);
|
||||||
else if (p.endsWith(".includes") || p.endsWith(".config") || p.endsWith(".cxxflags")
|
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));
|
QTC_CHECK(writeFile(m_cflagsFileName, Constants::GENERICPROJECT_CFLAGS_FILE_TEMPLATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
project->setExtraProjectFiles({FilePath::fromString(m_filesFileName),
|
project()->setExtraProjectFiles({FilePath::fromString(m_filesFileName),
|
||||||
FilePath::fromString(m_includesFileName),
|
FilePath::fromString(m_includesFileName),
|
||||||
FilePath::fromString(m_configFileName),
|
FilePath::fromString(m_configFileName),
|
||||||
FilePath::fromString(m_cxxflagsFileName),
|
FilePath::fromString(m_cxxflagsFileName),
|
||||||
FilePath::fromString(m_cflagsFileName)});
|
FilePath::fromString(m_cflagsFileName)});
|
||||||
|
|
||||||
connect(m_deployFileWatcher, &FileSystemWatcher::fileChanged,
|
connect(&m_deployFileWatcher, &FileSystemWatcher::fileChanged,
|
||||||
this, &GenericBuildSystem::updateDeploymentData);
|
this, &GenericBuildSystem::updateDeploymentData);
|
||||||
|
|
||||||
connect(project, &Project::activeTargetChanged, this, [this] { refresh(Everything); });
|
connect(target, &Target::activeBuildConfigurationChanged, this, [this] { refresh(Everything); });
|
||||||
|
|
||||||
connect(project, &Project::activeBuildConfigurationChanged, this, [this] { refresh(Everything); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GenericBuildSystem::~GenericBuildSystem()
|
GenericBuildSystem::~GenericBuildSystem()
|
||||||
@@ -261,6 +261,12 @@ GenericBuildSystem::~GenericBuildSystem()
|
|||||||
delete m_cppCodeModelUpdater;
|
delete m_cppCodeModelUpdater;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GenericBuildSystem::triggerParsing()
|
||||||
|
{
|
||||||
|
m_guard = guardParsingRun();
|
||||||
|
refresh(Everything);
|
||||||
|
}
|
||||||
|
|
||||||
static QStringList readLines(const QString &absoluteFileName)
|
static QStringList readLines(const QString &absoluteFileName)
|
||||||
{
|
{
|
||||||
QStringList lines;
|
QStringList lines;
|
||||||
@@ -455,7 +461,7 @@ FilePath GenericBuildSystem::findCommonSourceRoot()
|
|||||||
|
|
||||||
void GenericBuildSystem::refresh(RefreshOptions options)
|
void GenericBuildSystem::refresh(RefreshOptions options)
|
||||||
{
|
{
|
||||||
Project::ParseGuard guard = project()->guardParsingRun();
|
ParseGuard guard = guardParsingRun();
|
||||||
parse(options);
|
parse(options);
|
||||||
|
|
||||||
if (options & Files) {
|
if (options & Files) {
|
||||||
@@ -504,9 +510,7 @@ void GenericBuildSystem::refresh(RefreshOptions options)
|
|||||||
QStringList GenericBuildSystem::processEntries(const QStringList &paths,
|
QStringList GenericBuildSystem::processEntries(const QStringList &paths,
|
||||||
QHash<QString, QString> *map) const
|
QHash<QString, QString> *map) const
|
||||||
{
|
{
|
||||||
Target *target = project()->activeTarget();
|
const BuildConfiguration *const buildConfig = target()->activeBuildConfiguration();
|
||||||
const BuildConfiguration *const buildConfig = target ? target->activeBuildConfiguration()
|
|
||||||
: nullptr;
|
|
||||||
|
|
||||||
const Utils::Environment buildEnv = buildConfig ? buildConfig->environment()
|
const Utils::Environment buildEnv = buildConfig ? buildConfig->environment()
|
||||||
: Utils::Environment::systemEnvironment();
|
: Utils::Environment::systemEnvironment();
|
||||||
@@ -514,8 +518,8 @@ QStringList GenericBuildSystem::processEntries(const QStringList &paths,
|
|||||||
const Utils::MacroExpander *expander = project()->macroExpander();
|
const Utils::MacroExpander *expander = project()->macroExpander();
|
||||||
if (buildConfig)
|
if (buildConfig)
|
||||||
expander = buildConfig->macroExpander();
|
expander = buildConfig->macroExpander();
|
||||||
else if (target)
|
else
|
||||||
expander = target->macroExpander();
|
expander = target()->macroExpander();
|
||||||
|
|
||||||
const QDir projectDir(projectDirectory().toString());
|
const QDir projectDir(projectDirectory().toString());
|
||||||
|
|
||||||
@@ -560,7 +564,7 @@ void GenericBuildSystem::refreshCppCodeModel()
|
|||||||
rpp.setFlagsForC({nullptr, m_cflags});
|
rpp.setFlagsForC({nullptr, m_cflags});
|
||||||
rpp.setFiles(m_files);
|
rpp.setFiles(m_files);
|
||||||
|
|
||||||
m_cppCodeModelUpdater->update({project(), kitInfo, project()->activeParseEnvironment(), {rpp}});
|
m_cppCodeModelUpdater->update({project(), kitInfo, activeParseEnvironment(), {rpp}});
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericBuildSystem::updateDeploymentData()
|
void GenericBuildSystem::updateDeploymentData()
|
||||||
@@ -581,11 +585,11 @@ void GenericBuildSystem::updateDeploymentData()
|
|||||||
DeploymentData deploymentData;
|
DeploymentData deploymentData;
|
||||||
deploymentData.addFilesFromDeploymentFile(deploymentFilePath.toString(),
|
deploymentData.addFilesFromDeploymentFile(deploymentFilePath.toString(),
|
||||||
projectDirectory().toString());
|
projectDirectory().toString());
|
||||||
project()->activeTarget()->setDeploymentData(deploymentData);
|
setDeploymentData(deploymentData);
|
||||||
if (m_deployFileWatcher->files() != QStringList(deploymentFilePath.toString())) {
|
if (m_deployFileWatcher.files() != QStringList(deploymentFilePath.toString())) {
|
||||||
m_deployFileWatcher->removeFiles(m_deployFileWatcher->files());
|
m_deployFileWatcher.removeFiles(m_deployFileWatcher.files());
|
||||||
m_deployFileWatcher->addFile(deploymentFilePath.toString(),
|
m_deployFileWatcher.addFile(deploymentFilePath.toString(),
|
||||||
FileSystemWatcher::WatchModifiedDate);
|
FileSystemWatcher::WatchModifiedDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -622,7 +626,9 @@ Project::RestoreResult GenericProject::fromMap(const QVariantMap &map, QString *
|
|||||||
t->addRunConfiguration(new CustomExecutableRunConfiguration(t));
|
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;
|
return RestoreResult::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,7 +643,10 @@ bool GenericProjectFile::reload(QString *errorString, IDocument::ReloadFlag flag
|
|||||||
Q_UNUSED(flag)
|
Q_UNUSED(flag)
|
||||||
if (type == TypePermissions)
|
if (type == TypePermissions)
|
||||||
return true;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -646,14 +655,18 @@ void GenericProject::editFilesTriggered()
|
|||||||
SelectableFilesDialogEditFiles sfd(projectDirectory(),
|
SelectableFilesDialogEditFiles sfd(projectDirectory(),
|
||||||
files(Project::AllFiles),
|
files(Project::AllFiles),
|
||||||
ICore::mainWindow());
|
ICore::mainWindow());
|
||||||
if (sfd.exec() == QDialog::Accepted)
|
if (sfd.exec() == QDialog::Accepted) {
|
||||||
static_cast<GenericBuildSystem *>(buildSystem())
|
if (Target *t = activeTarget()) {
|
||||||
->setFiles(transform(sfd.selectedFiles(), &FilePath::toString));
|
auto bs = static_cast<GenericBuildSystem *>(t->buildSystem());
|
||||||
|
bs->setFiles(transform(sfd.selectedFiles(), &FilePath::toString));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericProject::removeFilesTriggered(const QStringList &filesToRemove)
|
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
|
} // namespace Internal
|
||||||
|
@@ -139,19 +139,17 @@ void IosRunConfiguration::updateDisplayNames()
|
|||||||
aspect<ExecutableAspect>()->setExecutable(localExecutable());
|
aspect<ExecutableAspect>()->setExecutable(localExecutable());
|
||||||
}
|
}
|
||||||
|
|
||||||
void IosRunConfiguration::updateEnabledState()
|
bool IosRunConfiguration::isEnabled() const
|
||||||
{
|
{
|
||||||
Core::Id devType = DeviceTypeKitAspect::deviceTypeId(target()->kit());
|
Core::Id devType = DeviceTypeKitAspect::deviceTypeId(target()->kit());
|
||||||
if (devType != Constants::IOS_DEVICE_TYPE && devType != Constants::IOS_SIMULATOR_TYPE) {
|
if (devType != Constants::IOS_DEVICE_TYPE && devType != Constants::IOS_SIMULATOR_TYPE)
|
||||||
setEnabled(false);
|
return false;
|
||||||
return;
|
|
||||||
}
|
|
||||||
IDevice::ConstPtr dev = DeviceKitAspect::device(target()->kit());
|
IDevice::ConstPtr dev = DeviceKitAspect::device(target()->kit());
|
||||||
if (dev.isNull() || dev->deviceState() != IDevice::DeviceReadyToUse) {
|
if (dev.isNull() || dev->deviceState() != IDevice::DeviceReadyToUse)
|
||||||
setEnabled(false);
|
return false;
|
||||||
return;
|
|
||||||
}
|
return true;
|
||||||
return RunConfiguration::updateEnabledState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString IosRunConfiguration::applicationName() const
|
QString IosRunConfiguration::applicationName() const
|
||||||
|
@@ -55,7 +55,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
friend class IosDeviceTypeAspect;
|
friend class IosDeviceTypeAspect;
|
||||||
void updateDisplayNames();
|
void updateDisplayNames();
|
||||||
void updateEnabledState() final;
|
bool isEnabled() const final;
|
||||||
|
|
||||||
IosDeviceTypeAspect *m_deviceTypeAspect = nullptr;
|
IosDeviceTypeAspect *m_deviceTypeAspect = nullptr;
|
||||||
};
|
};
|
||||||
|
@@ -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_TYPEID[] = "Nim.NimToolChain";
|
||||||
const char C_NIMTOOLCHAIN_COMPILER_COMMAND_KEY[] = "Nim.NimToolChain.CompilerCommand";
|
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
|
// NimProject
|
||||||
const char C_NIMPROJECT_EXCLUDEDFILES[] = "Nim.NimProjectExcludedFiles";
|
const char C_NIMPROJECT_EXCLUDEDFILES[] = "Nim.NimProjectExcludedFiles";
|
||||||
|
|
||||||
|
@@ -24,9 +24,11 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "nimblebuildconfiguration.h"
|
#include "nimblebuildconfiguration.h"
|
||||||
|
|
||||||
#include "nimconstants.h"
|
#include "nimconstants.h"
|
||||||
#include "nimblebuildstep.h"
|
#include "nimblebuildstep.h"
|
||||||
#include "nimbleproject.h"
|
#include "nimbleproject.h"
|
||||||
|
#include "nimblebuildsystem.h"
|
||||||
|
|
||||||
#include <projectexplorer/buildinfo.h>
|
#include <projectexplorer/buildinfo.h>
|
||||||
#include <projectexplorer/buildstep.h>
|
#include <projectexplorer/buildstep.h>
|
||||||
@@ -52,10 +54,8 @@ NimbleBuildConfiguration::NimbleBuildConfiguration(Target *target, Core::Id id)
|
|||||||
setConfigWidgetHasFrame(true);
|
setConfigWidgetHasFrame(true);
|
||||||
setBuildDirectorySettingsKey("Nim.NimbleBuildConfiguration.BuildDirectory");
|
setBuildDirectorySettingsKey("Nim.NimbleBuildConfiguration.BuildDirectory");
|
||||||
|
|
||||||
m_nimbleProject = dynamic_cast<NimbleProject*>(project());
|
m_nimbleBuildSystem = dynamic_cast<NimbleBuildSystem *>(buildSystem());
|
||||||
QTC_ASSERT(m_nimbleProject, return);
|
QTC_ASSERT(m_nimbleBuildSystem, return);
|
||||||
QObject::connect(m_nimbleProject, &NimbleProject::metadataChanged, this, &NimbleBuildConfiguration::updateApplicationTargets);
|
|
||||||
updateApplicationTargets();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildConfiguration::BuildType NimbleBuildConfiguration::buildType() const
|
BuildConfiguration::BuildType NimbleBuildConfiguration::buildType() const
|
||||||
@@ -72,35 +72,13 @@ void NimbleBuildConfiguration::initialize()
|
|||||||
setBuildDirectory(project()->projectDirectory());
|
setBuildDirectory(project()->projectDirectory());
|
||||||
|
|
||||||
// Don't add a nimble build step when the package has no binaries (i.e a library package)
|
// 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);
|
BuildStepList *buildSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
|
||||||
buildSteps->appendStep(new NimbleBuildStep(buildSteps));
|
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)
|
bool NimbleBuildConfiguration::fromMap(const QVariantMap &map)
|
||||||
{
|
{
|
||||||
m_buildType = static_cast<BuildType>(map[Constants::C_NIMBLEBUILDCONFIGURATION_BUILDTYPE].toInt());
|
m_buildType = static_cast<BuildType>(map[Constants::C_NIMBLEBUILDCONFIGURATION_BUILDTYPE].toInt());
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
namespace Nim {
|
namespace Nim {
|
||||||
|
|
||||||
class NimbleProject;
|
class NimbleBuildSystem;
|
||||||
|
|
||||||
class NimbleBuildConfiguration : public ProjectExplorer::BuildConfiguration
|
class NimbleBuildConfiguration : public ProjectExplorer::BuildConfiguration
|
||||||
{
|
{
|
||||||
@@ -49,10 +49,8 @@ class NimbleBuildConfiguration : public ProjectExplorer::BuildConfiguration
|
|||||||
protected:
|
protected:
|
||||||
void initialize() override;
|
void initialize() override;
|
||||||
|
|
||||||
void updateApplicationTargets();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NimbleProject *m_nimbleProject = nullptr;
|
NimbleBuildSystem *m_nimbleBuildSystem = nullptr;
|
||||||
BuildType m_buildType;
|
BuildType m_buildType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -26,6 +26,8 @@
|
|||||||
#include "nimblebuildsystem.h"
|
#include "nimblebuildsystem.h"
|
||||||
#include "nimbleproject.h"
|
#include "nimbleproject.h"
|
||||||
|
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
@@ -38,6 +40,9 @@ using namespace Utils;
|
|||||||
|
|
||||||
namespace {
|
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)
|
std::vector<NimbleTask> parseTasks(const QString &nimblePath, const QString &workingDirectory)
|
||||||
{
|
{
|
||||||
QProcess process;
|
QProcess process;
|
||||||
@@ -102,28 +107,25 @@ NimbleMetadata parseMetadata(const QString &nimblePath, const QString &workingDi
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NimbleBuildSystem::NimbleBuildSystem(Project *project)
|
NimbleBuildSystem::NimbleBuildSystem(Target *target)
|
||||||
: NimBuildSystem(project)
|
: NimBuildSystem(target)
|
||||||
{
|
{
|
||||||
// Not called in parseProject due to nimble behavior to create temporary
|
// Not called in parseProject due to nimble behavior to create temporary
|
||||||
// files in project directory. This creation in turn stimulate the fs watcher
|
// 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).
|
// that in turn causes project parsing (thus a loop if invoke in parseProject).
|
||||||
// For this reason we call this function manually during project creation
|
// For this reason we call this function manually during project creation
|
||||||
// See https://github.com/nim-lang/nimble/issues/720
|
// See https://github.com/nim-lang/nimble/issues/720
|
||||||
m_directoryWatcher.addFile(this->project()->projectFilePath().toString(),
|
m_directoryWatcher.addFile(projectFilePath().toString(), FileSystemWatcher::WatchModifiedDate);
|
||||||
FileSystemWatcher::WatchModifiedDate);
|
|
||||||
connect(&m_directoryWatcher, &FileSystemWatcher::fileChanged, this, [this](const QString &path) {
|
connect(&m_directoryWatcher, &FileSystemWatcher::fileChanged, this, [this](const QString &path) {
|
||||||
if (path == this->project()->projectFilePath().toString()) {
|
if (path == project()->projectFilePath().toString()) {
|
||||||
updateProject();
|
updateProject();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
updateProject();
|
updateProject();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NimbleBuildSystem::parseProject(BuildSystem::ParsingContext &&ctx)
|
|
||||||
{
|
|
||||||
NimBuildSystem::parseProject(std::move(ctx));
|
|
||||||
}
|
|
||||||
|
|
||||||
void NimbleBuildSystem::updateProject()
|
void NimbleBuildSystem::updateProject()
|
||||||
{
|
{
|
||||||
@@ -133,14 +135,82 @@ void NimbleBuildSystem::updateProject()
|
|||||||
|
|
||||||
void NimbleBuildSystem::updateProjectTasks()
|
void NimbleBuildSystem::updateProjectTasks()
|
||||||
{
|
{
|
||||||
auto prj = dynamic_cast<NimbleProject*>(project());
|
setTasks(parseTasks(QStandardPaths::findExecutable("nimble"), projectDirectory().toString()));
|
||||||
QTC_ASSERT(prj, return);
|
|
||||||
prj->setTasks(parseTasks(QStandardPaths::findExecutable("nimble"), project()->projectDirectory().toString()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NimbleBuildSystem::updateProjectMetaData()
|
void NimbleBuildSystem::updateProjectMetaData()
|
||||||
{
|
{
|
||||||
auto prj = dynamic_cast<NimbleProject*>(project());
|
setMetadata(parseMetadata(QStandardPaths::findExecutable("nimble"), projectDirectory().toString()));
|
||||||
QTC_ASSERT(prj, return);
|
}
|
||||||
prj->setMetadata(parseMetadata(QStandardPaths::findExecutable("nimble"), project()->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]});
|
||||||
}
|
}
|
||||||
|
@@ -29,19 +29,55 @@
|
|||||||
|
|
||||||
namespace Nim {
|
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
|
class NimbleBuildSystem : public NimBuildSystem
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NimbleBuildSystem(ProjectExplorer::Project *project);
|
NimbleBuildSystem(ProjectExplorer::Target *target);
|
||||||
|
|
||||||
protected:
|
std::vector<NimbleTask> tasks() const;
|
||||||
void parseProject(ParsingContext &&ctx) override;
|
|
||||||
|
NimbleMetadata metadata() const;
|
||||||
|
|
||||||
|
void setTasks(std::vector<NimbleTask> tasks);
|
||||||
|
void setMetadata(NimbleMetadata metadata);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void tasksChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void loadSettings() override;
|
||||||
|
void saveSettings() override;
|
||||||
|
|
||||||
void updateProject();
|
void updateProject();
|
||||||
void updateProjectTasks();
|
void updateProjectTasks();
|
||||||
void updateProjectMetaData();
|
void updateProjectMetaData();
|
||||||
|
void updateApplicationTargets();
|
||||||
|
|
||||||
|
NimbleMetadata m_metadata;
|
||||||
|
std::vector<NimbleTask> m_tasks;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -41,70 +41,7 @@ NimbleProject::NimbleProject(const Utils::FilePath &fileName)
|
|||||||
setDisplayName(fileName.toFileInfo().completeBaseName());
|
setDisplayName(fileName.toFileInfo().completeBaseName());
|
||||||
// ensure debugging is enabled (Nim plugin translates nim code to C code)
|
// ensure debugging is enabled (Nim plugin translates nim code to C code)
|
||||||
setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
|
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);
|
|
||||||
}
|
|
||||||
|
@@ -25,64 +25,17 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <projectexplorer/buildsystem.h>
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
|
|
||||||
namespace Nim {
|
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
|
class NimbleProject : public ProjectExplorer::Project
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NimbleProject(const Utils::FilePath &filename);
|
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -43,20 +43,15 @@ using namespace ProjectExplorer;
|
|||||||
NimbleRunConfiguration::NimbleRunConfiguration(ProjectExplorer::Target *target, Core::Id id)
|
NimbleRunConfiguration::NimbleRunConfiguration(ProjectExplorer::Target *target, Core::Id id)
|
||||||
: RunConfiguration(target, id)
|
: RunConfiguration(target, id)
|
||||||
{
|
{
|
||||||
auto project = dynamic_cast<NimbleProject*>(target->project());
|
|
||||||
QTC_ASSERT(project, return);
|
|
||||||
|
|
||||||
addAspect<LocalEnvironmentAspect>(target);
|
addAspect<LocalEnvironmentAspect>(target);
|
||||||
addAspect<ExecutableAspect>();
|
addAspect<ExecutableAspect>();
|
||||||
addAspect<ArgumentsAspect>();
|
addAspect<ArgumentsAspect>();
|
||||||
addAspect<WorkingDirectoryAspect>();
|
addAspect<WorkingDirectoryAspect>();
|
||||||
addAspect<TerminalAspect>();
|
addAspect<TerminalAspect>();
|
||||||
|
|
||||||
connect(project, &Project::parsingFinished,
|
connect(target, &Target::parsingFinished,
|
||||||
this, &NimbleRunConfiguration::updateTargetInformation);
|
this, &NimbleRunConfiguration::updateTargetInformation);
|
||||||
connect(project, &NimbleProject::metadataChanged,
|
connect(target, &Target::targetPropertiesChanged,
|
||||||
this, &NimbleRunConfiguration::updateTargetInformation);
|
|
||||||
connect(project, &NimbleProject::tasksChanged,
|
|
||||||
this, &NimbleRunConfiguration::updateTargetInformation);
|
this, &NimbleRunConfiguration::updateTargetInformation);
|
||||||
|
|
||||||
updateTargetInformation();
|
updateTargetInformation();
|
||||||
@@ -85,14 +80,6 @@ QString NimbleRunConfiguration::disabledReason() const
|
|||||||
return RunConfiguration::disabledReason();
|
return RunConfiguration::disabledReason();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NimbleRunConfiguration::updateEnabledState()
|
|
||||||
{
|
|
||||||
if (!isBuildTargetValid())
|
|
||||||
setEnabled(false);
|
|
||||||
else
|
|
||||||
RunConfiguration::updateEnabledState();
|
|
||||||
}
|
|
||||||
|
|
||||||
NimbleRunConfigurationFactory::NimbleRunConfigurationFactory()
|
NimbleRunConfigurationFactory::NimbleRunConfigurationFactory()
|
||||||
: RunConfigurationFactory()
|
: RunConfigurationFactory()
|
||||||
{
|
{
|
||||||
|
@@ -38,9 +38,6 @@ public:
|
|||||||
|
|
||||||
QString disabledReason() const override;
|
QString disabledReason() const override;
|
||||||
|
|
||||||
protected:
|
|
||||||
void updateEnabledState() override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateTargetInformation();
|
void updateTargetInformation();
|
||||||
|
|
||||||
|
@@ -104,10 +104,10 @@ bool NimbleTaskStep::validate()
|
|||||||
if (m_taskName.isEmpty())
|
if (m_taskName.isEmpty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
auto nimbleProject = dynamic_cast<NimbleProject*>(project());
|
auto nimbleBuildSystem = dynamic_cast<NimbleBuildSystem*>(buildSystem());
|
||||||
QTC_ASSERT(nimbleProject, return false);
|
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,
|
emit addTask(Task(Task::Error,
|
||||||
tr("Nimble task %1 not found").arg(m_taskName),
|
tr("Nimble task %1 not found").arg(m_taskName),
|
||||||
Utils::FilePath(), -1,
|
Utils::FilePath(), -1,
|
||||||
|
@@ -40,14 +40,14 @@ NimbleTaskStepWidget::NimbleTaskStepWidget(NimbleTaskStep *bs)
|
|||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
auto project = dynamic_cast<NimbleProject*>(bs->project());
|
auto buildSystem = dynamic_cast<NimbleBuildSystem *>(bs->buildSystem());
|
||||||
QTC_ASSERT(project, return);
|
QTC_ASSERT(buildSystem, return);
|
||||||
|
|
||||||
ui->taskList->setModel(&m_tasks);
|
ui->taskList->setModel(&m_tasks);
|
||||||
QObject::connect(&m_tasks, &QAbstractItemModel::dataChanged, this, &NimbleTaskStepWidget::onDataChanged);
|
QObject::connect(&m_tasks, &QAbstractItemModel::dataChanged, this, &NimbleTaskStepWidget::onDataChanged);
|
||||||
|
|
||||||
updateTaskList(project->tasks());
|
updateTaskList();
|
||||||
QObject::connect(project, &NimbleProject::tasksChanged, this, &NimbleTaskStepWidget::updateTaskList);
|
QObject::connect(buildSystem, &NimbleBuildSystem::tasksChanged, this, &NimbleTaskStepWidget::updateTaskList);
|
||||||
|
|
||||||
selectTask(bs->taskName());
|
selectTask(bs->taskName());
|
||||||
QObject::connect(bs, &NimbleTaskStep::taskNameChanged, this, &NimbleTaskStepWidget::selectTask);
|
QObject::connect(bs, &NimbleTaskStep::taskNameChanged, this, &NimbleTaskStepWidget::selectTask);
|
||||||
@@ -73,8 +73,12 @@ NimbleTaskStepWidget::~NimbleTaskStepWidget()
|
|||||||
delete ui;
|
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;
|
QSet<QString> newTasks;
|
||||||
for (const NimbleTask &t : tasks)
|
for (const NimbleTask &t : tasks)
|
||||||
newTasks.insert(t.name);
|
newTasks.insert(t.name);
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include <projectexplorer/buildstep.h>
|
#include <projectexplorer/buildstep.h>
|
||||||
|
|
||||||
#include <nim/project/nimbleproject.h>
|
#include <nim/project/nimbleproject.h>
|
||||||
|
#include <nim/project/nimblebuildsystem.h>
|
||||||
|
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
|
|
||||||
@@ -50,7 +51,7 @@ signals:
|
|||||||
void selectedTaskChanged(const QString &name);
|
void selectedTaskChanged(const QString &name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateTaskList(const std::vector<NimbleTask> &tasks);
|
void updateTaskList();
|
||||||
|
|
||||||
void selectTask(const QString &name);
|
void selectTask(const QString &name);
|
||||||
|
|
||||||
|
@@ -78,7 +78,7 @@ void NimBuildConfiguration::initialize()
|
|||||||
{
|
{
|
||||||
BuildConfiguration::initialize();
|
BuildConfiguration::initialize();
|
||||||
|
|
||||||
auto bs = qobject_cast<NimBuildSystem *>(project()->buildSystem());
|
auto bs = qobject_cast<NimBuildSystem *>(buildSystem());
|
||||||
QTC_ASSERT(bs, return );
|
QTC_ASSERT(bs, return );
|
||||||
|
|
||||||
// Create the build configuration and initialize it from build info
|
// Create the build configuration and initialize it from build info
|
||||||
|
@@ -25,9 +25,12 @@
|
|||||||
|
|
||||||
#include "nimbuildsystem.h"
|
#include "nimbuildsystem.h"
|
||||||
|
|
||||||
|
#include "nimproject.h"
|
||||||
#include "nimbleproject.h"
|
#include "nimbleproject.h"
|
||||||
#include "nimprojectnode.h"
|
#include "nimprojectnode.h"
|
||||||
|
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -42,11 +45,11 @@ namespace Nim {
|
|||||||
const char SETTINGS_KEY[] = "Nim.BuildSystem";
|
const char SETTINGS_KEY[] = "Nim.BuildSystem";
|
||||||
const char EXCLUDED_FILES_KEY[] = "ExcludedFiles";
|
const char EXCLUDED_FILES_KEY[] = "ExcludedFiles";
|
||||||
|
|
||||||
NimBuildSystem::NimBuildSystem(Project *project)
|
NimBuildSystem::NimBuildSystem(Target *target)
|
||||||
: BuildSystem(project)
|
: BuildSystem(target)
|
||||||
{
|
{
|
||||||
connect(project, &Project::settingsLoaded, this, &NimBuildSystem::loadSettings);
|
connect(target->project(), &Project::settingsLoaded, this, &NimBuildSystem::loadSettings);
|
||||||
connect(project, &Project::aboutToSaveSettings, this, &NimBuildSystem::saveSettings);
|
connect(target->project(), &Project::aboutToSaveSettings, this, &NimBuildSystem::saveSettings);
|
||||||
|
|
||||||
connect(&m_scanner, &TreeScanner::finished, this, &NimBuildSystem::updateProject);
|
connect(&m_scanner, &TreeScanner::finished, this, &NimBuildSystem::updateProject);
|
||||||
m_scanner.setFilter([this](const Utils::MimeType &, const Utils::FilePath &fp) {
|
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)
|
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);
|
return !filePaths.contains(f);
|
||||||
});
|
}));
|
||||||
requestParse();
|
requestParse();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NimBuildSystem::removeFiles(const QStringList &filePaths)
|
bool NimBuildSystem::removeFiles(const QStringList &filePaths)
|
||||||
{
|
{
|
||||||
m_excludedFiles.append(filePaths);
|
setExcludedFiles(Utils::filteredUnique(excludedFiles() + filePaths));
|
||||||
m_excludedFiles = Utils::filteredUnique(m_excludedFiles);
|
|
||||||
requestParse();
|
requestParse();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -82,27 +84,27 @@ bool NimBuildSystem::removeFiles(const QStringList &filePaths)
|
|||||||
bool NimBuildSystem::renameFile(const QString &filePath, const QString &newFilePath)
|
bool NimBuildSystem::renameFile(const QString &filePath, const QString &newFilePath)
|
||||||
{
|
{
|
||||||
Q_UNUSED(filePath)
|
Q_UNUSED(filePath)
|
||||||
m_excludedFiles.removeOne(newFilePath);
|
QStringList files = excludedFiles();
|
||||||
|
files.removeOne(newFilePath);
|
||||||
|
setExcludedFiles(files);
|
||||||
requestParse();
|
requestParse();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NimBuildSystem::setExcludedFiles(const QStringList &list)
|
void NimBuildSystem::setExcludedFiles(const QStringList &list)
|
||||||
{
|
{
|
||||||
m_excludedFiles = list;
|
static_cast<NimProject *>(project())->setExcludedFiles(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList NimBuildSystem::excludedFiles()
|
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_guard = guardParsingRun();
|
||||||
m_currentContext = std::move(ctx);
|
m_scanner.asyncScanForFiles(projectDirectory());
|
||||||
QTC_CHECK(m_currentContext.project);
|
|
||||||
m_scanner.asyncScanForFiles(m_currentContext.project->projectDirectory());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const FilePathList NimBuildSystem::nimFiles() const
|
const FilePathList NimBuildSystem::nimFiles() const
|
||||||
@@ -116,7 +118,7 @@ void NimBuildSystem::loadSettings()
|
|||||||
{
|
{
|
||||||
QVariantMap settings = project()->namedSettings(SETTINGS_KEY).toMap();
|
QVariantMap settings = project()->namedSettings(SETTINGS_KEY).toMap();
|
||||||
if (settings.contains(EXCLUDED_FILES_KEY))
|
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();
|
requestParse();
|
||||||
}
|
}
|
||||||
@@ -124,7 +126,7 @@ void NimBuildSystem::loadSettings()
|
|||||||
void NimBuildSystem::saveSettings()
|
void NimBuildSystem::saveSettings()
|
||||||
{
|
{
|
||||||
QVariantMap settings;
|
QVariantMap settings;
|
||||||
settings.insert(EXCLUDED_FILES_KEY, m_excludedFiles);
|
settings.insert(EXCLUDED_FILES_KEY, excludedFiles());
|
||||||
project()->setNamedSettings(SETTINGS_KEY, settings);
|
project()->setNamedSettings(SETTINGS_KEY, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,8 +158,8 @@ void NimBuildSystem::updateProject()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Complete scan
|
// Complete scan
|
||||||
m_currentContext.guard.markAsSuccess();
|
m_guard.markAsSuccess();
|
||||||
m_currentContext = {};
|
m_guard = {}; // Trigger destructor of previous object, emitting parsingFinished()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NimBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
|
bool NimBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
|
||||||
|
@@ -37,7 +37,7 @@ class NimBuildSystem : public ProjectExplorer::BuildSystem
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit NimBuildSystem(ProjectExplorer::Project *project);
|
explicit NimBuildSystem(ProjectExplorer::Target *target);
|
||||||
|
|
||||||
bool addFiles(const QStringList &filePaths);
|
bool addFiles(const QStringList &filePaths);
|
||||||
bool removeFiles(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
|
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
|
QStringList excludedFiles(); // Make private when no longer supporting Qt Creator 4.10
|
||||||
|
|
||||||
void parseProject(ParsingContext &&ctx) override;
|
void triggerParsing();
|
||||||
|
|
||||||
const Utils::FilePathList nimFiles() const;
|
const Utils::FilePathList nimFiles() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void loadSettings();
|
virtual void loadSettings();
|
||||||
void saveSettings();
|
virtual void saveSettings();
|
||||||
|
|
||||||
void collectProjectFiles();
|
void collectProjectFiles();
|
||||||
void updateProject();
|
void updateProject();
|
||||||
|
|
||||||
QStringList m_excludedFiles;
|
|
||||||
|
|
||||||
ProjectExplorer::TreeScanner m_scanner;
|
ProjectExplorer::TreeScanner m_scanner;
|
||||||
|
|
||||||
ParsingContext m_currentContext;
|
ParseGuard m_guard;
|
||||||
|
|
||||||
Utils::FileSystemWatcher m_directoryWatcher;
|
Utils::FileSystemWatcher m_directoryWatcher;
|
||||||
};
|
};
|
||||||
|
@@ -271,8 +271,8 @@ void NimCompilerBuildStep::updateTargetNimFile()
|
|||||||
{
|
{
|
||||||
if (!m_targetNimFile.isEmpty())
|
if (!m_targetNimFile.isEmpty())
|
||||||
return;
|
return;
|
||||||
const Utils::FilePathList nimFiles = static_cast<NimBuildSystem *>(project()->buildSystem())
|
const Utils::FilePathList nimFiles =
|
||||||
->nimFiles();
|
static_cast<NimBuildSystem *>(buildConfiguration()->buildSystem())->nimFiles();
|
||||||
if (!nimFiles.isEmpty())
|
if (!nimFiles.isEmpty())
|
||||||
setTargetNimFile(nimFiles.at(0));
|
setTargetNimFile(nimFiles.at(0));
|
||||||
}
|
}
|
||||||
|
@@ -116,7 +116,7 @@ void NimCompilerBuildStepConfigWidget::updateTargetComboBox()
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(m_buildStep, return );
|
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 );
|
QTC_ASSERT(bs, return );
|
||||||
|
|
||||||
// Re enter the files
|
// Re enter the files
|
||||||
|
@@ -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)
|
// ensure debugging is enabled (Nim plugin translates nim code to C code)
|
||||||
setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
|
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
|
Tasks NimProject::projectIssues(const Kit *k) const
|
||||||
@@ -65,17 +65,25 @@ Tasks NimProject::projectIssues(const Kit *k) const
|
|||||||
QVariantMap NimProject::toMap() const
|
QVariantMap NimProject::toMap() const
|
||||||
{
|
{
|
||||||
QVariantMap result = Project::toMap();
|
QVariantMap result = Project::toMap();
|
||||||
result[Constants::C_NIMPROJECT_EXCLUDEDFILES] = static_cast<NimBuildSystem *>(buildSystem())
|
result[Constants::C_NIMPROJECT_EXCLUDEDFILES] = m_excludedFiles;
|
||||||
->excludedFiles();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Project::RestoreResult NimProject::fromMap(const QVariantMap &map, QString *errorMessage)
|
Project::RestoreResult NimProject::fromMap(const QVariantMap &map, QString *errorMessage)
|
||||||
{
|
{
|
||||||
auto result = Project::fromMap(map, errorMessage);
|
auto result = Project::fromMap(map, errorMessage);
|
||||||
static_cast<NimBuildSystem *>(buildSystem())
|
m_excludedFiles = map.value(Constants::C_NIMPROJECT_EXCLUDEDFILES).toStringList();
|
||||||
->setExcludedFiles(map.value(Constants::C_NIMPROJECT_EXCLUDEDFILES).toStringList());
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList NimProject::excludedFiles() const
|
||||||
|
{
|
||||||
|
return m_excludedFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NimProject::setExcludedFiles(const QStringList &excludedFiles)
|
||||||
|
{
|
||||||
|
m_excludedFiles = excludedFiles;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Nim
|
} // namespace Nim
|
||||||
|
@@ -48,9 +48,14 @@ public:
|
|||||||
// Keep for compatibility with Qt Creator 4.10
|
// Keep for compatibility with Qt Creator 4.10
|
||||||
QVariantMap toMap() const final;
|
QVariantMap toMap() const final;
|
||||||
|
|
||||||
|
QStringList excludedFiles() const;
|
||||||
|
void setExcludedFiles(const QStringList &excludedFiles);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Keep for compatibility with Qt Creator 4.10
|
// Keep for compatibility with Qt Creator 4.10
|
||||||
RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) final;
|
RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) final;
|
||||||
|
|
||||||
|
QStringList m_excludedFiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Nim
|
} // namespace Nim
|
||||||
|
@@ -28,6 +28,8 @@
|
|||||||
#include "buildenvironmentwidget.h"
|
#include "buildenvironmentwidget.h"
|
||||||
#include "buildinfo.h"
|
#include "buildinfo.h"
|
||||||
#include "buildsteplist.h"
|
#include "buildsteplist.h"
|
||||||
|
#include "buildstepspage.h"
|
||||||
|
#include "buildsystem.h"
|
||||||
#include "namedwidget.h"
|
#include "namedwidget.h"
|
||||||
#include "kit.h"
|
#include "kit.h"
|
||||||
#include "kitinformation.h"
|
#include "kitinformation.h"
|
||||||
@@ -89,6 +91,7 @@ BuildConfiguration::BuildConfiguration(Target *target, Core::Id id)
|
|||||||
: ProjectConfiguration(target, id), d(new Internal::BuildConfigurationPrivate)
|
: ProjectConfiguration(target, id), d(new Internal::BuildConfigurationPrivate)
|
||||||
{
|
{
|
||||||
QTC_CHECK(target && target == this->target());
|
QTC_CHECK(target && target == this->target());
|
||||||
|
|
||||||
Utils::MacroExpander *expander = macroExpander();
|
Utils::MacroExpander *expander = macroExpander();
|
||||||
expander->setDisplayName(tr("Build Settings"));
|
expander->setDisplayName(tr("Build Settings"));
|
||||||
expander->setAccumulating(true);
|
expander->setAccumulating(true);
|
||||||
@@ -128,8 +131,8 @@ BuildConfiguration::BuildConfiguration(Target *target, Core::Id id)
|
|||||||
this->target()->buildEnvironmentChanged(this);
|
this->target()->buildEnvironmentChanged(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(project(), &Project::parsingStarted, this, &BuildConfiguration::enabledChanged);
|
connect(target, &Target::parsingStarted, this, &BuildConfiguration::enabledChanged);
|
||||||
connect(project(), &Project::parsingFinished, this, &BuildConfiguration::enabledChanged);
|
connect(target, &Target::parsingFinished, this, &BuildConfiguration::enabledChanged);
|
||||||
|
|
||||||
connect(this, &BuildConfiguration::enabledChanged, this, [this] {
|
connect(this, &BuildConfiguration::enabledChanged, this, [this] {
|
||||||
if (isActive() && project() == SessionManager::startupProject()) {
|
if (isActive() && project() == SessionManager::startupProject()) {
|
||||||
@@ -164,6 +167,19 @@ void BuildConfiguration::setBuildDirectory(const Utils::FilePath &dir)
|
|||||||
emitBuildDirectoryChanged();
|
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 *BuildConfiguration::createConfigWidget()
|
||||||
{
|
{
|
||||||
NamedWidget *named = new NamedWidget(d->m_configWidgetDisplayName);
|
NamedWidget *named = new NamedWidget(d->m_configWidgetDisplayName);
|
||||||
@@ -203,6 +219,12 @@ QList<NamedWidget *> BuildConfiguration::createSubConfigWidgets()
|
|||||||
return {new BuildEnvironmentWidget(this)};
|
return {new BuildEnvironmentWidget(this)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BuildSystem *BuildConfiguration::buildSystem() const
|
||||||
|
{
|
||||||
|
QTC_CHECK(target()->fallbackBuildSystem());
|
||||||
|
return target()->fallbackBuildSystem();
|
||||||
|
}
|
||||||
|
|
||||||
QList<Core::Id> BuildConfiguration::knownStepLists() const
|
QList<Core::Id> BuildConfiguration::knownStepLists() const
|
||||||
{
|
{
|
||||||
return Utils::transform(d->m_stepLists, &BuildStepList::id);
|
return Utils::transform(d->m_stepLists, &BuildStepList::id);
|
||||||
@@ -368,14 +390,14 @@ void BuildConfiguration::setUserEnvironmentChanges(const Utils::EnvironmentItems
|
|||||||
|
|
||||||
bool BuildConfiguration::isEnabled() const
|
bool BuildConfiguration::isEnabled() const
|
||||||
{
|
{
|
||||||
return !project()->isParsing() && project()->hasParsingData();
|
return !buildSystem()->isParsing() && buildSystem()->hasParsingData();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString BuildConfiguration::disabledReason() const
|
QString BuildConfiguration::disabledReason() const
|
||||||
{
|
{
|
||||||
if (project()->isParsing())
|
if (buildSystem()->isParsing())
|
||||||
return (tr("The project is currently being parsed."));
|
return (tr("The project is currently being parsed."));
|
||||||
if (!project()->hasParsingData())
|
if (!buildSystem()->hasParsingData())
|
||||||
return (tr("The project was not parsed successfully."));
|
return (tr("The project was not parsed successfully."));
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
@@ -38,6 +38,7 @@ namespace Internal { class BuildConfigurationPrivate; }
|
|||||||
|
|
||||||
class BaseStringAspect;
|
class BaseStringAspect;
|
||||||
class BuildInfo;
|
class BuildInfo;
|
||||||
|
class BuildSystem;
|
||||||
class BuildStepList;
|
class BuildStepList;
|
||||||
class Kit;
|
class Kit;
|
||||||
class NamedWidget;
|
class NamedWidget;
|
||||||
@@ -59,6 +60,8 @@ public:
|
|||||||
Utils::FilePath rawBuildDirectory() const;
|
Utils::FilePath rawBuildDirectory() const;
|
||||||
void setBuildDirectory(const Utils::FilePath &dir);
|
void setBuildDirectory(const Utils::FilePath &dir);
|
||||||
|
|
||||||
|
virtual BuildSystem *buildSystem() const;
|
||||||
|
|
||||||
virtual NamedWidget *createConfigWidget();
|
virtual NamedWidget *createConfigWidget();
|
||||||
virtual QList<NamedWidget *> createSubConfigWidgets();
|
virtual QList<NamedWidget *> createSubConfigWidgets();
|
||||||
|
|
||||||
@@ -110,6 +113,8 @@ public:
|
|||||||
void setConfigWidgetHasFrame(bool configWidgetHasFrame);
|
void setConfigWidgetHasFrame(bool configWidgetHasFrame);
|
||||||
void setBuildDirectorySettingsKey(const QString &key);
|
void setBuildDirectorySettingsKey(const QString &key);
|
||||||
|
|
||||||
|
void addConfigWidgets(const std::function<void (NamedWidget *)> &adder);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void environmentChanged();
|
void environmentChanged();
|
||||||
void buildDirectoryChanged();
|
void buildDirectoryChanged();
|
||||||
|
@@ -139,6 +139,7 @@ BuildSettingsWidget::BuildSettingsWidget(Target *target) :
|
|||||||
|
|
||||||
void BuildSettingsWidget::addSubWidget(NamedWidget *widget)
|
void BuildSettingsWidget::addSubWidget(NamedWidget *widget)
|
||||||
{
|
{
|
||||||
|
widget->setParent(this);
|
||||||
widget->setContentsMargins(0, 10, 0, 0);
|
widget->setContentsMargins(0, 10, 0, 0);
|
||||||
|
|
||||||
auto label = new QLabel(this);
|
auto label = new QLabel(this);
|
||||||
@@ -192,23 +193,8 @@ void BuildSettingsWidget::updateBuildSettings()
|
|||||||
m_renameButton->setEnabled(!bcs.isEmpty());
|
m_renameButton->setEnabled(!bcs.isEmpty());
|
||||||
m_cloneButton->setEnabled(!bcs.isEmpty());
|
m_cloneButton->setEnabled(!bcs.isEmpty());
|
||||||
|
|
||||||
if (!m_buildConfiguration)
|
if (m_buildConfiguration)
|
||||||
return;
|
m_buildConfiguration->addConfigWidgets([this](NamedWidget *w) { addSubWidget(w); });
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildSettingsWidget::currentIndexChanged(int index)
|
void BuildSettingsWidget::currentIndexChanged(int index)
|
||||||
|
@@ -204,6 +204,13 @@ ProjectConfiguration *BuildStep::projectConfiguration() const
|
|||||||
return static_cast<ProjectConfiguration *>(parent()->parent());
|
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)
|
void BuildStep::reportRunResult(QFutureInterface<bool> &fi, bool success)
|
||||||
{
|
{
|
||||||
fi.reportResult(success);
|
fi.reportResult(success);
|
||||||
|
@@ -44,6 +44,7 @@ class BuildConfiguration;
|
|||||||
class BuildStepConfigWidget;
|
class BuildStepConfigWidget;
|
||||||
class BuildStepFactory;
|
class BuildStepFactory;
|
||||||
class BuildStepList;
|
class BuildStepList;
|
||||||
|
class BuildSystem;
|
||||||
class DeployConfiguration;
|
class DeployConfiguration;
|
||||||
class Target;
|
class Target;
|
||||||
class Task;
|
class Task;
|
||||||
@@ -75,6 +76,8 @@ public:
|
|||||||
DeployConfiguration *deployConfiguration() const;
|
DeployConfiguration *deployConfiguration() const;
|
||||||
ProjectConfiguration *projectConfiguration() const;
|
ProjectConfiguration *projectConfiguration() const;
|
||||||
|
|
||||||
|
BuildSystem *buildSystem() const;
|
||||||
|
|
||||||
enum class OutputFormat {
|
enum class OutputFormat {
|
||||||
Stdout, Stderr, // These are for forwarded output from external tools
|
Stdout, Stderr, // These are for forwarded output from external tools
|
||||||
NormalMessage, ErrorMessage // These are for messages from Creator itself
|
NormalMessage, ErrorMessage // These are for messages from Creator itself
|
||||||
|
@@ -191,9 +191,9 @@ BuildStepsWidgetData::~BuildStepsWidgetData()
|
|||||||
// We do not own the step
|
// We do not own the step
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildStepListWidget::BuildStepListWidget(BuildStepList *bsl, QWidget *parent)
|
BuildStepListWidget::BuildStepListWidget(BuildStepList *bsl)
|
||||||
//: %1 is the name returned by BuildStepList::displayName
|
//: %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();
|
setupUi();
|
||||||
|
|
||||||
|
@@ -97,7 +97,7 @@ class BuildStepListWidget : public NamedWidget
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BuildStepListWidget(BuildStepList *bsl, QWidget *parent = nullptr);
|
explicit BuildStepListWidget(BuildStepList *bsl);
|
||||||
~BuildStepListWidget() override;
|
~BuildStepListWidget() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -26,10 +26,14 @@
|
|||||||
#include "buildsystem.h"
|
#include "buildsystem.h"
|
||||||
|
|
||||||
#include "buildconfiguration.h"
|
#include "buildconfiguration.h"
|
||||||
|
#include "runconfiguration.h"
|
||||||
|
#include "runcontrol.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
@@ -38,77 +42,129 @@ namespace ProjectExplorer {
|
|||||||
// BuildSystem:
|
// BuildSystem:
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
BuildSystem::BuildSystem(Project *project)
|
class BuildSystemPrivate
|
||||||
: m_project(project)
|
|
||||||
{
|
{
|
||||||
QTC_CHECK(project);
|
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(target);
|
||||||
|
d->m_target = target;
|
||||||
|
|
||||||
// Timer:
|
// 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
|
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
|
FilePath BuildSystem::projectFilePath() const
|
||||||
{
|
{
|
||||||
return m_project->projectFilePath();
|
return d->m_target->project()->projectFilePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePath BuildSystem::projectDirectory() const
|
FilePath BuildSystem::projectDirectory() const
|
||||||
{
|
{
|
||||||
return m_project->projectDirectory();
|
return d->m_target->project()->projectDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BuildSystem::isWaitingForParse() const
|
bool BuildSystem::isWaitingForParse() const
|
||||||
{
|
{
|
||||||
return m_delayedParsingTimer.isActive();
|
return d->m_delayedParsingTimer.isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildSystem::requestParse()
|
void BuildSystem::requestParse()
|
||||||
{
|
{
|
||||||
requestParse(0);
|
requestParseHelper(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildSystem::requestDelayedParse()
|
void BuildSystem::requestDelayedParse()
|
||||||
{
|
{
|
||||||
requestParse(1000);
|
requestParseHelper(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildSystem::requestParse(int delay)
|
bool BuildSystem::isParsing() const
|
||||||
{
|
{
|
||||||
m_delayedParsingTimer.setInterval(delay);
|
return d->m_isParsing;
|
||||||
m_delayedParsingTimer.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildSystem::triggerParsing()
|
bool BuildSystem::hasParsingData() const
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!project()->isParsing(), return );
|
return d->m_hasParsingData;
|
||||||
|
}
|
||||||
|
|
||||||
Project *p = project();
|
Environment BuildSystem::activeParseEnvironment() const
|
||||||
Target *t = p->activeTarget();
|
{
|
||||||
BuildConfiguration *bc = t ? t->activeBuildConfiguration() : nullptr;
|
const BuildConfiguration *const bc = d->m_target->activeBuildConfiguration();
|
||||||
|
|
||||||
MacroExpander *e = nullptr;
|
|
||||||
if (bc)
|
if (bc)
|
||||||
e = bc->macroExpander();
|
return bc->environment();
|
||||||
else if (t)
|
|
||||||
e = t->macroExpander();
|
|
||||||
else
|
|
||||||
e = p->macroExpander();
|
|
||||||
|
|
||||||
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))
|
void BuildSystem::requestParseHelper(int delay)
|
||||||
parseProject(std::move(ctx));
|
{
|
||||||
|
d->m_delayedParsingTimer.setInterval(delay);
|
||||||
|
d->m_delayedParsingTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BuildSystem::addFiles(Node *, const QStringList &filePaths, QStringList *notAdded)
|
bool BuildSystem::addFiles(Node *, const QStringList &filePaths, QStringList *notAdded)
|
||||||
@@ -157,4 +213,103 @@ bool BuildSystem::supportsAction(Node *, ProjectAction, const Node *) const
|
|||||||
return false;
|
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
|
} // namespace ProjectExplorer
|
||||||
|
@@ -27,15 +27,15 @@
|
|||||||
|
|
||||||
#include "projectexplorer_export.h"
|
#include "projectexplorer_export.h"
|
||||||
|
|
||||||
|
#include "buildtargetinfo.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "treescanner.h"
|
#include "treescanner.h"
|
||||||
|
|
||||||
#include <QTimer>
|
#include <QObject>
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
class BuildConfiguration;
|
class BuildConfiguration;
|
||||||
class ExtraCompiler;
|
|
||||||
class Node;
|
class Node;
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
@@ -47,11 +47,13 @@ class PROJECTEXPLORER_EXPORT BuildSystem : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BuildSystem(Project *project);
|
explicit BuildSystem(Target *target);
|
||||||
|
explicit BuildSystem(BuildConfiguration *bc);
|
||||||
BuildSystem(const BuildSystem &other) = delete;
|
~BuildSystem() override;
|
||||||
|
|
||||||
Project *project() const;
|
Project *project() const;
|
||||||
|
Target *target() const;
|
||||||
|
|
||||||
Utils::FilePath projectFilePath() const;
|
Utils::FilePath projectFilePath() const;
|
||||||
Utils::FilePath projectDirectory() const;
|
Utils::FilePath projectDirectory() const;
|
||||||
|
|
||||||
@@ -60,6 +62,11 @@ public:
|
|||||||
void requestParse();
|
void requestParse();
|
||||||
void requestDelayedParse();
|
void requestDelayedParse();
|
||||||
|
|
||||||
|
bool isParsing() const;
|
||||||
|
bool hasParsingData() const;
|
||||||
|
|
||||||
|
Utils::Environment activeParseEnvironment() const;
|
||||||
|
|
||||||
virtual bool addFiles(Node *context, const QStringList &filePaths, QStringList *notAdded = nullptr);
|
virtual bool addFiles(Node *context, const QStringList &filePaths, QStringList *notAdded = nullptr);
|
||||||
virtual RemovedFilesFromProject removeFiles(Node *context, const QStringList &filePaths,
|
virtual RemovedFilesFromProject removeFiles(Node *context, const QStringList &filePaths,
|
||||||
QStringList *notRemoved = nullptr);
|
QStringList *notRemoved = nullptr);
|
||||||
@@ -69,69 +76,64 @@ public:
|
|||||||
virtual bool addDependencies(Node *context, const QStringList &dependencies);
|
virtual bool addDependencies(Node *context, const QStringList &dependencies);
|
||||||
virtual bool supportsAction(Node *context, ProjectAction action, const Node *node) const;
|
virtual bool supportsAction(Node *context, ProjectAction action, const Node *node) const;
|
||||||
|
|
||||||
protected:
|
virtual QStringList filesGeneratedFrom(const QString &sourceFile) const;
|
||||||
class ParsingContext
|
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:
|
public:
|
||||||
ParsingContext() = default;
|
ParseGuard() = default;
|
||||||
|
~ParseGuard() { release(); }
|
||||||
|
|
||||||
ParsingContext(const ParsingContext &other) = delete;
|
void markAsSuccess() const { m_success = true; }
|
||||||
ParsingContext &operator=(const ParsingContext &other) = delete;
|
bool isSuccess() const { return m_success; }
|
||||||
ParsingContext(ParsingContext &&other)
|
bool guardsProject() const { return m_buildSystem; }
|
||||||
: 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;
|
ParseGuard(const ParseGuard &other) = delete;
|
||||||
|
ParseGuard &operator=(const ParseGuard &other) = delete;
|
||||||
Project *project = nullptr;
|
ParseGuard(ParseGuard &&other);
|
||||||
BuildConfiguration *buildConfiguration = nullptr;
|
ParseGuard &operator=(ParseGuard &&other);
|
||||||
Utils::MacroExpander *expander = nullptr;
|
|
||||||
Utils::Environment environment;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ParsingContext(Project::ParseGuard &&g,
|
BuildSystem *m_buildSystem = nullptr;
|
||||||
Project *p,
|
mutable bool m_success = false;
|
||||||
BuildConfiguration *bc,
|
|
||||||
Utils::MacroExpander *e,
|
|
||||||
Utils::Environment &env)
|
|
||||||
: guard(std::move(g))
|
|
||||||
, project(p)
|
|
||||||
, buildConfiguration(bc)
|
|
||||||
, expander(e)
|
|
||||||
, environment(env)
|
|
||||||
{}
|
|
||||||
|
|
||||||
friend class BuildSystem;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual bool validateParsingContext(const ParsingContext &ctx)
|
public:
|
||||||
{
|
// FIXME: Make this private and the BuildSystem a friend
|
||||||
Q_UNUSED(ctx)
|
ParseGuard guardParsingRun() { return ParseGuard(this); }
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void parseProject(ParsingContext &&) {} // actual code to parse project
|
QString disabledReason(const QString &buildKey) const;
|
||||||
|
|
||||||
|
virtual void triggerParsing() = 0;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void deploymentDataChanged();
|
||||||
|
void applicationTargetsChanged();
|
||||||
|
|
||||||
|
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:
|
private:
|
||||||
void requestParse(int delay); // request a (delayed!) parser run.
|
void requestParseHelper(int delay); // request a (delayed!) parser run.
|
||||||
void triggerParsing();
|
|
||||||
|
|
||||||
QTimer m_delayedParsingTimer;
|
class BuildSystemPrivate *d = nullptr;
|
||||||
|
|
||||||
Project *m_project;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ProjectExplorer
|
} // namespace ProjectExplorer
|
||||||
|
@@ -246,6 +246,11 @@ bool CustomExecutableRunConfiguration::isConfigured() const
|
|||||||
return !rawExecutable().isEmpty();
|
return !rawExecutable().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CustomExecutableRunConfiguration::isEnabled() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Runnable CustomExecutableRunConfiguration::runnable() const
|
Runnable CustomExecutableRunConfiguration::runnable() const
|
||||||
{
|
{
|
||||||
FilePath workingDirectory =
|
FilePath workingDirectory =
|
||||||
|
@@ -45,6 +45,7 @@ public:
|
|||||||
/** Returns whether this runconfiguration ever was configured with an executable
|
/** Returns whether this runconfiguration ever was configured with an executable
|
||||||
*/
|
*/
|
||||||
bool isConfigured() const override;
|
bool isConfigured() const override;
|
||||||
|
bool isEnabled() const override;
|
||||||
ConfigurationState ensureConfigured(QString *errorMessage) override;
|
ConfigurationState ensureConfigured(QString *errorMessage) override;
|
||||||
|
|
||||||
QString defaultDisplayName() const;
|
QString defaultDisplayName() const;
|
||||||
|
@@ -25,9 +25,11 @@
|
|||||||
|
|
||||||
#include "deploymentdataview.h"
|
#include "deploymentdataview.h"
|
||||||
|
|
||||||
|
#include "buildsystem.h"
|
||||||
#include "deploymentdata.h"
|
#include "deploymentdata.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/treemodel.h>
|
#include <utils/treemodel.h>
|
||||||
|
|
||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
@@ -78,7 +80,8 @@ DeploymentDataView::DeploymentDataView(Target *target)
|
|||||||
|
|
||||||
auto updatModel = [this, target, model, view] {
|
auto updatModel = [this, target, model, view] {
|
||||||
model->clear();
|
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));
|
model->rootItem()->appendChild(new DeploymentDataItem(file));
|
||||||
|
|
||||||
QHeaderView *header = view->header();
|
QHeaderView *header = view->header();
|
||||||
|
@@ -78,7 +78,7 @@ DesktopRunConfiguration::DesktopRunConfiguration(Target *target, Core::Id id, Ki
|
|||||||
|
|
||||||
if (kind == Qbs) {
|
if (kind == Qbs) {
|
||||||
|
|
||||||
connect(project(), &Project::parsingFinished,
|
connect(target, &Target::parsingFinished,
|
||||||
envAspect, &EnvironmentAspect::environmentChanged);
|
envAspect, &EnvironmentAspect::environmentChanged);
|
||||||
|
|
||||||
connect(target, &Target::deploymentDataChanged,
|
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);
|
this, &DesktopRunConfiguration::updateTargetInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopRunConfiguration::updateTargetInformation()
|
void DesktopRunConfiguration::updateTargetInformation()
|
||||||
{
|
{
|
||||||
|
if (!activeBuildSystem())
|
||||||
|
return;
|
||||||
|
|
||||||
BuildTargetInfo bti = buildTargetInfo();
|
BuildTargetInfo bti = buildTargetInfo();
|
||||||
|
|
||||||
auto terminalAspect = aspect<TerminalAspect>();
|
auto terminalAspect = aspect<TerminalAspect>();
|
||||||
@@ -184,28 +187,6 @@ Utils::FilePath DesktopRunConfiguration::executableToRun(const BuildTargetInfo &
|
|||||||
return appInLocalInstallDir.exists() ? appInLocalInstallDir : appInBuildDir;
|
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
|
// Factory
|
||||||
|
|
||||||
class DesktopQmakeRunConfiguration : public DesktopRunConfiguration
|
class DesktopQmakeRunConfiguration : public DesktopRunConfiguration
|
||||||
|
@@ -43,14 +43,10 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void doAdditionalSetup(const RunConfigurationCreationInfo &info) final;
|
void doAdditionalSetup(const RunConfigurationCreationInfo &info) final;
|
||||||
bool fromMap(const QVariantMap &map) final;
|
bool fromMap(const QVariantMap &map) final;
|
||||||
void updateEnabledState() final;
|
|
||||||
|
|
||||||
void updateTargetInformation();
|
void updateTargetInformation();
|
||||||
|
|
||||||
Utils::FilePath executableToRun(const BuildTargetInfo &targetInfo) const;
|
Utils::FilePath executableToRun(const BuildTargetInfo &targetInfo) const;
|
||||||
QString disabledReason() const override;
|
|
||||||
|
|
||||||
bool isBuildTargetValid() const;
|
|
||||||
|
|
||||||
const Kind m_kind;
|
const Kind m_kind;
|
||||||
};
|
};
|
||||||
|
@@ -443,7 +443,7 @@ MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep)
|
|||||||
this, &MakeStepConfigWidget::updateDetails);
|
this, &MakeStepConfigWidget::updateDetails);
|
||||||
connect(m_makeStep->buildConfiguration(), &BuildConfiguration::buildDirectoryChanged,
|
connect(m_makeStep->buildConfiguration(), &BuildConfiguration::buildDirectoryChanged,
|
||||||
this, &MakeStepConfigWidget::updateDetails);
|
this, &MakeStepConfigWidget::updateDetails);
|
||||||
connect(m_makeStep->project(), &Project::parsingFinished,
|
connect(m_makeStep->target(), &Target::parsingFinished,
|
||||||
this, &MakeStepConfigWidget::updateDetails);
|
this, &MakeStepConfigWidget::updateDetails);
|
||||||
|
|
||||||
Core::VariableChooser::addSupportForChildWidgets(this, m_makeStep->macroExpander());
|
Core::VariableChooser::addSupportForChildWidgets(this, m_makeStep->macroExpander());
|
||||||
|
@@ -176,14 +176,15 @@ public:
|
|||||||
~ProjectPrivate();
|
~ProjectPrivate();
|
||||||
|
|
||||||
Core::Id m_id;
|
Core::Id m_id;
|
||||||
bool m_isParsing = false;
|
|
||||||
bool m_hasParsingData = false;
|
|
||||||
bool m_needsInitialExpansion = false;
|
bool m_needsInitialExpansion = false;
|
||||||
bool m_canBuildProducts = false;
|
bool m_canBuildProducts = false;
|
||||||
bool m_knowsAllBuildExecutables = true;
|
bool m_knowsAllBuildExecutables = true;
|
||||||
bool m_hasMakeInstallEquivalent = false;
|
bool m_hasMakeInstallEquivalent = false;
|
||||||
bool m_needsBuildConfigurations = true;
|
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::unique_ptr<Core::IDocument> m_document;
|
||||||
std::vector<std::unique_ptr<Core::IDocument>> m_extraProjectDocuments;
|
std::vector<std::unique_ptr<Core::IDocument>> m_extraProjectDocuments;
|
||||||
std::unique_ptr<ProjectNode> m_rootProjectNode;
|
std::unique_ptr<ProjectNode> m_rootProjectNode;
|
||||||
@@ -255,9 +256,9 @@ bool Project::canBuildProducts() const
|
|||||||
return d->m_canBuildProducts;
|
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
|
Utils::FilePath Project::projectFilePath() const
|
||||||
@@ -341,8 +342,6 @@ void Project::setActiveTarget(Target *target)
|
|||||||
(target && Utils::contains(d->m_targets, target))) {
|
(target && Utils::contains(d->m_targets, target))) {
|
||||||
d->m_activeTarget = target;
|
d->m_activeTarget = target;
|
||||||
emit activeTargetChanged(d->m_activeTarget);
|
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)
|
bool Project::setupTarget(Target *t)
|
||||||
{
|
{
|
||||||
if (needsBuildConfigurations())
|
if (d->m_needsBuildConfigurations)
|
||||||
t->updateDefaultBuildConfigurations();
|
t->updateDefaultBuildConfigurations();
|
||||||
t->updateDefaultDeployConfigurations();
|
if (d->m_needsDeployConfigurations)
|
||||||
|
t->updateDefaultDeployConfigurations();
|
||||||
t->updateDefaultRunConfigurations();
|
t->updateDefaultRunConfigurations();
|
||||||
return true;
|
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)
|
void Project::setDisplayName(const QString &name)
|
||||||
{
|
{
|
||||||
if (name == d->m_displayName)
|
if (name == d->m_displayName)
|
||||||
@@ -596,9 +576,6 @@ void Project::saveSettings()
|
|||||||
|
|
||||||
Project::RestoreResult Project::restoreSettings(QString *errorMessage)
|
Project::RestoreResult Project::restoreSettings(QString *errorMessage)
|
||||||
{
|
{
|
||||||
BuildConfiguration *oldBc = activeTarget() ? activeTarget()->activeBuildConfiguration()
|
|
||||||
: nullptr;
|
|
||||||
|
|
||||||
if (!d->m_accessor)
|
if (!d->m_accessor)
|
||||||
d->m_accessor = std::make_unique<Internal::UserFileAccessor>(this);
|
d->m_accessor = std::make_unique<Internal::UserFileAccessor>(this);
|
||||||
QVariantMap map(d->m_accessor->restoreSettings(Core::ICore::mainWindow()));
|
QVariantMap map(d->m_accessor->restoreSettings(Core::ICore::mainWindow()));
|
||||||
@@ -606,10 +583,6 @@ Project::RestoreResult Project::restoreSettings(QString *errorMessage)
|
|||||||
if (result == RestoreResult::Ok)
|
if (result == RestoreResult::Ok)
|
||||||
emit settingsLoaded();
|
emit settingsLoaded();
|
||||||
|
|
||||||
BuildConfiguration *bc = activeTarget() ? activeTarget()->activeBuildConfiguration() : nullptr;
|
|
||||||
if (bc != oldBc)
|
|
||||||
emit activeBuildConfigurationChanged(bc);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -798,12 +771,6 @@ EditorConfiguration *Project::editorConfiguration() const
|
|||||||
return &d->m_editorConfiguration;
|
return &d->m_editorConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList Project::filesGeneratedFrom(const QString &file) const
|
|
||||||
{
|
|
||||||
Q_UNUSED(file)
|
|
||||||
return QStringList();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Project::isKnownFile(const Utils::FilePath &filename) const
|
bool Project::isKnownFile(const Utils::FilePath &filename) const
|
||||||
{
|
{
|
||||||
if (d->m_sortedNodeList.empty())
|
if (d->m_sortedNodeList.empty())
|
||||||
@@ -852,10 +819,6 @@ void Project::setHasMakeInstallEquivalent(bool enabled)
|
|||||||
d->m_hasMakeInstallEquivalent = enabled;
|
d->m_hasMakeInstallEquivalent = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Project::projectLoaded()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Project::setKnowsAllBuildExecutables(bool value)
|
void Project::setKnowsAllBuildExecutables(bool value)
|
||||||
{
|
{
|
||||||
d->m_knowsAllBuildExecutables = value;
|
d->m_knowsAllBuildExecutables = value;
|
||||||
@@ -866,31 +829,19 @@ void Project::setNeedsBuildConfigurations(bool value)
|
|||||||
d->m_needsBuildConfigurations = value;
|
d->m_needsBuildConfigurations = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Project::setNeedsDeployConfigurations(bool value)
|
||||||
|
{
|
||||||
|
d->m_needsDeployConfigurations = value;
|
||||||
|
}
|
||||||
|
|
||||||
Task Project::createProjectTask(Task::TaskType type, const QString &description)
|
Task Project::createProjectTask(Task::TaskType type, const QString &description)
|
||||||
{
|
{
|
||||||
return Task(type, description, Utils::FilePath(), -1, Core::Id());
|
return Task(type, description, Utils::FilePath(), -1, Core::Id());
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::Environment Project::activeParseEnvironment() const
|
void Project::setBuildSystemCreator(const std::function<BuildSystem *(Target *)> &creator)
|
||||||
{
|
{
|
||||||
const Target *const t = activeTarget();
|
d->m_buildSystemCreator = creator;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Project::setBuildSystemCreator(const std::function<BuildSystem *(Project *)> &creator)
|
|
||||||
{
|
|
||||||
d->m_buildSystem.reset(creator(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::Context Project::projectContext() const
|
Core::Context Project::projectContext() const
|
||||||
@@ -988,23 +939,6 @@ Utils::MacroExpander *Project::macroExpander() const
|
|||||||
return &d->m_macroExpander;
|
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
|
ProjectNode *Project::findNodeForBuildKey(const QString &buildKey) const
|
||||||
{
|
{
|
||||||
if (!d->m_rootProjectNode)
|
if (!d->m_rootProjectNode)
|
||||||
@@ -1072,6 +1006,14 @@ const QString TEST_PROJECT_MIMETYPE = "application/vnd.test.qmakeprofile";
|
|||||||
const QString TEST_PROJECT_DISPLAYNAME = "testProjectFoo";
|
const QString TEST_PROJECT_DISPLAYNAME = "testProjectFoo";
|
||||||
const char TEST_PROJECT_ID[] = "Test.Project.Id";
|
const char TEST_PROJECT_ID[] = "Test.Project.Id";
|
||||||
|
|
||||||
|
class TestBuildSystem : public BuildSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using BuildSystem::BuildSystem;
|
||||||
|
|
||||||
|
void triggerParsing() {}
|
||||||
|
};
|
||||||
|
|
||||||
class TestProject : public Project
|
class TestProject : public Project
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -1079,9 +1021,17 @@ public:
|
|||||||
{
|
{
|
||||||
setId(TEST_PROJECT_ID);
|
setId(TEST_PROJECT_ID);
|
||||||
setDisplayName(TEST_PROJECT_DISPLAYNAME);
|
setDisplayName(TEST_PROJECT_DISPLAYNAME);
|
||||||
|
setBuildSystemCreator([](Target *t) { return new TestBuildSystem(t); });
|
||||||
|
setNeedsBuildConfigurations(false);
|
||||||
|
setNeedsDeployConfigurations(false);
|
||||||
|
|
||||||
|
target = addTargetForKit(&testKit);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool needsConfiguration() const final { return false; }
|
bool needsConfiguration() const final { return false; }
|
||||||
|
|
||||||
|
Kit testKit;
|
||||||
|
Target *target = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
void ProjectExplorerPlugin::testProject_setup()
|
void ProjectExplorerPlugin::testProject_setup()
|
||||||
@@ -1108,8 +1058,8 @@ void ProjectExplorerPlugin::testProject_setup()
|
|||||||
|
|
||||||
QCOMPARE(project.id(), Core::Id(TEST_PROJECT_ID));
|
QCOMPARE(project.id(), Core::Id(TEST_PROJECT_ID));
|
||||||
|
|
||||||
QVERIFY(!project.isParsing());
|
QVERIFY(!project.target->buildSystem()->isParsing());
|
||||||
QVERIFY(!project.hasParsingData());
|
QVERIFY(!project.target->buildSystem()->hasParsingData());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectExplorerPlugin::testProject_changeDisplayName()
|
void ProjectExplorerPlugin::testProject_changeDisplayName()
|
||||||
@@ -1132,16 +1082,16 @@ void ProjectExplorerPlugin::testProject_parsingSuccess()
|
|||||||
{
|
{
|
||||||
TestProject project;
|
TestProject project;
|
||||||
|
|
||||||
QSignalSpy startSpy(&project, &Project::parsingStarted);
|
QSignalSpy startSpy(project.target, &Target::parsingStarted);
|
||||||
QSignalSpy stopSpy(&project, &Project::parsingFinished);
|
QSignalSpy stopSpy(project.target, &Target::parsingFinished);
|
||||||
|
|
||||||
{
|
{
|
||||||
Project::ParseGuard guard = project.guardParsingRun();
|
BuildSystem::ParseGuard guard = project.target->buildSystem()->guardParsingRun();
|
||||||
QCOMPARE(startSpy.count(), 1);
|
QCOMPARE(startSpy.count(), 1);
|
||||||
QCOMPARE(stopSpy.count(), 0);
|
QCOMPARE(stopSpy.count(), 0);
|
||||||
|
|
||||||
QVERIFY(project.isParsing());
|
QVERIFY(project.target->buildSystem()->isParsing());
|
||||||
QVERIFY(!project.hasParsingData());
|
QVERIFY(!project.target->buildSystem()->hasParsingData());
|
||||||
|
|
||||||
guard.markAsSuccess();
|
guard.markAsSuccess();
|
||||||
}
|
}
|
||||||
@@ -1150,32 +1100,32 @@ void ProjectExplorerPlugin::testProject_parsingSuccess()
|
|||||||
QCOMPARE(stopSpy.count(), 1);
|
QCOMPARE(stopSpy.count(), 1);
|
||||||
QCOMPARE(stopSpy.at(0), {QVariant(true)});
|
QCOMPARE(stopSpy.at(0), {QVariant(true)});
|
||||||
|
|
||||||
QVERIFY(!project.isParsing());
|
QVERIFY(!project.target->buildSystem()->isParsing());
|
||||||
QVERIFY(project.hasParsingData());
|
QVERIFY(project.target->buildSystem()->hasParsingData());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectExplorerPlugin::testProject_parsingFail()
|
void ProjectExplorerPlugin::testProject_parsingFail()
|
||||||
{
|
{
|
||||||
TestProject project;
|
TestProject project;
|
||||||
|
|
||||||
QSignalSpy startSpy(&project, &Project::parsingStarted);
|
QSignalSpy startSpy(project.target, &Target::parsingStarted);
|
||||||
QSignalSpy stopSpy(&project, &Project::parsingFinished);
|
QSignalSpy stopSpy(project.target, &Target::parsingFinished);
|
||||||
|
|
||||||
{
|
{
|
||||||
Project::ParseGuard guard = project.guardParsingRun();
|
BuildSystem::ParseGuard guard = project.target->buildSystem()->guardParsingRun();
|
||||||
QCOMPARE(startSpy.count(), 1);
|
QCOMPARE(startSpy.count(), 1);
|
||||||
QCOMPARE(stopSpy.count(), 0);
|
QCOMPARE(stopSpy.count(), 0);
|
||||||
|
|
||||||
QVERIFY(project.isParsing());
|
QVERIFY(project.target->buildSystem()->isParsing());
|
||||||
QVERIFY(!project.hasParsingData());
|
QVERIFY(!project.target->buildSystem()->hasParsingData());
|
||||||
}
|
}
|
||||||
|
|
||||||
QCOMPARE(startSpy.count(), 1);
|
QCOMPARE(startSpy.count(), 1);
|
||||||
QCOMPARE(stopSpy.count(), 1);
|
QCOMPARE(stopSpy.count(), 1);
|
||||||
QCOMPARE(stopSpy.at(0), {QVariant(false)});
|
QCOMPARE(stopSpy.at(0), {QVariant(false)});
|
||||||
|
|
||||||
QVERIFY(!project.isParsing());
|
QVERIFY(!project.target->buildSystem()->isParsing());
|
||||||
QVERIFY(!project.hasParsingData());
|
QVERIFY(!project.target->buildSystem()->hasParsingData());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ProjectNode> createFileTree(Project *project)
|
std::unique_ptr<ProjectNode> createFileTree(Project *project)
|
||||||
|
@@ -50,6 +50,7 @@ namespace ProjectExplorer {
|
|||||||
|
|
||||||
class BuildInfo;
|
class BuildInfo;
|
||||||
class BuildSystem;
|
class BuildSystem;
|
||||||
|
class BuildConfiguration;
|
||||||
class ContainerNode;
|
class ContainerNode;
|
||||||
class EditorConfiguration;
|
class EditorConfiguration;
|
||||||
class FolderNode;
|
class FolderNode;
|
||||||
@@ -64,7 +65,6 @@ class Target;
|
|||||||
class PROJECTEXPLORER_EXPORT Project : public QObject
|
class PROJECTEXPLORER_EXPORT Project : public QObject
|
||||||
{
|
{
|
||||||
friend class SessionManager; // for setActiveTarget
|
friend class SessionManager; // for setActiveTarget
|
||||||
friend class ProjectExplorerPlugin; // for projectLoaded
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -84,7 +84,7 @@ public:
|
|||||||
QString mimeType() const;
|
QString mimeType() const;
|
||||||
bool canBuildProducts() const;
|
bool canBuildProducts() const;
|
||||||
|
|
||||||
BuildSystem *buildSystem() const;
|
BuildSystem *createBuildSystem(Target *target) const;
|
||||||
|
|
||||||
Utils::FilePath projectFilePath() const;
|
Utils::FilePath projectFilePath() const;
|
||||||
Utils::FilePath projectDirectory() const;
|
Utils::FilePath projectDirectory() const;
|
||||||
@@ -124,7 +124,6 @@ public:
|
|||||||
static const NodeMatcher GeneratedFiles;
|
static const NodeMatcher GeneratedFiles;
|
||||||
|
|
||||||
Utils::FilePathList files(const NodeMatcher &matcher) const;
|
Utils::FilePathList files(const NodeMatcher &matcher) const;
|
||||||
virtual QStringList filesGeneratedFrom(const QString &sourceFile) const;
|
|
||||||
bool isKnownFile(const Utils::FilePath &filename) const;
|
bool isKnownFile(const Utils::FilePath &filename) const;
|
||||||
|
|
||||||
virtual QVariantMap toMap() const;
|
virtual QVariantMap toMap() const;
|
||||||
@@ -155,81 +154,20 @@ public:
|
|||||||
void setup(const QList<BuildInfo> &infoList);
|
void setup(const QList<BuildInfo> &infoList);
|
||||||
Utils::MacroExpander *macroExpander() const;
|
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;
|
ProjectNode *findNodeForBuildKey(const QString &buildKey) const;
|
||||||
|
|
||||||
bool needsInitialExpansion() const;
|
bool needsInitialExpansion() const;
|
||||||
void setNeedsInitialExpansion(bool needsInitialExpansion);
|
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);
|
void setRootProjectNode(std::unique_ptr<ProjectNode> &&root);
|
||||||
|
|
||||||
// Set project files that will be watched and trigger the same callback
|
// Set project files that will be watched and trigger the same callback
|
||||||
// as the main project file.
|
// as the main project file.
|
||||||
void setExtraProjectFiles(const QVector<Utils::FilePath> &projectDocumentPaths);
|
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:
|
signals:
|
||||||
void projectFileIsDirty(const Utils::FilePath &path);
|
void projectFileIsDirty(const Utils::FilePath &path);
|
||||||
@@ -243,11 +181,6 @@ signals:
|
|||||||
void removedProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
|
void removedProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
|
||||||
void addedProjectConfiguration(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 aboutToRemoveTarget(ProjectExplorer::Target *target);
|
||||||
void removedTarget(ProjectExplorer::Target *target);
|
void removedTarget(ProjectExplorer::Target *target);
|
||||||
void addedTarget(ProjectExplorer::Target *target);
|
void addedTarget(ProjectExplorer::Target *target);
|
||||||
@@ -257,8 +190,8 @@ signals:
|
|||||||
|
|
||||||
void projectLanguagesUpdated();
|
void projectLanguagesUpdated();
|
||||||
|
|
||||||
void parsingStarted();
|
void anyParsingStarted(Target *target);
|
||||||
void parsingFinished(bool success);
|
void anyParsingFinished(Target *target, bool success);
|
||||||
|
|
||||||
void rootProjectDirectoryChanged();
|
void rootProjectDirectoryChanged();
|
||||||
|
|
||||||
@@ -267,7 +200,6 @@ protected:
|
|||||||
void createTargetFromMap(const QVariantMap &map, int index);
|
void createTargetFromMap(const QVariantMap &map, int index);
|
||||||
virtual bool setupTarget(Target *t);
|
virtual bool setupTarget(Target *t);
|
||||||
|
|
||||||
void setDisplayName(const QString &name);
|
|
||||||
// Used to pre-check kits in the TargetSetupPage. RequiredKitPredicate
|
// Used to pre-check kits in the TargetSetupPage. RequiredKitPredicate
|
||||||
// is used to select kits available in the TargetSetupPage
|
// is used to select kits available in the TargetSetupPage
|
||||||
void setPreferredKitPredicate(const Kit::Predicate &predicate);
|
void setPreferredKitPredicate(const Kit::Predicate &predicate);
|
||||||
@@ -278,35 +210,26 @@ protected:
|
|||||||
|
|
||||||
void setId(Core::Id id);
|
void setId(Core::Id id);
|
||||||
void setProjectLanguages(Core::Context language);
|
void setProjectLanguages(Core::Context language);
|
||||||
void addProjectLanguage(Core::Id id);
|
|
||||||
void removeProjectLanguage(Core::Id id);
|
void removeProjectLanguage(Core::Id id);
|
||||||
void setProjectLanguage(Core::Id id, bool enabled);
|
|
||||||
void setHasMakeInstallEquivalent(bool enabled);
|
void setHasMakeInstallEquivalent(bool enabled);
|
||||||
virtual void projectLoaded(); // Called when the project is fully loaded.
|
|
||||||
|
|
||||||
void setKnowsAllBuildExecutables(bool value);
|
void setKnowsAllBuildExecutables(bool value);
|
||||||
void setNeedsBuildConfigurations(bool value);
|
void setNeedsBuildConfigurations(bool value);
|
||||||
|
void setNeedsDeployConfigurations(bool value);
|
||||||
|
|
||||||
static ProjectExplorer::Task createProjectTask(ProjectExplorer::Task::TaskType type,
|
static ProjectExplorer::Task createProjectTask(ProjectExplorer::Task::TaskType type,
|
||||||
const QString &description);
|
const QString &description);
|
||||||
|
|
||||||
void setBuildSystemCreator(const std::function<BuildSystem *(Project *)> &creator);
|
void setBuildSystemCreator(const std::function<BuildSystem *(Target *)> &creator);
|
||||||
|
|
||||||
private:
|
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 addTarget(std::unique_ptr<Target> &&target);
|
||||||
|
|
||||||
void handleSubTreeChanged(FolderNode *node);
|
void handleSubTreeChanged(FolderNode *node);
|
||||||
void setActiveTarget(Target *target);
|
void setActiveTarget(Target *target);
|
||||||
|
|
||||||
ProjectPrivate *d;
|
|
||||||
|
|
||||||
friend class ContainerNode;
|
friend class ContainerNode;
|
||||||
|
ProjectPrivate *d;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ProjectExplorer
|
} // namespace ProjectExplorer
|
||||||
|
@@ -2046,7 +2046,6 @@ ProjectExplorerPlugin::OpenProjectResult ProjectExplorerPlugin::openProject(cons
|
|||||||
return result;
|
return result;
|
||||||
dd->addToRecentProjects(fileName, project->displayName());
|
dd->addToRecentProjects(fileName, project->displayName());
|
||||||
SessionManager::setStartupProject(project);
|
SessionManager::setStartupProject(project);
|
||||||
project->projectLoaded();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2113,9 +2112,6 @@ ProjectExplorerPlugin::OpenProjectResult ProjectExplorerPlugin::openProjects(con
|
|||||||
appendError(errorString,
|
appendError(errorString,
|
||||||
tr("Failed opening project \"%1\": Project is not a file.").arg(fileName));
|
tr("Failed opening project \"%1\": Project is not a file.").arg(fileName));
|
||||||
} else if (Project *pro = ProjectManager::openProject(mt, filePath)) {
|
} else if (Project *pro = ProjectManager::openProject(mt, filePath)) {
|
||||||
QObject::connect(pro, &Project::parsingFinished, [pro]() {
|
|
||||||
emit SessionManager::instance()->projectFinishedParsing(pro);
|
|
||||||
});
|
|
||||||
QString restoreError;
|
QString restoreError;
|
||||||
Project::RestoreResult restoreResult = pro->restoreSettings(&restoreError);
|
Project::RestoreResult restoreResult = pro->restoreSettings(&restoreError);
|
||||||
if (restoreResult == Project::RestoreResult::Ok) {
|
if (restoreResult == Project::RestoreResult::Ok) {
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "projectmodels.h"
|
#include "projectmodels.h"
|
||||||
|
|
||||||
|
#include "buildsystem.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "projectnodes.h"
|
#include "projectnodes.h"
|
||||||
#include "projectexplorer.h"
|
#include "projectexplorer.h"
|
||||||
@@ -119,6 +120,8 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
|
|||||||
const FolderNode * const folderNode = node->asFolderNode();
|
const FolderNode * const folderNode = node->asFolderNode();
|
||||||
const ContainerNode * const containerNode = node->asContainerNode();
|
const ContainerNode * const containerNode = node->asContainerNode();
|
||||||
const Project * const project = containerNode ? containerNode->project() : nullptr;
|
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) {
|
switch (role) {
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
@@ -128,7 +131,7 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
|
|||||||
case Qt::ToolTipRole: {
|
case Qt::ToolTipRole: {
|
||||||
QString tooltip = node->tooltip();
|
QString tooltip = node->tooltip();
|
||||||
if (project) {
|
if (project) {
|
||||||
if (project->activeTarget()) {
|
if (target) {
|
||||||
QString projectIssues = toHtml(project->projectIssues(project->activeTarget()->kit()));
|
QString projectIssues = toHtml(project->projectIssues(project->activeTarget()->kit()));
|
||||||
if (!projectIssues.isEmpty())
|
if (!projectIssues.isEmpty())
|
||||||
tooltip += "<p>" + projectIssues;
|
tooltip += "<p>" + projectIssues;
|
||||||
@@ -148,10 +151,9 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
|
|||||||
static QIcon emptyIcon = Utils::Icons::EMPTY16.icon();
|
static QIcon emptyIcon = Utils::Icons::EMPTY16.icon();
|
||||||
if (project->needsConfiguration())
|
if (project->needsConfiguration())
|
||||||
return warnIcon;
|
return warnIcon;
|
||||||
if (project->isParsing())
|
if (bs && bs->isParsing())
|
||||||
return emptyIcon;
|
return emptyIcon;
|
||||||
if (!project->activeTarget()
|
if (!target || !project->projectIssues(target->kit()).isEmpty())
|
||||||
|| !project->projectIssues(project->activeTarget()->kit()).isEmpty())
|
|
||||||
return warnIcon;
|
return warnIcon;
|
||||||
return containerNode->rootProjectNode() ? containerNode->rootProjectNode()->icon()
|
return containerNode->rootProjectNode() ? containerNode->rootProjectNode()->icon()
|
||||||
: folderNode->icon();
|
: folderNode->icon();
|
||||||
@@ -167,7 +169,7 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
|
|||||||
case Project::FilePathRole:
|
case Project::FilePathRole:
|
||||||
return node->filePath().toString();
|
return node->filePath().toString();
|
||||||
case Project::isParsingRole:
|
case Project::isParsingRole:
|
||||||
return project ? project->isParsing() && !project->needsConfiguration() : false;
|
return project && bs ? bs->isParsing() && !project->needsConfiguration() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
@@ -359,12 +361,12 @@ void FlatModel::handleProjectAdded(Project *project)
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(project, return);
|
QTC_ASSERT(project, return);
|
||||||
|
|
||||||
connect(project, &Project::parsingStarted,
|
connect(project, &Project::anyParsingStarted,
|
||||||
this, [this, project]() {
|
this, [this, project]() {
|
||||||
if (nodeForProject(project))
|
if (nodeForProject(project))
|
||||||
parsingStateChanged(project);
|
parsingStateChanged(project);
|
||||||
});
|
});
|
||||||
connect(project, &Project::parsingFinished,
|
connect(project, &Project::anyParsingFinished,
|
||||||
this, [this, project]() {
|
this, [this, project]() {
|
||||||
if (nodeForProject(project))
|
if (nodeForProject(project))
|
||||||
parsingStateChanged(project);
|
parsingStateChanged(project);
|
||||||
|
@@ -25,10 +25,12 @@
|
|||||||
|
|
||||||
#include "projectnodes.h"
|
#include "projectnodes.h"
|
||||||
|
|
||||||
|
#include "buildconfiguration.h"
|
||||||
#include "buildsystem.h"
|
#include "buildsystem.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "projectexplorerconstants.h"
|
#include "projectexplorerconstants.h"
|
||||||
#include "projecttree.h"
|
#include "projecttree.h"
|
||||||
|
#include "target.h"
|
||||||
|
|
||||||
#include <coreplugin/fileiconprovider.h>
|
#include <coreplugin/fileiconprovider.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
@@ -988,7 +990,8 @@ void ProjectNode::setFallbackData(Core::Id key, const QVariant &value)
|
|||||||
BuildSystem *ProjectNode::buildSystem() const
|
BuildSystem *ProjectNode::buildSystem() const
|
||||||
{
|
{
|
||||||
Project *p = getProject();
|
Project *p = getProject();
|
||||||
return p ? p->buildSystem() : nullptr;
|
Target *t = p ? p->activeTarget() : nullptr;
|
||||||
|
return t ? t->buildSystem() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FolderNode::isEmpty() const
|
bool FolderNode::isEmpty() const
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include "projectnodes.h"
|
#include "projectnodes.h"
|
||||||
#include "projecttreewidget.h"
|
#include "projecttreewidget.h"
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
|
#include "target.h"
|
||||||
|
|
||||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||||
#include <coreplugin/actionmanager/actionmanager.h>
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
@@ -104,6 +105,18 @@ Project *ProjectTree::currentProject()
|
|||||||
return s_instance->m_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()
|
Node *ProjectTree::currentNode()
|
||||||
{
|
{
|
||||||
s_instance->update();
|
s_instance->update();
|
||||||
|
@@ -34,12 +34,14 @@
|
|||||||
namespace Utils { class FilePath; }
|
namespace Utils { class FilePath; }
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
|
class BuildSystem;
|
||||||
class FileNode;
|
class FileNode;
|
||||||
class FolderNode;
|
class FolderNode;
|
||||||
class Node;
|
class Node;
|
||||||
class Project;
|
class Project;
|
||||||
class ProjectNode;
|
class ProjectNode;
|
||||||
class SessionNode;
|
class SessionNode;
|
||||||
|
class Target;
|
||||||
|
|
||||||
namespace Internal { class ProjectTreeWidget; }
|
namespace Internal { class ProjectTreeWidget; }
|
||||||
|
|
||||||
@@ -53,6 +55,8 @@ public:
|
|||||||
static ProjectTree *instance();
|
static ProjectTree *instance();
|
||||||
|
|
||||||
static Project *currentProject();
|
static Project *currentProject();
|
||||||
|
static Target *currentTarget();
|
||||||
|
static BuildSystem *currentBuildSystem();
|
||||||
static Node *currentNode();
|
static Node *currentNode();
|
||||||
static Utils::FilePath currentFilePath();
|
static Utils::FilePath currentFilePath();
|
||||||
|
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "abi.h"
|
#include "abi.h"
|
||||||
#include "buildconfiguration.h"
|
#include "buildconfiguration.h"
|
||||||
|
#include "buildsystem.h"
|
||||||
#include "environmentaspect.h"
|
#include "environmentaspect.h"
|
||||||
#include "kitinformation.h"
|
#include "kitinformation.h"
|
||||||
#include "kitinformation.h"
|
#include "kitinformation.h"
|
||||||
@@ -168,8 +169,7 @@ RunConfiguration::RunConfiguration(Target *target, Core::Id id)
|
|||||||
: ProjectConfiguration(target, id)
|
: ProjectConfiguration(target, id)
|
||||||
{
|
{
|
||||||
QTC_CHECK(target && target == this->target());
|
QTC_CHECK(target && target == this->target());
|
||||||
connect(target->project(), &Project::parsingFinished,
|
connect(target, &Target::parsingFinished, this, [this] { updateEnabledState(); });
|
||||||
this, [this]() { updateEnabledState(); });
|
|
||||||
|
|
||||||
connect(target, &Target::addedRunConfiguration,
|
connect(target, &Target::addedRunConfiguration,
|
||||||
this, [this](const RunConfiguration *rc) {
|
this, [this](const RunConfiguration *rc) {
|
||||||
@@ -224,25 +224,16 @@ bool RunConfiguration::isActive() const
|
|||||||
return target()->isActive() && target()->activeRunConfiguration() == this;
|
return target()->isActive() && target()->activeRunConfiguration() == this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunConfiguration::setEnabled(bool enabled)
|
|
||||||
{
|
|
||||||
if (enabled == m_isEnabled)
|
|
||||||
return;
|
|
||||||
m_isEnabled = enabled;
|
|
||||||
emit enabledChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RunConfiguration::disabledReason() const
|
QString RunConfiguration::disabledReason() const
|
||||||
{
|
{
|
||||||
if (!project()->hasParsingData()) {
|
BuildSystem *bs = activeBuildSystem();
|
||||||
QString msg = project()->isParsing() ? tr("The project is currently being parsed.")
|
return bs ? bs->disabledReason(m_buildKey) : tr("No build system active");
|
||||||
: tr("The project could not be fully parsed.");
|
}
|
||||||
const FilePath projectFilePath = buildTargetInfo().projectFilePath;
|
|
||||||
if (!projectFilePath.isEmpty() && !projectFilePath.exists())
|
bool RunConfiguration::isEnabled() const
|
||||||
msg += '\n' + tr("The project file \"%1\" does not exist.").arg(projectFilePath.toString());
|
{
|
||||||
return msg;
|
BuildSystem *bs = activeBuildSystem();
|
||||||
}
|
return bs && bs->hasParsingData();
|
||||||
return QString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *RunConfiguration::createConfigurationWidget()
|
QWidget *RunConfiguration::createConfigurationWidget()
|
||||||
@@ -266,7 +257,7 @@ QWidget *RunConfiguration::createConfigurationWidget()
|
|||||||
|
|
||||||
void RunConfiguration::updateEnabledState()
|
void RunConfiguration::updateEnabledState()
|
||||||
{
|
{
|
||||||
setEnabled(project()->hasParsingData());
|
emit enabledChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunConfiguration::addAspectFactory(const AspectFactory &aspectFactory)
|
void RunConfiguration::addAspectFactory(const AspectFactory &aspectFactory)
|
||||||
@@ -312,11 +303,14 @@ RunConfiguration::ConfigurationState RunConfiguration::ensureConfigured(QString
|
|||||||
|
|
||||||
BuildConfiguration *RunConfiguration::activeBuildConfiguration() const
|
BuildConfiguration *RunConfiguration::activeBuildConfiguration() const
|
||||||
{
|
{
|
||||||
if (!target())
|
|
||||||
return nullptr;
|
|
||||||
return target()->activeBuildConfiguration();
|
return target()->activeBuildConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BuildSystem *RunConfiguration::activeBuildSystem() const
|
||||||
|
{
|
||||||
|
return target()->buildSystem();
|
||||||
|
}
|
||||||
|
|
||||||
QVariantMap RunConfiguration::toMap() const
|
QVariantMap RunConfiguration::toMap() const
|
||||||
{
|
{
|
||||||
QVariantMap map = ProjectConfiguration::toMap();
|
QVariantMap map = ProjectConfiguration::toMap();
|
||||||
@@ -344,7 +338,9 @@ CommandLine RunConfiguration::commandLine() const
|
|||||||
|
|
||||||
BuildTargetInfo RunConfiguration::buildTargetInfo() 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)
|
bool RunConfiguration::fromMap(const QVariantMap &map)
|
||||||
|
@@ -43,6 +43,7 @@ namespace Utils { class OutputFormatter; }
|
|||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
class BuildConfiguration;
|
class BuildConfiguration;
|
||||||
|
class BuildSystem;
|
||||||
class GlobalOrProjectAspect;
|
class GlobalOrProjectAspect;
|
||||||
class Runnable;
|
class Runnable;
|
||||||
class RunConfigurationFactory;
|
class RunConfigurationFactory;
|
||||||
@@ -126,10 +127,8 @@ public:
|
|||||||
|
|
||||||
bool isActive() const override;
|
bool isActive() const override;
|
||||||
|
|
||||||
bool isEnabled() const { return m_isEnabled; }
|
|
||||||
void setEnabled(bool enabled);
|
|
||||||
|
|
||||||
virtual QString disabledReason() const;
|
virtual QString disabledReason() const;
|
||||||
|
virtual bool isEnabled() const;
|
||||||
|
|
||||||
virtual QWidget *createConfigurationWidget();
|
virtual QWidget *createConfigurationWidget();
|
||||||
|
|
||||||
@@ -182,6 +181,7 @@ protected:
|
|||||||
|
|
||||||
/// convenience function to get current build configuration.
|
/// convenience function to get current build configuration.
|
||||||
BuildConfiguration *activeBuildConfiguration() const;
|
BuildConfiguration *activeBuildConfiguration() const;
|
||||||
|
BuildSystem *activeBuildSystem() const;
|
||||||
|
|
||||||
virtual void updateEnabledState();
|
virtual void updateEnabledState();
|
||||||
virtual void doAdditionalSetup(const RunConfigurationCreationInfo &) {}
|
virtual void doAdditionalSetup(const RunConfigurationCreationInfo &) {}
|
||||||
@@ -193,7 +193,6 @@ private:
|
|||||||
friend class RunConfigurationFactory;
|
friend class RunConfigurationFactory;
|
||||||
|
|
||||||
QString m_buildKey;
|
QString m_buildKey;
|
||||||
bool m_isEnabled = false;
|
|
||||||
CommandLineGetter m_commandLineGetter;
|
CommandLineGetter m_commandLineGetter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -376,7 +376,7 @@ void RunControl::setTarget(Target *target)
|
|||||||
QTC_CHECK(!d->target);
|
QTC_CHECK(!d->target);
|
||||||
d->target = target;
|
d->target = target;
|
||||||
|
|
||||||
if (!d->buildKey.isEmpty())
|
if (!d->buildKey.isEmpty() && target->buildSystem())
|
||||||
d->buildTargetInfo = target->buildTarget(d->buildKey);
|
d->buildTargetInfo = target->buildTarget(d->buildKey);
|
||||||
|
|
||||||
if (auto bc = target->activeBuildConfiguration()) {
|
if (auto bc = target->activeBuildConfiguration()) {
|
||||||
|
@@ -381,6 +381,17 @@ Project *SessionManager::startupProject()
|
|||||||
return d->m_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)
|
void SessionManager::addProject(Project *pro)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(pro, return);
|
QTC_ASSERT(pro, return);
|
||||||
|
@@ -42,7 +42,9 @@ namespace ProjectExplorer {
|
|||||||
class Project;
|
class Project;
|
||||||
class Target;
|
class Target;
|
||||||
class BuildConfiguration;
|
class BuildConfiguration;
|
||||||
|
class BuildSystem;
|
||||||
class DeployConfiguration;
|
class DeployConfiguration;
|
||||||
|
|
||||||
enum class SetActive { Cascade, NoCascade };
|
enum class SetActive { Cascade, NoCascade };
|
||||||
|
|
||||||
class PROJECTEXPLORER_EXPORT SessionManager : public QObject
|
class PROJECTEXPLORER_EXPORT SessionManager : public QObject
|
||||||
@@ -96,6 +98,8 @@ public:
|
|||||||
|
|
||||||
static Utils::FilePath sessionNameToFileName(const QString &session);
|
static Utils::FilePath sessionNameToFileName(const QString &session);
|
||||||
static Project *startupProject();
|
static Project *startupProject();
|
||||||
|
static Target *startupTarget();
|
||||||
|
static BuildSystem *startupBuildSystem();
|
||||||
|
|
||||||
static const QList<Project *> projects();
|
static const QList<Project *> projects();
|
||||||
static bool hasProjects();
|
static bool hasProjects();
|
||||||
@@ -119,6 +123,8 @@ public:
|
|||||||
static bool loadingSession();
|
static bool loadingSession();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void targetAdded(ProjectExplorer::Target *target);
|
||||||
|
void targetRemoved(ProjectExplorer::Target *target);
|
||||||
void projectAdded(ProjectExplorer::Project *project);
|
void projectAdded(ProjectExplorer::Project *project);
|
||||||
void aboutToRemoveProject(ProjectExplorer::Project *project);
|
void aboutToRemoveProject(ProjectExplorer::Project *project);
|
||||||
void projectDisplayNameChanged(ProjectExplorer::Project *project);
|
void projectDisplayNameChanged(ProjectExplorer::Project *project);
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
#include "buildconfiguration.h"
|
#include "buildconfiguration.h"
|
||||||
#include "buildinfo.h"
|
#include "buildinfo.h"
|
||||||
#include "buildmanager.h"
|
#include "buildmanager.h"
|
||||||
|
#include "buildsystem.h"
|
||||||
#include "buildtargetinfo.h"
|
#include "buildtargetinfo.h"
|
||||||
#include "deployconfiguration.h"
|
#include "deployconfiguration.h"
|
||||||
#include "deploymentdata.h"
|
#include "deploymentdata.h"
|
||||||
@@ -98,20 +99,24 @@ public:
|
|||||||
m_runConfigurationModel(t)
|
m_runConfigurationModel(t)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
~TargetPrivate()
|
||||||
|
{
|
||||||
|
delete m_buildSystem;
|
||||||
|
}
|
||||||
|
|
||||||
QIcon m_overlayIcon;
|
QIcon m_overlayIcon;
|
||||||
|
|
||||||
QList<BuildConfiguration *> m_buildConfigurations;
|
QList<BuildConfiguration *> m_buildConfigurations;
|
||||||
BuildConfiguration *m_activeBuildConfiguration = nullptr;
|
QPointer<BuildConfiguration> m_activeBuildConfiguration;
|
||||||
QList<DeployConfiguration *> m_deployConfigurations;
|
QList<DeployConfiguration *> m_deployConfigurations;
|
||||||
DeployConfiguration *m_activeDeployConfiguration = nullptr;
|
DeployConfiguration *m_activeDeployConfiguration = nullptr;
|
||||||
QList<RunConfiguration *> m_runConfigurations;
|
QList<RunConfiguration *> m_runConfigurations;
|
||||||
RunConfiguration* m_activeRunConfiguration = nullptr;
|
RunConfiguration* m_activeRunConfiguration = nullptr;
|
||||||
DeploymentData m_deploymentData;
|
|
||||||
QList<BuildTargetInfo> m_appTargets;
|
|
||||||
QVariantMap m_pluginSettings;
|
QVariantMap m_pluginSettings;
|
||||||
|
|
||||||
Kit *const m_kit;
|
Kit *const m_kit;
|
||||||
MacroExpander m_macroExpander;
|
MacroExpander m_macroExpander;
|
||||||
|
BuildSystem *m_buildSystem = nullptr;
|
||||||
|
|
||||||
ProjectConfigurationModel m_buildConfigurationModel;
|
ProjectConfigurationModel m_buildConfigurationModel;
|
||||||
ProjectConfigurationModel m_deployConfigurationModel;
|
ProjectConfigurationModel m_deployConfigurationModel;
|
||||||
@@ -123,13 +128,24 @@ Target::Target(Project *project, Kit *k, _constructor_tag) :
|
|||||||
QObject(project),
|
QObject(project),
|
||||||
d(std::make_unique<TargetPrivate>(this, k))
|
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);
|
QTC_CHECK(d->m_kit);
|
||||||
connect(DeviceManager::instance(), &DeviceManager::updated, this, &Target::updateDeviceState);
|
connect(DeviceManager::instance(), &DeviceManager::updated, this, &Target::updateDeviceState);
|
||||||
connect(project, &Project::parsingFinished, this, [this](bool success) {
|
|
||||||
if (success && this->project() == SessionManager::startupProject()
|
connect(this, &Target::parsingStarted, this, [this, project] {
|
||||||
&& this == this->project()->activeTarget()) {
|
project->anyParsingStarted(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(this, &Target::parsingFinished, this, [this, project](bool success) {
|
||||||
|
if (success && project == SessionManager::startupProject()
|
||||||
|
&& this == project->activeTarget()) {
|
||||||
updateDefaultRunConfigurations();
|
updateDefaultRunConfigurations();
|
||||||
}
|
}
|
||||||
|
// For testing.
|
||||||
|
emit SessionManager::instance()->projectFinishedParsing(project);
|
||||||
|
project->anyParsingFinished(this, success);
|
||||||
}, Qt::QueuedConnection); // Must wait for run configs to change their enabled state.
|
}, Qt::QueuedConnection); // Must wait for run configs to change their enabled state.
|
||||||
|
|
||||||
KitManager *km = KitManager::instance();
|
KitManager *km = KitManager::instance();
|
||||||
@@ -193,6 +209,37 @@ Kit *Target::kit() const
|
|||||||
return d->m_kit;
|
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
|
Core::Id Target::id() const
|
||||||
{
|
{
|
||||||
return d->m_kit->id();
|
return d->m_kit->id();
|
||||||
@@ -277,7 +324,6 @@ void Target::setActiveBuildConfiguration(BuildConfiguration *bc)
|
|||||||
(bc && d->m_buildConfigurations.contains(bc) &&
|
(bc && d->m_buildConfigurations.contains(bc) &&
|
||||||
bc != d->m_activeBuildConfiguration)) {
|
bc != d->m_activeBuildConfiguration)) {
|
||||||
d->m_activeBuildConfiguration = bc;
|
d->m_activeBuildConfiguration = bc;
|
||||||
project()->activeBuildConfigurationChanged(d->m_activeBuildConfiguration);
|
|
||||||
emit activeBuildConfigurationChanged(d->m_activeBuildConfiguration);
|
emit activeBuildConfigurationChanged(d->m_activeBuildConfiguration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -353,49 +399,6 @@ void Target::setActiveDeployConfiguration(DeployConfiguration *dc)
|
|||||||
updateDeviceState();
|
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
|
QList<RunConfiguration *> Target::runConfigurations() const
|
||||||
{
|
{
|
||||||
return d->m_runConfigurations;
|
return d->m_runConfigurations;
|
||||||
@@ -716,7 +719,7 @@ void Target::setNamedSettings(const QString &name, const QVariant &value)
|
|||||||
|
|
||||||
QVariant Target::additionalData(Core::Id id) const
|
QVariant Target::additionalData(Core::Id id) const
|
||||||
{
|
{
|
||||||
return project()->additionalData(id, this);
|
return buildSystem()->additionalData(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeInstallCommand Target::makeInstallCommand(const QString &installRoot) const
|
MakeInstallCommand Target::makeInstallCommand(const QString &installRoot) const
|
||||||
|
@@ -35,6 +35,7 @@ QT_FORWARD_DECLARE_CLASS(QIcon)
|
|||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
class BuildConfiguration;
|
class BuildConfiguration;
|
||||||
class BuildTargetInfo;
|
class BuildTargetInfo;
|
||||||
|
class BuildSystem;
|
||||||
class DeployConfiguration;
|
class DeployConfiguration;
|
||||||
class DeploymentData;
|
class DeploymentData;
|
||||||
class Kit;
|
class Kit;
|
||||||
@@ -60,6 +61,7 @@ public:
|
|||||||
|
|
||||||
Project *project() const;
|
Project *project() const;
|
||||||
Kit *kit() const;
|
Kit *kit() const;
|
||||||
|
BuildSystem *buildSystem() const;
|
||||||
|
|
||||||
Core::Id id() const;
|
Core::Id id() const;
|
||||||
QString displayName() const;
|
QString displayName() const;
|
||||||
@@ -79,15 +81,6 @@ public:
|
|||||||
QList<DeployConfiguration *> deployConfigurations() const;
|
QList<DeployConfiguration *> deployConfigurations() const;
|
||||||
DeployConfiguration *activeDeployConfiguration() 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
|
// Running
|
||||||
QList<RunConfiguration *> runConfigurations() const;
|
QList<RunConfiguration *> runConfigurations() const;
|
||||||
void addRunConfiguration(RunConfiguration *rc);
|
void addRunConfiguration(RunConfiguration *rc);
|
||||||
@@ -119,12 +112,20 @@ public:
|
|||||||
ProjectConfigurationModel *deployConfigurationModel() const;
|
ProjectConfigurationModel *deployConfigurationModel() const;
|
||||||
ProjectConfigurationModel *runConfigurationModel() const;
|
ProjectConfigurationModel *runConfigurationModel() const;
|
||||||
|
|
||||||
|
BuildSystem *fallbackBuildSystem() const;
|
||||||
|
|
||||||
|
DeploymentData deploymentData() const;
|
||||||
|
const QList<BuildTargetInfo> applicationTargets() const;
|
||||||
|
BuildTargetInfo buildTarget(const QString &buildKey) const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void targetEnabled(bool);
|
void targetEnabled(bool);
|
||||||
void iconChanged();
|
void iconChanged();
|
||||||
void overlayIconChanged();
|
void overlayIconChanged();
|
||||||
|
|
||||||
void kitChanged();
|
void kitChanged();
|
||||||
|
void parsingStarted();
|
||||||
|
void parsingFinished(bool);
|
||||||
|
|
||||||
// TODO clean up signal names
|
// TODO clean up signal names
|
||||||
// might be better to also have aboutToRemove signals
|
// might be better to also have aboutToRemove signals
|
||||||
@@ -143,6 +144,7 @@ signals:
|
|||||||
|
|
||||||
void deploymentDataChanged();
|
void deploymentDataChanged();
|
||||||
void applicationTargetsChanged();
|
void applicationTargetsChanged();
|
||||||
|
void targetPropertiesChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool fromMap(const QVariantMap &map);
|
bool fromMap(const QVariantMap &map);
|
||||||
|
@@ -39,6 +39,7 @@
|
|||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QProcessEnvironment>
|
#include <QProcessEnvironment>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
#include <coreplugin/documentmanager.h>
|
#include <coreplugin/documentmanager.h>
|
||||||
#include <coreplugin/icontext.h>
|
#include <coreplugin/icontext.h>
|
||||||
@@ -57,7 +58,7 @@ namespace Internal {
|
|||||||
class PythonBuildSystem : public BuildSystem
|
class PythonBuildSystem : public BuildSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit PythonBuildSystem(Project *project);
|
explicit PythonBuildSystem(Target *target);
|
||||||
|
|
||||||
bool supportsAction(Node *context, ProjectAction action, const Node *node) const override;
|
bool supportsAction(Node *context, ProjectAction action, const Node *node) const override;
|
||||||
bool addFiles(Node *, const QStringList &filePaths, QStringList *) override;
|
bool addFiles(Node *, const QStringList &filePaths, QStringList *) override;
|
||||||
@@ -74,11 +75,9 @@ public:
|
|||||||
bool writePyProjectFile(const QString &fileName, QString &content,
|
bool writePyProjectFile(const QString &fileName, QString &content,
|
||||||
const QStringList &rawList, QString *errorMessage);
|
const QStringList &rawList, QString *errorMessage);
|
||||||
|
|
||||||
void refresh();
|
void triggerParsing() final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PythonProject *project() const;
|
|
||||||
|
|
||||||
QStringList m_rawFileList;
|
QStringList m_rawFileList;
|
||||||
QStringList m_files;
|
QStringList m_files;
|
||||||
QHash<QString, QString> m_rawListEntries;
|
QHash<QString, QString> m_rawListEntries;
|
||||||
@@ -191,12 +190,12 @@ PythonProject::PythonProject(const FilePath &fileName)
|
|||||||
setDisplayName(fileName.toFileInfo().completeBaseName());
|
setDisplayName(fileName.toFileInfo().completeBaseName());
|
||||||
|
|
||||||
setNeedsBuildConfigurations(false);
|
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();
|
parse();
|
||||||
|
|
||||||
const QDir baseDir(projectDirectory().toString());
|
const QDir baseDir(projectDirectory().toString());
|
||||||
@@ -225,8 +224,7 @@ void PythonBuildSystem::refresh()
|
|||||||
}
|
}
|
||||||
project()->setRootProjectNode(std::move(newRoot));
|
project()->setRootProjectNode(std::move(newRoot));
|
||||||
|
|
||||||
if (Target *target = project()->activeTarget())
|
setApplicationTargets(appTargets);
|
||||||
target->setApplicationTargets(appTargets);
|
|
||||||
|
|
||||||
guard.markAsSuccess();
|
guard.markAsSuccess();
|
||||||
}
|
}
|
||||||
@@ -423,27 +421,16 @@ Project::RestoreResult PythonProject::fromMap(const QVariantMap &map, QString *e
|
|||||||
if (res == RestoreResult::Ok) {
|
if (res == RestoreResult::Ok) {
|
||||||
if (!activeTarget())
|
if (!activeTarget())
|
||||||
addTargetForDefaultKit();
|
addTargetForDefaultKit();
|
||||||
|
|
||||||
if (auto bs = dynamic_cast<PythonBuildSystem *>(buildSystem()))
|
|
||||||
bs->refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PythonProject::setupTarget(Target *t)
|
PythonBuildSystem::PythonBuildSystem(Target *target)
|
||||||
|
: BuildSystem(target)
|
||||||
{
|
{
|
||||||
bool res = Project::setupTarget(t);
|
connect(target->project(), &Project::projectFileIsDirty, this, [this]() { triggerParsing(); });
|
||||||
if (auto bs = dynamic_cast<PythonBuildSystem *>(buildSystem()))
|
QTimer::singleShot(0, this, &PythonBuildSystem::triggerParsing);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PythonBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
|
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);
|
return BuildSystem::supportsAction(context, action, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
PythonProject *PythonBuildSystem::project() const
|
|
||||||
{
|
|
||||||
return static_cast<PythonProject *>(BuildSystem::project());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Python
|
} // namespace Python
|
||||||
|
@@ -43,7 +43,6 @@ public:
|
|||||||
bool needsConfiguration() const final { return false; }
|
bool needsConfiguration() const final { return false; }
|
||||||
private:
|
private:
|
||||||
RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override;
|
RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override;
|
||||||
bool setupTarget(ProjectExplorer::Target *t) override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -279,7 +279,7 @@ PythonRunConfiguration::PythonRunConfiguration(Target *target, Core::Id id)
|
|||||||
|
|
||||||
connect(target, &Target::applicationTargetsChanged,
|
connect(target, &Target::applicationTargetsChanged,
|
||||||
this, &PythonRunConfiguration::updateTargetInformation);
|
this, &PythonRunConfiguration::updateTargetInformation);
|
||||||
connect(target->project(), &Project::parsingFinished,
|
connect(target, &Target::parsingFinished,
|
||||||
this, &PythonRunConfiguration::updateTargetInformation);
|
this, &PythonRunConfiguration::updateTargetInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -52,6 +52,7 @@
|
|||||||
#include <utils/qtcprocess.h>
|
#include <utils/qtcprocess.h>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QCryptographicHash>
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
@@ -92,6 +93,18 @@ QbsBuildConfiguration::QbsBuildConfiguration(Target *target, Core::Id id)
|
|||||||
this, &QbsBuildConfiguration::triggerReparseIfActive);
|
this, &QbsBuildConfiguration::triggerReparseIfActive);
|
||||||
connect(this, &QbsBuildConfiguration::qbsConfigurationChanged,
|
connect(this, &QbsBuildConfiguration::qbsConfigurationChanged,
|
||||||
this, &QbsBuildConfiguration::triggerReparseIfActive);
|
this, &QbsBuildConfiguration::triggerReparseIfActive);
|
||||||
|
|
||||||
|
m_buildSystem = new QbsBuildSystem(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
QbsBuildConfiguration::~QbsBuildConfiguration()
|
||||||
|
{
|
||||||
|
delete m_buildSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildSystem *QbsBuildConfiguration::buildSystem() const
|
||||||
|
{
|
||||||
|
return m_buildSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QbsBuildConfiguration::initialize()
|
void QbsBuildConfiguration::initialize()
|
||||||
@@ -119,7 +132,15 @@ void QbsBuildConfiguration::initialize()
|
|||||||
+ Utils::FileUtils::fileSystemFriendlyName(initialDisplayName());
|
+ 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);
|
BuildStepList *buildSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
|
||||||
auto bs = new QbsBuildStep(buildSteps);
|
auto bs = new QbsBuildStep(buildSteps);
|
||||||
@@ -137,7 +158,7 @@ void QbsBuildConfiguration::initialize()
|
|||||||
void QbsBuildConfiguration::triggerReparseIfActive()
|
void QbsBuildConfiguration::triggerReparseIfActive()
|
||||||
{
|
{
|
||||||
if (isActive())
|
if (isActive())
|
||||||
qbsProject()->delayParsing();
|
m_buildSystem->delayParsing();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QbsBuildConfiguration::fromMap(const QVariantMap &map)
|
bool QbsBuildConfiguration::fromMap(const QVariantMap &map)
|
||||||
@@ -169,11 +190,6 @@ QVariantMap QbsBuildConfiguration::qbsConfiguration() const
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
Internal::QbsProject *QbsBuildConfiguration::qbsProject() const
|
|
||||||
{
|
|
||||||
return qobject_cast<Internal::QbsProject *>(project());
|
|
||||||
}
|
|
||||||
|
|
||||||
BuildConfiguration::BuildType QbsBuildConfiguration::buildType() const
|
BuildConfiguration::BuildType QbsBuildConfiguration::buildType() const
|
||||||
{
|
{
|
||||||
QString variant;
|
QString variant;
|
||||||
|
@@ -46,15 +46,15 @@ class QbsBuildConfiguration : public ProjectExplorer::BuildConfiguration
|
|||||||
|
|
||||||
friend class ProjectExplorer::BuildConfigurationFactory;
|
friend class ProjectExplorer::BuildConfigurationFactory;
|
||||||
QbsBuildConfiguration(ProjectExplorer::Target *target, Core::Id id);
|
QbsBuildConfiguration(ProjectExplorer::Target *target, Core::Id id);
|
||||||
|
~QbsBuildConfiguration() final;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void initialize() override;
|
ProjectExplorer::BuildSystem *buildSystem() const final;
|
||||||
|
void initialize() final;
|
||||||
|
|
||||||
QbsBuildStep *qbsStep() const;
|
QbsBuildStep *qbsStep() const;
|
||||||
QVariantMap qbsConfiguration() const;
|
QVariantMap qbsConfiguration() const;
|
||||||
|
|
||||||
Internal::QbsProject *qbsProject() const;
|
|
||||||
|
|
||||||
BuildType buildType() const override;
|
BuildType buildType() const override;
|
||||||
|
|
||||||
void setChangedFiles(const QStringList &files);
|
void setChangedFiles(const QStringList &files);
|
||||||
@@ -67,7 +67,6 @@ public:
|
|||||||
QStringList products() const;
|
QStringList products() const;
|
||||||
|
|
||||||
QString configurationName() const;
|
QString configurationName() const;
|
||||||
|
|
||||||
QString equivalentCommandLine(const ProjectExplorer::BuildStep *buildStep) const;
|
QString equivalentCommandLine(const ProjectExplorer::BuildStep *buildStep) const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
@@ -80,7 +79,8 @@ private:
|
|||||||
QStringList m_changedFiles;
|
QStringList m_changedFiles;
|
||||||
QStringList m_activeFileTags;
|
QStringList m_activeFileTags;
|
||||||
QStringList m_products;
|
QStringList m_products;
|
||||||
ProjectExplorer::BaseStringAspect *m_configurationName;
|
ProjectExplorer::BaseStringAspect *m_configurationName = nullptr;
|
||||||
|
QbsBuildSystem *m_buildSystem = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QbsBuildConfigurationFactory : public ProjectExplorer::BuildConfigurationFactory
|
class QbsBuildConfigurationFactory : public ProjectExplorer::BuildConfigurationFactory
|
||||||
|
@@ -170,7 +170,7 @@ QbsBuildStep::~QbsBuildStep()
|
|||||||
|
|
||||||
bool QbsBuildStep::init()
|
bool QbsBuildStep::init()
|
||||||
{
|
{
|
||||||
if (project()->isParsing() || m_job)
|
if (qbsBuildSystem()->isParsing() || m_job)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto bc = static_cast<QbsBuildConfiguration *>(buildConfiguration());
|
auto bc = static_cast<QbsBuildConfiguration *>(buildConfiguration());
|
||||||
@@ -212,7 +212,7 @@ ProjectExplorer::BuildStepConfigWidget *QbsBuildStep::createConfigWidget()
|
|||||||
void QbsBuildStep::doCancel()
|
void QbsBuildStep::doCancel()
|
||||||
{
|
{
|
||||||
if (m_parsingProject)
|
if (m_parsingProject)
|
||||||
qbsProject()->cancelParsing();
|
qbsBuildSystem()->cancelParsing();
|
||||||
else if (m_job)
|
else if (m_job)
|
||||||
m_job->cancel();
|
m_job->cancel();
|
||||||
}
|
}
|
||||||
@@ -238,10 +238,8 @@ QVariantMap QbsBuildStep::qbsConfiguration(VariableHandling variableHandling) co
|
|||||||
|
|
||||||
void QbsBuildStep::setQbsConfiguration(const QVariantMap &config)
|
void QbsBuildStep::setQbsConfiguration(const QVariantMap &config)
|
||||||
{
|
{
|
||||||
auto pro = static_cast<QbsProject *>(project());
|
|
||||||
|
|
||||||
QVariantMap tmp = config;
|
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))
|
if (!tmp.contains(Constants::QBS_CONFIG_VARIANT_KEY))
|
||||||
tmp.insert(Constants::QBS_CONFIG_VARIANT_KEY,
|
tmp.insert(Constants::QBS_CONFIG_VARIANT_KEY,
|
||||||
QString::fromLatin1(Constants::QBS_VARIANT_DEBUG));
|
QString::fromLatin1(Constants::QBS_VARIANT_DEBUG));
|
||||||
@@ -347,14 +345,12 @@ void QbsBuildStep::buildingDone(bool success)
|
|||||||
createTaskAndOutput(ProjectExplorer::Task::Error, item.description(),
|
createTaskAndOutput(ProjectExplorer::Task::Error, item.description(),
|
||||||
item.codeLocation().filePath(), item.codeLocation().line());
|
item.codeLocation().filePath(), item.codeLocation().line());
|
||||||
|
|
||||||
auto pro = static_cast<QbsProject *>(project());
|
|
||||||
|
|
||||||
// Building can uncover additional target artifacts.
|
// 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
|
// 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.
|
// otherwise a potential additional build step could conflict with the parsing step.
|
||||||
if (pro->parsingScheduled())
|
if (qbsBuildSystem()->parsingScheduled())
|
||||||
parseProject();
|
parseProject();
|
||||||
else
|
else
|
||||||
finish();
|
finish();
|
||||||
@@ -362,7 +358,7 @@ void QbsBuildStep::buildingDone(bool success)
|
|||||||
|
|
||||||
void QbsBuildStep::reparsingDone(bool success)
|
void QbsBuildStep::reparsingDone(bool success)
|
||||||
{
|
{
|
||||||
disconnect(project(), &Project::parsingFinished, this, &QbsBuildStep::reparsingDone);
|
disconnect(target(), &Target::parsingFinished, this, &QbsBuildStep::reparsingDone);
|
||||||
m_parsingProject = false;
|
m_parsingProject = false;
|
||||||
if (m_job) { // This was a scheduled reparsing after building.
|
if (m_job) { // This was a scheduled reparsing after building.
|
||||||
finish();
|
finish();
|
||||||
@@ -431,6 +427,11 @@ QString QbsBuildStep::buildVariant() const
|
|||||||
return qbsConfiguration(PreserveVariables).value(Constants::QBS_CONFIG_VARIANT_KEY).toString();
|
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)
|
void QbsBuildStep::setBuildVariant(const QString &variant)
|
||||||
{
|
{
|
||||||
if (m_qbsConfiguration.value(Constants::QBS_CONFIG_VARIANT_KEY).toString() == variant)
|
if (m_qbsConfiguration.value(Constants::QBS_CONFIG_VARIANT_KEY).toString() == variant)
|
||||||
@@ -490,8 +491,8 @@ void QbsBuildStep::setCleanInstallRoot(bool clean)
|
|||||||
void QbsBuildStep::parseProject()
|
void QbsBuildStep::parseProject()
|
||||||
{
|
{
|
||||||
m_parsingProject = true;
|
m_parsingProject = true;
|
||||||
connect(project(), &Project::parsingFinished, this, &QbsBuildStep::reparsingDone);
|
connect(target(), &Target::parsingFinished, this, &QbsBuildStep::reparsingDone);
|
||||||
qbsProject()->parseCurrentBuildConfiguration();
|
qbsBuildSystem()->parseCurrentBuildConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QbsBuildStep::build()
|
void QbsBuildStep::build()
|
||||||
@@ -503,7 +504,7 @@ void QbsBuildStep::build()
|
|||||||
options.setLogElapsedTime(!qEnvironmentVariableIsEmpty(Constants::QBS_PROFILING_ENV));
|
options.setLogElapsedTime(!qEnvironmentVariableIsEmpty(Constants::QBS_PROFILING_ENV));
|
||||||
|
|
||||||
QString error;
|
QString error;
|
||||||
m_job = qbsProject()->build(options, m_products, error);
|
m_job = qbsBuildSystem()->build(options, m_products, error);
|
||||||
if (!m_job) {
|
if (!m_job) {
|
||||||
emit addOutput(error, OutputFormat::ErrorMessage);
|
emit addOutput(error, OutputFormat::ErrorMessage);
|
||||||
emit finished(false);
|
emit finished(false);
|
||||||
|
@@ -79,6 +79,8 @@ public:
|
|||||||
}
|
}
|
||||||
bool isQmlDebuggingEnabled() const { return m_enableQmlDebugging; }
|
bool isQmlDebuggingEnabled() const { return m_enableQmlDebugging; }
|
||||||
|
|
||||||
|
QbsBuildSystem *qbsBuildSystem() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void qbsConfigurationChanged();
|
void qbsConfigurationChanged();
|
||||||
void qbsBuildOptionsChanged();
|
void qbsBuildOptionsChanged();
|
||||||
|
@@ -81,7 +81,7 @@ QbsCleanStep::~QbsCleanStep()
|
|||||||
|
|
||||||
bool QbsCleanStep::init()
|
bool QbsCleanStep::init()
|
||||||
{
|
{
|
||||||
if (project()->isParsing() || m_job)
|
if (buildSystem()->isParsing() || m_job)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto bc = static_cast<QbsBuildConfiguration *>(buildConfiguration());
|
auto bc = static_cast<QbsBuildConfiguration *>(buildConfiguration());
|
||||||
@@ -95,13 +95,12 @@ bool QbsCleanStep::init()
|
|||||||
|
|
||||||
void QbsCleanStep::doRun()
|
void QbsCleanStep::doRun()
|
||||||
{
|
{
|
||||||
auto pro = static_cast<QbsProject *>(project());
|
|
||||||
qbs::CleanOptions options;
|
qbs::CleanOptions options;
|
||||||
options.setDryRun(m_dryRunAspect->value());
|
options.setDryRun(m_dryRunAspect->value());
|
||||||
options.setKeepGoing(m_keepGoingAspect->value());
|
options.setKeepGoing(m_keepGoingAspect->value());
|
||||||
|
|
||||||
QString error;
|
QString error;
|
||||||
m_job = pro->clean(options, m_products, error);
|
m_job = qbsBuildSystem()->clean(options, m_products, error);
|
||||||
if (!m_job) {
|
if (!m_job) {
|
||||||
emit addOutput(error, OutputFormat::ErrorMessage);
|
emit addOutput(error, OutputFormat::ErrorMessage);
|
||||||
emit finished(false);
|
emit finished(false);
|
||||||
@@ -157,6 +156,11 @@ void QbsCleanStep::createTaskAndOutput(ProjectExplorer::Task::TaskType type, con
|
|||||||
emit addOutput(message, OutputFormat::Stdout);
|
emit addOutput(message, OutputFormat::Stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QbsBuildSystem *QbsCleanStep::qbsBuildSystem() const
|
||||||
|
{
|
||||||
|
return static_cast<QbsBuildSystem *>(buildSystem());
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
// QbsCleanStepFactory:
|
// QbsCleanStepFactory:
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
@@ -62,6 +62,8 @@ private:
|
|||||||
ProjectExplorer::BaseBoolAspect *m_dryRunAspect = nullptr;
|
ProjectExplorer::BaseBoolAspect *m_dryRunAspect = nullptr;
|
||||||
ProjectExplorer::BaseBoolAspect *m_keepGoingAspect = nullptr;
|
ProjectExplorer::BaseBoolAspect *m_keepGoingAspect = nullptr;
|
||||||
|
|
||||||
|
QbsBuildSystem *qbsBuildSystem() const;
|
||||||
|
|
||||||
QStringList m_products;
|
QStringList m_products;
|
||||||
|
|
||||||
qbs::CleanJob *m_job = nullptr;
|
qbs::CleanJob *m_job = nullptr;
|
||||||
|
@@ -109,14 +109,14 @@ QbsInstallStep::~QbsInstallStep()
|
|||||||
|
|
||||||
bool QbsInstallStep::init()
|
bool QbsInstallStep::init()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!project()->isParsing() && !m_job, return false);
|
QTC_ASSERT(!buildConfiguration()->buildSystem()->isParsing() && !m_job, return false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QbsInstallStep::doRun()
|
void QbsInstallStep::doRun()
|
||||||
{
|
{
|
||||||
auto pro = static_cast<QbsProject *>(project());
|
auto bs = static_cast<QbsBuildSystem *>(buildSystem());
|
||||||
m_job = pro->install(m_qbsInstallOptions);
|
m_job = bs->install(m_qbsInstallOptions);
|
||||||
|
|
||||||
if (!m_job) {
|
if (!m_job) {
|
||||||
emit finished(false);
|
emit finished(false);
|
||||||
@@ -336,7 +336,7 @@ QbsInstallStepConfigWidget::QbsInstallStepConfigWidget(QbsInstallStep *step) :
|
|||||||
connect(m_keepGoingCheckBox, &QAbstractButton::toggled,
|
connect(m_keepGoingCheckBox, &QAbstractButton::toggled,
|
||||||
this, &QbsInstallStepConfigWidget::changeKeepGoing);
|
this, &QbsInstallStepConfigWidget::changeKeepGoing);
|
||||||
|
|
||||||
connect(m_step->project(), &Project::parsingFinished,
|
connect(m_step->target(), &Target::parsingFinished,
|
||||||
this, &QbsInstallStepConfigWidget::updateState);
|
this, &QbsInstallStepConfigWidget::updateState);
|
||||||
|
|
||||||
updateState();
|
updateState();
|
||||||
|
@@ -54,35 +54,6 @@ using namespace ProjectExplorer;
|
|||||||
namespace QbsProjectManager {
|
namespace QbsProjectManager {
|
||||||
namespace Internal {
|
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 {
|
class FileTreeNode {
|
||||||
public:
|
public:
|
||||||
explicit FileTreeNode(const QString &n = QString(), FileTreeNode *p = nullptr, bool f = false) :
|
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:
|
// QbsGroupNode:
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
@@ -337,16 +298,11 @@ QbsProjectNode::QbsProjectNode(const Utils::FilePath &projectDirectory) :
|
|||||||
setIcon(projectIcon);
|
setIcon(projectIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
QbsProject *QbsProjectNode::project() const
|
Project *QbsProjectNode::project() const
|
||||||
{
|
{
|
||||||
return static_cast<QbsProjectNode *>(parentFolderNode())->project();
|
return static_cast<QbsProjectNode *>(parentFolderNode())->project();
|
||||||
}
|
}
|
||||||
|
|
||||||
const qbs::Project QbsProjectNode::qbsProject() const
|
|
||||||
{
|
|
||||||
return project()->qbsProject();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QbsProjectNode::setProjectData(const qbs::ProjectData &data)
|
void QbsProjectNode::setProjectData(const qbs::ProjectData &data)
|
||||||
{
|
{
|
||||||
m_projectData = data;
|
m_projectData = data;
|
||||||
@@ -356,156 +312,11 @@ void QbsProjectNode::setProjectData(const qbs::ProjectData &data)
|
|||||||
// QbsRootProjectNode:
|
// QbsRootProjectNode:
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
QbsRootProjectNode::QbsRootProjectNode(QbsProject *project) :
|
QbsRootProjectNode::QbsRootProjectNode(Project *project) :
|
||||||
QbsProjectNode(project->projectDirectory()),
|
QbsProjectNode(project->projectDirectory()),
|
||||||
m_project(project)
|
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 Internal
|
||||||
} // namespace QbsProjectManager
|
} // namespace QbsProjectManager
|
||||||
|
@@ -35,26 +35,7 @@ namespace Internal {
|
|||||||
|
|
||||||
class QbsNodeTreeBuilder;
|
class QbsNodeTreeBuilder;
|
||||||
class QbsProject;
|
class QbsProject;
|
||||||
|
class QbsBuildSystem;
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
// QbsGroupNode:
|
// QbsGroupNode:
|
||||||
@@ -106,8 +87,7 @@ class QbsProjectNode : public ProjectExplorer::ProjectNode
|
|||||||
public:
|
public:
|
||||||
explicit QbsProjectNode(const Utils::FilePath &projectDirectory);
|
explicit QbsProjectNode(const Utils::FilePath &projectDirectory);
|
||||||
|
|
||||||
virtual QbsProject *project() const;
|
virtual ProjectExplorer::Project *project() const;
|
||||||
const qbs::Project qbsProject() const;
|
|
||||||
const qbs::ProjectData qbsProjectData() const { return m_projectData; }
|
const qbs::ProjectData qbsProjectData() const { return m_projectData; }
|
||||||
|
|
||||||
void setProjectData(const qbs::ProjectData &data); // FIXME: Needed?
|
void setProjectData(const qbs::ProjectData &data); // FIXME: Needed?
|
||||||
@@ -125,12 +105,12 @@ private:
|
|||||||
class QbsRootProjectNode : public QbsProjectNode
|
class QbsRootProjectNode : public QbsProjectNode
|
||||||
{
|
{
|
||||||
public:
|
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:
|
private:
|
||||||
QbsProject *const m_project;
|
ProjectExplorer::Project *const m_project;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -203,19 +203,19 @@ QStringList unreferencedBuildSystemFiles(const qbs::Project &p)
|
|||||||
|
|
||||||
} // namespace
|
} // 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 {};
|
return {};
|
||||||
|
|
||||||
auto root = std::make_unique<QbsRootProjectNode>(project);
|
auto root = std::make_unique<QbsRootProjectNode>(buildSystem->project());
|
||||||
setupProjectNode(root.get(), project->qbsProjectData(), project->qbsProject());
|
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"));
|
buildSystemFiles->setDisplayName(QCoreApplication::translate("QbsRootProjectNode", "Qbs files"));
|
||||||
|
|
||||||
const FilePath base = project->projectDirectory();
|
const FilePath base = buildSystem->projectDirectory();
|
||||||
const QStringList files = unreferencedBuildSystemFiles(project->qbsProject());
|
const QStringList files = unreferencedBuildSystemFiles(buildSystem->qbsProject());
|
||||||
for (const QString &f : files) {
|
for (const QString &f : files) {
|
||||||
const FilePath filePath = FilePath::fromString(f);
|
const FilePath filePath = FilePath::fromString(f);
|
||||||
if (filePath.isChildOf(base))
|
if (filePath.isChildOf(base))
|
||||||
|
@@ -39,7 +39,7 @@ namespace Internal {
|
|||||||
class QbsNodeTreeBuilder
|
class QbsNodeTreeBuilder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<QbsRootProjectNode> buildTree(QbsProject *project);
|
static std::unique_ptr<QbsRootProjectNode> buildTree(QbsBuildSystem *project);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -127,57 +127,16 @@ private:
|
|||||||
|
|
||||||
QbsProject::QbsProject(const FilePath &fileName)
|
QbsProject::QbsProject(const FilePath &fileName)
|
||||||
: Project(Constants::MIME_TYPE, fileName)
|
: Project(Constants::MIME_TYPE, fileName)
|
||||||
, m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
|
|
||||||
{
|
{
|
||||||
m_parsingDelay.setInterval(1000); // delay parsing by 1s.
|
|
||||||
|
|
||||||
setId(Constants::PROJECT_ID);
|
setId(Constants::PROJECT_ID);
|
||||||
setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
|
setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
|
||||||
setCanBuildProducts();
|
setCanBuildProducts();
|
||||||
|
setDisplayName(fileName.toFileInfo().completeBaseName());
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QbsProject::~QbsProject()
|
QbsProject::~QbsProject()
|
||||||
{
|
{
|
||||||
delete m_cppCodeModelUpdater;
|
|
||||||
delete m_qbsProjectParser;
|
|
||||||
delete m_importer;
|
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
|
ProjectImporter *QbsProject::projectImporter() const
|
||||||
@@ -187,12 +146,223 @@ ProjectImporter *QbsProject::projectImporter() const
|
|||||||
return m_importer;
|
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") {
|
if (id == "QmlDesignerImportPath") {
|
||||||
const qbs::Project qbsProject = m_qbsProjects.value(const_cast<Target *>(target));
|
const qbs::ProjectData projectData = m_qbsProject.isValid()
|
||||||
const qbs::ProjectData projectData = qbsProject.isValid()
|
? m_qbsProject.projectData() : qbs::ProjectData();
|
||||||
? qbsProject.projectData() : qbs::ProjectData();
|
|
||||||
QStringList designerImportPaths;
|
QStringList designerImportPaths;
|
||||||
foreach (const qbs::ProductData &product, projectData.allProducts()) {
|
foreach (const qbs::ProductData &product, projectData.allProducts()) {
|
||||||
designerImportPaths << product.properties()
|
designerImportPaths << product.properties()
|
||||||
@@ -200,7 +370,7 @@ QVariant QbsProject::additionalData(Id id, const Target *target) const
|
|||||||
}
|
}
|
||||||
return designerImportPaths;
|
return designerImportPaths;
|
||||||
}
|
}
|
||||||
return Project::additionalData(id, target);
|
return BuildSystem::additionalData(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectExplorer::DeploymentKnowledge QbsProject::deploymentKnowledge() const
|
ProjectExplorer::DeploymentKnowledge QbsProject::deploymentKnowledge() const
|
||||||
@@ -208,7 +378,7 @@ ProjectExplorer::DeploymentKnowledge QbsProject::deploymentKnowledge() const
|
|||||||
return DeploymentKnowledge::Perfect;
|
return DeploymentKnowledge::Perfect;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList QbsProject::filesGeneratedFrom(const QString &sourceFile) const
|
QStringList QbsBuildSystem::filesGeneratedFrom(const QString &sourceFile) const
|
||||||
{
|
{
|
||||||
QStringList generated;
|
QStringList generated;
|
||||||
foreach (const qbs::ProductData &data, m_projectData.allProducts())
|
foreach (const qbs::ProductData &data, m_projectData.allProducts())
|
||||||
@@ -216,12 +386,12 @@ QStringList QbsProject::filesGeneratedFrom(const QString &sourceFile) const
|
|||||||
return generated;
|
return generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QbsProject::isProjectEditable() const
|
bool QbsBuildSystem::isProjectEditable() const
|
||||||
{
|
{
|
||||||
return m_qbsProject.isValid() && !isParsing() && !BuildManager::isBuilding();
|
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
|
// Ensure that the file is not read only
|
||||||
QFileInfo fi(file);
|
QFileInfo fi(file);
|
||||||
@@ -242,9 +412,9 @@ bool QbsProject::ensureWriteableQbsFile(const QString &file)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QbsProject::addFilesToProduct(const QStringList &filePaths,
|
bool QbsBuildSystem::addFilesToProduct(const QStringList &filePaths,
|
||||||
const qbs::ProductData productData,
|
const qbs::ProductData productData,
|
||||||
const qbs::GroupData groupData, QStringList *notAdded)
|
const qbs::GroupData groupData, QStringList *notAdded)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_qbsProject.isValid(), return false);
|
QTC_ASSERT(m_qbsProject.isValid(), return false);
|
||||||
QStringList allPaths = groupData.allFilePaths();
|
QStringList allPaths = groupData.allFilePaths();
|
||||||
@@ -267,10 +437,10 @@ bool QbsProject::addFilesToProduct(const QStringList &filePaths,
|
|||||||
return notAdded->isEmpty();
|
return notAdded->isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
RemovedFilesFromProject QbsProject::removeFilesFromProduct(const QStringList &filePaths,
|
RemovedFilesFromProject QbsBuildSystem::removeFilesFromProduct(const QStringList &filePaths,
|
||||||
const qbs::ProductData &productData,
|
const qbs::ProductData &productData,
|
||||||
const qbs::GroupData &groupData,
|
const qbs::GroupData &groupData,
|
||||||
QStringList *notRemoved)
|
QStringList *notRemoved)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_qbsProject.isValid(), return RemovedFilesFromProject::Error);
|
QTC_ASSERT(m_qbsProject.isValid(), return RemovedFilesFromProject::Error);
|
||||||
|
|
||||||
@@ -313,9 +483,9 @@ RemovedFilesFromProject QbsProject::removeFilesFromProduct(const QStringList &fi
|
|||||||
return RemovedFilesFromProject::Ok;
|
return RemovedFilesFromProject::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QbsProject::renameFileInProduct(const QString &oldPath, const QString &newPath,
|
bool QbsBuildSystem::renameFileInProduct(const QString &oldPath, const QString &newPath,
|
||||||
const qbs::ProductData productData,
|
const qbs::ProductData productData,
|
||||||
const qbs::GroupData groupData)
|
const qbs::GroupData groupData)
|
||||||
{
|
{
|
||||||
if (newPath.isEmpty())
|
if (newPath.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
@@ -326,7 +496,7 @@ bool QbsProject::renameFileInProduct(const QString &oldPath, const QString &newP
|
|||||||
}
|
}
|
||||||
qbs::ProductData newProductData;
|
qbs::ProductData newProductData;
|
||||||
foreach (const qbs::ProductData &p, m_projectData.allProducts()) {
|
foreach (const qbs::ProductData &p, m_projectData.allProducts()) {
|
||||||
if (uniqueProductName(p) == uniqueProductName(productData)) {
|
if (QbsProject::uniqueProductName(p) == QbsProject::uniqueProductName(productData)) {
|
||||||
newProductData = p;
|
newProductData = p;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -365,8 +535,8 @@ static qbs::AbstractJob *doBuildOrClean(const qbs::Project &project,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Options>
|
template<typename Options>
|
||||||
qbs::AbstractJob *QbsProject::buildOrClean(const Options &opts, const QStringList &productNames,
|
qbs::AbstractJob *QbsBuildSystem::buildOrClean(const Options &opts, const QStringList &productNames,
|
||||||
QString &error)
|
QString &error)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(qbsProject().isValid(), return nullptr);
|
QTC_ASSERT(qbsProject().isValid(), return nullptr);
|
||||||
QTC_ASSERT(!isParsing(), 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) {
|
foreach (const QString &productName, productNames) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
foreach (const qbs::ProductData &data, qbsProjectData().allProducts()) {
|
foreach (const qbs::ProductData &data, qbsProjectData().allProducts()) {
|
||||||
if (uniqueProductName(data) == productName) {
|
if (QbsProject::uniqueProductName(data) == productName) {
|
||||||
found = true;
|
found = true;
|
||||||
products.append(data);
|
products.append(data);
|
||||||
break;
|
break;
|
||||||
@@ -391,41 +561,41 @@ qbs::AbstractJob *QbsProject::buildOrClean(const Options &opts, const QStringLis
|
|||||||
return doBuildOrClean(qbsProject(), products, opts);
|
return doBuildOrClean(qbsProject(), products, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
qbs::BuildJob *QbsProject::build(const qbs::BuildOptions &opts, QStringList productNames,
|
qbs::BuildJob *QbsBuildSystem::build(const qbs::BuildOptions &opts, QStringList productNames,
|
||||||
QString &error)
|
QString &error)
|
||||||
{
|
{
|
||||||
return static_cast<qbs::BuildJob *>(buildOrClean(opts, productNames, error));
|
return static_cast<qbs::BuildJob *>(buildOrClean(opts, productNames, error));
|
||||||
}
|
}
|
||||||
|
|
||||||
qbs::CleanJob *QbsProject::clean(const qbs::CleanOptions &opts, const QStringList &productNames,
|
qbs::CleanJob *QbsBuildSystem::clean(const qbs::CleanOptions &opts, const QStringList &productNames,
|
||||||
QString &error)
|
QString &error)
|
||||||
{
|
{
|
||||||
return static_cast<qbs::CleanJob *>(buildOrClean(opts, productNames, 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())
|
if (!qbsProject().isValid())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return qbsProject().installAllProducts(opts);
|
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;
|
return m_qbsProject;
|
||||||
}
|
}
|
||||||
|
|
||||||
qbs::ProjectData QbsProject::qbsProjectData() const
|
qbs::ProjectData QbsBuildSystem::qbsProjectData() const
|
||||||
{
|
{
|
||||||
return m_projectData;
|
return m_projectData;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QbsProject::checkCancelStatus()
|
bool QbsBuildSystem::checkCancelStatus()
|
||||||
{
|
{
|
||||||
const CancelStatus cancelStatus = m_cancelStatus;
|
const CancelStatus cancelStatus = m_cancelStatus;
|
||||||
m_cancelStatus = CancelStatusNone;
|
m_cancelStatus = CancelStatusNone;
|
||||||
@@ -439,7 +609,7 @@ bool QbsProject::checkCancelStatus()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QbsProject::updateAfterParse()
|
void QbsBuildSystem::updateAfterParse()
|
||||||
{
|
{
|
||||||
qCDebug(qbsPmLog) << "Updating data after parse";
|
qCDebug(qbsPmLog) << "Updating data after parse";
|
||||||
OpTimer opTimer("updateAfterParse");
|
OpTimer opTimer("updateAfterParse");
|
||||||
@@ -448,27 +618,24 @@ void QbsProject::updateAfterParse()
|
|||||||
updateBuildTargetData();
|
updateBuildTargetData();
|
||||||
updateCppCodeModel();
|
updateCppCodeModel();
|
||||||
updateQmlJsCodeModel();
|
updateQmlJsCodeModel();
|
||||||
emit fileListChanged();
|
emit project()->fileListChanged();
|
||||||
m_envCache.clear();
|
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");
|
OpTimer opTimer("updateProjectNodes");
|
||||||
rebuildProjectTree();
|
rebuildProjectTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePath QbsProject::installRoot()
|
FilePath QbsBuildSystem::installRoot()
|
||||||
{
|
{
|
||||||
if (!activeTarget())
|
const auto dc = target()->activeDeployConfiguration();
|
||||||
return FilePath();
|
|
||||||
const auto dc = activeTarget()->activeDeployConfiguration();
|
|
||||||
if (dc) {
|
if (dc) {
|
||||||
const QList<BuildStep *> steps = dc->stepList()->steps();
|
const QList<BuildStep *> steps = dc->stepList()->steps();
|
||||||
for (const BuildStep * const step : steps) {
|
for (const BuildStep * const step : steps) {
|
||||||
@@ -478,15 +645,11 @@ FilePath QbsProject::installRoot()
|
|||||||
return FilePath::fromString(qbsInstallStep->installRoot());
|
return FilePath::fromString(qbsInstallStep->installRoot());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto * const bc
|
const QbsBuildStep * const buildStep = m_buildConfiguration->qbsStep();
|
||||||
= qobject_cast<QbsBuildConfiguration *>(activeTarget()->activeBuildConfiguration());
|
|
||||||
if (!bc)
|
|
||||||
return FilePath();
|
|
||||||
const QbsBuildStep * const buildStep = bc->qbsStep();
|
|
||||||
return buildStep && buildStep->install() ? buildStep->installRoot() : FilePath();
|
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_qbsProjectParser, return);
|
||||||
QTC_ASSERT(m_qbsUpdateFutureInterface, return);
|
QTC_ASSERT(m_qbsUpdateFutureInterface, return);
|
||||||
@@ -499,7 +662,6 @@ void QbsProject::handleQbsParsingDone(bool success)
|
|||||||
generateErrors(m_qbsProjectParser->error());
|
generateErrors(m_qbsProjectParser->error());
|
||||||
|
|
||||||
m_qbsProject = m_qbsProjectParser->qbsProject();
|
m_qbsProject = m_qbsProjectParser->qbsProject();
|
||||||
m_qbsProjects.insert(activeTarget(), m_qbsProject);
|
|
||||||
bool dataChanged = false;
|
bool dataChanged = false;
|
||||||
bool envChanged = m_lastParseEnv != m_qbsProjectParser->environment();
|
bool envChanged = m_lastParseEnv != m_qbsProjectParser->environment();
|
||||||
m_lastParseEnv = m_qbsProjectParser->environment();
|
m_lastParseEnv = m_qbsProjectParser->environment();
|
||||||
@@ -528,14 +690,14 @@ void QbsProject::handleQbsParsingDone(bool success)
|
|||||||
m_guard = {};
|
m_guard = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void QbsProject::rebuildProjectTree()
|
void QbsBuildSystem::rebuildProjectTree()
|
||||||
{
|
{
|
||||||
std::unique_ptr<QbsRootProjectNode> newRoot = Internal::QbsNodeTreeBuilder::buildTree(this);
|
std::unique_ptr<QbsRootProjectNode> newRoot = Internal::QbsNodeTreeBuilder::buildTree(this);
|
||||||
setDisplayName(newRoot ? newRoot->displayName() : projectFilePath().toFileInfo().completeBaseName());
|
project()->setDisplayName(newRoot ? newRoot->displayName() : projectFilePath().toFileInfo().completeBaseName());
|
||||||
setRootProjectNode(std::move(newRoot));
|
project()->setRootProjectNode(std::move(newRoot));
|
||||||
}
|
}
|
||||||
|
|
||||||
void QbsProject::handleRuleExecutionDone()
|
void QbsBuildSystem::handleRuleExecutionDone()
|
||||||
{
|
{
|
||||||
qCDebug(qbsPmLog) << "Rule execution done";
|
qCDebug(qbsPmLog) << "Rule execution done";
|
||||||
|
|
||||||
@@ -553,28 +715,17 @@ void QbsProject::handleRuleExecutionDone()
|
|||||||
updateAfterParse();
|
updateAfterParse();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QbsProject::changeActiveTarget(Target *t)
|
void QbsBuildSystem::changeActiveTarget(Target *t)
|
||||||
{
|
{
|
||||||
bool targetFound = false;
|
if (t)
|
||||||
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())
|
|
||||||
delayParsing();
|
delayParsing();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QbsProject::startParsing()
|
void QbsBuildSystem::triggerParsing()
|
||||||
{
|
{
|
||||||
// Qbs does update the build graph during the build. So we cannot
|
// 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.
|
// start to parse while a build is running or we will lose information.
|
||||||
if (BuildManager::isBuilding(this)) {
|
if (BuildManager::isBuilding(project())) {
|
||||||
scheduleParsing();
|
scheduleParsing();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -582,12 +733,13 @@ void QbsProject::startParsing()
|
|||||||
parseCurrentBuildConfiguration();
|
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;
|
m_parsingScheduled = false;
|
||||||
if (m_cancelStatus == CancelStatusCancelingForReparse)
|
if (m_cancelStatus == CancelStatusCancelingForReparse)
|
||||||
@@ -598,12 +750,6 @@ void QbsProject::parseCurrentBuildConfiguration()
|
|||||||
// but of course not while canceling is in progress).
|
// but of course not while canceling is in progress).
|
||||||
QTC_ASSERT(m_cancelStatus == CancelStatusNone, return);
|
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.
|
// New parse requests override old ones.
|
||||||
// NOTE: We need to wait for the current operation to finish, since otherwise there could
|
// 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
|
// be a conflict. Consider the case where the old qbs::ProjectSetupJob is writing
|
||||||
@@ -616,28 +762,44 @@ void QbsProject::parseCurrentBuildConfiguration()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
parse(bc->qbsConfiguration(), bc->environment(), bc->buildDirectory().toString(),
|
QVariantMap config = m_buildConfiguration->qbsConfiguration();
|
||||||
bc->configurationName());
|
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);
|
QTC_ASSERT(m_qbsProjectParser, return);
|
||||||
m_cancelStatus = CancelStatusCancelingAltoghether;
|
m_cancelStatus = CancelStatusCancelingAltoghether;
|
||||||
m_qbsProjectParser->cancel();
|
m_qbsProjectParser->cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QbsProject::updateAfterBuild()
|
void QbsBuildSystem::updateAfterBuild()
|
||||||
{
|
{
|
||||||
OpTimer opTimer("updateAfterBuild");
|
OpTimer opTimer("updateAfterBuild");
|
||||||
QTC_ASSERT(m_qbsProject.isValid(), return);
|
QTC_ASSERT(m_qbsProject.isValid(), return);
|
||||||
const qbs::ProjectData &projectData = m_qbsProject.projectData();
|
const qbs::ProjectData &projectData = m_qbsProject.projectData();
|
||||||
if (projectData == m_projectData) {
|
if (projectData == m_projectData) {
|
||||||
if (activeTarget()) {
|
DeploymentData deploymentDataTmp = deploymentData();
|
||||||
DeploymentData deploymentData = activeTarget()->deploymentData();
|
deploymentDataTmp.setLocalInstallRoot(installRoot());
|
||||||
deploymentData.setLocalInstallRoot(installRoot());
|
setDeploymentData(deploymentDataTmp);
|
||||||
activeTarget()->setDeploymentData(deploymentData);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qCDebug(qbsPmLog) << "Updating data after build";
|
qCDebug(qbsPmLog) << "Updating data after build";
|
||||||
@@ -649,29 +811,9 @@ void QbsProject::updateAfterBuild()
|
|||||||
updateCppCodeModel();
|
updateCppCodeModel();
|
||||||
}
|
}
|
||||||
m_envCache.clear();
|
m_envCache.clear();
|
||||||
emit dataChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QbsProject::registerQbsProjectParser(QbsProjectParser *p)
|
void QbsBuildSystem::generateErrors(const qbs::ErrorInfo &e)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
foreach (const qbs::ErrorItem &item, e.items())
|
foreach (const qbs::ErrorItem &item, e.items())
|
||||||
TaskHub::addTask(Task::Error, item.description(),
|
TaskHub::addTask(Task::Error, item.description(),
|
||||||
@@ -697,24 +839,11 @@ void QbsProject::configureAsExampleProject()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
setup(infoList);
|
setup(infoList);
|
||||||
prepareForParsing();
|
if (activeTarget())
|
||||||
|
static_cast<QbsBuildSystem *>(activeTarget()->buildSystem())->prepareForParsing();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QbsProject::parse(const QVariantMap &config, const Environment &env, const QString &dir,
|
void QbsBuildSystem::prepareForParsing()
|
||||||
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()
|
|
||||||
{
|
{
|
||||||
TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
|
TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
|
||||||
if (m_qbsUpdateFutureInterface) {
|
if (m_qbsUpdateFutureInterface) {
|
||||||
@@ -727,11 +856,11 @@ void QbsProject::prepareForParsing()
|
|||||||
m_qbsUpdateFutureInterface = new QFutureInterface<bool>();
|
m_qbsUpdateFutureInterface = new QFutureInterface<bool>();
|
||||||
m_qbsUpdateFutureInterface->setProgressRange(0, 0);
|
m_qbsUpdateFutureInterface->setProgressRange(0, 0);
|
||||||
ProgressManager::addTask(m_qbsUpdateFutureInterface->future(),
|
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();
|
m_qbsUpdateFutureInterface->reportStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QbsProject::updateDocuments(const std::set<QString> &files)
|
void QbsBuildSystem::updateDocuments(const std::set<QString> &files)
|
||||||
{
|
{
|
||||||
OpTimer opTimer("updateDocuments");
|
OpTimer opTimer("updateDocuments");
|
||||||
|
|
||||||
@@ -742,7 +871,7 @@ void QbsProject::updateDocuments(const std::set<QString> &files)
|
|||||||
[buildDir](const FilePath &p) {
|
[buildDir](const FilePath &p) {
|
||||||
return !p.isChildOf(buildDir);
|
return !p.isChildOf(buildDir);
|
||||||
});
|
});
|
||||||
setExtraProjectFiles(nonBuildDirFilePaths);
|
project()->setExtraProjectFiles(nonBuildDirFilePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString getMimeType(const qbs::ArtifactData &sourceFile)
|
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");
|
OpTimer optimer("updateCppCodeModel");
|
||||||
if (!m_projectData.isValid())
|
if (!m_projectData.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QList<ProjectExplorer::ExtraCompilerFactory *> factories =
|
const QList<ExtraCompilerFactory *> factories = ExtraCompilerFactory::extraCompilerFactories();
|
||||||
ProjectExplorer::ExtraCompilerFactory::extraCompilerFactories();
|
|
||||||
const auto factoriesBegin = factories.constBegin();
|
const auto factoriesBegin = factories.constBegin();
|
||||||
const auto factoriesEnd = factories.constEnd();
|
const auto factoriesEnd = factories.constEnd();
|
||||||
|
|
||||||
qDeleteAll(m_extraCompilers);
|
qDeleteAll(m_extraCompilers);
|
||||||
m_extraCompilers.clear();
|
m_extraCompilers.clear();
|
||||||
|
|
||||||
QtSupport::CppKitInfo kitInfo(this);
|
QtSupport::CppKitInfo kitInfo(project());
|
||||||
QTC_ASSERT(kitInfo.isValid(), return);
|
QTC_ASSERT(kitInfo.isValid(), return);
|
||||||
|
|
||||||
RawProjectParts rpps;
|
RawProjectParts rpps;
|
||||||
@@ -959,7 +1087,7 @@ void QbsProject::updateCppCodeModel()
|
|||||||
rpp.setDisplayName(grp.name());
|
rpp.setDisplayName(grp.name());
|
||||||
rpp.setProjectFileLocation(grp.location().filePath(),
|
rpp.setProjectFileLocation(grp.location().filePath(),
|
||||||
grp.location().line(), grp.location().column());
|
grp.location().line(), grp.location().column());
|
||||||
rpp.setBuildSystemTarget(uniqueProductName(prd));
|
rpp.setBuildSystemTarget(QbsProject::uniqueProductName(prd));
|
||||||
rpp.setBuildTargetType(prd.isRunnable() ? ProjectExplorer::BuildTargetType::Executable
|
rpp.setBuildTargetType(prd.isRunnable() ? ProjectExplorer::BuildTargetType::Executable
|
||||||
: ProjectExplorer::BuildTargetType::Library);
|
: ProjectExplorer::BuildTargetType::Library);
|
||||||
|
|
||||||
@@ -996,7 +1124,7 @@ void QbsProject::updateCppCodeModel()
|
|||||||
return Utils::FilePath::fromString(s);
|
return Utils::FilePath::fromString(s);
|
||||||
});
|
});
|
||||||
m_extraCompilers.append((*i)->create(
|
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);
|
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");
|
OpTimer optimer("updateQmlJsCodeModel");
|
||||||
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
|
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
|
||||||
@@ -1049,7 +1177,7 @@ void QbsProject::updateQmlJsCodeModel()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
QmlJS::ModelManagerInterface::ProjectInfo projectInfo =
|
QmlJS::ModelManagerInterface::ProjectInfo projectInfo =
|
||||||
modelManager->defaultProjectInfoForProject(this);
|
modelManager->defaultProjectInfoForProject(project());
|
||||||
foreach (const qbs::ProductData &product, m_projectData.allProducts()) {
|
foreach (const qbs::ProductData &product, m_projectData.allProducts()) {
|
||||||
static const QString propertyName = QLatin1String("qmlImportPaths");
|
static const QString propertyName = QLatin1String("qmlImportPaths");
|
||||||
foreach (const QString &path, product.properties().value(propertyName).toStringList()) {
|
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());
|
!projectInfo.sourceFiles.isEmpty());
|
||||||
modelManager->updateProjectInfo(projectInfo, this);
|
modelManager->updateProjectInfo(projectInfo, project());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QbsProject::updateApplicationTargets()
|
void QbsBuildSystem::updateApplicationTargets()
|
||||||
{
|
{
|
||||||
QList<BuildTargetInfo> applications;
|
QList<BuildTargetInfo> applications;
|
||||||
foreach (const qbs::ProductData &productData, m_projectData.allProducts()) {
|
foreach (const qbs::ProductData &productData, m_projectData.allProducts()) {
|
||||||
@@ -1125,11 +1253,10 @@ void QbsProject::updateApplicationTargets()
|
|||||||
|
|
||||||
applications.append(bti);
|
applications.append(bti);
|
||||||
}
|
}
|
||||||
if (activeTarget())
|
setApplicationTargets(applications);
|
||||||
activeTarget()->setApplicationTargets(applications);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QbsProject::updateDeploymentInfo()
|
void QbsBuildSystem::updateDeploymentInfo()
|
||||||
{
|
{
|
||||||
DeploymentData deploymentData;
|
DeploymentData deploymentData;
|
||||||
if (m_qbsProject.isValid()) {
|
if (m_qbsProject.isValid()) {
|
||||||
@@ -1139,11 +1266,10 @@ void QbsProject::updateDeploymentInfo()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
deploymentData.setLocalInstallRoot(installRoot());
|
deploymentData.setLocalInstallRoot(installRoot());
|
||||||
if (activeTarget())
|
setDeploymentData(deploymentData);
|
||||||
activeTarget()->setDeploymentData(deploymentData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QbsProject::updateBuildTargetData()
|
void QbsBuildSystem::updateBuildTargetData()
|
||||||
{
|
{
|
||||||
OpTimer optimer("updateBuildTargetData");
|
OpTimer optimer("updateBuildTargetData");
|
||||||
updateApplicationTargets();
|
updateApplicationTargets();
|
||||||
|
@@ -41,12 +41,12 @@
|
|||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
namespace Core { class IDocument; }
|
|
||||||
namespace CppTools { class CppProjectUpdater; }
|
namespace CppTools { class CppProjectUpdater; }
|
||||||
|
|
||||||
namespace QbsProjectManager {
|
namespace QbsProjectManager {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
class QbsBuildConfiguration;
|
||||||
class QbsProjectParser;
|
class QbsProjectParser;
|
||||||
|
|
||||||
class QbsProject : public ProjectExplorer::Project
|
class QbsProject : public ProjectExplorer::Project
|
||||||
@@ -55,9 +55,43 @@ class QbsProject : public ProjectExplorer::Project
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QbsProject(const Utils::FilePath &filename);
|
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;
|
bool isProjectEditable() const;
|
||||||
// qbs::ProductData and qbs::GroupData are held by the nodes in the project tree.
|
// 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);
|
static ProjectExplorer::FileType fileTypeFor(const QSet<QString> &tags);
|
||||||
|
|
||||||
QString profileForTarget(const ProjectExplorer::Target *t) const;
|
QString profile() const;
|
||||||
void parseCurrentBuildConfiguration();
|
void parseCurrentBuildConfiguration();
|
||||||
void scheduleParsing() { m_parsingScheduled = true; }
|
void scheduleParsing() { m_parsingScheduled = true; }
|
||||||
bool parsingScheduled() const { return m_parsingScheduled; }
|
bool parsingScheduled() const { return m_parsingScheduled; }
|
||||||
void cancelParsing();
|
void cancelParsing();
|
||||||
void updateAfterBuild();
|
void updateAfterBuild();
|
||||||
|
|
||||||
void registerQbsProjectParser(QbsProjectParser *p);
|
|
||||||
|
|
||||||
qbs::Project qbsProject() const;
|
qbs::Project qbsProject() const;
|
||||||
qbs::ProjectData qbsProjectData() const;
|
qbs::ProjectData qbsProjectData() const;
|
||||||
|
|
||||||
void generateErrors(const qbs::ErrorInfo &e);
|
void generateErrors(const qbs::ErrorInfo &e);
|
||||||
|
|
||||||
static QString uniqueProductName(const qbs::ProductData &product);
|
|
||||||
|
|
||||||
void configureAsExampleProject() final;
|
|
||||||
|
|
||||||
void delayParsing();
|
void delayParsing();
|
||||||
|
|
||||||
signals:
|
|
||||||
void dataChanged();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class QbsProject;
|
||||||
void handleQbsParsingDone(bool success);
|
void handleQbsParsingDone(bool success);
|
||||||
|
|
||||||
void rebuildProjectTree();
|
void rebuildProjectTree();
|
||||||
|
|
||||||
void changeActiveTarget(ProjectExplorer::Target *t);
|
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 prepareForParsing();
|
||||||
void updateDocuments(const std::set<QString> &files);
|
void updateDocuments(const std::set<QString> &files);
|
||||||
@@ -129,19 +151,12 @@ private:
|
|||||||
void updateProjectNodes();
|
void updateProjectNodes();
|
||||||
Utils::FilePath installRoot();
|
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);
|
static bool ensureWriteableQbsFile(const QString &file);
|
||||||
|
|
||||||
template<typename Options> qbs::AbstractJob *buildOrClean(const Options &opts,
|
template<typename Options> qbs::AbstractJob *buildOrClean(const Options &opts,
|
||||||
const QStringList &productNames, QString &error);
|
const QStringList &productNames, QString &error);
|
||||||
|
|
||||||
QHash<ProjectExplorer::Target *, qbs::Project> m_qbsProjects;
|
qbs::Project m_qbsProject;
|
||||||
qbs::Project m_qbsProject; // for activeTarget()
|
|
||||||
qbs::ProjectData m_projectData; // Cached m_qbsProject.projectData()
|
qbs::ProjectData m_projectData; // Cached m_qbsProject.projectData()
|
||||||
Utils::Environment m_lastParseEnv;
|
Utils::Environment m_lastParseEnv;
|
||||||
|
|
||||||
@@ -158,15 +173,14 @@ private:
|
|||||||
|
|
||||||
CppTools::CppProjectUpdater *m_cppCodeModelUpdater = nullptr;
|
CppTools::CppProjectUpdater *m_cppCodeModelUpdater = nullptr;
|
||||||
|
|
||||||
mutable ProjectExplorer::ProjectImporter *m_importer = nullptr;
|
|
||||||
|
|
||||||
QTimer m_parsingDelay;
|
QTimer m_parsingDelay;
|
||||||
QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers;
|
QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers;
|
||||||
bool m_extraCompilersPending = false;
|
bool m_extraCompilersPending = false;
|
||||||
|
|
||||||
QHash<QString, Utils::Environment> m_envCache;
|
QHash<QString, Utils::Environment> m_envCache;
|
||||||
|
|
||||||
ParseGuard m_guard;
|
ProjectExplorer::BuildSystem::ParseGuard m_guard;
|
||||||
|
QbsBuildConfiguration *m_buildConfiguration = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -246,9 +246,9 @@ bool QbsProjectManagerPlugin::initialize(const QStringList &arguments, QString *
|
|||||||
connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged,
|
connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged,
|
||||||
this, &QbsProjectManagerPlugin::updateBuildActions);
|
this, &QbsProjectManagerPlugin::updateBuildActions);
|
||||||
|
|
||||||
connect(SessionManager::instance(), &SessionManager::projectAdded,
|
connect(SessionManager::instance(), &SessionManager::targetAdded,
|
||||||
this, &QbsProjectManagerPlugin::projectWasAdded);
|
this, &QbsProjectManagerPlugin::targetWasAdded);
|
||||||
connect(SessionManager::instance(), &SessionManager::projectRemoved,
|
connect(SessionManager::instance(), &SessionManager::targetRemoved,
|
||||||
this, &QbsProjectManagerPlugin::updateBuildActions);
|
this, &QbsProjectManagerPlugin::updateBuildActions);
|
||||||
connect(SessionManager::instance(), &SessionManager::startupProjectChanged,
|
connect(SessionManager::instance(), &SessionManager::startupProjectChanged,
|
||||||
this, &QbsProjectManagerPlugin::updateReparseQbsAction);
|
this, &QbsProjectManagerPlugin::updateReparseQbsAction);
|
||||||
@@ -264,16 +264,14 @@ bool QbsProjectManagerPlugin::initialize(const QStringList &arguments, QString *
|
|||||||
void QbsProjectManagerPlugin::extensionsInitialized()
|
void QbsProjectManagerPlugin::extensionsInitialized()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void QbsProjectManagerPlugin::projectWasAdded(Project *project)
|
void QbsProjectManagerPlugin::targetWasAdded(Target *target)
|
||||||
{
|
{
|
||||||
auto qbsProject = qobject_cast<QbsProject *>(project);
|
if (!qobject_cast<QbsProject *>(target->project()))
|
||||||
|
|
||||||
if (!qbsProject)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
connect(qbsProject, &Project::parsingStarted,
|
connect(target, &Target::parsingStarted,
|
||||||
this, &QbsProjectManagerPlugin::projectChanged);
|
this, &QbsProjectManagerPlugin::projectChanged);
|
||||||
connect(qbsProject, &Project::parsingFinished,
|
connect(target, &Target::parsingFinished,
|
||||||
this, &QbsProjectManagerPlugin::projectChanged);
|
this, &QbsProjectManagerPlugin::projectChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +280,8 @@ void QbsProjectManagerPlugin::updateContextActions()
|
|||||||
auto project = qobject_cast<Internal::QbsProject *>(ProjectTree::currentProject());
|
auto project = qobject_cast<Internal::QbsProject *>(ProjectTree::currentProject());
|
||||||
const Node *node = ProjectTree::currentNode();
|
const Node *node = ProjectTree::currentNode();
|
||||||
bool isEnabled = !BuildManager::isBuilding(project)
|
bool isEnabled = !BuildManager::isBuilding(project)
|
||||||
&& project && !project->isParsing()
|
&& project && project->activeTarget()
|
||||||
|
&& !project->activeTarget()->buildSystem()->isParsing()
|
||||||
&& node && node->isEnabled();
|
&& node && node->isEnabled();
|
||||||
|
|
||||||
const bool isFile = project && node && node->asFileNode();
|
const bool isFile = project && node && node->asFileNode();
|
||||||
@@ -305,7 +304,8 @@ void QbsProjectManagerPlugin::updateReparseQbsAction()
|
|||||||
auto project = qobject_cast<QbsProject *>(SessionManager::startupProject());
|
auto project = qobject_cast<QbsProject *>(SessionManager::startupProject());
|
||||||
m_reparseQbs->setEnabled(project
|
m_reparseQbs->setEnabled(project
|
||||||
&& !BuildManager::isBuilding(project)
|
&& !BuildManager::isBuilding(project)
|
||||||
&& !project->isParsing());
|
&& project && project->activeTarget()
|
||||||
|
&& !project->activeTarget()->buildSystem()->isParsing());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QbsProjectManagerPlugin::updateBuildActions()
|
void QbsProjectManagerPlugin::updateBuildActions()
|
||||||
@@ -334,7 +334,9 @@ void QbsProjectManagerPlugin::updateBuildActions()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (QbsProject *editorProject = currentEditorProject()) {
|
if (QbsProject *editorProject = currentEditorProject()) {
|
||||||
enabled = !BuildManager::isBuilding(editorProject) && !editorProject->isParsing();
|
enabled = !BuildManager::isBuilding(editorProject)
|
||||||
|
&& editorProject->activeTarget()
|
||||||
|
&& !editorProject->activeTarget()->buildSystem()->isParsing();
|
||||||
fileVisible = productNode
|
fileVisible = productNode
|
||||||
|| dynamic_cast<QbsProjectNode *>(parentProjectNode)
|
|| dynamic_cast<QbsProjectNode *>(parentProjectNode)
|
||||||
|| dynamic_cast<QbsGroupNode *>(parentProjectNode);
|
|| dynamic_cast<QbsGroupNode *>(parentProjectNode);
|
||||||
@@ -567,12 +569,20 @@ void QbsProjectManagerPlugin::reparseProject(QbsProject *project)
|
|||||||
if (!project)
|
if (!project)
|
||||||
return;
|
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
|
// 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.
|
// start to parse while a build is running or we will lose information.
|
||||||
if (BuildManager::isBuilding(project))
|
if (BuildManager::isBuilding(project))
|
||||||
project->scheduleParsing();
|
bs->scheduleParsing();
|
||||||
else
|
else
|
||||||
project->parseCurrentBuildConfiguration();
|
bs->parseCurrentBuildConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QbsProjectManagerPlugin::buildNamedProduct(QbsProject *project, const QString &product)
|
void QbsProjectManagerPlugin::buildNamedProduct(QbsProject *project, const QString &product)
|
||||||
|
@@ -29,7 +29,7 @@
|
|||||||
#include <extensionsystem/iplugin.h>
|
#include <extensionsystem/iplugin.h>
|
||||||
#include <utils/parameteraction.h>
|
#include <utils/parameteraction.h>
|
||||||
|
|
||||||
namespace ProjectExplorer { class Project; }
|
namespace ProjectExplorer { class Target; }
|
||||||
|
|
||||||
namespace QbsProjectManager {
|
namespace QbsProjectManager {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -51,7 +51,7 @@ private:
|
|||||||
bool initialize(const QStringList &arguments, QString *errorMessage) final;
|
bool initialize(const QStringList &arguments, QString *errorMessage) final;
|
||||||
void extensionsInitialized() final;
|
void extensionsInitialized() final;
|
||||||
|
|
||||||
void projectWasAdded(ProjectExplorer::Project *project);
|
void targetWasAdded(ProjectExplorer::Target *target);
|
||||||
void projectChanged();
|
void projectChanged();
|
||||||
|
|
||||||
void buildFileContextMenu();
|
void buildFileContextMenu();
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user