forked from qt-creator/qt-creator
CMake: Make sure a CMakeBuildConfiguration always has a CMakeBuildSystem
For this to work, we need to make sure no parsing is triggered before the project is fully set up. Otherwise it would be QTCREATORBUG-23816 again... Change-Id: If81f4c6b9c82283abdaa8a635f93ebe0bcaf8159 Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
@@ -63,6 +63,8 @@ const char CONFIGURATION_KEY[] = "CMake.Configuration";
|
||||
CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Core::Id id)
|
||||
: BuildConfiguration(target, id)
|
||||
{
|
||||
m_buildSystem = new CMakeBuildSystem(this);
|
||||
|
||||
setBuildDirectory(shadowBuildDirectory(project()->projectFilePath(),
|
||||
target->kit(),
|
||||
displayName(),
|
||||
@@ -149,21 +151,12 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Core::Id id)
|
||||
}
|
||||
|
||||
setConfigurationForCMake(config);
|
||||
|
||||
// Only do this after everything has been set up!
|
||||
m_buildSystem = new CMakeBuildSystem(this);
|
||||
});
|
||||
|
||||
const auto qmlDebuggingAspect = addAspect<QtSupport::QmlDebuggingAspect>();
|
||||
qmlDebuggingAspect->setKit(target->kit());
|
||||
connect(qmlDebuggingAspect, &QtSupport::QmlDebuggingAspect::changed,
|
||||
this, &CMakeBuildConfiguration::configurationForCMakeChanged);
|
||||
|
||||
// m_buildSystem is still nullptr here since it the build directory to be available
|
||||
// before it can get created.
|
||||
//
|
||||
// This means this needs to be done in the lambda for the setInitializer(...) call
|
||||
// defined above as well as in fromMap!
|
||||
}
|
||||
|
||||
CMakeBuildConfiguration::~CMakeBuildConfiguration()
|
||||
@@ -182,8 +175,6 @@ QVariantMap CMakeBuildConfiguration::toMap() const
|
||||
|
||||
bool CMakeBuildConfiguration::fromMap(const QVariantMap &map)
|
||||
{
|
||||
QTC_CHECK(!m_buildSystem);
|
||||
|
||||
if (!BuildConfiguration::fromMap(map))
|
||||
return false;
|
||||
|
||||
@@ -194,8 +185,6 @@ bool CMakeBuildConfiguration::fromMap(const QVariantMap &map)
|
||||
|
||||
setConfigurationForCMake(conf);
|
||||
|
||||
m_buildSystem = new CMakeBuildSystem(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -40,6 +40,7 @@
|
||||
#include <cpptools/generatedcodemodelsupport.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||
|
||||
@@ -196,95 +197,10 @@ CMakeBuildSystem::CMakeBuildSystem(CMakeBuildConfiguration *bc)
|
||||
cmakeBuildConfiguration()->clearError(CMakeBuildConfiguration::ForceEnabledChanged::True);
|
||||
});
|
||||
|
||||
// Kit changed:
|
||||
connect(KitManager::instance(), &KitManager::kitUpdated, this, [this](Kit *k) {
|
||||
if (k != 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
|
||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to kit being updated";
|
||||
m_buildDirManager.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||
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
|
||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to active target changed";
|
||||
m_buildDirManager
|
||||
.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||
BuildDirManager::REPARSE_CHECK_CONFIGURATION);
|
||||
} else {
|
||||
m_buildDirManager.stopParsingAndClearState();
|
||||
}
|
||||
});
|
||||
connect(target(), &Target::activeBuildConfigurationChanged, this, [this](BuildConfiguration *bc) {
|
||||
if (cmakeBuildConfiguration()->isActive()) {
|
||||
if (cmakeBuildConfiguration() == 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
|
||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to active BC changed";
|
||||
m_buildDirManager
|
||||
.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||
BuildDirManager::REPARSE_CHECK_CONFIGURATION);
|
||||
} else {
|
||||
m_buildDirManager.stopParsingAndClearState();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// BuildConfiguration changed:
|
||||
connect(cmakeBuildConfiguration(), &CMakeBuildConfiguration::environmentChanged, this, [this]() {
|
||||
if (cmakeBuildConfiguration()->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
|
||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to environment change";
|
||||
m_buildDirManager
|
||||
.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||
BuildDirManager::REPARSE_CHECK_CONFIGURATION);
|
||||
}
|
||||
});
|
||||
connect(cmakeBuildConfiguration(), &CMakeBuildConfiguration::buildDirectoryChanged, this, [this]() {
|
||||
if (cmakeBuildConfiguration()->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.
|
||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to build directory change";
|
||||
m_buildDirManager
|
||||
.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||
BuildDirManager::REPARSE_CHECK_CONFIGURATION);
|
||||
}
|
||||
});
|
||||
connect(cmakeBuildConfiguration(), &CMakeBuildConfiguration::configurationForCMakeChanged, this, [this]() {
|
||||
if (cmakeBuildConfiguration()->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
|
||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to cmake configuration change";
|
||||
m_buildDirManager
|
||||
.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||
BuildDirManager::REPARSE_FORCE_CONFIGURATION);
|
||||
}
|
||||
});
|
||||
|
||||
connect(project(), &Project::projectFileIsDirty, this, [this]() {
|
||||
if (cmakeBuildConfiguration()->isActive() && !isParsing()) {
|
||||
const auto cmake = CMakeKitAspect::cmakeTool(cmakeBuildConfiguration()->target()->kit());
|
||||
if (cmake && cmake->isAutoRun()) {
|
||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to dirty project file";
|
||||
m_buildDirManager.setParametersAndRequestParse(BuildDirParameters(
|
||||
cmakeBuildConfiguration()),
|
||||
BuildDirManager::REPARSE_DEFAULT);
|
||||
}
|
||||
}
|
||||
});
|
||||
connect(SessionManager::instance(),
|
||||
&SessionManager::projectAdded,
|
||||
this,
|
||||
&CMakeBuildSystem::wireUpConnections);
|
||||
}
|
||||
|
||||
CMakeBuildSystem::~CMakeBuildSystem()
|
||||
@@ -638,6 +554,115 @@ void CMakeBuildSystem::handleParsingFailed(const QString &msg)
|
||||
handleParsingError();
|
||||
}
|
||||
|
||||
void CMakeBuildSystem::wireUpConnections(const Project *p)
|
||||
{
|
||||
if (p != project())
|
||||
return; // That's not us...
|
||||
|
||||
disconnect(SessionManager::instance(), nullptr, this, nullptr);
|
||||
|
||||
// At this point the entire project will be fully configured, so let's connect everything and
|
||||
// trigger an initial parser run
|
||||
|
||||
// Kit changed:
|
||||
connect(KitManager::instance(), &KitManager::kitUpdated, this, [this](Kit *k) {
|
||||
if (k != 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
|
||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to kit being updated";
|
||||
m_buildDirManager.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||
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
|
||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to active target changed";
|
||||
m_buildDirManager
|
||||
.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||
BuildDirManager::REPARSE_CHECK_CONFIGURATION);
|
||||
} else {
|
||||
m_buildDirManager.stopParsingAndClearState();
|
||||
}
|
||||
});
|
||||
connect(target(), &Target::activeBuildConfigurationChanged, this, [this](BuildConfiguration *bc) {
|
||||
if (cmakeBuildConfiguration()->isActive()) {
|
||||
if (cmakeBuildConfiguration() == 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
|
||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to active BC changed";
|
||||
m_buildDirManager
|
||||
.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||
BuildDirManager::REPARSE_CHECK_CONFIGURATION);
|
||||
} else {
|
||||
m_buildDirManager.stopParsingAndClearState();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// BuildConfiguration changed:
|
||||
connect(cmakeBuildConfiguration(), &CMakeBuildConfiguration::environmentChanged, this, [this]() {
|
||||
if (cmakeBuildConfiguration()->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
|
||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to environment change";
|
||||
m_buildDirManager
|
||||
.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||
BuildDirManager::REPARSE_CHECK_CONFIGURATION);
|
||||
}
|
||||
});
|
||||
connect(cmakeBuildConfiguration(), &CMakeBuildConfiguration::buildDirectoryChanged, this, [this]() {
|
||||
if (cmakeBuildConfiguration()->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.
|
||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to build directory change";
|
||||
m_buildDirManager
|
||||
.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||
BuildDirManager::REPARSE_CHECK_CONFIGURATION);
|
||||
}
|
||||
});
|
||||
connect(cmakeBuildConfiguration(),
|
||||
&CMakeBuildConfiguration::configurationForCMakeChanged,
|
||||
this,
|
||||
[this]() {
|
||||
if (cmakeBuildConfiguration()->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
|
||||
qCDebug(cmakeBuildSystemLog)
|
||||
<< "Requesting parse due to cmake configuration change";
|
||||
m_buildDirManager
|
||||
.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||
BuildDirManager::REPARSE_FORCE_CONFIGURATION);
|
||||
}
|
||||
});
|
||||
|
||||
connect(project(), &Project::projectFileIsDirty, this, [this]() {
|
||||
if (cmakeBuildConfiguration()->isActive() && !isParsing()) {
|
||||
const auto cmake = CMakeKitAspect::cmakeTool(cmakeBuildConfiguration()->target()->kit());
|
||||
if (cmake && cmake->isAutoRun()) {
|
||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to dirty project file";
|
||||
m_buildDirManager.setParametersAndRequestParse(BuildDirParameters(
|
||||
cmakeBuildConfiguration()),
|
||||
BuildDirManager::REPARSE_DEFAULT);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Force initial parsing run:
|
||||
m_buildDirManager.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||
BuildDirManager::REPARSE_CHECK_CONFIGURATION);
|
||||
}
|
||||
|
||||
CMakeBuildConfiguration *CMakeBuildSystem::cmakeBuildConfiguration() const
|
||||
{
|
||||
return static_cast<CMakeBuildConfiguration *>(BuildSystem::buildConfiguration());
|
||||
|
@@ -101,6 +101,8 @@ private:
|
||||
void handleParsingSucceeded();
|
||||
void handleParsingFailed(const QString &msg);
|
||||
|
||||
void wireUpConnections(const ProjectExplorer::Project *p);
|
||||
|
||||
BuildDirManager m_buildDirManager;
|
||||
|
||||
ProjectExplorer::TreeScanner m_treeScanner;
|
||||
|
Reference in New Issue
Block a user