summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libs/utils/aspects.cpp2
-rw-r--r--src/plugins/cmakeprojectmanager/builddirparameters.cpp13
-rw-r--r--src/plugins/cmakeprojectmanager/builddirparameters.h3
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp388
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h26
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp27
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsystem.h5
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp15
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeconfigitem.h6
-rw-r--r--src/plugins/cmakeprojectmanager/configmodel.cpp63
-rw-r--r--src/plugins/cmakeprojectmanager/configmodel.h18
-rw-r--r--src/plugins/cmakeprojectmanager/fileapireader.cpp13
12 files changed, 457 insertions, 122 deletions
diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp
index 8118d11ea7..8470d0de10 100644
--- a/src/libs/utils/aspects.cpp
+++ b/src/libs/utils/aspects.cpp
@@ -204,7 +204,7 @@ void BaseAspect::setVisible(bool visible)
// This may happen during layout building. Explicit setting visibility here
// may create a show a toplevel widget for a moment until it is parented
// to some non-shown widget.
- if (visible && w->parentWidget())
+ if (w->parentWidget())
w->setVisible(visible);
}
}
diff --git a/src/plugins/cmakeprojectmanager/builddirparameters.cpp b/src/plugins/cmakeprojectmanager/builddirparameters.cpp
index 1ef1215d22..048dead9d2 100644
--- a/src/plugins/cmakeprojectmanager/builddirparameters.cpp
+++ b/src/plugins/cmakeprojectmanager/builddirparameters.cpp
@@ -59,11 +59,14 @@ BuildDirParameters::BuildDirParameters(CMakeBuildConfiguration *bc)
});
initialCMakeArguments = Utils::filtered(expandedArguments,
[](const QString &s) { return !s.isEmpty(); });
- extraCMakeArguments = Utils::transform(bc->configurationChangesArguments(),
- [expander](const QString &s) {
- return expander->expand(s);
- });
-
+ configurationChangesArguments = Utils::transform(bc->configurationChangesArguments(),
+ [expander](const QString &s) {
+ return expander->expand(s);
+ });
+ additionalCMakeArguments = Utils::transform(bc->additionalCMakeArguments(),
+ [expander](const QString &s) {
+ return expander->expand(s);
+ });
const Target *t = bc->target();
const Kit *k = t->kit();
const Project *p = t->project();
diff --git a/src/plugins/cmakeprojectmanager/builddirparameters.h b/src/plugins/cmakeprojectmanager/builddirparameters.h
index 7b990aaa56..13ecedee24 100644
--- a/src/plugins/cmakeprojectmanager/builddirparameters.h
+++ b/src/plugins/cmakeprojectmanager/builddirparameters.h
@@ -61,7 +61,8 @@ public:
Utils::Id cmakeToolId;
QStringList initialCMakeArguments;
- QStringList extraCMakeArguments;
+ QStringList configurationChangesArguments;
+ QStringList additionalCMakeArguments;
};
} // namespace Internal
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
index 7e94c90a6b..8bce7209d5 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
@@ -35,6 +35,7 @@
#include "cmakespecificsettings.h"
#include "configmodel.h"
#include "configmodelitemdelegate.h"
+#include "fileapiparser.h"
#include <android/androidconstants.h>
#include <docker/dockerconstants.h>
@@ -119,16 +120,21 @@ private:
void updateButtonState();
void updateAdvancedCheckBox();
void updateFromKit();
+ void updateConfigurationStateIndex(int index);
CMakeProjectManager::CMakeConfig getQmlDebugCxxFlags();
CMakeProjectManager::CMakeConfig getSigningFlagsChanges();
void updateSelection();
+ void updateConfigurationStateSelection();
+ bool isInitialConfiguration() const;
void setVariableUnsetFlag(bool unsetFlag);
QAction *createForceAction(int type, const QModelIndex &idx);
bool eventFilter(QObject *target, QEvent *event) override;
void batchEditConfiguration();
+ void reconfigureWithInitialParameters(CMakeBuildConfiguration *bc);
+ void updateInitialCMakeArguments();
CMakeBuildConfiguration *m_buildConfiguration;
QTreeView *m_configView;
@@ -142,6 +148,7 @@ private:
QPushButton *m_unsetButton;
QPushButton *m_resetButton;
QCheckBox *m_showAdvancedCheckBox;
+ QTabBar *m_configurationStates;
QPushButton *m_reconfigureButton;
QTimer m_showProgressTimer;
FancyLineEdit *m_filterEdit;
@@ -188,34 +195,6 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
m_configModel->flush(); // clear out config cache...;
});
- auto clearCMakeConfiguration = new QPushButton(tr("Re-configure with Initial Parameters"));
- connect(clearCMakeConfiguration, &QPushButton::clicked, this, [bc]() {
- auto *settings = CMakeProjectPlugin::projectTypeSpecificSettings();
- bool doNotAsk = !settings->askBeforeReConfigureInitialParams.value();
- if (!doNotAsk) {
- QDialogButtonBox::StandardButton reply = Utils::CheckableMessageBox::question(
- Core::ICore::dialogParent(),
- tr("Re-configure with Initial Parameters"),
- tr("Clear CMake configuration and configure with initial parameters?"),
- tr("Do not ask again"),
- &doNotAsk,
- QDialogButtonBox::Yes | QDialogButtonBox::No,
- QDialogButtonBox::Yes);
-
- settings->askBeforeReConfigureInitialParams.setValue(!doNotAsk);
- settings->writeSettings(Core::ICore::settings());
-
- if (reply != QDialogButtonBox::Yes) {
- return;
- }
- }
-
- auto cbc = static_cast<CMakeBuildSystem*>(bc->buildSystem());
- cbc->clearCMakeCache();
- if (ProjectExplorerPlugin::saveModifiedFiles())
- cbc->runCMake();
- });
-
auto buildTypeAspect = bc->aspect<BuildTypeAspect>();
connect(buildTypeAspect, &BaseAspect::changed, this, [this, buildTypeAspect]() {
if (!m_buildConfiguration->isMultiConfig()) {
@@ -234,6 +213,13 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
m_warningMessageLabel = new InfoLabel({}, InfoLabel::Warning);
m_warningMessageLabel->setVisible(false);
+ m_configurationStates = new QTabBar(this);
+ m_configurationStates->addTab(tr("Initial Configuration"));
+ m_configurationStates->addTab(tr("Current Configuration"));
+ connect(m_configurationStates, &QTabBar::currentChanged, this, [this](int index) {
+ updateConfigurationStateIndex(index);
+ });
+
m_filterEdit = new FancyLineEdit;
m_filterEdit->setPlaceholderText(tr("Filter"));
m_filterEdit->setFiltering(true);
@@ -318,7 +304,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
updateSelection();
});
- m_reconfigureButton = new QPushButton(tr("Apply Configuration Changes"));
+ m_reconfigureButton = new QPushButton(tr("Run CMake"));
m_reconfigureButton->setEnabled(false);
using namespace Layouting;
@@ -342,14 +328,19 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
Form {
buildDirAspect,
bc->aspect<BuildTypeAspect>(),
- bc->aspect<InitialCMakeArgumentsAspect>(),
- QString(), clearCMakeConfiguration, Break(),
qmlDebugAspect
},
m_warningMessageLabel,
Space(10),
- cmakeConfiguration,
- m_reconfigureButton,
+ m_configurationStates,
+ Group {
+ cmakeConfiguration,
+ Row {
+ bc->aspect<InitialCMakeArgumentsAspect>(),
+ bc->aspect<AdditionalCMakeArgumentsAspect>()
+ },
+ m_reconfigureButton,
+ }
}.attachTo(details, false);
updateAdvancedCheckBox();
@@ -366,22 +357,36 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
m_showProgressTimer.start();
else {
m_configModel->setConfiguration(m_buildConfiguration->configurationFromCMake());
+ m_configModel->setInitialParametersConfiguration(
+ m_buildConfiguration->initialCMakeConfiguration());
m_configView->expandAll();
}
connect(bc->buildSystem(), &BuildSystem::parsingFinished, this, [this, stretcher] {
+ m_configModel->flush();
m_configModel->setConfiguration(m_buildConfiguration->configurationFromCMake());
+ m_configModel->setInitialParametersConfiguration(
+ m_buildConfiguration->initialCMakeConfiguration());
+ m_buildConfiguration->filterConfigArgumentsFromAdditionalCMakeArguments();
m_configView->expandAll();
m_configView->setEnabled(true);
stretcher->stretch();
updateButtonState();
m_showProgressTimer.stop();
m_progressIndicator->hide();
+ updateConfigurationStateSelection();
+ });
+
+ auto cbc = static_cast<CMakeBuildSystem *>(bc->buildSystem());
+ connect(cbc, &CMakeBuildSystem::configurationCleared, this, [this]() {
+ updateConfigurationStateSelection();
});
+
connect(m_buildConfiguration, &CMakeBuildConfiguration::errorOccurred,
this, [this]() {
m_showProgressTimer.stop();
m_progressIndicator->hide();
+ updateConfigurationStateSelection();
});
connect(m_configTextFilterModel, &QAbstractItemModel::modelReset, this, [this, stretcher]() {
m_configView->expandAll();
@@ -410,11 +415,17 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
QRegularExpression::CaseInsensitiveOption));
});
- connect(m_resetButton, &QPushButton::clicked, m_configModel, &ConfigModel::resetAllChanges);
- connect(m_reconfigureButton, &QPushButton::clicked, this, [this]() {
+ connect(m_resetButton, &QPushButton::clicked, this, [this](){
+ m_configModel->resetAllChanges(isInitialConfiguration());
+ });
+ connect(m_reconfigureButton, &QPushButton::clicked, this, [this, bc]() {
auto buildSystem = static_cast<CMakeBuildSystem *>(m_buildConfiguration->buildSystem());
if (!buildSystem->isParsing()) {
- buildSystem->runCMakeWithExtraArguments();
+ if (isInitialConfiguration()) {
+ reconfigureWithInitialParameters(bc);
+ } else {
+ buildSystem->runCMakeWithExtraArguments();
+ }
} else {
buildSystem->stopCMakeRun();
m_reconfigureButton->setEnabled(false);
@@ -438,7 +449,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
if (type == ConfigModel::DataItem::BOOLEAN)
value = QString::fromLatin1("OFF");
- m_configModel->appendConfiguration(tr("<UNSET>"), value, type);
+ m_configModel->appendConfiguration(tr("<UNSET>"), value, type, isInitialConfiguration());
const TreeItem *item = m_configModel->findNonRootItem([&value, type](TreeItem *item) {
ConfigModel::DataItem dataItem = ConfigModel::dataItemFromIndex(item->index());
return dataItem.key == tr("<UNSET>") && dataItem.type == type && dataItem.value == value;
@@ -466,12 +477,10 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
this, [this]() {
if (m_buildConfiguration->isEnabled())
setError(QString());
-
- m_batchEditButton->setEnabled(m_buildConfiguration->isEnabled());
- m_addButton->setEnabled(m_buildConfiguration->isEnabled());
});
updateSelection();
+ updateConfigurationStateSelection();
}
@@ -511,16 +520,84 @@ void CMakeBuildSettingsWidget::batchEditConfiguration()
[expander](const QString &s) {
return expander->expand(s);
});
- const CMakeConfig config = CMakeConfig::fromArguments(expandedLines);
+ const bool isInitial = isInitialConfiguration();
+ QStringList unknownArguments;
+ CMakeConfig config = CMakeConfig::fromArguments(isInitial ? lines : expandedLines,
+ unknownArguments);
+ for (auto &ci : config)
+ ci.isInitial = isInitial;
m_configModel->setBatchEditConfiguration(config);
});
- editor->setPlainText(m_buildConfiguration->configurationChangesArguments().join('\n'));
+ editor->setPlainText(
+ m_buildConfiguration->configurationChangesArguments(isInitialConfiguration())
+ .join('\n'));
dialog->show();
}
+void CMakeBuildSettingsWidget::reconfigureWithInitialParameters(CMakeBuildConfiguration *bc)
+{
+ CMakeSpecificSettings *settings = CMakeProjectPlugin::projectTypeSpecificSettings();
+ bool doNotAsk = !settings->askBeforeReConfigureInitialParams.value();
+ if (!doNotAsk) {
+ QDialogButtonBox::StandardButton reply = Utils::CheckableMessageBox::question(
+ Core::ICore::dialogParent(),
+ tr("Re-configure with Initial Parameters"),
+ tr("Clear CMake configuration and configure with initial parameters?"),
+ tr("Do not ask again"),
+ &doNotAsk,
+ QDialogButtonBox::Yes | QDialogButtonBox::No,
+ QDialogButtonBox::Yes);
+
+ settings->askBeforeReConfigureInitialParams.setValue(!doNotAsk);
+ settings->writeSettings(Core::ICore::settings());
+
+ if (reply != QDialogButtonBox::Yes) {
+ return;
+ }
+ }
+
+ auto cbc = static_cast<CMakeBuildSystem*>(bc->buildSystem());
+ cbc->clearCMakeCache();
+
+ updateInitialCMakeArguments();
+
+ if (ProjectExplorerPlugin::saveModifiedFiles())
+ cbc->runCMake();
+}
+
+void CMakeBuildSettingsWidget::updateInitialCMakeArguments()
+{
+ CMakeConfig initialList = m_buildConfiguration->initialCMakeConfiguration();
+
+ for (const CMakeConfigItem &ci : m_buildConfiguration->configurationChanges()) {
+ if (!ci.isInitial)
+ continue;
+ auto it = std::find_if(initialList.begin(),
+ initialList.end(),
+ [ci](const CMakeConfigItem &item) {
+ return item.key == ci.key;
+ });
+ if (it != initialList.end()) {
+ *it = ci;
+ if (ci.isUnset)
+ initialList.erase(it);
+ } else {
+ initialList.push_back(ci);
+ }
+ }
+
+ m_buildConfiguration->aspect<InitialCMakeArgumentsAspect>()->setCMakeConfiguration(initialList);
+
+ // value() will contain only the unknown arguments (the non -D/-U arguments)
+ // As the user would expect to have e.g. "--preset" from "Initial Configuration"
+ // to "Current Configuration" as additional parameters
+ m_buildConfiguration->setAdditionalCMakeArguments(ProcessArgs::splitArgs(
+ m_buildConfiguration->aspect<InitialCMakeArgumentsAspect>()->value()));
+}
+
void CMakeBuildSettingsWidget::setError(const QString &message)
{
m_buildConfiguration->buildDirectoryAspect()->setProblem(message);
@@ -548,6 +625,7 @@ void CMakeBuildSettingsWidget::updateButtonState()
ni.value = i.value.toUtf8();
ni.documentation = i.description.toUtf8();
ni.isAdvanced = i.isAdvanced;
+ ni.isInitial = i.isInitial;
ni.isUnset = i.isUnset;
ni.inCMakeCache = i.inCMakeCache;
ni.values = i.values;
@@ -572,30 +650,49 @@ void CMakeBuildSettingsWidget::updateButtonState()
return ni;
});
- m_resetButton->setEnabled(m_configModel->hasChanges() && !isParsing);
- m_reconfigureButton->setEnabled(true);
+ const bool isInitial = isInitialConfiguration();
+ m_resetButton->setEnabled(m_configModel->hasChanges(isInitial) && !isParsing);
- if (isParsing)
+ m_buildConfiguration->aspect<InitialCMakeArgumentsAspect>()->setVisible(isInitialConfiguration());
+ m_buildConfiguration->aspect<AdditionalCMakeArgumentsAspect>()->setVisible(!isInitialConfiguration());
+
+ m_buildConfiguration->aspect<InitialCMakeArgumentsAspect>()->setEnabled(!isParsing);
+ m_buildConfiguration->aspect<AdditionalCMakeArgumentsAspect>()->setEnabled(!isParsing);
+
+ // Update label and text boldness of the reconfigure button
+ QFont reconfigureButtonFont = m_reconfigureButton->font();
+ if (isParsing) {
m_reconfigureButton->setText(tr("Stop CMake"));
- else if (m_configModel->hasChanges())
- m_reconfigureButton->setText(tr("Apply Configuration Changes"));
- else
- m_reconfigureButton->setText(tr("Run CMake"));
+ reconfigureButtonFont.setBold(false);
+ } else {
+ m_reconfigureButton->setEnabled(true);
+ if (isInitial) {
+ m_reconfigureButton->setText(tr("Re-configure with Initial Parameters"));
+ } else {
+ m_reconfigureButton->setText(tr("Run CMake"));
+ }
+ reconfigureButtonFont.setBold(m_configModel->hasChanges(isInitial));
+ }
+ m_reconfigureButton->setFont(reconfigureButtonFont);
m_buildConfiguration->setConfigurationChanges(configChanges);
+
+ // Update the tooltip with the changes
+ m_reconfigureButton->setToolTip(
+ m_buildConfiguration->configurationChangesArguments(isInitialConfiguration()).join('\n'));
}
void CMakeBuildSettingsWidget::updateAdvancedCheckBox()
{
if (m_showAdvancedCheckBox->isChecked()) {
- m_configFilterModel->setSourceModel(nullptr);
- m_configTextFilterModel->setSourceModel(m_configModel);
+ m_configFilterModel->setFilterRole(ConfigModel::ItemIsAdvancedRole);
+ m_configFilterModel->setFilterRegularExpression("[01]");
} else {
- m_configTextFilterModel->setSourceModel(nullptr);
- m_configFilterModel->setSourceModel(m_configModel);
- m_configTextFilterModel->setSourceModel(m_configFilterModel);
+ m_configFilterModel->setFilterRole(ConfigModel::ItemIsAdvancedRole);
+ m_configFilterModel->setFilterFixedString("0");
}
+ updateButtonState();
}
void CMakeBuildSettingsWidget::updateFromKit()
@@ -603,13 +700,28 @@ void CMakeBuildSettingsWidget::updateFromKit()
const Kit *k = m_buildConfiguration->kit();
const CMakeConfig config = CMakeConfigurationKitAspect::configuration(k);
- QHash<QString, QString> configHash;
+ ConfigModel::KitConfiguration configHash;
for (const CMakeConfigItem &i : config)
- configHash.insert(QString::fromUtf8(i.key), i.expandedValue(k));
+ configHash.insert(QString::fromUtf8(i.key),
+ qMakePair(QString::fromUtf8(i.value), i.expandedValue(k)));
m_configModel->setConfigurationFromKit(configHash);
}
+void CMakeBuildSettingsWidget::updateConfigurationStateIndex(int index)
+{
+ if (index == 0) {
+ m_configFilterModel->setFilterRole(ConfigModel::ItemIsInitialRole);
+ m_configFilterModel->setFilterFixedString("1");
+ } else {
+ updateAdvancedCheckBox();
+ }
+
+ m_showAdvancedCheckBox->setEnabled(index != 0);
+
+ updateButtonState();
+}
+
CMakeConfig CMakeBuildSettingsWidget::getQmlDebugCxxFlags()
{
const auto aspect = m_buildConfiguration->aspect<QtSupport::QmlDebuggingAspect>();
@@ -693,6 +805,23 @@ void CMakeBuildSettingsWidget::updateSelection()
m_editButton->setEnabled(editableCount == 1);
}
+void CMakeBuildSettingsWidget::updateConfigurationStateSelection()
+{
+ const bool hasReplyFile
+ = FileApiParser::scanForCMakeReplyFile(m_buildConfiguration->buildDirectory()).exists();
+
+ const int switchToIndex = hasReplyFile ? 1 : 0;
+ if (m_configurationStates->currentIndex() != switchToIndex)
+ m_configurationStates->setCurrentIndex(switchToIndex);
+ else
+ emit m_configurationStates->currentChanged(switchToIndex);
+}
+
+bool CMakeBuildSettingsWidget::isInitialConfiguration() const
+{
+ return m_configurationStates->currentIndex() == 0;
+}
+
void CMakeBuildSettingsWidget::setVariableUnsetFlag(bool unsetFlag)
{
const QModelIndexList selectedIndexes = m_configView->selectionModel()->selectedIndexes();
@@ -771,10 +900,11 @@ bool CMakeBuildSettingsWidget::eventFilter(QObject *target, QEvent *event)
return index.isValid() && index.flags().testFlag(Qt::ItemIsSelectable);
});
- const QStringList variableList = Utils::transform(validIndexes, [this](const QModelIndex &index) {
- return ConfigModel::dataItemFromIndex(index)
- .toCMakeConfigItem().toArgument(m_buildConfiguration->macroExpander());
- });
+ const QStringList variableList
+ = Utils::transform(validIndexes, [this](const QModelIndex &index) {
+ return ConfigModel::dataItemFromIndex(index).toCMakeConfigItem().toArgument(
+ isInitialConfiguration() ? nullptr : m_buildConfiguration->macroExpander());
+ });
QApplication::clipboard()->setText(variableList.join('\n'), QClipboard::Clipboard);
});
@@ -887,7 +1017,11 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
});
auto initialCMakeArgumentsAspect = addAspect<InitialCMakeArgumentsAspect>();
- initialCMakeArgumentsAspect->setMacroExpanderProvider([this]{ return macroExpander(); });
+ initialCMakeArgumentsAspect->setMacroExpanderProvider([this] { return macroExpander(); });
+
+ auto additionalCMakeArgumentsAspect = addAspect<AdditionalCMakeArgumentsAspect>();
+ additionalCMakeArgumentsAspect->setMacroExpanderProvider([this] { return macroExpander(); });
+
macroExpander()->registerVariable(DEVELOPMENT_TEAM_FLAG,
tr("The CMake flag for the development team"),
[this] {
@@ -1126,15 +1260,23 @@ CMakeConfig CMakeBuildConfiguration::configurationChanges() const
return m_configurationChanges;
}
-QStringList CMakeBuildConfiguration::configurationChangesArguments() const
+QStringList CMakeBuildConfiguration::configurationChangesArguments(bool initialParameters) const
{
- return Utils::transform(m_configurationChanges.toList(),
- [](const CMakeConfigItem &i) { return i.toArgument(); });
+ const QList<CMakeConfigItem> filteredInitials
+ = Utils::filtered(m_configurationChanges, [initialParameters](const CMakeConfigItem &ci) {
+ return initialParameters ? ci.isInitial : !ci.isInitial;
+ });
+ return Utils::transform(filteredInitials, &CMakeConfigItem::toArgument);
}
QStringList CMakeBuildConfiguration::initialCMakeArguments() const
{
- return aspect<InitialCMakeArgumentsAspect>()->value().split('\n', Qt::SkipEmptyParts);
+ return aspect<InitialCMakeArgumentsAspect>()->allValues();
+}
+
+CMakeConfig CMakeBuildConfiguration::initialCMakeConfiguration() const
+{
+ return aspect<InitialCMakeArgumentsAspect>()->cmakeConfiguration();
}
void CMakeBuildConfiguration::setConfigurationFromCMake(const CMakeConfig &config)
@@ -1170,7 +1312,43 @@ void CMakeBuildConfiguration::clearError(ForceEnabledChanged fec)
void CMakeBuildConfiguration::setInitialCMakeArguments(const QStringList &args)
{
- aspect<InitialCMakeArgumentsAspect>()->setValue(args.join('\n'));
+ QStringList additionalArguments;
+ aspect<InitialCMakeArgumentsAspect>()->setAllValues(args.join('\n'), additionalArguments);
+
+ // Set the unknown additional arguments also for the "Current Configuration"
+ setAdditionalCMakeArguments(additionalArguments);
+}
+
+QStringList CMakeBuildConfiguration::additionalCMakeArguments() const
+{
+ return ProcessArgs::splitArgs(aspect<AdditionalCMakeArgumentsAspect>()->value());
+}
+
+void CMakeBuildConfiguration::setAdditionalCMakeArguments(const QStringList &args)
+{
+ const QStringList expandedAdditionalArguments = Utils::transform(args, [this](const QString &s) {
+ return macroExpander()->expand(s);
+ });
+ const QStringList nonEmptyAdditionalArguments = Utils::filtered(expandedAdditionalArguments,
+ [](const QString &s) {
+ return !s.isEmpty();
+ });
+ aspect<AdditionalCMakeArgumentsAspect>()->setValue(
+ ProcessArgs::joinArgs(nonEmptyAdditionalArguments));
+}
+
+void CMakeBuildConfiguration::filterConfigArgumentsFromAdditionalCMakeArguments()
+{
+ // On iOS the %{Ios:DevelopmentTeam:Flag} evalues to something like
+ // -DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM:STRING=MAGICSTRING
+ // which is already part of the CMake variables and should not be also
+ // in the addtional CMake parameters
+ const QStringList arguments = ProcessArgs::splitArgs(
+ aspect<AdditionalCMakeArgumentsAspect>()->value());
+ QStringList unknownArguments;
+ const CMakeConfig config = CMakeConfig::fromArguments(arguments, unknownArguments);
+
+ aspect<AdditionalCMakeArgumentsAspect>()->setValue(ProcessArgs::joinArgs(unknownArguments));
}
void CMakeBuildConfiguration::setError(const QString &message)
@@ -1346,9 +1524,10 @@ FilePath CMakeBuildConfiguration::sourceDirectory() const
QString CMakeBuildConfiguration::cmakeBuildType() const
{
- auto setBuildTypeFromConfig = [this](const CMakeConfig &config){
- auto it = std::find_if(config.begin(), config.end(),
- [](const CMakeConfigItem &item) { return item.key == "CMAKE_BUILD_TYPE";});
+ auto setBuildTypeFromConfig = [this](const CMakeConfig &config) {
+ auto it = std::find_if(config.begin(), config.end(), [](const CMakeConfigItem &item) {
+ return item.key == "CMAKE_BUILD_TYPE" && !item.isInitial;
+ });
if (it != config.end())
const_cast<CMakeBuildConfiguration*>(this)
->setCMakeBuildType(QString::fromUtf8(it->value));
@@ -1370,10 +1549,10 @@ QString CMakeBuildConfiguration::cmakeBuildType() const
QString errorMessage;
config = CMakeBuildSystem::parseCMakeCacheDotTxt(cmakeCacheTxt, &errorMessage);
} else {
- config = CMakeConfig::fromArguments(initialCMakeArguments());
+ config = initialCMakeConfiguration();
}
} else if (!hasCMakeCache) {
- config = CMakeConfig::fromArguments(initialCMakeArguments());
+ config = initialCMakeConfiguration();
}
if (!config.isEmpty() && !isMultiConfig())
@@ -1408,11 +1587,74 @@ namespace Internal {
// - InitialCMakeParametersAspect:
// ----------------------------------------------------------------------
+const CMakeConfig &InitialCMakeArgumentsAspect::cmakeConfiguration() const
+{
+ return m_cmakeConfiguration;
+}
+
+const QStringList InitialCMakeArgumentsAspect::allValues() const
+{
+ QStringList initialCMakeArguments = Utils::transform(m_cmakeConfiguration.toList(),
+ [](const CMakeConfigItem &ci) {
+ return ci.toArgument(nullptr);
+ });
+
+ initialCMakeArguments.append(ProcessArgs::splitArgs(value()));
+
+ return initialCMakeArguments;
+}
+
+void InitialCMakeArgumentsAspect::setAllValues(const QString &values, QStringList &additionalArguments)
+{
+ QStringList arguments = values.split('\n', Qt::SkipEmptyParts);
+ for (QString &arg: arguments) {
+ if (arg.startsWith("-G"))
+ arg.replace("-G", "-DCMAKE_GENERATOR:STRING=");
+ if (arg.startsWith("-A"))
+ arg.replace("-A", "-DCMAKE_GENERATOR_PLATFORM:STRING=");
+ if (arg.startsWith("-T"))
+ arg.replace("-T", "-DCMAKE_GENERATOR_TOOLSET:STRING=");
+ }
+ m_cmakeConfiguration = CMakeConfig::fromArguments(arguments, additionalArguments);
+
+ // Display the unknown arguments in "Additional CMake parameters"
+ const QString additionalArgumentsValue = ProcessArgs::joinArgs(additionalArguments);
+ BaseAspect::setValueQuietly(additionalArgumentsValue);
+}
+
+void InitialCMakeArgumentsAspect::setCMakeConfiguration(const CMakeConfig &config)
+{
+ m_cmakeConfiguration = config;
+}
+
+void InitialCMakeArgumentsAspect::fromMap(const QVariantMap &map)
+{
+ const QString value = map.value(settingsKey(), defaultValue()).toString();
+ QStringList additionalArguments;
+ setAllValues(value, additionalArguments);
+}
+
+void InitialCMakeArgumentsAspect::toMap(QVariantMap &map) const
+{
+ saveToMap(map, allValues().join('\n'), defaultValue(), settingsKey());
+}
+
InitialCMakeArgumentsAspect::InitialCMakeArgumentsAspect()
{
setSettingsKey("CMake.Initial.Parameters");
- setLabelText(tr("Initial CMake parameters:"));
- setDisplayStyle(TextEditDisplay);
+ setLabelText(tr("Additional CMake parameters:"));
+ setDisplayStyle(LineEditDisplay);
+}
+
+// ----------------------------------------------------------------------
+// - AdditionalCMakeParametersAspect:
+// ----------------------------------------------------------------------
+
+AdditionalCMakeArgumentsAspect::AdditionalCMakeArgumentsAspect()
+{
+ setSettingsKey("CMake.Additional.Parameters");
+ setLabelText(tr("Additional CMake parameters:"));
+ setDisplayStyle(LineEditDisplay);
}
// -----------------------------------------------------------------------------
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
index 31f905cc52..4f6b909592 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
+++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
@@ -54,9 +54,10 @@ public:
CMakeConfig configurationFromCMake() const;
CMakeConfig configurationChanges() const;
- QStringList configurationChangesArguments() const;
+ QStringList configurationChangesArguments(bool initialParameters = false) const;
QStringList initialCMakeArguments() const;
+ CMakeConfig initialCMakeConfiguration() const;
QString error() const;
QString warning() const;
@@ -78,6 +79,10 @@ public:
bool isMultiConfig() const;
void setIsMultiConfig(bool isMultiConfig);
+ QStringList additionalCMakeArguments() const;
+ void setAdditionalCMakeArguments(const QStringList &args);
+ void filterConfigArgumentsFromAdditionalCMakeArguments();
+
signals:
void errorOccurred(const QString &message);
void warningOccurred(const QString &message);
@@ -106,7 +111,6 @@ private:
void setError(const QString &message);
void setWarning(const QString &message);
- CMakeConfig m_initialConfiguration;
QString m_error;
QString m_warning;
@@ -114,7 +118,6 @@ private:
CMakeConfig m_configurationChanges;
Internal::CMakeBuildSystem *m_buildSystem = nullptr;
- QStringList m_extraCMakeArguments;
bool m_isMultiConfig = false;
friend class Internal::CMakeBuildSettingsWidget;
@@ -148,8 +151,25 @@ class InitialCMakeArgumentsAspect final : public Utils::StringAspect
{
Q_OBJECT
+ CMakeConfig m_cmakeConfiguration;
public:
InitialCMakeArgumentsAspect();
+
+ const CMakeConfig &cmakeConfiguration() const;
+ const QStringList allValues() const;
+ void setAllValues(const QString &values, QStringList &additionalArguments);
+ void setCMakeConfiguration(const CMakeConfig &config);
+
+ void fromMap(const QVariantMap &map) final;
+ void toMap(QVariantMap &map) const final;
+};
+
+class AdditionalCMakeArgumentsAspect final : public Utils::StringAspect
+{
+ Q_OBJECT
+
+public:
+ AdditionalCMakeArgumentsAspect();
};
class SourceDirectoryAspect final : public Utils::StringAspect
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
index 459052edb5..beacad9706 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
@@ -264,7 +264,7 @@ void CMakeBuildSystem::triggerParsing()
}
if ((0 == (reparseParameters & REPARSE_FORCE_EXTRA_CONFIGURATION))
- && mustApplyExtraArguments(m_parameters)) {
+ && mustApplyConfigurationChangesArguments(m_parameters)) {
reparseParameters |= REPARSE_FORCE_CMAKE_RUN | REPARSE_FORCE_EXTRA_CONFIGURATION;
}
@@ -395,16 +395,17 @@ void CMakeBuildSystem::setParametersAndRequestParse(const BuildDirParameters &pa
}
}
-bool CMakeBuildSystem::mustApplyExtraArguments(const BuildDirParameters &parameters) const
+bool CMakeBuildSystem::mustApplyConfigurationChangesArguments(const BuildDirParameters &parameters) const
{
- if (parameters.extraCMakeArguments.isEmpty())
+ if (parameters.configurationChangesArguments.isEmpty())
return false;
auto answer = QMessageBox::question(Core::ICore::mainWindow(),
tr("Apply configuration changes?"),
"<p>" + tr("Run CMake with configuration changes?")
+ "</p><pre>"
- + parameters.extraCMakeArguments.join("\n") + "</pre>",
+ + parameters.configurationChangesArguments.join("\n")
+ + "</pre>",
QMessageBox::Apply | QMessageBox::Discard,
QMessageBox::Apply);
return answer == QMessageBox::Apply;
@@ -437,7 +438,7 @@ void CMakeBuildSystem::runCMakeWithExtraArguments()
void CMakeBuildSystem::stopCMakeRun()
{
qCDebug(cmakeBuildSystemLog) << cmakeBuildConfiguration()->displayName()
- << "stopping CMake's runb";
+ << "stopping CMake's run";
m_reader.stopCMakeRun();
}
@@ -459,10 +460,10 @@ bool CMakeBuildSystem::persistCMakeState()
int reparseFlags = REPARSE_DEFAULT;
qCDebug(cmakeBuildSystemLog) << "Checking whether build system needs to be persisted:"
<< "buildDir:" << parameters.buildDirectory
- << "Has extraargs:" << !parameters.extraCMakeArguments.isEmpty();
+ << "Has extraargs:" << !parameters.configurationChangesArguments.isEmpty();
if (parameters.buildDirectory == parameters.buildDirectory
- && mustApplyExtraArguments(parameters)) {
+ && mustApplyConfigurationChangesArguments(parameters)) {
reparseFlags = REPARSE_FORCE_EXTRA_CONFIGURATION;
qCDebug(cmakeBuildSystemLog) << " -> must run CMake with extra arguments.";
}
@@ -497,6 +498,8 @@ void CMakeBuildSystem::clearCMakeCache()
for (const FilePath &path : pathsToDelete)
path.removeRecursively();
+
+ emit configurationCleared();
}
void CMakeBuildSystem::combineScanAndParse(bool restoredFromBackup)
@@ -730,6 +733,8 @@ void CMakeBuildSystem::updateCMakeConfiguration(QString &errorMessage)
if (!errorMessage.isEmpty()) {
const CMakeConfig changes = cmakeBuildConfiguration()->configurationChanges();
for (const auto &ci : changes) {
+ if (ci.isInitial)
+ continue;
const bool haveConfigItem = Utils::contains(cmakeConfig, [ci](const CMakeConfigItem& i) {
return i.key == ci.key;
});
@@ -1252,8 +1257,8 @@ void CMakeBuildSystem::updateQmlJSCodeModel(const QStringList &extraHeaderPaths,
void CMakeBuildSystem::updateInitialCMakeExpandableVars()
{
const CMakeConfig &cm = cmakeBuildConfiguration()->configurationFromCMake();
- const CMakeConfig &initialConfig =
- CMakeConfig::fromArguments(cmakeBuildConfiguration()->initialCMakeArguments());
+ const CMakeConfig &initialConfig
+ = cmakeBuildConfiguration()->initialCMakeConfiguration();
CMakeConfig config;
@@ -1280,7 +1285,7 @@ void CMakeBuildSystem::updateInitialCMakeExpandableVars()
};
for (const auto &var : singlePathList) {
auto it = std::find_if(cm.cbegin(), cm.cend(), [var](const CMakeConfigItem &item) {
- return item.key == var;
+ return item.key == var && !item.isInitial;
});
if (it != cm.cend()) {
@@ -1304,7 +1309,7 @@ void CMakeBuildSystem::updateInitialCMakeExpandableVars()
};
for (const auto &var : multiplePathList) {
auto it = std::find_if(cm.cbegin(), cm.cend(), [var](const CMakeConfigItem &item) {
- return item.key == var;
+ return item.key == var && !item.isInitial;
});
if (it != cm.cend()) {
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h
index 60b4f4e97d..51901eb701 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h
@@ -108,6 +108,9 @@ public:
CMakeProject *project() const;
+signals:
+ void configurationCleared();
+
private:
// Actually ask for parsing:
enum ReparseParameters {
@@ -123,7 +126,7 @@ private:
void setParametersAndRequestParse(const BuildDirParameters &parameters,
const int reparseParameters);
- bool mustApplyExtraArguments(const BuildDirParameters &parameters) const;
+ bool mustApplyConfigurationChangesArguments(const BuildDirParameters &parameters) const;
// State handling:
// Parser states:
diff --git a/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp b/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp
index 53bec6a52a..a2eabe627a 100644
--- a/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp
@@ -310,7 +310,7 @@ static CMakeConfigItem unsetItemFromString(const QString &input)
return item;
}
-CMakeConfig CMakeConfig::fromArguments(const QStringList &list)
+CMakeConfig CMakeConfig::fromArguments(const QStringList &list, QStringList &unknownArguments)
{
CMakeConfig result;
bool inSet = false;
@@ -340,8 +340,10 @@ CMakeConfig CMakeConfig::fromArguments(const QStringList &list)
}
if (i.startsWith("-D")) {
result.append(setItemFromString(i.mid(2)));
+ continue;
}
- // ignore everything else as that does not define a configuration option
+
+ unknownArguments.append(i);
}
return result;
}
@@ -446,6 +448,11 @@ QString CMakeConfigItem::toString(const Utils::MacroExpander *expander) const
return QString::fromUtf8(key) + QLatin1Char(':') + typeStr + QLatin1Char('=') + expandedValue;
}
+QString CMakeConfigItem::toArgument() const
+{
+ return toArgument(nullptr);
+}
+
QString CMakeConfigItem::toArgument(const Utils::MacroExpander *expander) const
{
if (isUnset)
@@ -468,12 +475,12 @@ QString CMakeConfigItem::toCMakeSetLine(const Utils::MacroExpander *expander) co
bool CMakeConfigItem::operator==(const CMakeConfigItem &o) const
{
// type, isAdvanced and documentation do not matter for a match!
- return o.key == key && o.value == value && o.isUnset == isUnset;
+ return o.key == key && o.value == value && o.isUnset == isUnset && o.isInitial == isInitial;
}
Utils::QHashValueType qHash(const CMakeConfigItem &it)
{
- return ::qHash(it.key) ^ ::qHash(it.value) ^ ::qHash(it.isUnset);
+ return ::qHash(it.key) ^ ::qHash(it.value) ^ ::qHash(it.isUnset) ^ ::qHash(it.isInitial);
}
#if WITH_TESTS
diff --git a/src/plugins/cmakeprojectmanager/cmakeconfigitem.h b/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
index f94674f623..056a31ac98 100644
--- a/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
+++ b/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
@@ -64,7 +64,8 @@ public:
static bool less(const CMakeConfigItem &a, const CMakeConfigItem &b);
static CMakeConfigItem fromString(const QString &s);
QString toString(const Utils::MacroExpander *expander = nullptr) const;
- QString toArgument(const Utils::MacroExpander *expander = nullptr) const;
+ QString toArgument() const;
+ QString toArgument(const Utils::MacroExpander *expander) const;
QString toCMakeSetLine(const Utils::MacroExpander *expander = nullptr) const;
bool operator==(const CMakeConfigItem &o) const;
@@ -75,6 +76,7 @@ public:
bool isAdvanced = false;
bool inCMakeCache = false;
bool isUnset = false;
+ bool isInitial = false;
QByteArray value; // converted to string as needed
QByteArray documentation;
QStringList values;
@@ -89,7 +91,7 @@ public:
const QList<CMakeConfigItem> &toList() const { return *this; }
- static CMakeConfig fromArguments(const QStringList &list);
+ static CMakeConfig fromArguments(const QStringList &list, QStringList &unknownArguments);
static CMakeConfig fromFile(const Utils::FilePath &input, QString *errorMessage);
QByteArray valueOf(const QByteArray &key) const;
diff --git a/src/plugins/cmakeprojectmanager/configmodel.cpp b/src/plugins/cmakeprojectmanager/configmodel.cpp
index 737f78e689..83e326e530 100644
--- a/src/plugins/cmakeprojectmanager/configmodel.cpp
+++ b/src/plugins/cmakeprojectmanager/configmodel.cpp
@@ -52,6 +52,14 @@ QVariant ConfigModel::data(const QModelIndex &idx, int role) const
}) != nullptr;
return hasNormalChildren ? "0" : "1";
}
+ if (role == ItemIsInitialRole && item->childCount() > 0) {
+ const bool hasInitialChildren = item->findAnyChild([](const Utils::TreeItem *ti) {
+ if (auto cmti = dynamic_cast<const Internal::ConfigModelTreeItem*>(ti))
+ return cmti->dataItem->isInitial;
+ return false;
+ }) != nullptr;
+ return hasInitialChildren ? "1" : "0";
+ }
return Utils::TreeModel<>::data(idx, role);
}
@@ -59,7 +67,7 @@ ConfigModel::~ConfigModel() = default;
void ConfigModel::appendConfiguration(const QString &key,
const QString &value,
- const ConfigModel::DataItem::Type type,
+ const ConfigModel::DataItem::Type type, bool isInitial,
const QString &description,
const QStringList &values)
{
@@ -67,6 +75,7 @@ void ConfigModel::appendConfiguration(const QString &key,
item.key = key;
item.type = type;
item.value = value;
+ item.isInitial = isInitial;
item.description = description;
item.values = values;
@@ -74,7 +83,8 @@ void ConfigModel::appendConfiguration(const QString &key,
internalItem.isUserNew = true;
if (m_kitConfiguration.contains(key))
- internalItem.kitValue = m_kitConfiguration.value(key);
+ internalItem.kitValue = isInitial ? m_kitConfiguration.value(key).first
+ : m_kitConfiguration.value(key).second;
m_configuration.append(internalItem);
setConfiguration(m_configuration);
@@ -85,13 +95,14 @@ void ConfigModel::setConfiguration(const QList<DataItem> &config)
setConfiguration(Utils::transform(config, [](const DataItem &di) { return InternalDataItem(di); }));
}
-void ConfigModel::setConfigurationFromKit(const QHash<QString, QString> &kitConfig)
+void ConfigModel::setConfigurationFromKit(const KitConfiguration &kitConfig)
{
m_kitConfiguration = kitConfig;
for (InternalDataItem &i : m_configuration) {
if (m_kitConfiguration.contains(i.key))
- i.kitValue = m_kitConfiguration.value(i.key);
+ i.kitValue = i.isInitial ? m_kitConfiguration.value(i.key).first
+ : m_kitConfiguration.value(i.key).second;
}
setConfiguration(m_configuration);
}
@@ -101,24 +112,36 @@ void ConfigModel::flush()
setConfiguration(QList<InternalDataItem>());
}
-void ConfigModel::resetAllChanges()
+void ConfigModel::resetAllChanges(bool initialParameters)
{
- const QList<InternalDataItem> tmp
+ QList<InternalDataItem> notNew
= Utils::filtered(m_configuration,
[](const InternalDataItem &i) { return !i.isUserNew; });
- setConfiguration(Utils::transform(tmp, [](const InternalDataItem &i) {
+ notNew = Utils::transform(notNew, [](const InternalDataItem &i) {
InternalDataItem ni(i);
ni.newValue.clear();
ni.isUserChanged = false;
ni.isUnset = false;
return ni;
+ });
+
+ // add the changes from the other list, which shouldn't get reset
+ notNew.append(Utils::filtered(m_configuration, [initialParameters](const InternalDataItem &i) {
+ return !(initialParameters ? i.isInitial : !i.isInitial) && i.isUserNew;
}));
+
+ setConfiguration(notNew);
}
-bool ConfigModel::hasChanges() const
+bool ConfigModel::hasChanges(bool initialParameters) const
{
- return Utils::contains(m_configuration, [](const InternalDataItem &i) {
+ const QList<InternalDataItem> filtered
+ = Utils::filtered(m_configuration, [initialParameters](const InternalDataItem &i) {
+ return initialParameters ? i.isInitial : !i.isInitial;
+ });
+
+ return Utils::contains(filtered, [initialParameters](const InternalDataItem &i) {
return i.isUserChanged || i.isUserNew || i.isUnset;
});
}
@@ -177,6 +200,7 @@ ConfigModel::DataItem ConfigModel::dataItemFromIndex(const QModelIndex &idx)
di.type = cmti->dataItem->type;
di.isHidden = cmti->dataItem->isHidden;
di.isAdvanced = cmti->dataItem->isAdvanced;
+ di.isInitial = cmti->dataItem->isInitial;
di.inCMakeCache = cmti->dataItem->inCMakeCache;
di.value = cmti->dataItem->currentValue();
di.description = cmti->dataItem->description;
@@ -232,6 +256,19 @@ void ConfigModel::setBatchEditConfiguration(const CMakeConfig &config)
generateTree();
}
+void ConfigModel::setInitialParametersConfiguration(const CMakeConfig &config)
+{
+ for (const auto &c: config) {
+ DataItem di(c);
+ InternalDataItem i(di);
+ i.inCMakeCache = true;
+ i.isInitial = true;
+ i.newValue = di.value;
+ m_configuration.append(i);
+ }
+ generateTree();
+}
+
void ConfigModel::setConfiguration(const QList<ConfigModel::InternalDataItem> &config)
{
QList<InternalDataItem> tmp = config;
@@ -331,8 +368,14 @@ QVariant ConfigModelTreeItem::data(int column, int role) const
}
// Leaf node:
- if (role == ConfigModel::ItemIsAdvancedRole)
+ if (role == ConfigModel::ItemIsAdvancedRole) {
+ if (dataItem->isInitial)
+ return "2";
return dataItem->isAdvanced ? "1" : "0";
+ }
+ if (role == ConfigModel::ItemIsInitialRole) {
+ return dataItem->isInitial ? "1" : "0";
+ }
switch (column) {
case 0:
diff --git a/src/plugins/cmakeprojectmanager/configmodel.h b/src/plugins/cmakeprojectmanager/configmodel.h
index a5cb94612e..03192cad6f 100644
--- a/src/plugins/cmakeprojectmanager/configmodel.h
+++ b/src/plugins/cmakeprojectmanager/configmodel.h
@@ -42,11 +42,12 @@ class ConfigModel : public Utils::TreeModel<>
public:
enum Roles {
ItemIsAdvancedRole = Qt::UserRole,
+ ItemIsInitialRole
};
struct DataItem {
bool operator == (const DataItem& other) const {
- return key == other.key;
+ return key == other.key && isInitial == other.isInitial;
}
DataItem() {}
@@ -58,6 +59,7 @@ public:
inCMakeCache = cmi.inCMakeCache;
isAdvanced = cmi.isAdvanced;
+ isInitial = cmi.isInitial;
isHidden = cmi.type == CMakeConfigItem::INTERNAL || cmi.type == CMakeConfigItem::STATIC;
setType(cmi.type);
@@ -106,6 +108,7 @@ public:
}
cmi.isUnset = isUnset;
cmi.isAdvanced = isAdvanced;
+ cmi.isInitial = isInitial;
cmi.values = values;
cmi.documentation = description.toUtf8();
@@ -118,6 +121,7 @@ public:
Type type = STRING;
bool isHidden = false;
bool isAdvanced = false;
+ bool isInitial = false;
bool inCMakeCache = false;
bool isUnset = false;
QString value;
@@ -133,17 +137,21 @@ public:
void appendConfiguration(const QString &key,
const QString &value = QString(),
const DataItem::Type type = DataItem::UNKNOWN,
+ bool isInitial = false,
const QString &description = QString(),
const QStringList &values = QStringList());
void setConfiguration(const CMakeConfig &config);
void setBatchEditConfiguration(const CMakeConfig &config);
+ void setInitialParametersConfiguration(const CMakeConfig &config);
void setConfiguration(const QList<DataItem> &config);
- void setConfigurationFromKit(const QHash<QString, QString> &kitConfig);
+
+ using KitConfiguration = QHash<QString, QPair<QString,QString>>;
+ void setConfigurationFromKit(const KitConfiguration &kitConfig);
void flush();
- void resetAllChanges();
+ void resetAllChanges(bool initialParameters = false);
- bool hasChanges() const;
+ bool hasChanges(bool initialParameters = false) const;
bool canForceTo(const QModelIndex &idx, const DataItem::Type type) const;
void forceTo(const QModelIndex &idx, const DataItem::Type type);
@@ -175,7 +183,7 @@ private:
void setConfiguration(const QList<InternalDataItem> &config);
QList<InternalDataItem> m_configuration;
- QHash<QString, QString> m_kitConfiguration;
+ KitConfiguration m_kitConfiguration;
friend class Internal::ConfigModelTreeItem;
};
diff --git a/src/plugins/cmakeprojectmanager/fileapireader.cpp b/src/plugins/cmakeprojectmanager/fileapireader.cpp
index 1aeff39d7d..3233dbe192 100644
--- a/src/plugins/cmakeprojectmanager/fileapireader.cpp
+++ b/src/plugins/cmakeprojectmanager/fileapireader.cpp
@@ -110,8 +110,10 @@ void FileApiReader::parse(bool forceCMakeRun,
const QStringList args = (forceInitialConfiguration ? m_parameters.initialCMakeArguments
: QStringList())
- + (forceExtraConfiguration ? m_parameters.extraCMakeArguments
- : QStringList());
+ + (forceExtraConfiguration
+ ? (m_parameters.configurationChangesArguments
+ + m_parameters.additionalCMakeArguments)
+ : QStringList());
qCDebug(cmakeFileApiMode) << "Parameters request these CMake arguments:" << args;
const FilePath replyFile = FileApiParser::scanForCMakeReplyFile(m_parameters.buildDirectory);
@@ -323,12 +325,11 @@ void FileApiReader::writeConfigurationIntoBuildDirectory(const QStringList &conf
QTC_CHECK(buildDir.ensureWritableDir());
QByteArray contents;
+ QStringList unknownArguments;
contents.append("# This file is managed by Qt Creator, do not edit!\n\n");
contents.append(
- transform(CMakeConfig::fromArguments(configurationArguments).toList(),
- [](const CMakeConfigItem &item) {
- return item.toCMakeSetLine(nullptr);
- })
+ transform(CMakeConfig::fromArguments(configurationArguments, unknownArguments).toList(),
+ [](const CMakeConfigItem &item) { return item.toCMakeSetLine(nullptr); })
.join('\n')
.toUtf8());