Commit c0185305 authored by Tobias Hunger's avatar Tobias Hunger
Browse files

ProjectExplorer: Handle imperfect build systems

Handle buildsystems with imperfect knowledge about what they
build more gracefully.

Leave RunConfigurations around if the build system can not tell
whether or not the relevant target was configured out of the
current build or completely removed from the build system.

This patch should not change the observable behavior of the code.

Change-Id: I0ddb4bd3966d184a4b5c9818e68adb107047ed1f
Reviewed-by: default avatarEike Ziller <>
Reviewed-by: default avatarTim Jenssen <>
parent 6ed9ac35
......@@ -684,6 +684,11 @@ bool Project::needsSpecialDeployment() const
return false;
bool Project::knowsAllBuildExecutables() const
return true;
void Project::setup(QList<const BuildInfo *> infoList)
QList<Target *> toRegister;
......@@ -139,6 +139,9 @@ public:
void setPreferredKitMatcher(const KitMatcher &matcher);
virtual bool needsSpecialDeployment() const;
// The build system is able to report all executables that can be built, independent
// of configuration.
virtual bool knowsAllBuildExecutables() const;
void setup(QList<const BuildInfo *> infoList);
Utils::MacroExpander *macroExpander() const;
......@@ -590,14 +590,10 @@ void Target::updateDefaultRunConfigurations()
QList<RunConfiguration *> newConfigured; // NEW configured Rcs
QList<RunConfiguration *> newUnconfigured; // NEW unconfigured RCs
// sort existing RCs into configured/unconfigured.
foreach (RunConfiguration *rc, runConfigurations()) {
if (!rc->isConfigured())
existingUnconfigured << rc;
existingConfigured << rc;
std::tie(existingConfigured, existingUnconfigured)
= Utils::partition(runConfigurations(),
[](const RunConfiguration *rc) { return rc->isConfigured(); });
int configuredCount = existingConfigured.count();
// find all RC ids that can get created:
......@@ -617,7 +613,7 @@ void Target::updateDefaultRunConfigurations()
foreach (RunConfiguration *rc, existingConfigured) {
if (availableFactoryIds.contains(rc->id()))
toIgnore.append(rc->id()); // Already there
else if (project()->knowsAllBuildExecutables())
toRemove << rc;
foreach (Core::Id i, toIgnore)
......@@ -679,25 +675,27 @@ void Target::updateDefaultRunConfigurations()
// Make sure a configured RC will be active after we delete the RCs:
RunConfiguration *active = activeRunConfiguration();
if (removalList.contains(active)) {
if (!existingConfigured.isEmpty()) {
} else if (!newConfigured.isEmpty()) {
RunConfiguration *selected =;
// Try to find a runconfiguration that matches the project name. That is a good
// candidate for something to run initially.
selected = Utils::findOr(newConfigured, selected,
Utils::equal(&RunConfiguration::displayName, project()->displayName()));
} else if (!newUnconfigured.isEmpty()){
} else {
if (!removalList.isEmpty())
// Nothing will be left after removal: We set this to the last of in the removal list
// since that gives us the minimum number of signals (one signal for the change here and
// one more when the last RC is removed and the active RC becomes 0).
if (removalList.contains(active) || !active->isEnabled()) {
RunConfiguration *newConfiguredDefault = newConfigured.isEmpty() ? nullptr :;
RunConfiguration *rc
= Utils::findOrDefault(existingConfigured,
[](RunConfiguration *rc) { return rc->isEnabled(); });
if (!rc) {
rc = Utils::findOr(newConfigured, newConfiguredDefault,
Utils::equal(&RunConfiguration::displayName, project()->displayName()));
if (!rc)
rc = newUnconfigured.isEmpty() ? nullptr :;
if (!rc) {
// No RCs will be deleted, so use the one that will emit the minimum number of signals.
// One signal will be emitted from the next setActiveRunConfiguration, another one
// when the RC gets removed (and the activeRunConfiguration turns into a nullptr).
rc = removalList.isEmpty() ? nullptr : removalList.last();
if (rc)
// Remove the RCs that are no longer needed:
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment