forked from qt-creator/qt-creator
CMakePM: Add support for build CMake presets
This patchset will add support for version 2 of the CMakePresets feature that has been implemented in CMake 3.20 https://cmake.org/cmake/help/v3.20/manual/cmake-presets.7.html Task-number: QTCREATORBUG-24555 Change-Id: I08934243cc04487d38c4b59c2ad4a4a8d0484492 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -1301,8 +1301,8 @@ static void addCMakeConfigurePresetToInitialArguments(QStringList &initialArgume
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Utils::EnvironmentItems getEnvironmentItemsFromCMakePreset(const CMakeProject *project,
|
static Utils::EnvironmentItems getEnvironmentItemsFromCMakeConfigurePreset(
|
||||||
const Kit *k)
|
const CMakeProject *project, const Kit *k)
|
||||||
|
|
||||||
{
|
{
|
||||||
Utils::EnvironmentItems envItems;
|
Utils::EnvironmentItems envItems;
|
||||||
@@ -1324,6 +1324,27 @@ static Utils::EnvironmentItems getEnvironmentItemsFromCMakePreset(const CMakePro
|
|||||||
return envItems;
|
return envItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Utils::EnvironmentItems getEnvironmentItemsFromCMakeBuildPreset(
|
||||||
|
const CMakeProject *project, const Kit *k, const QString &buildPresetName)
|
||||||
|
|
||||||
|
{
|
||||||
|
Utils::EnvironmentItems envItems;
|
||||||
|
|
||||||
|
const CMakeConfigItem presetItem = CMakeConfigurationKitAspect::cmakePresetConfigItem(k);
|
||||||
|
if (presetItem.isNull())
|
||||||
|
return envItems;
|
||||||
|
|
||||||
|
PresetsDetails::BuildPreset buildPreset
|
||||||
|
= Utils::findOrDefault(project->presetsData().buildPresets,
|
||||||
|
[buildPresetName](const PresetsDetails::BuildPreset &preset) {
|
||||||
|
return preset.name == buildPresetName;
|
||||||
|
});
|
||||||
|
|
||||||
|
CMakePresets::Macros::expand(buildPreset, envItems, project->projectDirectory());
|
||||||
|
|
||||||
|
return envItems;
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// CMakeBuildConfigurationPrivate:
|
// CMakeBuildConfigurationPrivate:
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@@ -1423,8 +1444,7 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
|
|||||||
addAspect<BuildTypeAspect>();
|
addAspect<BuildTypeAspect>();
|
||||||
addAspect<QtSupport::QmlDebuggingAspect>(this);
|
addAspect<QtSupport::QmlDebuggingAspect>(this);
|
||||||
|
|
||||||
appendInitialBuildStep(Constants::CMAKE_BUILD_STEP_ID);
|
setInitialBuildAndCleanSteps(target);
|
||||||
appendInitialCleanStep(Constants::CMAKE_BUILD_STEP_ID);
|
|
||||||
|
|
||||||
setInitializer([this, target](const BuildInfo &info) {
|
setInitializer([this, target](const BuildInfo &info) {
|
||||||
const Kit *k = target->kit();
|
const Kit *k = target->kit();
|
||||||
@@ -1527,7 +1547,7 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
|
|||||||
cmd.addArg("-DCMAKE_CXX_FLAGS_INIT:STRING=%{" + QLatin1String(QT_QML_DEBUG_FLAG) + "}");
|
cmd.addArg("-DCMAKE_CXX_FLAGS_INIT:STRING=%{" + QLatin1String(QT_QML_DEBUG_FLAG) + "}");
|
||||||
|
|
||||||
CMakeProject *cmakeProject = static_cast<CMakeProject *>(target->project());
|
CMakeProject *cmakeProject = static_cast<CMakeProject *>(target->project());
|
||||||
setUserConfigureEnvironmentChanges(getEnvironmentItemsFromCMakePreset(cmakeProject, k));
|
setUserConfigureEnvironmentChanges(getEnvironmentItemsFromCMakeConfigurePreset(cmakeProject, k));
|
||||||
|
|
||||||
QStringList initialCMakeArguments = cmd.splitArguments();
|
QStringList initialCMakeArguments = cmd.splitArguments();
|
||||||
addCMakeConfigurePresetToInitialArguments(initialCMakeArguments,
|
addCMakeConfigurePresetToInitialArguments(initialCMakeArguments,
|
||||||
@@ -1537,6 +1557,8 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
|
|||||||
m_buildSystem->setInitialCMakeArguments(initialCMakeArguments);
|
m_buildSystem->setInitialCMakeArguments(initialCMakeArguments);
|
||||||
m_buildSystem->setCMakeBuildType(buildType);
|
m_buildSystem->setCMakeBuildType(buildType);
|
||||||
updateAndEmitConfigureEnvironmentChanged();
|
updateAndEmitConfigureEnvironmentChanged();
|
||||||
|
|
||||||
|
setBuildPresetToBuildSteps(target);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1799,6 +1821,104 @@ CMakeConfig CMakeBuildConfiguration::signingFlags() const
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMakeBuildConfiguration::setInitialBuildAndCleanSteps(const ProjectExplorer::Target *target)
|
||||||
|
{
|
||||||
|
const CMakeConfigItem presetItem = CMakeConfigurationKitAspect::cmakePresetConfigItem(
|
||||||
|
target->kit());
|
||||||
|
|
||||||
|
if (!presetItem.isNull()) {
|
||||||
|
const QString presetName = presetItem.expandedValue(target->kit());
|
||||||
|
const CMakeProject *project = static_cast<const CMakeProject *>(target->project());
|
||||||
|
|
||||||
|
const auto buildPresets = project->presetsData().buildPresets;
|
||||||
|
const int count = std::count_if(buildPresets.begin(),
|
||||||
|
buildPresets.end(),
|
||||||
|
[presetName](const PresetsDetails::BuildPreset &preset) {
|
||||||
|
return preset.configurePreset == presetName
|
||||||
|
&& !preset.hidden.value();
|
||||||
|
});
|
||||||
|
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
appendInitialBuildStep(Constants::CMAKE_BUILD_STEP_ID);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
appendInitialBuildStep(Constants::CMAKE_BUILD_STEP_ID);
|
||||||
|
}
|
||||||
|
appendInitialCleanStep(Constants::CMAKE_BUILD_STEP_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeBuildConfiguration::setBuildPresetToBuildSteps(const ProjectExplorer::Target *target)
|
||||||
|
{
|
||||||
|
const CMakeConfigItem presetItem = CMakeConfigurationKitAspect::cmakePresetConfigItem(
|
||||||
|
target->kit());
|
||||||
|
|
||||||
|
if (presetItem.isNull())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const QString presetName = presetItem.expandedValue(target->kit());
|
||||||
|
const CMakeProject *project = static_cast<const CMakeProject *>(target->project());
|
||||||
|
|
||||||
|
const auto allBuildPresets = project->presetsData().buildPresets;
|
||||||
|
const auto buildPresets
|
||||||
|
= Utils::filtered(allBuildPresets, [presetName](const PresetsDetails::BuildPreset &preset) {
|
||||||
|
return preset.configurePreset == presetName && !preset.hidden.value();
|
||||||
|
});
|
||||||
|
|
||||||
|
const QList<BuildStep *> buildStepList
|
||||||
|
= Utils::filtered(buildSteps()->steps(), [](const BuildStep *bs) {
|
||||||
|
return bs->id() == Constants::CMAKE_BUILD_STEP_ID;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (buildPresets.size() != buildStepList.size())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (qsizetype i = 0; i < buildStepList.size(); ++i) {
|
||||||
|
CMakeBuildStep *cbs = qobject_cast<CMakeBuildStep *>(buildStepList[i]);
|
||||||
|
cbs->setBuildPreset(buildPresets[i].name);
|
||||||
|
cbs->setUserEnvironmentChanges(
|
||||||
|
getEnvironmentItemsFromCMakeBuildPreset(project, target->kit(), buildPresets[i].name));
|
||||||
|
|
||||||
|
if (buildPresets[i].targets) {
|
||||||
|
QString targets = buildPresets[i].targets.value().join(" ");
|
||||||
|
|
||||||
|
CMakePresets::Macros::expand(buildPresets[i],
|
||||||
|
cbs->environment(),
|
||||||
|
project->projectDirectory(),
|
||||||
|
targets);
|
||||||
|
|
||||||
|
cbs->setBuildTargets(targets.split(" "));
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList cmakeArguments;
|
||||||
|
if (buildPresets[i].jobs)
|
||||||
|
cmakeArguments.append(QString("-j %1").arg(buildPresets[i].jobs.value()));
|
||||||
|
if (buildPresets[i].verbose && buildPresets[i].verbose.value())
|
||||||
|
cmakeArguments.append("--verbose");
|
||||||
|
if (buildPresets[i].cleanFirst && buildPresets[i].cleanFirst.value())
|
||||||
|
cmakeArguments.append("--clean-first");
|
||||||
|
if (!cmakeArguments.isEmpty())
|
||||||
|
cbs->setCMakeArguments(cmakeArguments);
|
||||||
|
|
||||||
|
if (buildPresets[i].nativeToolOptions) {
|
||||||
|
QString nativeToolOptions = buildPresets[i].nativeToolOptions.value().join(" ");
|
||||||
|
|
||||||
|
CMakePresets::Macros::expand(buildPresets[i],
|
||||||
|
cbs->environment(),
|
||||||
|
project->projectDirectory(),
|
||||||
|
nativeToolOptions);
|
||||||
|
|
||||||
|
cbs->setToolArguments(nativeToolOptions.split(" "));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buildPresets[i].configuration)
|
||||||
|
cbs->setConfiguration(buildPresets[i].configuration.value());
|
||||||
|
|
||||||
|
// Leave only the first build step enabled
|
||||||
|
if (i > 0)
|
||||||
|
cbs->setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class CMakeBuildConfigurationFactory
|
\class CMakeBuildConfigurationFactory
|
||||||
*/
|
*/
|
||||||
|
@@ -69,6 +69,9 @@ private:
|
|||||||
|
|
||||||
virtual CMakeConfig signingFlags() const;
|
virtual CMakeConfig signingFlags() const;
|
||||||
|
|
||||||
|
void setInitialBuildAndCleanSteps(const ProjectExplorer::Target *target);
|
||||||
|
void setBuildPresetToBuildSteps(const ProjectExplorer::Target *target);
|
||||||
|
|
||||||
Internal::CMakeBuildSystem *m_buildSystem = nullptr;
|
Internal::CMakeBuildSystem *m_buildSystem = nullptr;
|
||||||
|
|
||||||
friend class Internal::CMakeBuildSettingsWidget;
|
friend class Internal::CMakeBuildSettingsWidget;
|
||||||
|
@@ -7,11 +7,14 @@
|
|||||||
#include "cmakebuildsystem.h"
|
#include "cmakebuildsystem.h"
|
||||||
#include "cmakekitinformation.h"
|
#include "cmakekitinformation.h"
|
||||||
#include "cmakeparser.h"
|
#include "cmakeparser.h"
|
||||||
|
#include "cmakeproject.h"
|
||||||
#include "cmakeprojectconstants.h"
|
#include "cmakeprojectconstants.h"
|
||||||
#include "cmaketool.h"
|
#include "cmaketool.h"
|
||||||
|
|
||||||
#include <coreplugin/find/itemviewfind.h>
|
#include <coreplugin/find/itemviewfind.h>
|
||||||
#include <projectexplorer/buildsteplist.h>
|
#include <projectexplorer/buildsteplist.h>
|
||||||
|
#include <projectexplorer/devicesupport/idevice.h>
|
||||||
|
#include <projectexplorer/environmentwidget.h>
|
||||||
#include <projectexplorer/gnumakeparser.h>
|
#include <projectexplorer/gnumakeparser.h>
|
||||||
#include <projectexplorer/kitinformation.h>
|
#include <projectexplorer/kitinformation.h>
|
||||||
#include <projectexplorer/processparameters.h>
|
#include <projectexplorer/processparameters.h>
|
||||||
@@ -29,6 +32,7 @@
|
|||||||
#include <QListWidget>
|
#include <QListWidget>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QTreeView>
|
#include <QTreeView>
|
||||||
|
#include <QCheckBox>
|
||||||
|
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
@@ -42,6 +46,9 @@ const char CMAKE_ARGUMENTS_KEY[] = "CMakeProjectManager.MakeStep.CMakeArguments"
|
|||||||
const char TOOL_ARGUMENTS_KEY[] = "CMakeProjectManager.MakeStep.AdditionalArguments";
|
const char TOOL_ARGUMENTS_KEY[] = "CMakeProjectManager.MakeStep.AdditionalArguments";
|
||||||
const char IOS_AUTOMATIC_PROVISIONG_UPDATES_ARGUMENTS_KEY[] =
|
const char IOS_AUTOMATIC_PROVISIONG_UPDATES_ARGUMENTS_KEY[] =
|
||||||
"CMakeProjectManager.MakeStep.iOSAutomaticProvisioningUpdates";
|
"CMakeProjectManager.MakeStep.iOSAutomaticProvisioningUpdates";
|
||||||
|
const char CLEAR_SYSTEM_ENVIRONMENT_KEY[] = "CMakeProjectManager.MakeStep.ClearSystemEnvironment";
|
||||||
|
const char USER_ENVIRONMENT_CHANGES_KEY[] = "CMakeProjectManager.MakeStep.UserEnvironmentChanges";
|
||||||
|
const char BUILD_PRESET_KEY[] = "CMakeProjectManager.MakeStep.BuildPreset";
|
||||||
|
|
||||||
// CmakeProgressParser
|
// CmakeProgressParser
|
||||||
|
|
||||||
@@ -186,11 +193,12 @@ CMakeBuildStep::CMakeBuildStep(BuildStepList *bsl, Utils::Id id) :
|
|||||||
|
|
||||||
setCommandLineProvider([this] { return cmakeCommand(); });
|
setCommandLineProvider([this] { return cmakeCommand(); });
|
||||||
|
|
||||||
setEnvironmentModifier([](Environment &env) {
|
setEnvironmentModifier([this](Environment &env) {
|
||||||
const QString ninjaProgressString = "[%f/%t "; // ninja: [33/100
|
const QString ninjaProgressString = "[%f/%t "; // ninja: [33/100
|
||||||
env.setupEnglishOutput();
|
env.setupEnglishOutput();
|
||||||
if (!env.expandedValueForKey("NINJA_STATUS").startsWith(ninjaProgressString))
|
if (!env.expandedValueForKey("NINJA_STATUS").startsWith(ninjaProgressString))
|
||||||
env.set("NINJA_STATUS", ninjaProgressString + "%o/sec] ");
|
env.set("NINJA_STATUS", ninjaProgressString + "%o/sec] ");
|
||||||
|
env.modify(m_userEnvironmentChanges);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(target(), &Target::parsingFinished, this, [this](bool success) {
|
connect(target(), &Target::parsingFinished, this, [this](bool success) {
|
||||||
@@ -207,12 +215,26 @@ QVariantMap CMakeBuildStep::toMap() const
|
|||||||
{
|
{
|
||||||
QVariantMap map(AbstractProcessStep::toMap());
|
QVariantMap map(AbstractProcessStep::toMap());
|
||||||
map.insert(BUILD_TARGETS_KEY, m_buildTargets);
|
map.insert(BUILD_TARGETS_KEY, m_buildTargets);
|
||||||
|
map.insert(QLatin1String(CLEAR_SYSTEM_ENVIRONMENT_KEY), m_clearSystemEnvironment);
|
||||||
|
map.insert(QLatin1String(USER_ENVIRONMENT_CHANGES_KEY), EnvironmentItem::toStringList(m_userEnvironmentChanges));
|
||||||
|
map.insert(QLatin1String(BUILD_PRESET_KEY), m_buildPreset);
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMakeBuildStep::fromMap(const QVariantMap &map)
|
bool CMakeBuildStep::fromMap(const QVariantMap &map)
|
||||||
{
|
{
|
||||||
setBuildTargets(map.value(BUILD_TARGETS_KEY).toStringList());
|
setBuildTargets(map.value(BUILD_TARGETS_KEY).toStringList());
|
||||||
|
|
||||||
|
m_clearSystemEnvironment = map.value(QLatin1String(CLEAR_SYSTEM_ENVIRONMENT_KEY))
|
||||||
|
.toBool();
|
||||||
|
m_userEnvironmentChanges = EnvironmentItem::fromStringList(
|
||||||
|
map.value(QLatin1String(USER_ENVIRONMENT_CHANGES_KEY)).toStringList());
|
||||||
|
|
||||||
|
updateAndEmitEnvironmentChanged();
|
||||||
|
|
||||||
|
m_buildPreset = map.value(QLatin1String(BUILD_PRESET_KEY)).toString();
|
||||||
|
|
||||||
return BuildStep::fromMap(map);
|
return BuildStep::fromMap(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,6 +370,14 @@ QString CMakeBuildStep::defaultBuildTarget() const
|
|||||||
return allTarget();
|
return allTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CMakeBuildStep::isCleanStep() const
|
||||||
|
{
|
||||||
|
const BuildStepList *const bsl = stepList();
|
||||||
|
QTC_ASSERT(bsl, return false);
|
||||||
|
const Utils::Id parentId = bsl->id();
|
||||||
|
return parentId == ProjectExplorer::Constants::BUILDSTEPS_CLEAN;
|
||||||
|
}
|
||||||
|
|
||||||
QStringList CMakeBuildStep::buildTargets() const
|
QStringList CMakeBuildStep::buildTargets() const
|
||||||
{
|
{
|
||||||
return m_buildTargets;
|
return m_buildTargets;
|
||||||
@@ -401,7 +431,10 @@ CommandLine CMakeBuildStep::cmakeCommand() const
|
|||||||
auto bs = qobject_cast<CMakeBuildSystem*>(buildSystem());
|
auto bs = qobject_cast<CMakeBuildSystem*>(buildSystem());
|
||||||
if (bs && bs->isMultiConfigReader()) {
|
if (bs && bs->isMultiConfigReader()) {
|
||||||
cmd.addArg("--config");
|
cmd.addArg("--config");
|
||||||
cmd.addArg(bs->cmakeBuildType());
|
if (m_configuration)
|
||||||
|
cmd.addArg(m_configuration.value());
|
||||||
|
else
|
||||||
|
cmd.addArg(bs->cmakeBuildType());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_cmakeArguments->value().isEmpty())
|
if (!m_cmakeArguments->value().isEmpty())
|
||||||
@@ -453,13 +486,36 @@ QString CMakeBuildStep::activeRunConfigTarget() const
|
|||||||
return rc ? rc->buildKey() : QString();
|
return rc ? rc->buildKey() : QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMakeBuildStep::setBuildPreset(const QString &preset)
|
||||||
|
{
|
||||||
|
m_buildPreset = preset;
|
||||||
|
}
|
||||||
|
|
||||||
QWidget *CMakeBuildStep::createConfigWidget()
|
QWidget *CMakeBuildStep::createConfigWidget()
|
||||||
{
|
{
|
||||||
auto updateDetails = [this] {
|
auto updateDetails = [this] {
|
||||||
ProcessParameters param;
|
ProcessParameters param;
|
||||||
setupProcessParameters(¶m);
|
setupProcessParameters(¶m);
|
||||||
param.setCommandLine(cmakeCommand());
|
param.setCommandLine(cmakeCommand());
|
||||||
setSummaryText(param.summary(displayName()));
|
|
||||||
|
QString summaryText = param.summary(displayName());
|
||||||
|
|
||||||
|
if (!m_buildPreset.isEmpty()) {
|
||||||
|
const CMakeProject *cp = static_cast<const CMakeProject *>(project());
|
||||||
|
|
||||||
|
const auto buildPresets = cp->presetsData().buildPresets;
|
||||||
|
const PresetsDetails::BuildPreset preset
|
||||||
|
= Utils::findOrDefault(buildPresets, [this](const PresetsDetails::BuildPreset &bp) {
|
||||||
|
return bp.name == m_buildPreset;
|
||||||
|
});
|
||||||
|
|
||||||
|
const QString presetDisplayName = preset.displayName ? preset.displayName.value()
|
||||||
|
: preset.name;
|
||||||
|
if (!presetDisplayName.isEmpty())
|
||||||
|
summaryText.append(QString("<br><b>Preset</b>: %1").arg(presetDisplayName));
|
||||||
|
}
|
||||||
|
|
||||||
|
setSummaryText(summaryText);
|
||||||
};
|
};
|
||||||
|
|
||||||
setDisplayName(tr("Build", "ConfigWidget display name."));
|
setDisplayName(tr("Build", "ConfigWidget display name."));
|
||||||
@@ -473,6 +529,34 @@ QWidget *CMakeBuildStep::createConfigWidget()
|
|||||||
auto frame = ItemViewFind::createSearchableWrapper(buildTargetsView,
|
auto frame = ItemViewFind::createSearchableWrapper(buildTargetsView,
|
||||||
ItemViewFind::LightColored);
|
ItemViewFind::LightColored);
|
||||||
|
|
||||||
|
auto createAndAddEnvironmentWidgets = [this](Layouting::Form &builder) {
|
||||||
|
auto clearBox = new QCheckBox(tr("Clear system environment"));
|
||||||
|
clearBox->setChecked(useClearEnvironment());
|
||||||
|
|
||||||
|
auto envWidget = new EnvironmentWidget(nullptr, EnvironmentWidget::TypeLocal, clearBox);
|
||||||
|
envWidget->setBaseEnvironment(baseEnvironment());
|
||||||
|
envWidget->setBaseEnvironmentText(baseEnvironmentText());
|
||||||
|
envWidget->setUserChanges(userEnvironmentChanges());
|
||||||
|
|
||||||
|
connect(envWidget, &EnvironmentWidget::userChangesChanged, this, [this, envWidget] {
|
||||||
|
setUserEnvironmentChanges(envWidget->userChanges());
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(clearBox, &QAbstractButton::toggled, this, [this, envWidget](bool checked) {
|
||||||
|
setUseClearEnvironment(checked);
|
||||||
|
envWidget->setBaseEnvironment(baseEnvironment());
|
||||||
|
envWidget->setBaseEnvironmentText(baseEnvironmentText());
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(this, &CMakeBuildStep::environmentChanged, this, [this, envWidget] {
|
||||||
|
envWidget->setBaseEnvironment(baseEnvironment());
|
||||||
|
envWidget->setBaseEnvironmentText(baseEnvironmentText());
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.addRow(clearBox);
|
||||||
|
builder.addRow(envWidget);
|
||||||
|
};
|
||||||
|
|
||||||
Layouting::Form builder;
|
Layouting::Form builder;
|
||||||
builder.addRow(m_cmakeArguments);
|
builder.addRow(m_cmakeArguments);
|
||||||
builder.addRow(m_toolArguments);
|
builder.addRow(m_toolArguments);
|
||||||
@@ -481,6 +565,10 @@ QWidget *CMakeBuildStep::createConfigWidget()
|
|||||||
builder.addRow(m_useiOSAutomaticProvisioningUpdates);
|
builder.addRow(m_useiOSAutomaticProvisioningUpdates);
|
||||||
|
|
||||||
builder.addRow({new QLabel(tr("Targets:")), frame});
|
builder.addRow({new QLabel(tr("Targets:")), frame});
|
||||||
|
|
||||||
|
if (!isCleanStep() && !m_buildPreset.isEmpty())
|
||||||
|
createAndAddEnvironmentWidgets(builder);
|
||||||
|
|
||||||
auto widget = builder.emerge(Layouting::WithoutMargins);
|
auto widget = builder.emerge(Layouting::WithoutMargins);
|
||||||
|
|
||||||
updateDetails();
|
updateDetails();
|
||||||
@@ -552,6 +640,83 @@ void CMakeBuildStep::updateBuildTargetsModel()
|
|||||||
emit buildTargetsChanged();
|
emit buildTargetsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMakeBuildStep::setConfiguration(const QString &configuration)
|
||||||
|
{
|
||||||
|
m_configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeBuildStep::setToolArguments(const QStringList &nativeToolArguments)
|
||||||
|
{
|
||||||
|
m_toolArguments->setValue(nativeToolArguments.join(" "));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeBuildStep::setCMakeArguments(const QStringList &cmakeArguments)
|
||||||
|
{
|
||||||
|
m_cmakeArguments->setValue(cmakeArguments.join(" "));
|
||||||
|
}
|
||||||
|
|
||||||
|
Environment CMakeBuildStep::environment() const
|
||||||
|
{
|
||||||
|
return m_environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeBuildStep::setUserEnvironmentChanges(const Utils::EnvironmentItems &diff)
|
||||||
|
{
|
||||||
|
if (m_userEnvironmentChanges == diff)
|
||||||
|
return;
|
||||||
|
m_userEnvironmentChanges = diff;
|
||||||
|
updateAndEmitEnvironmentChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
EnvironmentItems CMakeBuildStep::userEnvironmentChanges() const
|
||||||
|
{
|
||||||
|
return m_userEnvironmentChanges;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMakeBuildStep::useClearEnvironment() const
|
||||||
|
{
|
||||||
|
return m_clearSystemEnvironment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeBuildStep::setUseClearEnvironment(bool b)
|
||||||
|
{
|
||||||
|
if (useClearEnvironment() == b)
|
||||||
|
return;
|
||||||
|
m_clearSystemEnvironment = b;
|
||||||
|
updateAndEmitEnvironmentChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeBuildStep::updateAndEmitEnvironmentChanged()
|
||||||
|
{
|
||||||
|
Environment env = baseEnvironment();
|
||||||
|
env.modify(userEnvironmentChanges());
|
||||||
|
if (env == m_environment)
|
||||||
|
return;
|
||||||
|
m_environment = env;
|
||||||
|
emit environmentChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
Environment CMakeBuildStep::baseEnvironment() const
|
||||||
|
{
|
||||||
|
Environment result;
|
||||||
|
if (!useClearEnvironment()) {
|
||||||
|
ProjectExplorer::IDevice::ConstPtr devicePtr = BuildDeviceKitAspect::device(kit());
|
||||||
|
result = devicePtr ? devicePtr->systemEnvironment() : Environment::systemEnvironment();
|
||||||
|
}
|
||||||
|
buildConfiguration()->addToEnvironment(result);
|
||||||
|
kit()->addToBuildEnvironment(result);
|
||||||
|
result.modify(project()->additionalEnvironment());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CMakeBuildStep::baseEnvironmentText() const
|
||||||
|
{
|
||||||
|
if (useClearEnvironment())
|
||||||
|
return tr("Clean Environment");
|
||||||
|
else
|
||||||
|
return tr("System Environment");
|
||||||
|
}
|
||||||
|
|
||||||
void CMakeBuildStep::processFinished(int exitCode, QProcess::ExitStatus status)
|
void CMakeBuildStep::processFinished(int exitCode, QProcess::ExitStatus status)
|
||||||
{
|
{
|
||||||
AbstractProcessStep::processFinished(exitCode, status);
|
AbstractProcessStep::processFinished(exitCode, status);
|
||||||
|
@@ -54,8 +54,26 @@ public:
|
|||||||
|
|
||||||
QString activeRunConfigTarget() const;
|
QString activeRunConfigTarget() const;
|
||||||
|
|
||||||
|
void setBuildPreset(const QString &preset);
|
||||||
|
|
||||||
|
Utils::Environment environment() const;
|
||||||
|
void setUserEnvironmentChanges(const Utils::EnvironmentItems &diff);
|
||||||
|
Utils::EnvironmentItems userEnvironmentChanges() const;
|
||||||
|
bool useClearEnvironment() const;
|
||||||
|
void setUseClearEnvironment(bool b);
|
||||||
|
void updateAndEmitEnvironmentChanged();
|
||||||
|
|
||||||
|
Utils::Environment baseEnvironment() const;
|
||||||
|
QString baseEnvironmentText() const;
|
||||||
|
|
||||||
|
void setCMakeArguments(const QStringList &cmakeArguments);
|
||||||
|
void setToolArguments(const QStringList &nativeToolArguments);
|
||||||
|
|
||||||
|
void setConfiguration(const QString &configuration);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void buildTargetsChanged();
|
void buildTargetsChanged();
|
||||||
|
void environmentChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Utils::CommandLine cmakeCommand() const;
|
Utils::CommandLine cmakeCommand() const;
|
||||||
@@ -69,6 +87,7 @@ private:
|
|||||||
QWidget *createConfigWidget() override;
|
QWidget *createConfigWidget() override;
|
||||||
|
|
||||||
QString defaultBuildTarget() const;
|
QString defaultBuildTarget() const;
|
||||||
|
bool isCleanStep() const;
|
||||||
|
|
||||||
void runImpl();
|
void runImpl();
|
||||||
void handleProjectWasParsed(bool success);
|
void handleProjectWasParsed(bool success);
|
||||||
@@ -90,6 +109,12 @@ private:
|
|||||||
QString m_installTarget = "install";
|
QString m_installTarget = "install";
|
||||||
|
|
||||||
Utils::TreeModel<Utils::TreeItem, CMakeTargetItem> m_buildTargetModel;
|
Utils::TreeModel<Utils::TreeItem, CMakeTargetItem> m_buildTargetModel;
|
||||||
|
|
||||||
|
Utils::Environment m_environment;
|
||||||
|
Utils::EnvironmentItems m_userEnvironmentChanges;
|
||||||
|
bool m_clearSystemEnvironment = false;
|
||||||
|
QString m_buildPreset;
|
||||||
|
std::optional<QString> m_configuration;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CMakeBuildStepFactory : public ProjectExplorer::BuildStepFactory
|
class CMakeBuildStepFactory : public ProjectExplorer::BuildStepFactory
|
||||||
|
@@ -88,54 +88,93 @@ Internal::PresetsData CMakeProject::combinePresets(Internal::PresetsData &cmakeP
|
|||||||
result.version = cmakePresetsData.version;
|
result.version = cmakePresetsData.version;
|
||||||
result.cmakeMinimimRequired = cmakePresetsData.cmakeMinimimRequired;
|
result.cmakeMinimimRequired = cmakePresetsData.cmakeMinimimRequired;
|
||||||
|
|
||||||
QHash<QString, PresetsDetails::ConfigurePreset> configurePresets;
|
auto combinePresetsInternal = [](auto &presetsHash,
|
||||||
|
auto &presets,
|
||||||
|
auto &userPresets,
|
||||||
|
const QString &presetType) {
|
||||||
|
// Populate the hash map with the CMakePresets
|
||||||
|
for (const auto &p : presets)
|
||||||
|
presetsHash.insert(p.name, p);
|
||||||
|
|
||||||
// Populate the hash map with the CMakePresets
|
auto resolveInherits = [](const auto &presetsHash, auto &presetsList) {
|
||||||
for (const PresetsDetails::ConfigurePreset &p: cmakePresetsData.configurePresets)
|
for (auto &p : presetsList) {
|
||||||
configurePresets.insert(p.name, p);
|
if (!p.inherits)
|
||||||
|
|
||||||
auto resolveInherits =
|
|
||||||
[configurePresets](std::vector<PresetsDetails::ConfigurePreset> &configurePresetsList) {
|
|
||||||
for (PresetsDetails::ConfigurePreset &cp : configurePresetsList) {
|
|
||||||
if (!cp.inherits)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (const QString &inheritFromName : cp.inherits.value())
|
for (const QString &inheritFromName : p.inherits.value())
|
||||||
if (configurePresets.contains(inheritFromName))
|
if (presetsHash.contains(inheritFromName))
|
||||||
cp.inheritFrom(configurePresets[inheritFromName]);
|
p.inheritFrom(presetsHash[inheritFromName]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// First resolve the CMakePresets
|
// First resolve the CMakePresets
|
||||||
resolveInherits(cmakePresetsData.configurePresets);
|
resolveInherits(presetsHash, presets);
|
||||||
|
|
||||||
// Add the CMakeUserPresets to the resolve hash map
|
// Add the CMakeUserPresets to the resolve hash map
|
||||||
for (const PresetsDetails::ConfigurePreset &cp : cmakeUserPresetsData.configurePresets) {
|
for (const auto &p : userPresets) {
|
||||||
if (configurePresets.contains(cp.name)) {
|
if (presetsHash.contains(p.name)) {
|
||||||
TaskHub::addTask(BuildSystemTask(
|
TaskHub::addTask(
|
||||||
Task::TaskType::Error,
|
BuildSystemTask(Task::TaskType::Error,
|
||||||
tr("CMakeUserPresets.json cannot re-define the configure preset: %1").arg(cp.name),
|
tr("CMakeUserPresets.json cannot re-define the %1 preset: %2")
|
||||||
"CMakeUserPresets.json"));
|
.arg(presetType)
|
||||||
TaskHub::requestPopup();
|
.arg(p.name),
|
||||||
} else {
|
"CMakeUserPresets.json"));
|
||||||
configurePresets.insert(cp.name, cp);
|
TaskHub::requestPopup();
|
||||||
|
} else {
|
||||||
|
presetsHash.insert(p.name, p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Then resolve the CMakeUserPresets
|
// Then resolve the CMakeUserPresets
|
||||||
resolveInherits(cmakeUserPresetsData.configurePresets);
|
resolveInherits(presetsHash, userPresets);
|
||||||
|
|
||||||
// Get both CMakePresets and CMakeUserPresets into the result
|
// Get both CMakePresets and CMakeUserPresets into the result
|
||||||
result.configurePresets = cmakePresetsData.configurePresets;
|
auto result = presets;
|
||||||
|
|
||||||
// std::vector doesn't have append
|
// std::vector doesn't have append
|
||||||
std::copy(cmakeUserPresetsData.configurePresets.begin(),
|
std::copy(userPresets.begin(), userPresets.end(), std::back_inserter(result));
|
||||||
cmakeUserPresetsData.configurePresets.end(),
|
return result;
|
||||||
std::back_inserter(result.configurePresets));
|
};
|
||||||
|
|
||||||
|
QHash<QString, PresetsDetails::ConfigurePreset> configurePresetsHash;
|
||||||
|
QHash<QString, PresetsDetails::BuildPreset> buildPresetsHash;
|
||||||
|
|
||||||
|
result.configurePresets = combinePresetsInternal(configurePresetsHash,
|
||||||
|
cmakePresetsData.configurePresets,
|
||||||
|
cmakeUserPresetsData.configurePresets,
|
||||||
|
"configure");
|
||||||
|
result.buildPresets = combinePresetsInternal(buildPresetsHash,
|
||||||
|
cmakePresetsData.buildPresets,
|
||||||
|
cmakeUserPresetsData.buildPresets,
|
||||||
|
"build");
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMakeProject::setupBuildPresets(Internal::PresetsData &presetsData)
|
||||||
|
{
|
||||||
|
for (auto &buildPreset : presetsData.buildPresets) {
|
||||||
|
if (buildPreset.inheritConfigureEnvironment) {
|
||||||
|
if (!buildPreset.configurePreset) {
|
||||||
|
TaskHub::addTask(BuildSystemTask(
|
||||||
|
Task::TaskType::Error,
|
||||||
|
tr("Build preset %1 is missing a corresponding configure preset.")
|
||||||
|
.arg(buildPreset.name)));
|
||||||
|
TaskHub::requestPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &configurePresetName = buildPreset.configurePreset.value();
|
||||||
|
buildPreset.environment
|
||||||
|
= Utils::findOrDefault(presetsData.configurePresets,
|
||||||
|
[configurePresetName](
|
||||||
|
const PresetsDetails::ConfigurePreset &configurePreset) {
|
||||||
|
return configurePresetName == configurePreset.name;
|
||||||
|
})
|
||||||
|
.environment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CMakeProject::readPresets()
|
void CMakeProject::readPresets()
|
||||||
{
|
{
|
||||||
auto parsePreset = [](const Utils::FilePath &presetFile) -> Internal::PresetsData {
|
auto parsePreset = [](const Utils::FilePath &presetFile) -> Internal::PresetsData {
|
||||||
@@ -168,6 +207,7 @@ void CMakeProject::readPresets()
|
|||||||
Internal::PresetsData cmakeUserPresetsData = parsePreset(cmakeUserPresetsJson);
|
Internal::PresetsData cmakeUserPresetsData = parsePreset(cmakeUserPresetsJson);
|
||||||
|
|
||||||
m_presetsData = combinePresets(cmakePresetsData, cmakeUserPresetsData);
|
m_presetsData = combinePresets(cmakePresetsData, cmakeUserPresetsData);
|
||||||
|
setupBuildPresets(m_presetsData);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMakeProject::setupTarget(Target *t)
|
bool CMakeProject::setupTarget(Target *t)
|
||||||
|
@@ -38,6 +38,7 @@ private:
|
|||||||
ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override;
|
ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override;
|
||||||
Internal::PresetsData combinePresets(Internal::PresetsData &cmakePresetsData,
|
Internal::PresetsData combinePresets(Internal::PresetsData &cmakePresetsData,
|
||||||
Internal::PresetsData &cmakeUserPresetsData);
|
Internal::PresetsData &cmakeUserPresetsData);
|
||||||
|
void setupBuildPresets(Internal::PresetsData &presetsData);
|
||||||
|
|
||||||
mutable Internal::CMakeProjectImporter *m_projectImporter = nullptr;
|
mutable Internal::CMakeProjectImporter *m_projectImporter = nullptr;
|
||||||
|
|
||||||
|
@@ -12,9 +12,9 @@
|
|||||||
|
|
||||||
namespace CMakeProjectManager::Internal::CMakePresets::Macros {
|
namespace CMakeProjectManager::Internal::CMakePresets::Macros {
|
||||||
|
|
||||||
static void expandAllButEnv(const PresetsDetails::ConfigurePreset &configurePreset,
|
void expandAllButEnv(const PresetsDetails::ConfigurePreset &preset,
|
||||||
const Utils::FilePath &sourceDirectory,
|
const Utils::FilePath &sourceDirectory,
|
||||||
QString &value)
|
QString &value)
|
||||||
{
|
{
|
||||||
value.replace("${dollar}", "$");
|
value.replace("${dollar}", "$");
|
||||||
|
|
||||||
@@ -22,23 +22,36 @@ static void expandAllButEnv(const PresetsDetails::ConfigurePreset &configurePres
|
|||||||
value.replace("${sourceParentDir}", sourceDirectory.parentDir().toString());
|
value.replace("${sourceParentDir}", sourceDirectory.parentDir().toString());
|
||||||
value.replace("${sourceDirName}", sourceDirectory.fileName());
|
value.replace("${sourceDirName}", sourceDirectory.fileName());
|
||||||
|
|
||||||
value.replace("${presetName}", configurePreset.name);
|
value.replace("${presetName}", preset.name);
|
||||||
if (configurePreset.generator)
|
if (preset.generator)
|
||||||
value.replace("${generator}", configurePreset.generator.value());
|
value.replace("${generator}", preset.generator.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
void expand(const PresetsDetails::ConfigurePreset &configurePreset,
|
void expandAllButEnv(const PresetsDetails::BuildPreset &preset,
|
||||||
|
const Utils::FilePath &sourceDirectory,
|
||||||
|
QString &value)
|
||||||
|
{
|
||||||
|
value.replace("${dollar}", "$");
|
||||||
|
|
||||||
|
value.replace("${sourceDir}", sourceDirectory.toString());
|
||||||
|
value.replace("${sourceParentDir}", sourceDirectory.parentDir().toString());
|
||||||
|
value.replace("${sourceDirName}", sourceDirectory.fileName());
|
||||||
|
|
||||||
|
value.replace("${presetName}", preset.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class PresetType>
|
||||||
|
void expand(const PresetType &preset,
|
||||||
Utils::Environment &env,
|
Utils::Environment &env,
|
||||||
const Utils::FilePath &sourceDirectory)
|
const Utils::FilePath &sourceDirectory)
|
||||||
{
|
{
|
||||||
const QHash<QString, QString> presetEnv = configurePreset.environment
|
const QHash<QString, QString> presetEnv = preset.environment ? preset.environment.value()
|
||||||
? configurePreset.environment.value()
|
: QHash<QString, QString>();
|
||||||
: QHash<QString, QString>();
|
|
||||||
for (auto it = presetEnv.constKeyValueBegin(); it != presetEnv.constKeyValueEnd(); ++it) {
|
for (auto it = presetEnv.constKeyValueBegin(); it != presetEnv.constKeyValueEnd(); ++it) {
|
||||||
const QString key = it->first;
|
const QString key = it->first;
|
||||||
QString value = it->second;
|
QString value = it->second;
|
||||||
|
|
||||||
expandAllButEnv(configurePreset, sourceDirectory, value);
|
expandAllButEnv(preset, sourceDirectory, value);
|
||||||
|
|
||||||
QRegularExpression envRegex(R"((\$env\{(\w+)\}))");
|
QRegularExpression envRegex(R"((\$env\{(\w+)\}))");
|
||||||
for (const QRegularExpressionMatch &match : envRegex.globalMatch(value)) {
|
for (const QRegularExpressionMatch &match : envRegex.globalMatch(value)) {
|
||||||
@@ -69,19 +82,19 @@ void expand(const PresetsDetails::ConfigurePreset &configurePreset,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void expand(const PresetsDetails::ConfigurePreset &configurePreset,
|
template<class PresetType>
|
||||||
|
void expand(const PresetType &preset,
|
||||||
Utils::EnvironmentItems &envItems,
|
Utils::EnvironmentItems &envItems,
|
||||||
const Utils::FilePath &sourceDirectory)
|
const Utils::FilePath &sourceDirectory)
|
||||||
{
|
{
|
||||||
const QHash<QString, QString> presetEnv = configurePreset.environment
|
const QHash<QString, QString> presetEnv = preset.environment ? preset.environment.value()
|
||||||
? configurePreset.environment.value()
|
: QHash<QString, QString>();
|
||||||
: QHash<QString, QString>();
|
|
||||||
|
|
||||||
for (auto it = presetEnv.constKeyValueBegin(); it != presetEnv.constKeyValueEnd(); ++it) {
|
for (auto it = presetEnv.constKeyValueBegin(); it != presetEnv.constKeyValueEnd(); ++it) {
|
||||||
const QString key = it->first;
|
const QString key = it->first;
|
||||||
QString value = it->second;
|
QString value = it->second;
|
||||||
|
|
||||||
expandAllButEnv(configurePreset, sourceDirectory, value);
|
expandAllButEnv(preset, sourceDirectory, value);
|
||||||
|
|
||||||
QRegularExpression envRegex(R"((\$env\{(\w+)\}))");
|
QRegularExpression envRegex(R"((\$env\{(\w+)\}))");
|
||||||
for (const QRegularExpressionMatch &match : envRegex.globalMatch(value)) {
|
for (const QRegularExpressionMatch &match : envRegex.globalMatch(value)) {
|
||||||
@@ -108,16 +121,16 @@ void expand(const PresetsDetails::ConfigurePreset &configurePreset,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void expand(const PresetsDetails::ConfigurePreset &configurePreset,
|
template<class PresetType>
|
||||||
|
void expand(const PresetType &preset,
|
||||||
const Utils::Environment &env,
|
const Utils::Environment &env,
|
||||||
const Utils::FilePath &sourceDirectory,
|
const Utils::FilePath &sourceDirectory,
|
||||||
QString &value)
|
QString &value)
|
||||||
{
|
{
|
||||||
expandAllButEnv(configurePreset, sourceDirectory, value);
|
expandAllButEnv(preset, sourceDirectory, value);
|
||||||
|
|
||||||
const QHash<QString, QString> presetEnv = configurePreset.environment
|
const QHash<QString, QString> presetEnv = preset.environment ? preset.environment.value()
|
||||||
? configurePreset.environment.value()
|
: QHash<QString, QString>();
|
||||||
: QHash<QString, QString>();
|
|
||||||
|
|
||||||
QRegularExpression envRegex(R"((\$env\{(\w+)\}))");
|
QRegularExpression envRegex(R"((\$env\{(\w+)\}))");
|
||||||
for (const QRegularExpressionMatch &match : envRegex.globalMatch(value))
|
for (const QRegularExpressionMatch &match : envRegex.globalMatch(value))
|
||||||
@@ -128,4 +141,32 @@ void expand(const PresetsDetails::ConfigurePreset &configurePreset,
|
|||||||
value.replace(match.captured(1), env.value(match.captured(2)));
|
value.replace(match.captured(1), env.value(match.captured(2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Expand for PresetsDetails::ConfigurePreset
|
||||||
|
template void expand<PresetsDetails::ConfigurePreset>(const PresetsDetails::ConfigurePreset &preset,
|
||||||
|
Utils::Environment &env,
|
||||||
|
const Utils::FilePath &sourceDirectory);
|
||||||
|
|
||||||
|
template void expand<PresetsDetails::ConfigurePreset>(const PresetsDetails::ConfigurePreset &preset,
|
||||||
|
Utils::EnvironmentItems &envItems,
|
||||||
|
const Utils::FilePath &sourceDirectory);
|
||||||
|
|
||||||
|
template void expand<PresetsDetails::ConfigurePreset>(const PresetsDetails::ConfigurePreset &preset,
|
||||||
|
const Utils::Environment &env,
|
||||||
|
const Utils::FilePath &sourceDirectory,
|
||||||
|
QString &value);
|
||||||
|
|
||||||
|
// Expand for PresetsDetails::BuildPreset
|
||||||
|
template void expand<PresetsDetails::BuildPreset>(const PresetsDetails::BuildPreset &preset,
|
||||||
|
Utils::Environment &env,
|
||||||
|
const Utils::FilePath &sourceDirectory);
|
||||||
|
|
||||||
|
template void expand<PresetsDetails::BuildPreset>(const PresetsDetails::BuildPreset &preset,
|
||||||
|
Utils::EnvironmentItems &envItems,
|
||||||
|
const Utils::FilePath &sourceDirectory);
|
||||||
|
|
||||||
|
template void expand<PresetsDetails::BuildPreset>(const PresetsDetails::BuildPreset &preset,
|
||||||
|
const Utils::Environment &env,
|
||||||
|
const Utils::FilePath &sourceDirectory,
|
||||||
|
QString &value);
|
||||||
|
|
||||||
} // namespace CMakeProjectManager::Internal::CMakePresets::Macros
|
} // namespace CMakeProjectManager::Internal::CMakePresets::Macros
|
||||||
|
@@ -12,16 +12,13 @@ class FilePath;
|
|||||||
|
|
||||||
namespace CMakeProjectManager::Internal {
|
namespace CMakeProjectManager::Internal {
|
||||||
|
|
||||||
namespace PresetsDetails {
|
|
||||||
class ConfigurePreset;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace CMakePresets::Macros {
|
namespace CMakePresets::Macros {
|
||||||
/**
|
/**
|
||||||
* Expands the CMakePresets Macros using Utils::Environment as target and source for parent environment values.
|
* Expands the CMakePresets Macros using Utils::Environment as target and source for parent environment values.
|
||||||
* $penv{PATH} is taken from Utils::Environment
|
* $penv{PATH} is taken from Utils::Environment
|
||||||
*/
|
*/
|
||||||
void expand(const PresetsDetails::ConfigurePreset &configurePreset,
|
template<class PresetType>
|
||||||
|
void expand(const PresetType &preset,
|
||||||
Utils::Environment &env,
|
Utils::Environment &env,
|
||||||
const Utils::FilePath &sourceDirectory);
|
const Utils::FilePath &sourceDirectory);
|
||||||
|
|
||||||
@@ -29,14 +26,16 @@ void expand(const PresetsDetails::ConfigurePreset &configurePreset,
|
|||||||
* Expands the CMakePresets Macros using Utils::Environment as target
|
* Expands the CMakePresets Macros using Utils::Environment as target
|
||||||
* $penv{PATH} is replaced with Qt Creator macros ${PATH}
|
* $penv{PATH} is replaced with Qt Creator macros ${PATH}
|
||||||
*/
|
*/
|
||||||
void expand(const PresetsDetails::ConfigurePreset &configurePreset,
|
template<class PresetType>
|
||||||
|
void expand(const PresetType &preset,
|
||||||
Utils::EnvironmentItems &envItems,
|
Utils::EnvironmentItems &envItems,
|
||||||
const Utils::FilePath &sourceDirectory);
|
const Utils::FilePath &sourceDirectory);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expands the CMakePresets macros inside the @value QString parameter.
|
* Expands the CMakePresets macros inside the @value QString parameter.
|
||||||
*/
|
*/
|
||||||
void expand(const PresetsDetails::ConfigurePreset &configurePreset,
|
template<class PresetType>
|
||||||
|
void expand(const PresetType &preset,
|
||||||
const Utils::Environment &env,
|
const Utils::Environment &env,
|
||||||
const Utils::FilePath &sourceDirectory,
|
const Utils::FilePath &sourceDirectory,
|
||||||
QString &value);
|
QString &value);
|
||||||
|
@@ -13,7 +13,7 @@ namespace Internal {
|
|||||||
|
|
||||||
bool parseVersion(const QJsonValue &jsonValue, int &version)
|
bool parseVersion(const QJsonValue &jsonValue, int &version)
|
||||||
{
|
{
|
||||||
if (jsonValue.isNull())
|
if (jsonValue.isUndefined())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const int invalidVersion = -1;
|
const int invalidVersion = -1;
|
||||||
@@ -23,7 +23,7 @@ bool parseVersion(const QJsonValue &jsonValue, int &version)
|
|||||||
|
|
||||||
bool parseCMakeMinimumRequired(const QJsonValue &jsonValue, QVersionNumber &versionNumber)
|
bool parseCMakeMinimumRequired(const QJsonValue &jsonValue, QVersionNumber &versionNumber)
|
||||||
{
|
{
|
||||||
if (jsonValue.isNull() || !jsonValue.isObject())
|
if (jsonValue.isUndefined() || !jsonValue.isObject())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QJsonObject object = jsonValue.toObject();
|
QJsonObject object = jsonValue.toObject();
|
||||||
@@ -38,7 +38,7 @@ bool parseConfigurePresets(const QJsonValue &jsonValue,
|
|||||||
std::vector<PresetsDetails::ConfigurePreset> &configurePresets)
|
std::vector<PresetsDetails::ConfigurePreset> &configurePresets)
|
||||||
{
|
{
|
||||||
// The whole section is optional
|
// The whole section is optional
|
||||||
if (jsonValue.isNull())
|
if (jsonValue.isUndefined())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!jsonValue.isArray())
|
if (!jsonValue.isArray())
|
||||||
@@ -56,7 +56,7 @@ bool parseConfigurePresets(const QJsonValue &jsonValue,
|
|||||||
preset.hidden = object.value("hidden").toBool();
|
preset.hidden = object.value("hidden").toBool();
|
||||||
|
|
||||||
QJsonValue inherits = object.value("inherits");
|
QJsonValue inherits = object.value("inherits");
|
||||||
if (!inherits.isNull()) {
|
if (!inherits.isUndefined()) {
|
||||||
preset.inherits = QStringList();
|
preset.inherits = QStringList();
|
||||||
if (inherits.isArray()) {
|
if (inherits.isArray()) {
|
||||||
const QJsonArray inheritsArray = inherits.toArray();
|
const QJsonArray inheritsArray = inherits.toArray();
|
||||||
@@ -184,6 +184,97 @@ bool parseConfigurePresets(const QJsonValue &jsonValue,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool parseBuildPresets(const QJsonValue &jsonValue,
|
||||||
|
std::vector<PresetsDetails::BuildPreset> &buildPresets)
|
||||||
|
{
|
||||||
|
// The whole section is optional
|
||||||
|
if (jsonValue.isUndefined())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!jsonValue.isArray())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const QJsonArray buildPresetsArray = jsonValue.toArray();
|
||||||
|
for (const QJsonValue &presetJson : buildPresetsArray) {
|
||||||
|
if (!presetJson.isObject())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
QJsonObject object = presetJson.toObject();
|
||||||
|
PresetsDetails::BuildPreset preset;
|
||||||
|
|
||||||
|
preset.name = object.value("name").toString();
|
||||||
|
preset.hidden = object.value("hidden").toBool();
|
||||||
|
|
||||||
|
QJsonValue inherits = object.value("inherits");
|
||||||
|
if (!inherits.isUndefined()) {
|
||||||
|
preset.inherits = QStringList();
|
||||||
|
if (inherits.isArray()) {
|
||||||
|
const QJsonArray inheritsArray = inherits.toArray();
|
||||||
|
for (const QJsonValue &inheritsValue : inheritsArray)
|
||||||
|
preset.inherits.value() << inheritsValue.toString();
|
||||||
|
} else {
|
||||||
|
QString inheritsValue = inherits.toString();
|
||||||
|
if (!inheritsValue.isEmpty())
|
||||||
|
preset.inherits.value() << inheritsValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (object.contains("displayName"))
|
||||||
|
preset.displayName = object.value("displayName").toString();
|
||||||
|
if (object.contains("description"))
|
||||||
|
preset.description = object.value("description").toString();
|
||||||
|
|
||||||
|
const QJsonObject environmentObj = object.value("environment").toObject();
|
||||||
|
for (const QString &envKey : environmentObj.keys()) {
|
||||||
|
if (!preset.environment)
|
||||||
|
preset.environment = QHash<QString, QString>();
|
||||||
|
|
||||||
|
QJsonValue envValue = environmentObj.value(envKey);
|
||||||
|
preset.environment.value().insert(envKey, envValue.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object.contains("configurePreset"))
|
||||||
|
preset.configurePreset = object.value("configurePreset").toString();
|
||||||
|
if (object.contains("inheritConfigureEnvironment"))
|
||||||
|
preset.inheritConfigureEnvironment = object.value("inheritConfigureEnvironment").toBool();
|
||||||
|
if (object.contains("jobs"))
|
||||||
|
preset.jobs = object.value("jobs").toInt();
|
||||||
|
|
||||||
|
QJsonValue targets = object.value("targets");
|
||||||
|
if (!targets.isUndefined()) {
|
||||||
|
preset.targets = QStringList();
|
||||||
|
if (targets.isArray()) {
|
||||||
|
const QJsonArray targetsArray = targets.toArray();
|
||||||
|
for (const QJsonValue &targetsValue : targetsArray)
|
||||||
|
preset.targets.value() << targetsValue.toString();
|
||||||
|
} else {
|
||||||
|
QString targetsValue = targets.toString();
|
||||||
|
if (!targetsValue.isEmpty())
|
||||||
|
preset.targets.value() << targetsValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (object.contains("configuration"))
|
||||||
|
preset.configuration = object.value("configuration").toString();
|
||||||
|
if (object.contains("verbose"))
|
||||||
|
preset.verbose = object.value("verbose").toBool();
|
||||||
|
if (object.contains("cleanFirst"))
|
||||||
|
preset.cleanFirst = object.value("cleanFirst").toBool();
|
||||||
|
|
||||||
|
QJsonValue nativeToolOptions = object.value("nativeToolOptions");
|
||||||
|
if (!nativeToolOptions.isUndefined()) {
|
||||||
|
if (nativeToolOptions.isArray()) {
|
||||||
|
preset.nativeToolOptions = QStringList();
|
||||||
|
const QJsonArray toolOptionsArray = nativeToolOptions.toArray();
|
||||||
|
for (const QJsonValue &toolOptionsValue : toolOptionsArray)
|
||||||
|
preset.nativeToolOptions.value() << toolOptionsValue.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildPresets.emplace_back(preset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const PresetsData &PresetsParser::presetsData() const
|
const PresetsData &PresetsParser::presetsData() const
|
||||||
{
|
{
|
||||||
return m_presetsData;
|
return m_presetsData;
|
||||||
@@ -232,9 +323,19 @@ bool PresetsParser::parse(const Utils::FilePath &jsonFile, QString &errorMessage
|
|||||||
|
|
||||||
// optional
|
// optional
|
||||||
if (!parseConfigurePresets(root.value("configurePresets"), m_presetsData.configurePresets)) {
|
if (!parseConfigurePresets(root.value("configurePresets"), m_presetsData.configurePresets)) {
|
||||||
errorMessage = QCoreApplication::translate(
|
errorMessage
|
||||||
"CMakeProjectManager::Internal",
|
= QCoreApplication::translate("CMakeProjectManager::Internal",
|
||||||
"Invalid \"configurePresets\" section in %1 file").arg(jsonFile.fileName());
|
"Invalid \"configurePresets\" section in %1 file")
|
||||||
|
.arg(jsonFile.fileName());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// optional
|
||||||
|
if (!parseBuildPresets(root.value("buildPresets"), m_presetsData.buildPresets)) {
|
||||||
|
errorMessage
|
||||||
|
= QCoreApplication::translate("CMakeProjectManager::Internal",
|
||||||
|
"Invalid \"buildPresets\" section in %1 file")
|
||||||
|
.arg(jsonFile.fileName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,5 +378,38 @@ void PresetsDetails::ConfigurePreset::inheritFrom(const ConfigurePreset &other)
|
|||||||
debug = other.debug;
|
debug = other.debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PresetsDetails::BuildPreset::inheritFrom(const BuildPreset &other)
|
||||||
|
{
|
||||||
|
if (!vendor && other.vendor)
|
||||||
|
vendor = other.vendor;
|
||||||
|
|
||||||
|
if (!environment && other.environment)
|
||||||
|
environment = other.environment;
|
||||||
|
|
||||||
|
if (!configurePreset && other.configurePreset)
|
||||||
|
configurePreset = other.configurePreset;
|
||||||
|
|
||||||
|
if (!inheritConfigureEnvironment && other.inheritConfigureEnvironment)
|
||||||
|
inheritConfigureEnvironment = other.inheritConfigureEnvironment;
|
||||||
|
|
||||||
|
if (!jobs && other.jobs)
|
||||||
|
jobs = other.jobs;
|
||||||
|
|
||||||
|
if (!targets && other.targets)
|
||||||
|
targets = other.targets;
|
||||||
|
|
||||||
|
if (!configuration && other.configuration)
|
||||||
|
configuration = other.configuration;
|
||||||
|
|
||||||
|
if (!verbose && other.verbose)
|
||||||
|
verbose = other.verbose;
|
||||||
|
|
||||||
|
if (!cleanFirst && other.cleanFirst)
|
||||||
|
cleanFirst = other.cleanFirst;
|
||||||
|
|
||||||
|
if (!nativeToolOptions && other.nativeToolOptions)
|
||||||
|
nativeToolOptions = other.nativeToolOptions;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace CMakeProjectManager
|
} // namespace CMakeProjectManager
|
||||||
|
@@ -67,6 +67,27 @@ public:
|
|||||||
std::optional<Debug> debug;
|
std::optional<Debug> debug;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BuildPreset {
|
||||||
|
public:
|
||||||
|
void inheritFrom(const BuildPreset &other);
|
||||||
|
|
||||||
|
QString name;
|
||||||
|
std::optional<bool> hidden = false;
|
||||||
|
std::optional<QStringList> inherits;
|
||||||
|
std::optional<QHash<QString, QString>> vendor;
|
||||||
|
std::optional<QString> displayName;
|
||||||
|
std::optional<QString> description;
|
||||||
|
std::optional<QHash<QString, QString>> environment;
|
||||||
|
std::optional<QString> configurePreset;
|
||||||
|
std::optional<bool> inheritConfigureEnvironment = true;
|
||||||
|
std::optional<int> jobs;
|
||||||
|
std::optional<QStringList> targets;
|
||||||
|
std::optional<QString> configuration;
|
||||||
|
std::optional<bool> verbose;
|
||||||
|
std::optional<bool> cleanFirst;
|
||||||
|
std::optional<QStringList> nativeToolOptions;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace PresetsDetails
|
} // namespace PresetsDetails
|
||||||
|
|
||||||
class PresetsData
|
class PresetsData
|
||||||
@@ -76,6 +97,7 @@ public:
|
|||||||
QVersionNumber cmakeMinimimRequired;
|
QVersionNumber cmakeMinimimRequired;
|
||||||
QHash<QString, QString> vendor;
|
QHash<QString, QString> vendor;
|
||||||
std::vector<PresetsDetails::ConfigurePreset> configurePresets;
|
std::vector<PresetsDetails::ConfigurePreset> configurePresets;
|
||||||
|
std::vector<PresetsDetails::BuildPreset> buildPresets;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PresetsParser
|
class PresetsParser
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"version": 1,
|
"version": 2,
|
||||||
"cmakeMinimumRequired": {
|
"cmakeMinimumRequired": {
|
||||||
"major": 3,
|
"major": 3,
|
||||||
"minor": 19,
|
"minor": 20,
|
||||||
"patch": 0
|
"patch": 0
|
||||||
},
|
},
|
||||||
"configurePresets": [
|
"configurePresets": [
|
||||||
@@ -13,10 +13,10 @@
|
|||||||
"binaryDir": "${sourceDir}/build-${presetName}-release",
|
"binaryDir": "${sourceDir}/build-${presetName}-release",
|
||||||
"cacheVariables": {
|
"cacheVariables": {
|
||||||
"CMAKE_BUILD_TYPE": "Release",
|
"CMAKE_BUILD_TYPE": "Release",
|
||||||
"CMAKE_PREFIX_PATH": "c:/Qt/6.3.1/mingw_64"
|
"CMAKE_PREFIX_PATH": "c:/Qt/6.3.2/mingw_64"
|
||||||
},
|
},
|
||||||
"environment": {
|
"environment": {
|
||||||
"PATH": "c:/mingw64/bin;$penv{PATH}"
|
"PATH": "c:/Qt/Tools/mingw1120_64/bin;$penv{PATH}"
|
||||||
},
|
},
|
||||||
"debug" : {
|
"debug" : {
|
||||||
"find" : true
|
"find" : true
|
||||||
@@ -37,8 +37,38 @@
|
|||||||
"value": "x64"
|
"value": "x64"
|
||||||
},
|
},
|
||||||
"cacheVariables": {
|
"cacheVariables": {
|
||||||
"CMAKE_PREFIX_PATH": "c:/Qt/6.3.1/msvc2019_64"
|
"CMAKE_PREFIX_PATH": "c:/Qt/6.3.2/msvc2019_64"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"buildPresets": [
|
||||||
|
{
|
||||||
|
"name": "mingw",
|
||||||
|
"displayName": "MinGW default",
|
||||||
|
"configurePreset": "mingw",
|
||||||
|
"targets": "${sourceDirName}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mingw-verbose",
|
||||||
|
"inherits": "mingw",
|
||||||
|
"displayName": "MinGW verbose",
|
||||||
|
"verbose": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mingw-make",
|
||||||
|
"displayName": "MinGW make 4 CPUs",
|
||||||
|
"configurePreset": "mingw-make",
|
||||||
|
"jobs": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "visualc-debug",
|
||||||
|
"configurePreset": "visualc",
|
||||||
|
"configuration": "Debug"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "visualc-relwithdebinfo",
|
||||||
|
"inherits": "visualc-debug",
|
||||||
|
"configuration": "RelWithDebInfo"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user