From d86d2780441b62696b6c16e24a0273c7683b69f4 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Wed, 10 Aug 2022 19:12:40 +0200 Subject: [PATCH] CMakePM: Add configure environment widget CMakePresets have the concept of modifying the configure process environment variables. Qt Creator had only one "build environment". Change-Id: I131d54971b4bf7e5f87e680f817f93868d62ab29 Reviewed-by: Reviewed-by: hjk Reviewed-by: Alessandro Portale --- .../builddirparameters.cpp | 2 +- .../cmakebuildconfiguration.cpp | 116 +++++++++++++++++- .../cmakebuildconfiguration.h | 14 +++ 3 files changed, 130 insertions(+), 2 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/builddirparameters.cpp b/src/plugins/cmakeprojectmanager/builddirparameters.cpp index 81b79ecfc5b..9f90d25d3bb 100644 --- a/src/plugins/cmakeprojectmanager/builddirparameters.cpp +++ b/src/plugins/cmakeprojectmanager/builddirparameters.cpp @@ -80,7 +80,7 @@ BuildDirParameters::BuildDirParameters(CMakeBuildSystem *buildSystem) cmakeBuildType = buildSystem->cmakeBuildType(); - environment = bc->environment(); + environment = bc->configureEnvironment(); // Disable distributed building for configuration runs. CMake does not do those in parallel, // so there is no win in sending data over the network. // Unfortunately distcc does not have a simple environment flag to turn it off:-/ diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 7392afebfd1..c2a3182e1bc 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -107,6 +108,8 @@ const char QT_QML_DEBUG_FLAG[] = "Qt:QML_DEBUG_FLAG"; const char CMAKE_QT6_TOOLCHAIN_FILE_ARG[] = "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=%{Qt:QT_INSTALL_PREFIX}/lib/cmake/Qt6/qt.toolchain.cmake"; const char CMAKE_BUILD_TYPE[] = "CMake.Build.Type"; +const char CLEAR_SYSTEM_ENVIRONMENT_KEY[] = "CMake.Configure.ClearSystemEnvironment"; +const char USER_ENVIRONMENT_CHANGES_KEY[] = "CMake.Configure.UserEnvironmentChanges"; namespace Internal { @@ -189,6 +192,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildSystem *bs) : { QTC_ASSERT(bs, return); BuildConfiguration *bc = bs->buildConfiguration(); + CMakeBuildConfiguration *cbc = static_cast(bc); auto vbox = new QVBoxLayout(this); vbox->setContentsMargins(0, 0, 0, 0); @@ -325,6 +329,32 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildSystem *bs) : m_reconfigureButton = new QPushButton(tr("Run CMake")); m_reconfigureButton->setEnabled(false); + auto clearBox = new QCheckBox(tr("Clear system environment"), this); + clearBox->setChecked(cbc->useClearConfigureEnvironment()); + + auto envWidget = new EnvironmentWidget(this, EnvironmentWidget::TypeLocal, clearBox); + envWidget->setBaseEnvironment(cbc->baseConfigureEnvironment()); + envWidget->setBaseEnvironmentText(cbc->baseConfigureEnvironmentText()); + envWidget->setUserChanges(cbc->userConfigureEnvironmentChanges()); + + connect(envWidget, &EnvironmentWidget::userChangesChanged, this, [cbc, envWidget] { + cbc->setUserConfigureEnvironmentChanges(envWidget->userChanges()); + }); + + connect(clearBox, &QAbstractButton::toggled, this, [cbc, envWidget](bool checked) { + cbc->setUseClearConfigureEnvironment(checked); + envWidget->setBaseEnvironment(cbc->baseConfigureEnvironment()); + envWidget->setBaseEnvironmentText(cbc->baseConfigureEnvironmentText()); + }); + + connect(cbc, &CMakeBuildConfiguration::configureEnvironmentChanged, this, [cbc, envWidget] { + envWidget->setBaseEnvironment(cbc->baseConfigureEnvironment()); + envWidget->setBaseEnvironmentText(cbc->baseConfigureEnvironmentText()); + }); + + vbox->addWidget(clearBox); + vbox->addWidget(envWidget); + using namespace Layouting; Grid cmakeConfiguration { m_filterEdit, br, @@ -1155,6 +1185,18 @@ static CommandLine defaultInitialCMakeCommand(const Kit *k, const QString buildT return cmd; } +// ----------------------------------------------------------------------------- +// CMakeBuildConfigurationPrivate: +// ----------------------------------------------------------------------------- + +class CMakeBuildConfigurationPrivate +{ +public: + Utils::Environment m_configureEnvironment; + Utils::EnvironmentItems m_userConfigureEnvironmentChanges; + bool m_clearSystemConfigureEnvironment = false; +}; + } // namespace Internal // ----------------------------------------------------------------------------- @@ -1162,7 +1204,7 @@ static CommandLine defaultInitialCMakeCommand(const Kit *k, const QString buildT // ----------------------------------------------------------------------------- CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id) - : BuildConfiguration(target, id) + : BuildConfiguration(target, id), d(new Internal::CMakeBuildConfigurationPrivate()) { m_buildSystem = new CMakeBuildSystem(this); @@ -1353,11 +1395,14 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id) CMakeBuildConfiguration::~CMakeBuildConfiguration() { delete m_buildSystem; + delete d; } QVariantMap CMakeBuildConfiguration::toMap() const { QVariantMap map(BuildConfiguration::toMap()); + map.insert(QLatin1String(CLEAR_SYSTEM_ENVIRONMENT_KEY), d->m_clearSystemConfigureEnvironment); + map.insert(QLatin1String(USER_ENVIRONMENT_CHANGES_KEY), EnvironmentItem::toStringList(d->m_userConfigureEnvironmentChanges)); return map; } @@ -1392,6 +1437,13 @@ bool CMakeBuildConfiguration::fromMap(const QVariantMap &map) m_buildSystem->setInitialCMakeArguments(cmd.splitArguments()); } + d->m_clearSystemConfigureEnvironment = map.value(QLatin1String(CLEAR_SYSTEM_ENVIRONMENT_KEY)) + .toBool(); + d->m_userConfigureEnvironmentChanges = EnvironmentItem::fromStringList( + map.value(QLatin1String(USER_ENVIRONMENT_CHANGES_KEY)).toStringList()); + + updateAndEmitConfigureEnvironmentChanged(); + return true; } @@ -1749,6 +1801,68 @@ void CMakeBuildConfiguration::addToEnvironment(Utils::Environment &env) const } } +Environment CMakeBuildConfiguration::configureEnvironment() const +{ + return d->m_configureEnvironment; +} + +void CMakeBuildConfiguration::setUserConfigureEnvironmentChanges(const Utils::EnvironmentItems &diff) +{ + if (d->m_userConfigureEnvironmentChanges == diff) + return; + d->m_userConfigureEnvironmentChanges = diff; + updateAndEmitConfigureEnvironmentChanged(); +} + +EnvironmentItems CMakeBuildConfiguration::userConfigureEnvironmentChanges() const +{ + return d->m_userConfigureEnvironmentChanges; +} + +bool CMakeBuildConfiguration::useClearConfigureEnvironment() const +{ + return d->m_clearSystemConfigureEnvironment; +} + +void CMakeBuildConfiguration::setUseClearConfigureEnvironment(bool b) +{ + if (useClearConfigureEnvironment() == b) + return; + d->m_clearSystemConfigureEnvironment = b; + updateAndEmitConfigureEnvironmentChanged(); +} + +void CMakeBuildConfiguration::updateAndEmitConfigureEnvironmentChanged() +{ + Environment env = baseConfigureEnvironment(); + env.modify(userConfigureEnvironmentChanges()); + if (env == d->m_configureEnvironment) + return; + d->m_configureEnvironment = env; + emit configureEnvironmentChanged(); +} + +Environment CMakeBuildConfiguration::baseConfigureEnvironment() const +{ + Environment result; + if (!useClearConfigureEnvironment()) { + ProjectExplorer::IDevice::ConstPtr devicePtr = BuildDeviceKitAspect::device(kit()); + result = devicePtr ? devicePtr->systemEnvironment() : Environment::systemEnvironment(); + } + addToEnvironment(result); + kit()->addToBuildEnvironment(result); + result.modify(project()->additionalEnvironment()); + return result; +} + +QString CMakeBuildConfiguration::baseConfigureEnvironmentText() const +{ + if (useClearConfigureEnvironment()) + return tr("Clean Environment"); + else + return tr("System Environment"); +} + QString CMakeBuildSystem::cmakeBuildType() const { auto setBuildTypeFromConfig = [this](const CMakeConfig &config) { diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h index ba20d2bae04..eee31e10f02 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h @@ -37,6 +37,7 @@ class CMakeProject; namespace Internal { class CMakeBuildSystem; +class CMakeBuildConfigurationPrivate; class CMakeBuildSettingsWidget; class CMakeProjectImporter; @@ -65,8 +66,19 @@ public: void addToEnvironment(Utils::Environment &env) const override; + Utils::Environment configureEnvironment() const; + void setUserConfigureEnvironmentChanges(const Utils::EnvironmentItems &diff); + Utils::EnvironmentItems userConfigureEnvironmentChanges() const; + bool useClearConfigureEnvironment() const; + void setUseClearConfigureEnvironment(bool b); + void updateAndEmitConfigureEnvironmentChanged(); + + Utils::Environment baseConfigureEnvironment() const; + QString baseConfigureEnvironmentText() const; + signals: void signingFlagsChanged(); + void configureEnvironmentChanged(); protected: bool fromMap(const QVariantMap &map) override; @@ -83,6 +95,8 @@ private: friend class Internal::CMakeBuildSettingsWidget; friend class Internal::CMakeBuildSystem; + + Internal::CMakeBuildConfigurationPrivate *d = nullptr; }; class CMAKE_EXPORT CMakeBuildConfigurationFactory