2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
2009-11-23 12:11:48 +01:00
|
|
|
|
|
|
|
|
#include "cmakebuildconfiguration.h"
|
2010-01-07 18:17:24 +01:00
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
#include "cmakebuildconfiguration.h"
|
2016-01-07 12:33:52 +01:00
|
|
|
#include "cmakebuildstep.h"
|
2020-04-17 15:30:05 +02:00
|
|
|
#include "cmakebuildsystem.h"
|
2021-02-12 16:15:26 +01:00
|
|
|
#include "cmakeconfigitem.h"
|
2016-02-03 13:52:50 +01:00
|
|
|
#include "cmakekitinformation.h"
|
2022-05-30 19:04:54 +02:00
|
|
|
#include "cmakeproject.h"
|
2012-10-02 17:46:19 +02:00
|
|
|
#include "cmakeprojectconstants.h"
|
2021-02-18 18:50:11 +01:00
|
|
|
#include "cmakeprojectplugin.h"
|
|
|
|
|
#include "cmakespecificsettings.h"
|
2021-02-12 16:15:26 +01:00
|
|
|
#include "configmodel.h"
|
|
|
|
|
#include "configmodelitemdelegate.h"
|
2021-12-28 21:42:29 +01:00
|
|
|
#include "fileapiparser.h"
|
2022-05-30 19:04:54 +02:00
|
|
|
#include "presetsmacros.h"
|
|
|
|
|
#include "presetsparser.h"
|
2010-01-07 18:17:24 +01:00
|
|
|
|
2019-03-06 14:17:17 +02:00
|
|
|
#include <android/androidconstants.h>
|
2021-09-14 13:39:05 +02:00
|
|
|
#include <docker/dockerconstants.h>
|
2021-02-02 16:10:45 +01:00
|
|
|
#include <ios/iosconstants.h>
|
2021-05-17 20:03:09 +02:00
|
|
|
#include <qnx/qnxconstants.h>
|
2021-03-23 18:33:42 +01:00
|
|
|
#include <webassembly/webassemblyconstants.h>
|
2021-02-12 16:15:26 +01:00
|
|
|
|
|
|
|
|
#include <coreplugin/find/itemviewfind.h>
|
2021-03-19 13:09:49 +01:00
|
|
|
#include <coreplugin/icore.h>
|
2021-02-12 16:15:26 +01:00
|
|
|
|
2020-03-16 10:24:35 +01:00
|
|
|
#include <projectexplorer/buildaspects.h>
|
2019-01-29 16:51:17 +01:00
|
|
|
#include <projectexplorer/buildinfo.h>
|
2016-11-14 15:18:25 +01:00
|
|
|
#include <projectexplorer/buildmanager.h>
|
2010-07-16 14:00:41 +02:00
|
|
|
#include <projectexplorer/buildsteplist.h>
|
2022-04-12 21:01:45 +02:00
|
|
|
#include <projectexplorer/devicesupport/idevice.h>
|
2022-08-10 19:12:40 +02:00
|
|
|
#include <projectexplorer/environmentwidget.h>
|
2019-01-07 12:15:40 +01:00
|
|
|
#include <projectexplorer/kitinformation.h>
|
2021-02-12 16:15:26 +01:00
|
|
|
#include <projectexplorer/namedwidget.h>
|
2022-07-21 18:09:29 +02:00
|
|
|
#include <projectexplorer/processparameters.h>
|
2021-02-12 16:15:26 +01:00
|
|
|
#include <projectexplorer/project.h>
|
2021-09-21 12:42:44 +02:00
|
|
|
#include <projectexplorer/projectexplorer.h>
|
2022-06-22 15:43:33 +02:00
|
|
|
#include <projectexplorer/projectexplorerconstants.h>
|
2012-04-24 15:49:09 +02:00
|
|
|
#include <projectexplorer/target.h>
|
2021-09-21 12:42:44 +02:00
|
|
|
#include <projectexplorer/taskhub.h>
|
2020-06-17 06:35:31 +02:00
|
|
|
|
2019-10-18 09:25:14 +03:00
|
|
|
#include <qtsupport/baseqtversion.h>
|
2020-02-05 15:16:04 +01:00
|
|
|
#include <qtsupport/qtbuildaspects.h>
|
2019-08-07 10:10:01 +02:00
|
|
|
#include <qtsupport/qtkitinformation.h>
|
|
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
#include <utils/algorithm.h>
|
|
|
|
|
#include <utils/categorysortfiltermodel.h>
|
2021-03-19 13:09:49 +01:00
|
|
|
#include <utils/checkablemessagebox.h>
|
2022-03-02 04:12:25 +01:00
|
|
|
#include <utils/commandline.h>
|
2021-02-12 16:15:26 +01:00
|
|
|
#include <utils/detailswidget.h>
|
|
|
|
|
#include <utils/headerviewstretcher.h>
|
|
|
|
|
#include <utils/infolabel.h>
|
|
|
|
|
#include <utils/itemviews.h>
|
|
|
|
|
#include <utils/layoutbuilder.h>
|
|
|
|
|
#include <utils/progressindicator.h>
|
2013-07-22 15:53:57 +02:00
|
|
|
#include <utils/qtcassert.h>
|
2020-06-17 06:35:31 +02:00
|
|
|
#include <utils/stringutils.h>
|
2021-02-24 14:33:38 +01:00
|
|
|
#include <utils/variablechooser.h>
|
2013-07-22 15:53:57 +02:00
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
#include <QBoxLayout>
|
|
|
|
|
#include <QCheckBox>
|
2021-02-24 14:33:38 +01:00
|
|
|
#include <QDialog>
|
|
|
|
|
#include <QDialogButtonBox>
|
2020-03-24 11:01:40 +01:00
|
|
|
#include <QDir>
|
2021-02-12 16:15:26 +01:00
|
|
|
#include <QGridLayout>
|
2019-08-09 12:20:49 +02:00
|
|
|
#include <QLoggingCategory>
|
2021-02-12 16:15:26 +01:00
|
|
|
#include <QMenu>
|
2020-03-24 11:01:40 +01:00
|
|
|
#include <QMessageBox>
|
2021-02-24 14:33:38 +01:00
|
|
|
#include <QPlainTextEdit>
|
2021-02-12 16:15:26 +01:00
|
|
|
#include <QPushButton>
|
|
|
|
|
#include <QTimer>
|
2019-08-09 12:20:49 +02:00
|
|
|
|
2014-10-22 09:16:55 +02:00
|
|
|
using namespace ProjectExplorer;
|
|
|
|
|
using namespace Utils;
|
2021-02-04 14:53:42 +01:00
|
|
|
using namespace CMakeProjectManager::Internal;
|
2014-10-22 09:16:55 +02:00
|
|
|
|
|
|
|
|
namespace CMakeProjectManager {
|
2009-11-23 13:29:45 +01:00
|
|
|
|
2020-01-15 14:39:23 +01:00
|
|
|
static Q_LOGGING_CATEGORY(cmakeBuildConfigurationLog, "qtc.cmake.bc", QtWarningMsg);
|
2019-08-09 12:20:49 +02:00
|
|
|
|
2016-02-03 13:52:50 +01:00
|
|
|
const char CONFIGURATION_KEY[] = "CMake.Configuration";
|
2021-02-04 14:53:42 +01:00
|
|
|
const char DEVELOPMENT_TEAM_FLAG[] = "Ios:DevelopmentTeam:Flag";
|
|
|
|
|
const char PROVISIONING_PROFILE_FLAG[] = "Ios:ProvisioningProfile:Flag";
|
Add workarounds for running under Rosetta on macOS
When Qt Creator is built as an Intel binary, and runs on
an Apple Silicon (ARM) Mac, it will be run via the Rosetta
translation layer. This means any process spawned by QtC,
including qmake, CMake, and lldb, will launch as x86_64
binaries as well.
For qmake and CMake, this affects their default choice of
build architecture, resulting in x86_64 builds of user
applications. We want to produce native arm64 apps, even
if Qt Creator itself isn't one, so we explicitly detect
the situation, and if Qt has an arm64 slice, we default
to arm64 builds.
The logic of adding CONFIG+=x86_64 to the qmake step has
been disabled, as the assumption that a single qmake run
and build will produce only a single architecture does no
longer hold. The corresponding logic in Qt was removed
in 2015 (qtbase f58e95f098c8d78a5f2db7729606126fe093cbdf).
In the case of lldb, running it as an x86_64 binary fails
to attach to the running application. We work around this
by using the 'arch' tool to explicitly launch it as an
arm64 binary. This works for debugging both arm64 and
x86_64 applications.
Change-Id: I65cc0f600223990f25c76cef18d927895e551260
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
2021-06-22 00:11:58 +02:00
|
|
|
const char CMAKE_OSX_ARCHITECTURES_FLAG[] = "CMAKE_OSX_ARCHITECTURES:DefaultFlag";
|
2022-05-18 11:56:01 +02:00
|
|
|
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";
|
CMake: Add 'Profile' configuration
Get rid of the hardcoded QML Debugging for Debug & RelWithDebInfo from
the project template, because RelWithDebInfo is actually a good
configuration for doing releases (we use it for Qt Creator), and
enabling QML debugging for releases is a bad idea.
Instead enable QML Debugging in Qt Creator for the Debug configuration,
and add a 'Profile' configuration that is 'RelWithDebInfo + QML
Debugging'.
When importing a build, we only set the "QML debugging" option of the
build configuration, if it is enabled in the imported build, even if it
uses CMAKE_BUILD_TYPE=Debug .
One drawback: When not importing a build, but just setting the build
directory of a "Profile" or "Debug" configuration to an existing build,
Qt Creator asks if it should apply "-DCMAKE_CXX_FLAGS=-DQT_QML_DEBUG".
The user can choose not to, but then is asked the next time again, and
it is not obvious that the "QML debugging" option is responsible for
this.
That is somewhat orthogonal to this change though: Even without this
change, if the user changes the QML debugging option from "Leave at
Default" to "Enable", the same happens, and it is also not clear to the
user how to get rid of it. The user might not even have realized that
they changed the option (e.g. on platforms where the mouse wheel cycles
combo box values).
I think the correct solution is to 1. make clearer where the CMake flags
came from in that dialog, 2. allow the user to cancel a build from that
dialog, 3. allow the user to discard these changes (by changing the
setting) from that dialog. But that is for another patch.
Amends 3300182d405bffe062a0f2be900f35822a9e20b0
Amends 77fed0b0fdce2a93f465c20cd87c41900117dcda
Change-Id: I95de59473b67c5afd6a53ea7f49838dbaef770d4
Reviewed-by: Artem Sokolovskii <artem.sokolovskii@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
2022-05-18 10:40:31 +02:00
|
|
|
const char CMAKE_BUILD_TYPE[] = "CMake.Build.Type";
|
2022-08-10 19:12:40 +02:00
|
|
|
const char CLEAR_SYSTEM_ENVIRONMENT_KEY[] = "CMake.Configure.ClearSystemEnvironment";
|
|
|
|
|
const char USER_ENVIRONMENT_CHANGES_KEY[] = "CMake.Configure.UserEnvironmentChanges";
|
2021-02-04 14:53:42 +01:00
|
|
|
|
|
|
|
|
namespace Internal {
|
2014-10-22 09:16:55 +02:00
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
class CMakeBuildSettingsWidget : public NamedWidget
|
|
|
|
|
{
|
2021-03-19 10:46:11 +01:00
|
|
|
Q_DECLARE_TR_FUNCTIONS(CMakeProjectManager::Internal::CMakeBuildSettingsWidget)
|
|
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
public:
|
2022-05-02 18:02:37 +02:00
|
|
|
CMakeBuildSettingsWidget(CMakeBuildSystem *bc);
|
2021-02-12 16:15:26 +01:00
|
|
|
|
|
|
|
|
void setError(const QString &message);
|
|
|
|
|
void setWarning(const QString &message);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
void updateButtonState();
|
|
|
|
|
void updateAdvancedCheckBox();
|
|
|
|
|
void updateFromKit();
|
2021-12-28 21:42:29 +01:00
|
|
|
void updateConfigurationStateIndex(int index);
|
2022-02-07 17:01:09 +01:00
|
|
|
CMakeConfig getQmlDebugCxxFlags();
|
|
|
|
|
CMakeConfig getSigningFlagsChanges();
|
2021-02-12 16:15:26 +01:00
|
|
|
|
|
|
|
|
void updateSelection();
|
2021-12-28 21:42:29 +01:00
|
|
|
void updateConfigurationStateSelection();
|
|
|
|
|
bool isInitialConfiguration() const;
|
2021-02-12 16:15:26 +01:00
|
|
|
void setVariableUnsetFlag(bool unsetFlag);
|
|
|
|
|
QAction *createForceAction(int type, const QModelIndex &idx);
|
|
|
|
|
|
|
|
|
|
bool eventFilter(QObject *target, QEvent *event) override;
|
|
|
|
|
|
2021-02-24 14:33:38 +01:00
|
|
|
void batchEditConfiguration();
|
2022-05-02 18:02:37 +02:00
|
|
|
void reconfigureWithInitialParameters();
|
2021-12-28 21:42:29 +01:00
|
|
|
void updateInitialCMakeArguments();
|
2022-01-29 15:03:54 +01:00
|
|
|
void kitCMakeConfiguration();
|
2022-07-21 18:09:29 +02:00
|
|
|
void updateConfigureDetailsWidgetsSummary(
|
|
|
|
|
const QStringList &configurationArguments = QStringList());
|
2021-02-24 14:33:38 +01:00
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
CMakeBuildSystem *m_buildSystem;
|
2021-02-12 16:15:26 +01:00
|
|
|
QTreeView *m_configView;
|
|
|
|
|
ConfigModel *m_configModel;
|
|
|
|
|
CategorySortFilterModel *m_configFilterModel;
|
|
|
|
|
CategorySortFilterModel *m_configTextFilterModel;
|
|
|
|
|
ProgressIndicator *m_progressIndicator;
|
|
|
|
|
QPushButton *m_addButton;
|
|
|
|
|
QPushButton *m_editButton;
|
|
|
|
|
QPushButton *m_setButton;
|
|
|
|
|
QPushButton *m_unsetButton;
|
|
|
|
|
QPushButton *m_resetButton;
|
|
|
|
|
QCheckBox *m_showAdvancedCheckBox;
|
2021-12-28 21:42:29 +01:00
|
|
|
QTabBar *m_configurationStates;
|
2021-02-12 16:15:26 +01:00
|
|
|
QPushButton *m_reconfigureButton;
|
|
|
|
|
QTimer m_showProgressTimer;
|
|
|
|
|
FancyLineEdit *m_filterEdit;
|
|
|
|
|
InfoLabel *m_warningMessageLabel;
|
2022-07-21 18:09:29 +02:00
|
|
|
DetailsWidget *m_configureDetailsWidget;
|
2021-02-24 14:33:38 +01:00
|
|
|
|
|
|
|
|
QPushButton *m_batchEditButton = nullptr;
|
2022-01-29 15:03:54 +01:00
|
|
|
QPushButton *m_kitConfiguration = nullptr;
|
2021-02-12 16:15:26 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static QModelIndex mapToSource(const QAbstractItemView *view, const QModelIndex &idx)
|
|
|
|
|
{
|
|
|
|
|
if (!idx.isValid())
|
|
|
|
|
return idx;
|
|
|
|
|
|
|
|
|
|
QAbstractItemModel *model = view->model();
|
|
|
|
|
QModelIndex result = idx;
|
|
|
|
|
while (auto proxy = qobject_cast<const QSortFilterProxyModel *>(model)) {
|
|
|
|
|
result = proxy->mapToSource(result);
|
|
|
|
|
model = proxy->sourceModel();
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildSystem *bs) :
|
2021-02-12 16:15:26 +01:00
|
|
|
NamedWidget(tr("CMake")),
|
2022-05-02 18:02:37 +02:00
|
|
|
m_buildSystem(bs),
|
2021-02-12 16:15:26 +01:00
|
|
|
m_configModel(new ConfigModel(this)),
|
|
|
|
|
m_configFilterModel(new CategorySortFilterModel(this)),
|
|
|
|
|
m_configTextFilterModel(new CategorySortFilterModel(this))
|
|
|
|
|
{
|
2022-05-02 18:02:37 +02:00
|
|
|
QTC_ASSERT(bs, return);
|
|
|
|
|
BuildConfiguration *bc = bs->buildConfiguration();
|
2022-08-10 19:12:40 +02:00
|
|
|
CMakeBuildConfiguration *cbc = static_cast<CMakeBuildConfiguration *>(bc);
|
2021-02-12 16:15:26 +01:00
|
|
|
|
|
|
|
|
auto vbox = new QVBoxLayout(this);
|
|
|
|
|
vbox->setContentsMargins(0, 0, 0, 0);
|
2022-07-21 18:09:29 +02:00
|
|
|
m_configureDetailsWidget = new DetailsWidget;
|
2021-02-12 16:15:26 +01:00
|
|
|
|
2022-07-21 18:09:29 +02:00
|
|
|
updateConfigureDetailsWidgetsSummary();
|
|
|
|
|
|
|
|
|
|
vbox->addWidget(m_configureDetailsWidget);
|
|
|
|
|
|
|
|
|
|
auto details = new QWidget(m_configureDetailsWidget);
|
|
|
|
|
m_configureDetailsWidget->setWidget(details);
|
2021-02-12 16:15:26 +01:00
|
|
|
|
|
|
|
|
auto buildDirAspect = bc->buildDirectoryAspect();
|
2021-06-22 13:54:16 +02:00
|
|
|
buildDirAspect->setAutoApplyOnEditingFinished(true);
|
2021-02-12 16:15:26 +01:00
|
|
|
connect(buildDirAspect, &BaseAspect::changed, this, [this]() {
|
|
|
|
|
m_configModel->flush(); // clear out config cache...;
|
|
|
|
|
});
|
|
|
|
|
|
2021-03-18 14:20:02 +01:00
|
|
|
auto buildTypeAspect = bc->aspect<BuildTypeAspect>();
|
2022-05-02 18:02:37 +02:00
|
|
|
connect(buildTypeAspect, &BaseAspect::changed, this, [this, buildTypeAspect] {
|
|
|
|
|
if (!m_buildSystem->isMultiConfig()) {
|
2021-03-18 14:20:02 +01:00
|
|
|
CMakeConfig config;
|
|
|
|
|
config << CMakeConfigItem("CMAKE_BUILD_TYPE", buildTypeAspect->value().toUtf8());
|
|
|
|
|
|
|
|
|
|
m_configModel->setBatchEditConfiguration(config);
|
|
|
|
|
}
|
|
|
|
|
});
|
2021-02-12 16:15:26 +01:00
|
|
|
|
|
|
|
|
auto qmlDebugAspect = bc->aspect<QtSupport::QmlDebuggingAspect>();
|
|
|
|
|
connect(qmlDebugAspect, &QtSupport::QmlDebuggingAspect::changed, this, [this]() {
|
|
|
|
|
updateButtonState();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
m_warningMessageLabel = new InfoLabel({}, InfoLabel::Warning);
|
|
|
|
|
m_warningMessageLabel->setVisible(false);
|
|
|
|
|
|
2021-12-28 21:42:29 +01:00
|
|
|
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);
|
|
|
|
|
});
|
|
|
|
|
|
2022-01-29 15:03:54 +01:00
|
|
|
m_kitConfiguration = new QPushButton(tr("Kit Configuration"));
|
|
|
|
|
m_kitConfiguration->setToolTip(tr("Edit the current kit's CMake configuration."));
|
|
|
|
|
m_kitConfiguration->setFixedWidth(m_kitConfiguration->sizeHint().width());
|
|
|
|
|
connect(m_kitConfiguration, &QPushButton::clicked, this, [this]() { kitCMakeConfiguration(); });
|
|
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
m_filterEdit = new FancyLineEdit;
|
|
|
|
|
m_filterEdit->setPlaceholderText(tr("Filter"));
|
|
|
|
|
m_filterEdit->setFiltering(true);
|
|
|
|
|
auto tree = new TreeView;
|
|
|
|
|
connect(tree, &TreeView::activated,
|
|
|
|
|
tree, [tree](const QModelIndex &idx) { tree->edit(idx); });
|
|
|
|
|
m_configView = tree;
|
|
|
|
|
|
|
|
|
|
m_configView->viewport()->installEventFilter(this);
|
|
|
|
|
|
|
|
|
|
m_configFilterModel->setSourceModel(m_configModel);
|
|
|
|
|
m_configFilterModel->setFilterKeyColumn(0);
|
|
|
|
|
m_configFilterModel->setFilterRole(ConfigModel::ItemIsAdvancedRole);
|
|
|
|
|
m_configFilterModel->setFilterFixedString("0");
|
|
|
|
|
|
|
|
|
|
m_configTextFilterModel->setSourceModel(m_configFilterModel);
|
|
|
|
|
m_configTextFilterModel->setSortRole(Qt::DisplayRole);
|
|
|
|
|
m_configTextFilterModel->setFilterKeyColumn(-1);
|
|
|
|
|
|
|
|
|
|
connect(m_configTextFilterModel, &QAbstractItemModel::layoutChanged, this, [this]() {
|
|
|
|
|
QModelIndex selectedIdx = m_configView->currentIndex();
|
|
|
|
|
if (selectedIdx.isValid())
|
|
|
|
|
m_configView->scrollTo(selectedIdx);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
m_configView->setModel(m_configTextFilterModel);
|
|
|
|
|
m_configView->setMinimumHeight(300);
|
|
|
|
|
m_configView->setUniformRowHeights(true);
|
|
|
|
|
m_configView->setSortingEnabled(true);
|
|
|
|
|
m_configView->sortByColumn(0, Qt::AscendingOrder);
|
2022-04-12 17:26:41 +02:00
|
|
|
(void) new HeaderViewStretcher(m_configView->header(), 0);
|
2021-02-12 16:15:26 +01:00
|
|
|
m_configView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
2022-02-02 22:11:47 +01:00
|
|
|
m_configView->setSelectionBehavior(QAbstractItemView::SelectItems);
|
2022-02-01 11:08:14 +01:00
|
|
|
m_configView->setAlternatingRowColors(true);
|
2021-02-12 16:15:26 +01:00
|
|
|
m_configView->setFrameShape(QFrame::NoFrame);
|
2022-05-02 18:02:37 +02:00
|
|
|
m_configView->setItemDelegate(new ConfigModelItemDelegate(bc->project()->projectDirectory(),
|
2021-02-12 16:15:26 +01:00
|
|
|
m_configView));
|
2021-12-23 17:11:41 +01:00
|
|
|
m_configView->setRootIsDecorated(false);
|
2021-02-12 16:15:26 +01:00
|
|
|
QFrame *findWrapper = Core::ItemViewFind::createSearchableWrapper(m_configView, Core::ItemViewFind::LightColored);
|
|
|
|
|
findWrapper->setFrameStyle(QFrame::StyledPanel);
|
|
|
|
|
|
|
|
|
|
m_progressIndicator = new ProgressIndicator(ProgressIndicatorSize::Large, findWrapper);
|
|
|
|
|
m_progressIndicator->attachToWidget(findWrapper);
|
|
|
|
|
m_progressIndicator->raise();
|
|
|
|
|
m_progressIndicator->hide();
|
|
|
|
|
m_showProgressTimer.setSingleShot(true);
|
|
|
|
|
m_showProgressTimer.setInterval(50); // don't show progress for < 50ms tasks
|
|
|
|
|
connect(&m_showProgressTimer, &QTimer::timeout, [this]() { m_progressIndicator->show(); });
|
|
|
|
|
|
|
|
|
|
m_addButton = new QPushButton(tr("&Add"));
|
|
|
|
|
m_addButton->setToolTip(tr("Add a new configuration value."));
|
2021-03-15 09:12:49 +01:00
|
|
|
auto addButtonMenu = new QMenu(this);
|
|
|
|
|
addButtonMenu->addAction(tr("&Boolean"))->setData(
|
|
|
|
|
QVariant::fromValue(static_cast<int>(ConfigModel::DataItem::BOOLEAN)));
|
|
|
|
|
addButtonMenu->addAction(tr("&String"))->setData(
|
|
|
|
|
QVariant::fromValue(static_cast<int>(ConfigModel::DataItem::STRING)));
|
|
|
|
|
addButtonMenu->addAction(tr("&Directory"))->setData(
|
|
|
|
|
QVariant::fromValue(static_cast<int>(ConfigModel::DataItem::DIRECTORY)));
|
|
|
|
|
addButtonMenu->addAction(tr("&File"))->setData(
|
|
|
|
|
QVariant::fromValue(static_cast<int>(ConfigModel::DataItem::FILE)));
|
|
|
|
|
m_addButton->setMenu(addButtonMenu);
|
|
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
m_editButton = new QPushButton(tr("&Edit"));
|
|
|
|
|
m_editButton->setToolTip(tr("Edit the current CMake configuration value."));
|
2021-03-15 09:12:49 +01:00
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
m_setButton = new QPushButton(tr("&Set"));
|
|
|
|
|
m_setButton->setToolTip(tr("Set a value in the CMake configuration."));
|
2021-03-15 09:12:49 +01:00
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
m_unsetButton = new QPushButton(tr("&Unset"));
|
|
|
|
|
m_unsetButton->setToolTip(tr("Unset a value in the CMake configuration."));
|
2021-03-15 09:12:49 +01:00
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
m_resetButton = new QPushButton(tr("&Reset"));
|
|
|
|
|
m_resetButton->setToolTip(tr("Reset all unapplied changes."));
|
|
|
|
|
m_resetButton->setEnabled(false);
|
2021-03-15 09:12:49 +01:00
|
|
|
|
2021-02-24 14:33:38 +01:00
|
|
|
m_batchEditButton = new QPushButton(tr("Batch Edit..."));
|
2022-02-16 18:00:07 +01:00
|
|
|
m_batchEditButton->setToolTip(tr("Set or reset multiple values in the CMake configuration."));
|
2021-02-12 16:15:26 +01:00
|
|
|
|
2021-03-15 09:12:49 +01:00
|
|
|
m_showAdvancedCheckBox = new QCheckBox(tr("Advanced"));
|
2021-02-12 16:15:26 +01:00
|
|
|
|
|
|
|
|
connect(m_configView->selectionModel(), &QItemSelectionModel::selectionChanged,
|
|
|
|
|
this, [this](const QItemSelection &, const QItemSelection &) {
|
|
|
|
|
updateSelection();
|
|
|
|
|
});
|
|
|
|
|
|
2021-12-28 21:42:29 +01:00
|
|
|
m_reconfigureButton = new QPushButton(tr("Run CMake"));
|
2021-02-12 16:15:26 +01:00
|
|
|
m_reconfigureButton->setEnabled(false);
|
2021-03-15 09:12:49 +01:00
|
|
|
|
2022-08-10 19:12:40 +02:00
|
|
|
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);
|
|
|
|
|
|
2021-03-15 09:12:49 +01:00
|
|
|
using namespace Layouting;
|
|
|
|
|
Grid cmakeConfiguration {
|
2022-07-22 18:54:04 +02:00
|
|
|
m_filterEdit, br,
|
2021-03-15 09:12:49 +01:00
|
|
|
findWrapper,
|
|
|
|
|
Column {
|
|
|
|
|
m_addButton,
|
|
|
|
|
m_editButton,
|
|
|
|
|
m_setButton,
|
|
|
|
|
m_unsetButton,
|
|
|
|
|
m_resetButton,
|
|
|
|
|
m_batchEditButton,
|
|
|
|
|
Space(10),
|
|
|
|
|
m_showAdvancedCheckBox,
|
2022-07-22 18:54:04 +02:00
|
|
|
st
|
2021-03-15 09:12:49 +01:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Column {
|
|
|
|
|
Form {
|
2021-03-23 10:38:16 +01:00
|
|
|
buildDirAspect,
|
|
|
|
|
bc->aspect<BuildTypeAspect>(),
|
2021-03-15 09:12:49 +01:00
|
|
|
qmlDebugAspect
|
|
|
|
|
},
|
|
|
|
|
m_warningMessageLabel,
|
2022-02-15 10:41:13 +01:00
|
|
|
m_kitConfiguration,
|
|
|
|
|
Column {
|
|
|
|
|
m_configurationStates,
|
|
|
|
|
Group {
|
2022-07-21 11:10:34 +02:00
|
|
|
Column {
|
|
|
|
|
cmakeConfiguration,
|
|
|
|
|
Row {
|
|
|
|
|
bc->aspect<InitialCMakeArgumentsAspect>(),
|
|
|
|
|
bc->aspect<AdditionalCMakeOptionsAspect>()
|
|
|
|
|
},
|
|
|
|
|
m_reconfigureButton,
|
|
|
|
|
}
|
2022-02-15 10:41:13 +01:00
|
|
|
}
|
|
|
|
|
}.setSpacing(0)
|
2022-07-26 11:35:19 +02:00
|
|
|
}.attachTo(details, WithoutMargins);
|
2021-02-12 16:15:26 +01:00
|
|
|
|
|
|
|
|
updateAdvancedCheckBox();
|
2022-05-02 18:02:37 +02:00
|
|
|
setError(m_buildSystem->error());
|
|
|
|
|
setWarning(m_buildSystem->warning());
|
2021-02-12 16:15:26 +01:00
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
connect(m_buildSystem, &BuildSystem::parsingStarted, this, [this] {
|
2021-02-12 16:15:26 +01:00
|
|
|
updateButtonState();
|
|
|
|
|
m_configView->setEnabled(false);
|
|
|
|
|
m_showProgressTimer.start();
|
|
|
|
|
});
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
m_configModel->setMacroExpander(bc->macroExpander());
|
2022-01-24 13:41:13 +01:00
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
if (m_buildSystem->isParsing())
|
2021-02-12 16:15:26 +01:00
|
|
|
m_showProgressTimer.start();
|
|
|
|
|
else {
|
2022-05-02 18:02:37 +02:00
|
|
|
m_configModel->setConfiguration(m_buildSystem->configurationFromCMake());
|
2021-12-28 21:42:29 +01:00
|
|
|
m_configModel->setInitialParametersConfiguration(
|
2022-05-02 18:02:37 +02:00
|
|
|
m_buildSystem->initialCMakeConfiguration());
|
2021-02-12 16:15:26 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
connect(m_buildSystem, &BuildSystem::parsingFinished, this, [this] {
|
CMake: Make QML debugging state reflect build system state
After parsing the CMake response, we make the configuration variables
table reflect the actual configuration in the build directory. It is one
of our "promises" that we do not break an existing build configuration,
to avoid unexpected rebuilds.
This was not quite true for the "QML debugging and profiling" setting.
When that setting and the actual build directory disagreed, the user
would get a dialog asking for running CMake with additional parameters,
and when running CMake via the button in projects mode or the menu, it
would just change these configuration parameters, potentially leading to
an unexpected complete rebuild of the application.
So, after parsing check if the actual CMake configuration matches our
QML debugging setting, and if not, change the setting to "Leave at
Default", to ensure that we don't mess with the build.
Fix the "Run CMake" button state (in the "Current Configuration") when
changing the QML debugging option, which should become bold, if the
CMake parameters change.
Amends 2577ce8ba1a69ad716c2fc2a5d0d5cc742c3c4cf and fixes the drawback
mentioned there, i.e. setting the build directory of a "Debug" build
configuration to an existing build directory with QML debugging
disabled, will now simply set the QML debugging option to "Leave at
Default" instead of forcing it to "Enabled".
Change-Id: Ie6d4875d59319687d94e44e459ca76038e5813c0
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
2022-06-07 10:18:34 +02:00
|
|
|
const CMakeConfig config = m_buildSystem->configurationFromCMake();
|
|
|
|
|
auto qmlDebugAspect = m_buildSystem->buildConfiguration()
|
|
|
|
|
->aspect<QtSupport::QmlDebuggingAspect>();
|
|
|
|
|
const TriState qmlDebugSetting = qmlDebugAspect->value();
|
|
|
|
|
bool qmlDebugConfig = CMakeBuildConfiguration::hasQmlDebugging(config);
|
|
|
|
|
if ((qmlDebugSetting == TriState::Enabled && !qmlDebugConfig)
|
|
|
|
|
|| (qmlDebugSetting == TriState::Disabled && qmlDebugConfig)) {
|
|
|
|
|
qmlDebugAspect->setValue(TriState::Default);
|
|
|
|
|
}
|
|
|
|
|
m_configModel->setConfiguration(config);
|
2021-12-28 21:42:29 +01:00
|
|
|
m_configModel->setInitialParametersConfiguration(
|
2022-05-02 18:02:37 +02:00
|
|
|
m_buildSystem->initialCMakeConfiguration());
|
|
|
|
|
m_buildSystem->filterConfigArgumentsFromAdditionalCMakeArguments();
|
2022-01-24 13:41:13 +01:00
|
|
|
updateFromKit();
|
2021-02-12 16:15:26 +01:00
|
|
|
m_configView->setEnabled(true);
|
|
|
|
|
updateButtonState();
|
|
|
|
|
m_showProgressTimer.stop();
|
|
|
|
|
m_progressIndicator->hide();
|
2021-12-28 21:42:29 +01:00
|
|
|
updateConfigurationStateSelection();
|
|
|
|
|
});
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
connect(m_buildSystem, &CMakeBuildSystem::configurationCleared, this, [this] {
|
2021-12-28 21:42:29 +01:00
|
|
|
updateConfigurationStateSelection();
|
2021-02-12 16:15:26 +01:00
|
|
|
});
|
2021-12-28 21:42:29 +01:00
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
connect(m_buildSystem, &CMakeBuildSystem::errorOccurred, this, [this] {
|
2021-02-12 16:15:26 +01:00
|
|
|
m_showProgressTimer.stop();
|
|
|
|
|
m_progressIndicator->hide();
|
2021-12-28 21:42:29 +01:00
|
|
|
updateConfigurationStateSelection();
|
2021-02-12 16:15:26 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
connect(m_configModel, &QAbstractItemModel::dataChanged,
|
|
|
|
|
this, &CMakeBuildSettingsWidget::updateButtonState);
|
|
|
|
|
connect(m_configModel, &QAbstractItemModel::modelReset,
|
|
|
|
|
this, &CMakeBuildSettingsWidget::updateButtonState);
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
connect(m_buildSystem->cmakeBuildConfiguration(),
|
2021-02-04 14:53:42 +01:00
|
|
|
&CMakeBuildConfiguration::signingFlagsChanged,
|
|
|
|
|
this,
|
|
|
|
|
&CMakeBuildSettingsWidget::updateButtonState);
|
|
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
connect(m_showAdvancedCheckBox, &QCheckBox::stateChanged,
|
|
|
|
|
this, &CMakeBuildSettingsWidget::updateAdvancedCheckBox);
|
|
|
|
|
|
|
|
|
|
connect(m_filterEdit,
|
|
|
|
|
&QLineEdit::textChanged,
|
|
|
|
|
m_configTextFilterModel,
|
|
|
|
|
[this](const QString &txt) {
|
|
|
|
|
m_configTextFilterModel->setFilterRegularExpression(
|
|
|
|
|
QRegularExpression(QRegularExpression::escape(txt),
|
|
|
|
|
QRegularExpression::CaseInsensitiveOption));
|
|
|
|
|
});
|
|
|
|
|
|
2021-12-28 21:42:29 +01:00
|
|
|
connect(m_resetButton, &QPushButton::clicked, this, [this](){
|
|
|
|
|
m_configModel->resetAllChanges(isInitialConfiguration());
|
|
|
|
|
});
|
2022-05-02 18:02:37 +02:00
|
|
|
connect(m_reconfigureButton, &QPushButton::clicked, this, [this] {
|
|
|
|
|
if (!m_buildSystem->isParsing()) {
|
2021-12-28 21:42:29 +01:00
|
|
|
if (isInitialConfiguration()) {
|
2022-05-02 18:02:37 +02:00
|
|
|
reconfigureWithInitialParameters();
|
2021-12-28 21:42:29 +01:00
|
|
|
} else {
|
2022-05-02 18:02:37 +02:00
|
|
|
m_buildSystem->runCMakeWithExtraArguments();
|
2021-12-28 21:42:29 +01:00
|
|
|
}
|
2021-12-22 15:18:00 +01:00
|
|
|
} else {
|
2022-05-02 18:02:37 +02:00
|
|
|
m_buildSystem->stopCMakeRun();
|
2021-12-22 15:18:00 +01:00
|
|
|
m_reconfigureButton->setEnabled(false);
|
|
|
|
|
}
|
2021-02-12 16:15:26 +01:00
|
|
|
});
|
2021-12-22 15:18:00 +01:00
|
|
|
connect(m_setButton, &QPushButton::clicked, this, [this]() { setVariableUnsetFlag(false); });
|
2021-02-12 16:15:26 +01:00
|
|
|
connect(m_unsetButton, &QPushButton::clicked, this, [this]() {
|
|
|
|
|
setVariableUnsetFlag(true);
|
|
|
|
|
});
|
|
|
|
|
connect(m_editButton, &QPushButton::clicked, this, [this]() {
|
|
|
|
|
QModelIndex idx = m_configView->currentIndex();
|
|
|
|
|
if (idx.column() != 1)
|
|
|
|
|
idx = idx.sibling(idx.row(), 1);
|
|
|
|
|
m_configView->setCurrentIndex(idx);
|
|
|
|
|
m_configView->edit(idx);
|
|
|
|
|
});
|
2021-03-15 09:12:49 +01:00
|
|
|
connect(addButtonMenu, &QMenu::triggered, this, [this](QAction *action) {
|
2021-02-12 16:15:26 +01:00
|
|
|
ConfigModel::DataItem::Type type =
|
|
|
|
|
static_cast<ConfigModel::DataItem::Type>(action->data().value<int>());
|
|
|
|
|
QString value = tr("<UNSET>");
|
|
|
|
|
if (type == ConfigModel::DataItem::BOOLEAN)
|
|
|
|
|
value = QString::fromLatin1("OFF");
|
|
|
|
|
|
2021-12-28 21:42:29 +01:00
|
|
|
m_configModel->appendConfiguration(tr("<UNSET>"), value, type, isInitialConfiguration());
|
2021-02-12 16:15:26 +01:00
|
|
|
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;
|
|
|
|
|
});
|
|
|
|
|
QModelIndex idx = m_configModel->indexForItem(item);
|
|
|
|
|
idx = m_configTextFilterModel->mapFromSource(m_configFilterModel->mapFromSource(idx));
|
|
|
|
|
m_configView->setFocus();
|
|
|
|
|
m_configView->scrollTo(idx);
|
|
|
|
|
m_configView->setCurrentIndex(idx);
|
|
|
|
|
m_configView->edit(idx);
|
|
|
|
|
});
|
2021-02-24 14:33:38 +01:00
|
|
|
connect(m_batchEditButton, &QAbstractButton::clicked,
|
|
|
|
|
this, &CMakeBuildSettingsWidget::batchEditConfiguration);
|
2021-02-12 16:15:26 +01:00
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
connect(m_buildSystem, &CMakeBuildSystem::errorOccurred,
|
2022-04-25 14:03:03 +02:00
|
|
|
this, &CMakeBuildSettingsWidget::setError);
|
2022-05-02 18:02:37 +02:00
|
|
|
connect(m_buildSystem, &CMakeBuildSystem::warningOccurred,
|
2022-04-25 14:03:03 +02:00
|
|
|
this, &CMakeBuildSettingsWidget::setWarning);
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
connect(m_buildSystem, &CMakeBuildSystem::configurationChanged,
|
2022-04-25 14:03:03 +02:00
|
|
|
m_configModel, &ConfigModel::setBatchEditConfiguration);
|
2021-02-12 16:15:26 +01:00
|
|
|
|
|
|
|
|
updateFromKit();
|
2022-05-02 18:02:37 +02:00
|
|
|
connect(m_buildSystem->target(), &Target::kitChanged,
|
2021-02-12 16:15:26 +01:00
|
|
|
this, &CMakeBuildSettingsWidget::updateFromKit);
|
2022-05-02 18:02:37 +02:00
|
|
|
connect(bc, &CMakeBuildConfiguration::enabledChanged, this, [this, bc] {
|
|
|
|
|
if (bc->isEnabled())
|
2021-03-22 11:56:38 +01:00
|
|
|
setError(QString());
|
2021-02-12 16:15:26 +01:00
|
|
|
});
|
2022-02-10 16:50:43 +01:00
|
|
|
connect(this, &QObject::destroyed, this, [this] {
|
2022-01-28 16:44:05 +01:00
|
|
|
updateInitialCMakeArguments();
|
|
|
|
|
});
|
2021-02-12 16:15:26 +01:00
|
|
|
|
2022-02-03 16:12:41 +01:00
|
|
|
connect(bc->aspect<InitialCMakeArgumentsAspect>(),
|
|
|
|
|
&Utils::BaseAspect::labelLinkActivated,
|
2022-02-04 16:57:34 +01:00
|
|
|
this,
|
2022-02-10 16:50:43 +01:00
|
|
|
[this](const QString &) {
|
2022-05-02 18:02:37 +02:00
|
|
|
const CMakeTool *tool = CMakeKitAspect::cmakeTool(m_buildSystem->kit());
|
2022-02-04 16:57:34 +01:00
|
|
|
CMakeTool::openCMakeHelpUrl(tool, "%1/manual/cmake.1.html#options");
|
|
|
|
|
});
|
2022-02-03 16:12:41 +01:00
|
|
|
connect(bc->aspect<AdditionalCMakeOptionsAspect>(),
|
2022-05-02 18:02:37 +02:00
|
|
|
&Utils::BaseAspect::labelLinkActivated, this, [this](const QString &) {
|
|
|
|
|
const CMakeTool *tool = CMakeKitAspect::cmakeTool(m_buildSystem->kit());
|
2022-02-04 16:57:34 +01:00
|
|
|
CMakeTool::openCMakeHelpUrl(tool, "%1/manual/cmake.1.html#options");
|
|
|
|
|
});
|
2022-02-03 16:12:41 +01:00
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
updateSelection();
|
2021-12-28 21:42:29 +01:00
|
|
|
updateConfigurationStateSelection();
|
2021-02-12 16:15:26 +01:00
|
|
|
}
|
|
|
|
|
|
2021-02-24 14:33:38 +01:00
|
|
|
void CMakeBuildSettingsWidget::batchEditConfiguration()
|
|
|
|
|
{
|
|
|
|
|
auto dialog = new QDialog(this);
|
|
|
|
|
dialog->setWindowTitle(tr("Edit CMake Configuration"));
|
|
|
|
|
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
|
dialog->setModal(true);
|
|
|
|
|
auto layout = new QVBoxLayout(dialog);
|
|
|
|
|
auto editor = new QPlainTextEdit(dialog);
|
|
|
|
|
|
|
|
|
|
auto label = new QLabel(dialog);
|
2022-02-03 16:52:50 +01:00
|
|
|
label->setText(tr("Enter one CMake <a href=\"variable\">variable</a> per line.<br/>"
|
|
|
|
|
"To set or change a variable, use -D<variable>:<type>=<value>.<br/>"
|
|
|
|
|
"<type> can have one of the following values: FILEPATH, PATH, BOOL, INTERNAL, or STRING.<br/>"
|
|
|
|
|
"To unset a variable, use -U<variable>.<br/>"));
|
2022-02-10 16:50:43 +01:00
|
|
|
connect(label, &QLabel::linkActivated, this, [this](const QString &) {
|
2022-05-02 18:02:37 +02:00
|
|
|
const CMakeTool *tool = CMakeKitAspect::cmakeTool(m_buildSystem->target()->kit());
|
2022-02-03 16:52:50 +01:00
|
|
|
CMakeTool::openCMakeHelpUrl(tool, "%1/manual/cmake-variables.7.html");
|
|
|
|
|
});
|
2021-02-24 14:33:38 +01:00
|
|
|
editor->setMinimumSize(800, 200);
|
|
|
|
|
|
|
|
|
|
auto chooser = new Utils::VariableChooser(dialog);
|
|
|
|
|
chooser->addSupportedWidget(editor);
|
2022-05-02 18:02:37 +02:00
|
|
|
chooser->addMacroExpanderProvider([this] { return m_buildSystem->buildConfiguration()->macroExpander(); });
|
2021-02-24 14:33:38 +01:00
|
|
|
|
|
|
|
|
auto buttons = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
|
|
|
|
|
|
|
|
|
|
layout->addWidget(editor);
|
|
|
|
|
layout->addWidget(label);
|
|
|
|
|
layout->addWidget(buttons);
|
|
|
|
|
|
|
|
|
|
connect(buttons, &QDialogButtonBox::accepted, dialog, &QDialog::accept);
|
|
|
|
|
connect(buttons, &QDialogButtonBox::rejected, dialog, &QDialog::reject);
|
|
|
|
|
connect(dialog, &QDialog::accepted, this, [=]{
|
2022-05-02 18:02:37 +02:00
|
|
|
const auto expander = m_buildSystem->buildConfiguration()->macroExpander();
|
2021-03-01 20:18:08 +01:00
|
|
|
|
|
|
|
|
const QStringList lines = editor->toPlainText().split('\n', Qt::SkipEmptyParts);
|
|
|
|
|
const QStringList expandedLines = Utils::transform(lines,
|
|
|
|
|
[expander](const QString &s) {
|
|
|
|
|
return expander->expand(s);
|
|
|
|
|
});
|
2021-12-28 21:42:29 +01:00
|
|
|
const bool isInitial = isInitialConfiguration();
|
2022-02-03 11:24:56 +01:00
|
|
|
QStringList unknownOptions;
|
2021-12-28 21:42:29 +01:00
|
|
|
CMakeConfig config = CMakeConfig::fromArguments(isInitial ? lines : expandedLines,
|
2022-02-03 11:24:56 +01:00
|
|
|
unknownOptions);
|
2021-12-28 21:42:29 +01:00
|
|
|
for (auto &ci : config)
|
|
|
|
|
ci.isInitial = isInitial;
|
2021-02-24 14:33:38 +01:00
|
|
|
|
|
|
|
|
m_configModel->setBatchEditConfiguration(config);
|
|
|
|
|
});
|
|
|
|
|
|
2021-12-28 21:42:29 +01:00
|
|
|
editor->setPlainText(
|
2022-05-02 18:02:37 +02:00
|
|
|
m_buildSystem->configurationChangesArguments(isInitialConfiguration())
|
2021-12-28 21:42:29 +01:00
|
|
|
.join('\n'));
|
2021-02-24 14:33:38 +01:00
|
|
|
|
|
|
|
|
dialog->show();
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
void CMakeBuildSettingsWidget::reconfigureWithInitialParameters()
|
2021-12-28 21:42:29 +01:00
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
m_buildSystem->clearCMakeCache();
|
2021-12-28 21:42:29 +01:00
|
|
|
|
|
|
|
|
updateInitialCMakeArguments();
|
|
|
|
|
|
|
|
|
|
if (ProjectExplorerPlugin::saveModifiedFiles())
|
2022-05-02 18:02:37 +02:00
|
|
|
m_buildSystem->runCMake();
|
2021-12-28 21:42:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CMakeBuildSettingsWidget::updateInitialCMakeArguments()
|
|
|
|
|
{
|
2022-05-02 18:02:37 +02:00
|
|
|
CMakeConfig initialList = m_buildSystem->initialCMakeConfiguration();
|
2021-12-28 21:42:29 +01:00
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
for (const CMakeConfigItem &ci : m_buildSystem->configurationChanges()) {
|
2021-12-28 21:42:29 +01:00
|
|
|
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);
|
2022-03-29 15:46:28 +02:00
|
|
|
} else if (!ci.key.isEmpty()) {
|
2021-12-28 21:42:29 +01:00
|
|
|
initialList.push_back(ci);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
auto bc = m_buildSystem->buildConfiguration();
|
|
|
|
|
bc->aspect<InitialCMakeArgumentsAspect>()->setCMakeConfiguration(initialList);
|
2021-12-28 21:42:29 +01:00
|
|
|
|
|
|
|
|
// 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
|
2022-05-02 18:02:37 +02:00
|
|
|
m_buildSystem->setAdditionalCMakeArguments(ProcessArgs::splitArgs(
|
|
|
|
|
bc->aspect<InitialCMakeArgumentsAspect>()->value()));
|
2021-12-28 21:42:29 +01:00
|
|
|
}
|
|
|
|
|
|
2022-01-29 15:03:54 +01:00
|
|
|
void CMakeBuildSettingsWidget::kitCMakeConfiguration()
|
|
|
|
|
{
|
2022-05-02 18:02:37 +02:00
|
|
|
m_buildSystem->kit()->blockNotification();
|
2022-01-29 15:03:54 +01:00
|
|
|
|
|
|
|
|
auto dialog = new QDialog(this);
|
|
|
|
|
dialog->setWindowTitle(tr("Kit CMake Configuration"));
|
|
|
|
|
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
|
dialog->setModal(true);
|
2022-02-08 14:58:01 +01:00
|
|
|
dialog->setSizeGripEnabled(true);
|
2022-05-02 18:02:37 +02:00
|
|
|
connect(dialog, &QDialog::finished, this, [this] {
|
|
|
|
|
m_buildSystem->kit()->unblockNotification();
|
2022-01-29 15:03:54 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
CMakeKitAspect kitAspect;
|
|
|
|
|
CMakeGeneratorKitAspect generatorAspect;
|
|
|
|
|
CMakeConfigurationKitAspect configurationKitAspect;
|
|
|
|
|
|
|
|
|
|
auto layout = new QGridLayout(dialog);
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
kitAspect.createConfigWidget(m_buildSystem->kit())
|
2022-01-29 15:03:54 +01:00
|
|
|
->addToLayoutWithLabel(layout->parentWidget());
|
2022-05-02 18:02:37 +02:00
|
|
|
generatorAspect.createConfigWidget(m_buildSystem->kit())
|
2022-01-29 15:03:54 +01:00
|
|
|
->addToLayoutWithLabel(layout->parentWidget());
|
2022-05-02 18:02:37 +02:00
|
|
|
configurationKitAspect.createConfigWidget(m_buildSystem->kit())
|
2022-01-29 15:03:54 +01:00
|
|
|
->addToLayoutWithLabel(layout->parentWidget());
|
|
|
|
|
|
|
|
|
|
layout->setColumnStretch(1, 1);
|
|
|
|
|
|
2022-02-08 14:58:01 +01:00
|
|
|
auto buttons = new QDialogButtonBox(QDialogButtonBox::Close);
|
|
|
|
|
connect(buttons, &QDialogButtonBox::clicked, dialog, &QDialog::close);
|
|
|
|
|
layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Maximum, QSizePolicy::MinimumExpanding),
|
|
|
|
|
4, 0);
|
|
|
|
|
layout->addWidget(buttons, 5, 0, 1, -1);
|
|
|
|
|
|
2022-01-29 15:03:54 +01:00
|
|
|
dialog->setMinimumWidth(400);
|
|
|
|
|
dialog->resize(800, 1);
|
|
|
|
|
dialog->show();
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-21 18:09:29 +02:00
|
|
|
void CMakeBuildSettingsWidget::updateConfigureDetailsWidgetsSummary(
|
|
|
|
|
const QStringList &configurationArguments)
|
|
|
|
|
{
|
|
|
|
|
ProjectExplorer::ProcessParameters params;
|
|
|
|
|
|
|
|
|
|
CommandLine cmd;
|
|
|
|
|
const CMakeTool *tool = CMakeKitAspect::cmakeTool(m_buildSystem->kit());
|
|
|
|
|
cmd.setExecutable(tool ? tool->cmakeExecutable() : "cmake");
|
|
|
|
|
|
|
|
|
|
const BuildConfiguration *bc = m_buildSystem->buildConfiguration();
|
|
|
|
|
const FilePath buildDirectory = bc ? bc->buildDirectory() : ".";
|
|
|
|
|
|
|
|
|
|
cmd.addArgs({"-S", m_buildSystem->projectDirectory().path()});
|
|
|
|
|
cmd.addArgs({"-B", buildDirectory.onDevice(cmd.executable()).path()});
|
|
|
|
|
cmd.addArgs(configurationArguments);
|
|
|
|
|
|
|
|
|
|
params.setCommandLine(cmd);
|
|
|
|
|
m_configureDetailsWidget->setSummaryText(params.summary(tr("Configure")));
|
|
|
|
|
m_configureDetailsWidget->setState(DetailsWidget::Expanded);
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
void CMakeBuildSettingsWidget::setError(const QString &message)
|
|
|
|
|
{
|
2022-05-02 18:02:37 +02:00
|
|
|
m_buildSystem->buildConfiguration()->buildDirectoryAspect()->setProblem(message);
|
2021-02-12 16:15:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CMakeBuildSettingsWidget::setWarning(const QString &message)
|
|
|
|
|
{
|
|
|
|
|
bool showWarning = !message.isEmpty();
|
|
|
|
|
m_warningMessageLabel->setVisible(showWarning);
|
|
|
|
|
m_warningMessageLabel->setText(message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CMakeBuildSettingsWidget::updateButtonState()
|
|
|
|
|
{
|
2022-05-02 18:02:37 +02:00
|
|
|
const bool isParsing = m_buildSystem->isParsing();
|
2021-02-12 16:15:26 +01:00
|
|
|
|
|
|
|
|
// Update extra data in buildconfiguration
|
|
|
|
|
const QList<ConfigModel::DataItem> changes = m_configModel->configurationForCMake();
|
|
|
|
|
|
|
|
|
|
const CMakeConfig configChanges
|
2021-02-04 14:53:42 +01:00
|
|
|
= getQmlDebugCxxFlags() + getSigningFlagsChanges()
|
|
|
|
|
+ Utils::transform(changes, [](const ConfigModel::DataItem &i) {
|
|
|
|
|
CMakeConfigItem ni;
|
|
|
|
|
ni.key = i.key.toUtf8();
|
|
|
|
|
ni.value = i.value.toUtf8();
|
|
|
|
|
ni.documentation = i.description.toUtf8();
|
|
|
|
|
ni.isAdvanced = i.isAdvanced;
|
2021-12-28 21:42:29 +01:00
|
|
|
ni.isInitial = i.isInitial;
|
2021-02-04 14:53:42 +01:00
|
|
|
ni.isUnset = i.isUnset;
|
|
|
|
|
ni.inCMakeCache = i.inCMakeCache;
|
|
|
|
|
ni.values = i.values;
|
|
|
|
|
switch (i.type) {
|
2022-02-07 17:01:09 +01:00
|
|
|
case ConfigModel::DataItem::BOOLEAN:
|
2021-02-04 14:53:42 +01:00
|
|
|
ni.type = CMakeConfigItem::BOOL;
|
|
|
|
|
break;
|
2022-02-07 17:01:09 +01:00
|
|
|
case ConfigModel::DataItem::FILE:
|
2021-02-04 14:53:42 +01:00
|
|
|
ni.type = CMakeConfigItem::FILEPATH;
|
|
|
|
|
break;
|
2022-02-07 17:01:09 +01:00
|
|
|
case ConfigModel::DataItem::DIRECTORY:
|
2021-02-04 14:53:42 +01:00
|
|
|
ni.type = CMakeConfigItem::PATH;
|
|
|
|
|
break;
|
2022-02-07 17:01:09 +01:00
|
|
|
case ConfigModel::DataItem::STRING:
|
2021-02-04 14:53:42 +01:00
|
|
|
ni.type = CMakeConfigItem::STRING;
|
|
|
|
|
break;
|
2022-02-07 17:01:09 +01:00
|
|
|
case ConfigModel::DataItem::UNKNOWN:
|
2021-02-04 14:53:42 +01:00
|
|
|
default:
|
2021-03-03 18:07:56 +01:00
|
|
|
ni.type = CMakeConfigItem::UNINITIALIZED;
|
2021-02-04 14:53:42 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return ni;
|
|
|
|
|
});
|
2021-02-12 16:15:26 +01:00
|
|
|
|
2021-12-28 21:42:29 +01:00
|
|
|
const bool isInitial = isInitialConfiguration();
|
|
|
|
|
m_resetButton->setEnabled(m_configModel->hasChanges(isInitial) && !isParsing);
|
2021-12-22 15:18:00 +01:00
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
BuildConfiguration *bc = m_buildSystem->buildConfiguration();
|
|
|
|
|
bc->aspect<InitialCMakeArgumentsAspect>()->setVisible(isInitialConfiguration());
|
|
|
|
|
bc->aspect<AdditionalCMakeOptionsAspect>()->setVisible(!isInitialConfiguration());
|
2021-12-28 21:42:29 +01:00
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
bc->aspect<InitialCMakeArgumentsAspect>()->setEnabled(!isParsing);
|
|
|
|
|
bc->aspect<AdditionalCMakeOptionsAspect>()->setEnabled(!isParsing);
|
2021-12-28 21:42:29 +01:00
|
|
|
|
|
|
|
|
// Update label and text boldness of the reconfigure button
|
|
|
|
|
QFont reconfigureButtonFont = m_reconfigureButton->font();
|
|
|
|
|
if (isParsing) {
|
2021-12-22 15:18:00 +01:00
|
|
|
m_reconfigureButton->setText(tr("Stop CMake"));
|
2021-12-28 21:42:29 +01:00
|
|
|
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"));
|
|
|
|
|
}
|
CMake: Make QML debugging state reflect build system state
After parsing the CMake response, we make the configuration variables
table reflect the actual configuration in the build directory. It is one
of our "promises" that we do not break an existing build configuration,
to avoid unexpected rebuilds.
This was not quite true for the "QML debugging and profiling" setting.
When that setting and the actual build directory disagreed, the user
would get a dialog asking for running CMake with additional parameters,
and when running CMake via the button in projects mode or the menu, it
would just change these configuration parameters, potentially leading to
an unexpected complete rebuild of the application.
So, after parsing check if the actual CMake configuration matches our
QML debugging setting, and if not, change the setting to "Leave at
Default", to ensure that we don't mess with the build.
Fix the "Run CMake" button state (in the "Current Configuration") when
changing the QML debugging option, which should become bold, if the
CMake parameters change.
Amends 2577ce8ba1a69ad716c2fc2a5d0d5cc742c3c4cf and fixes the drawback
mentioned there, i.e. setting the build directory of a "Debug" build
configuration to an existing build directory with QML debugging
disabled, will now simply set the QML debugging option to "Leave at
Default" instead of forcing it to "Enabled".
Change-Id: Ie6d4875d59319687d94e44e459ca76038e5813c0
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
2022-06-07 10:18:34 +02:00
|
|
|
reconfigureButtonFont.setBold(isInitial ? m_configModel->hasChanges(isInitial)
|
|
|
|
|
: !configChanges.isEmpty());
|
2021-12-28 21:42:29 +01:00
|
|
|
}
|
|
|
|
|
m_reconfigureButton->setFont(reconfigureButtonFont);
|
2021-12-22 15:18:00 +01:00
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
m_buildSystem->setConfigurationChanges(configChanges);
|
2021-12-28 21:42:29 +01:00
|
|
|
|
|
|
|
|
// Update the tooltip with the changes
|
2022-07-21 18:09:29 +02:00
|
|
|
const QStringList configurationArguments = m_buildSystem->configurationChangesArguments(
|
|
|
|
|
isInitialConfiguration());
|
|
|
|
|
m_reconfigureButton->setToolTip(configurationArguments.join('\n'));
|
|
|
|
|
updateConfigureDetailsWidgetsSummary(configurationArguments);
|
2021-02-12 16:15:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CMakeBuildSettingsWidget::updateAdvancedCheckBox()
|
|
|
|
|
{
|
|
|
|
|
if (m_showAdvancedCheckBox->isChecked()) {
|
2021-12-28 21:42:29 +01:00
|
|
|
m_configFilterModel->setFilterRole(ConfigModel::ItemIsAdvancedRole);
|
|
|
|
|
m_configFilterModel->setFilterRegularExpression("[01]");
|
2021-02-12 16:15:26 +01:00
|
|
|
|
|
|
|
|
} else {
|
2021-12-28 21:42:29 +01:00
|
|
|
m_configFilterModel->setFilterRole(ConfigModel::ItemIsAdvancedRole);
|
|
|
|
|
m_configFilterModel->setFilterFixedString("0");
|
2021-02-12 16:15:26 +01:00
|
|
|
}
|
2021-12-28 21:42:29 +01:00
|
|
|
updateButtonState();
|
2021-02-12 16:15:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CMakeBuildSettingsWidget::updateFromKit()
|
|
|
|
|
{
|
2022-05-02 18:02:37 +02:00
|
|
|
const Kit *k = m_buildSystem->kit();
|
2022-02-08 20:40:22 +01:00
|
|
|
CMakeConfig config = CMakeConfigurationKitAspect::configuration(k);
|
|
|
|
|
|
|
|
|
|
config.append(CMakeGeneratorKitAspect::generatorCMakeConfig(k));
|
2021-02-12 16:15:26 +01:00
|
|
|
|
2022-02-01 16:37:52 +01:00
|
|
|
// First the key value parameters
|
2021-12-28 21:42:29 +01:00
|
|
|
ConfigModel::KitConfiguration configHash;
|
2021-02-12 16:15:26 +01:00
|
|
|
for (const CMakeConfigItem &i : config)
|
2022-02-01 16:37:52 +01:00
|
|
|
configHash.insert(QString::fromUtf8(i.key), i);
|
2021-02-12 16:15:26 +01:00
|
|
|
|
|
|
|
|
m_configModel->setConfigurationFromKit(configHash);
|
2022-02-01 16:37:52 +01:00
|
|
|
|
|
|
|
|
// Then the additional parameters
|
|
|
|
|
const QStringList additionalKitCMake = ProcessArgs::splitArgs(
|
|
|
|
|
CMakeConfigurationKitAspect::additionalConfiguration(k));
|
|
|
|
|
const QStringList additionalInitialCMake = ProcessArgs::splitArgs(
|
2022-05-02 18:02:37 +02:00
|
|
|
m_buildSystem->buildConfiguration()->aspect<InitialCMakeArgumentsAspect>()->value());
|
2022-02-01 16:37:52 +01:00
|
|
|
|
|
|
|
|
QStringList mergedArgumentList;
|
|
|
|
|
std::set_union(additionalInitialCMake.begin(),
|
|
|
|
|
additionalInitialCMake.end(),
|
|
|
|
|
additionalKitCMake.begin(),
|
|
|
|
|
additionalKitCMake.end(),
|
|
|
|
|
std::back_inserter(mergedArgumentList));
|
2022-05-02 18:02:37 +02:00
|
|
|
m_buildSystem->buildConfiguration()->aspect<InitialCMakeArgumentsAspect>()->setValue(
|
2022-02-01 16:37:52 +01:00
|
|
|
ProcessArgs::joinArgs(mergedArgumentList));
|
2021-02-12 16:15:26 +01:00
|
|
|
}
|
|
|
|
|
|
2021-12-28 21:42:29 +01:00
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
CMakeConfig CMakeBuildSettingsWidget::getQmlDebugCxxFlags()
|
|
|
|
|
{
|
2022-05-02 18:02:37 +02:00
|
|
|
const auto aspect = m_buildSystem->buildConfiguration()->aspect<QtSupport::QmlDebuggingAspect>();
|
2021-02-22 07:41:51 +01:00
|
|
|
const TriState qmlDebuggingState = aspect->value();
|
2021-02-12 16:15:26 +01:00
|
|
|
if (qmlDebuggingState == TriState::Default) // don't touch anything
|
|
|
|
|
return {};
|
2021-02-22 07:41:51 +01:00
|
|
|
const bool enable = aspect->value() == TriState::Enabled;
|
2021-02-12 16:15:26 +01:00
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
const CMakeConfig configList = m_buildSystem->configurationFromCMake();
|
2022-05-18 11:56:01 +02:00
|
|
|
const QByteArrayList cxxFlagsPrev{"CMAKE_CXX_FLAGS",
|
|
|
|
|
"CMAKE_CXX_FLAGS_DEBUG",
|
|
|
|
|
"CMAKE_CXX_FLAGS_RELWITHDEBINFO",
|
|
|
|
|
"CMAKE_CXX_FLAGS_INIT"};
|
|
|
|
|
const QByteArrayList cxxFlags{"CMAKE_CXX_FLAGS_INIT", "CMAKE_CXX_FLAGS"};
|
2021-02-12 16:15:26 +01:00
|
|
|
const QByteArray qmlDebug("-DQT_QML_DEBUG");
|
|
|
|
|
|
|
|
|
|
CMakeConfig changedConfig;
|
|
|
|
|
|
2022-05-18 11:56:01 +02:00
|
|
|
if (enable) {
|
|
|
|
|
const FilePath cmakeCache = m_buildSystem->cmakeBuildConfiguration()->buildDirectory().pathAppended("CMakeCache.txt");
|
2021-02-12 16:15:26 +01:00
|
|
|
|
2022-05-18 11:56:01 +02:00
|
|
|
// Only modify the CMAKE_CXX_FLAGS variable if the project was previously configured
|
|
|
|
|
// otherwise CMAKE_CXX_FLAGS_INIT will take care of setting the qmlDebug define
|
|
|
|
|
if (cmakeCache.exists()) {
|
|
|
|
|
for (const CMakeConfigItem &item : configList) {
|
|
|
|
|
if (!cxxFlags.contains(item.key))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
CMakeConfigItem it(item);
|
|
|
|
|
if (!it.value.contains(qmlDebug)) {
|
|
|
|
|
it.value = it.value.append(' ').append(qmlDebug).trimmed();
|
|
|
|
|
changedConfig.append(it);
|
|
|
|
|
}
|
2021-02-12 16:15:26 +01:00
|
|
|
}
|
2022-05-18 11:56:01 +02:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Remove -DQT_QML_DEBUG from all configurations, potentially set by previous Qt Creator versions
|
|
|
|
|
for (const CMakeConfigItem &item : configList) {
|
|
|
|
|
if (!cxxFlagsPrev.contains(item.key))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
CMakeConfigItem it(item);
|
2021-02-12 16:15:26 +01:00
|
|
|
int index = it.value.indexOf(qmlDebug);
|
|
|
|
|
if (index != -1) {
|
|
|
|
|
it.value.remove(index, qmlDebug.length());
|
|
|
|
|
it.value = it.value.trimmed();
|
|
|
|
|
changedConfig.append(it);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return changedConfig;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-04 14:53:42 +01:00
|
|
|
CMakeConfig CMakeBuildSettingsWidget::getSigningFlagsChanges()
|
|
|
|
|
{
|
2022-05-02 18:02:37 +02:00
|
|
|
const CMakeConfig flags = m_buildSystem->cmakeBuildConfiguration()->signingFlags();
|
2021-02-04 14:53:42 +01:00
|
|
|
if (flags.isEmpty())
|
|
|
|
|
return {};
|
2022-05-02 18:02:37 +02:00
|
|
|
const CMakeConfig configList = m_buildSystem->configurationFromCMake();
|
2021-02-04 14:53:42 +01:00
|
|
|
if (configList.isEmpty()) {
|
|
|
|
|
// we don't have any configuration --> initial configuration takes care of this itself
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
CMakeConfig changedConfig;
|
|
|
|
|
for (const CMakeConfigItem &signingFlag : flags) {
|
|
|
|
|
const CMakeConfigItem existingFlag = Utils::findOrDefault(configList,
|
|
|
|
|
Utils::equal(&CMakeConfigItem::key,
|
|
|
|
|
signingFlag.key));
|
|
|
|
|
const bool notInConfig = existingFlag.key.isEmpty();
|
|
|
|
|
if (notInConfig != signingFlag.isUnset || existingFlag.value != signingFlag.value)
|
|
|
|
|
changedConfig.append(signingFlag);
|
|
|
|
|
}
|
|
|
|
|
return changedConfig;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
void CMakeBuildSettingsWidget::updateSelection()
|
|
|
|
|
{
|
|
|
|
|
const QModelIndexList selectedIndexes = m_configView->selectionModel()->selectedIndexes();
|
|
|
|
|
unsigned int setableCount = 0;
|
|
|
|
|
unsigned int unsetableCount = 0;
|
|
|
|
|
unsigned int editableCount = 0;
|
|
|
|
|
|
|
|
|
|
for (const QModelIndex &index : selectedIndexes) {
|
|
|
|
|
if (index.isValid() && index.flags().testFlag(Qt::ItemIsSelectable)) {
|
|
|
|
|
const ConfigModel::DataItem di = ConfigModel::dataItemFromIndex(index);
|
|
|
|
|
if (di.isUnset)
|
|
|
|
|
setableCount++;
|
|
|
|
|
else
|
|
|
|
|
unsetableCount++;
|
|
|
|
|
}
|
|
|
|
|
if (index.isValid() && index.flags().testFlag(Qt::ItemIsEditable))
|
|
|
|
|
editableCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_setButton->setEnabled(setableCount > 0);
|
|
|
|
|
m_unsetButton->setEnabled(unsetableCount > 0);
|
|
|
|
|
m_editButton->setEnabled(editableCount == 1);
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-28 21:42:29 +01:00
|
|
|
void CMakeBuildSettingsWidget::updateConfigurationStateSelection()
|
|
|
|
|
{
|
|
|
|
|
const bool hasReplyFile
|
2022-05-02 18:02:37 +02:00
|
|
|
= FileApiParser::scanForCMakeReplyFile(
|
|
|
|
|
m_buildSystem->buildConfiguration()->buildDirectory()).exists();
|
2021-12-28 21:42:29 +01:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
void CMakeBuildSettingsWidget::setVariableUnsetFlag(bool unsetFlag)
|
|
|
|
|
{
|
|
|
|
|
const QModelIndexList selectedIndexes = m_configView->selectionModel()->selectedIndexes();
|
|
|
|
|
bool unsetFlagToggled = false;
|
|
|
|
|
for (const QModelIndex &index : selectedIndexes) {
|
|
|
|
|
if (index.isValid()) {
|
|
|
|
|
const ConfigModel::DataItem di = ConfigModel::dataItemFromIndex(index);
|
|
|
|
|
if (di.isUnset != unsetFlag) {
|
|
|
|
|
m_configModel->toggleUnsetFlag(mapToSource(m_configView, index));
|
|
|
|
|
unsetFlagToggled = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (unsetFlagToggled)
|
|
|
|
|
updateSelection();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QAction *CMakeBuildSettingsWidget::createForceAction(int type, const QModelIndex &idx)
|
|
|
|
|
{
|
|
|
|
|
auto t = static_cast<ConfigModel::DataItem::Type>(type);
|
|
|
|
|
QString typeString;
|
|
|
|
|
switch (type) {
|
|
|
|
|
case ConfigModel::DataItem::BOOLEAN:
|
|
|
|
|
typeString = tr("bool", "display string for cmake type BOOLEAN");
|
|
|
|
|
break;
|
|
|
|
|
case ConfigModel::DataItem::FILE:
|
|
|
|
|
typeString = tr("file", "display string for cmake type FILE");
|
|
|
|
|
break;
|
|
|
|
|
case ConfigModel::DataItem::DIRECTORY:
|
|
|
|
|
typeString = tr("directory", "display string for cmake type DIRECTORY");
|
|
|
|
|
break;
|
|
|
|
|
case ConfigModel::DataItem::STRING:
|
|
|
|
|
typeString = tr("string", "display string for cmake type STRING");
|
|
|
|
|
break;
|
|
|
|
|
case ConfigModel::DataItem::UNKNOWN:
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
QAction *forceAction = new QAction(tr("Force to %1").arg(typeString), nullptr);
|
|
|
|
|
forceAction->setEnabled(m_configModel->canForceTo(idx, t));
|
|
|
|
|
connect(forceAction, &QAction::triggered,
|
|
|
|
|
this, [this, idx, t]() { m_configModel->forceTo(idx, t); });
|
|
|
|
|
return forceAction;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CMakeBuildSettingsWidget::eventFilter(QObject *target, QEvent *event)
|
|
|
|
|
{
|
|
|
|
|
// handle context menu events:
|
|
|
|
|
if (target != m_configView->viewport() || event->type() != QEvent::ContextMenu)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
auto e = static_cast<QContextMenuEvent *>(event);
|
|
|
|
|
const QModelIndex idx = mapToSource(m_configView, m_configView->indexAt(e->pos()));
|
|
|
|
|
if (!idx.isValid())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
auto menu = new QMenu(this);
|
|
|
|
|
connect(menu, &QMenu::triggered, menu, &QMenu::deleteLater);
|
|
|
|
|
|
2022-02-04 16:25:58 +01:00
|
|
|
auto help = new QAction(tr("Help"), this);
|
|
|
|
|
menu->addAction(help);
|
|
|
|
|
connect(help, &QAction::triggered, this, [=] {
|
|
|
|
|
const CMakeConfigItem item = ConfigModel::dataItemFromIndex(idx).toCMakeConfigItem();
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
const CMakeTool *tool = CMakeKitAspect::cmakeTool(m_buildSystem->target()->kit());
|
2022-02-04 16:25:58 +01:00
|
|
|
const QString linkUrl = "%1/variable/" + QString::fromUtf8(item.key) + ".html";
|
|
|
|
|
CMakeTool::openCMakeHelpUrl(tool, linkUrl);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
menu->addSeparator();
|
|
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
QAction *action = nullptr;
|
|
|
|
|
if ((action = createForceAction(ConfigModel::DataItem::BOOLEAN, idx)))
|
|
|
|
|
menu->addAction(action);
|
|
|
|
|
if ((action = createForceAction(ConfigModel::DataItem::FILE, idx)))
|
|
|
|
|
menu->addAction(action);
|
|
|
|
|
if ((action = createForceAction(ConfigModel::DataItem::DIRECTORY, idx)))
|
|
|
|
|
menu->addAction(action);
|
|
|
|
|
if ((action = createForceAction(ConfigModel::DataItem::STRING, idx)))
|
|
|
|
|
menu->addAction(action);
|
|
|
|
|
|
2022-01-28 18:16:23 +01:00
|
|
|
menu->addSeparator();
|
|
|
|
|
|
|
|
|
|
auto applyKitOrInitialValue = new QAction(isInitialConfiguration()
|
|
|
|
|
? tr("Apply Kit Value")
|
|
|
|
|
: tr("Apply Initial Configuration Value"),
|
|
|
|
|
this);
|
|
|
|
|
menu->addAction(applyKitOrInitialValue);
|
|
|
|
|
connect(applyKitOrInitialValue, &QAction::triggered, this, [this] {
|
|
|
|
|
const QModelIndexList selectedIndexes = m_configView->selectionModel()->selectedIndexes();
|
|
|
|
|
|
|
|
|
|
const QModelIndexList validIndexes = Utils::filtered(selectedIndexes, [](const QModelIndex &index) {
|
|
|
|
|
return index.isValid() && index.flags().testFlag(Qt::ItemIsSelectable);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
for (const QModelIndex &index : validIndexes) {
|
|
|
|
|
if (isInitialConfiguration())
|
|
|
|
|
m_configModel->applyKitValue(mapToSource(m_configView, index));
|
|
|
|
|
else
|
|
|
|
|
m_configModel->applyInitialValue(mapToSource(m_configView, index));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
menu->addSeparator();
|
|
|
|
|
|
2021-02-25 15:21:01 +01:00
|
|
|
auto copy = new QAction(tr("Copy"), this);
|
|
|
|
|
menu->addAction(copy);
|
|
|
|
|
connect(copy, &QAction::triggered, this, [this] {
|
|
|
|
|
const QModelIndexList selectedIndexes = m_configView->selectionModel()->selectedIndexes();
|
|
|
|
|
|
|
|
|
|
const QModelIndexList validIndexes = Utils::filtered(selectedIndexes, [](const QModelIndex &index) {
|
|
|
|
|
return index.isValid() && index.flags().testFlag(Qt::ItemIsSelectable);
|
|
|
|
|
});
|
|
|
|
|
|
2021-12-28 21:42:29 +01:00
|
|
|
const QStringList variableList
|
|
|
|
|
= Utils::transform(validIndexes, [this](const QModelIndex &index) {
|
|
|
|
|
return ConfigModel::dataItemFromIndex(index).toCMakeConfigItem().toArgument(
|
2022-05-02 18:02:37 +02:00
|
|
|
isInitialConfiguration() ? nullptr
|
|
|
|
|
: m_buildSystem->buildConfiguration()->macroExpander());
|
2021-12-28 21:42:29 +01:00
|
|
|
});
|
2021-02-25 15:21:01 +01:00
|
|
|
|
2022-07-14 15:44:58 +02:00
|
|
|
setClipboardAndSelection(variableList.join('\n'));
|
2021-02-25 15:21:01 +01:00
|
|
|
});
|
|
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
menu->move(e->globalPos());
|
|
|
|
|
menu->show();
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2020-04-02 14:49:05 +02:00
|
|
|
|
2021-03-23 18:33:42 +01:00
|
|
|
static bool isWebAssembly(const Kit *k)
|
|
|
|
|
{
|
|
|
|
|
return DeviceTypeKitAspect::deviceTypeId(k) == WebAssembly::Constants::WEBASSEMBLY_DEVICE_TYPE;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-17 20:03:09 +02:00
|
|
|
static bool isQnx(const Kit *k)
|
|
|
|
|
{
|
|
|
|
|
return DeviceTypeKitAspect::deviceTypeId(k) == Qnx::Constants::QNX_QNX_OS_TYPE;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-01 13:46:58 +01:00
|
|
|
static bool isWindowsARM64(const Kit *k)
|
|
|
|
|
{
|
2022-01-21 08:23:13 +01:00
|
|
|
ToolChain *toolchain = ToolChainKitAspect::cxxToolChain(k);
|
2022-02-08 11:16:21 +01:00
|
|
|
if (!toolchain)
|
|
|
|
|
return false;
|
2022-01-21 08:23:13 +01:00
|
|
|
const Abi targetAbi = toolchain->targetAbi();
|
2021-12-01 13:46:58 +01:00
|
|
|
return targetAbi.os() == Abi::WindowsOS && targetAbi.architecture() == Abi::ArmArchitecture
|
2022-02-11 10:49:15 +01:00
|
|
|
&& targetAbi.wordWidth() == 64;
|
2021-12-01 13:46:58 +01:00
|
|
|
}
|
|
|
|
|
|
2022-01-26 11:21:00 +01:00
|
|
|
static CommandLine defaultInitialCMakeCommand(const Kit *k, const QString buildType)
|
2020-04-02 14:49:05 +02:00
|
|
|
{
|
|
|
|
|
// Generator:
|
2022-01-26 11:21:00 +01:00
|
|
|
CMakeTool *tool = CMakeKitAspect::cmakeTool(k);
|
|
|
|
|
QTC_ASSERT(tool, return {});
|
|
|
|
|
|
|
|
|
|
CommandLine cmd{tool->cmakeExecutable()};
|
|
|
|
|
cmd.addArgs(CMakeGeneratorKitAspect::generatorArguments(k));
|
2020-04-02 14:49:05 +02:00
|
|
|
|
|
|
|
|
// CMAKE_BUILD_TYPE:
|
2022-01-26 11:21:00 +01:00
|
|
|
if (!buildType.isEmpty() && !CMakeGeneratorKitAspect::isMultiConfigGenerator(k))
|
|
|
|
|
cmd.addArg("-DCMAKE_BUILD_TYPE:STRING=" + buildType);
|
2020-04-02 14:49:05 +02:00
|
|
|
|
2021-02-18 18:50:11 +01:00
|
|
|
Internal::CMakeSpecificSettings *settings
|
|
|
|
|
= Internal::CMakeProjectPlugin::projectTypeSpecificSettings();
|
|
|
|
|
|
2022-06-29 11:07:20 +02:00
|
|
|
// Package manager auto setup. The file auto-setup.cmake resides on the host,
|
|
|
|
|
// so it's not accessible for remotely running cmakes. We need to exclude that case.
|
|
|
|
|
if (!cmd.executable().needsDevice() && settings->packageManagerAutoSetup.value()) {
|
2022-02-07 13:09:21 +01:00
|
|
|
cmd.addArg("-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH="
|
2022-01-26 11:21:00 +01:00
|
|
|
"%{IDE:ResourcePath}/package-manager/auto-setup.cmake");
|
|
|
|
|
}
|
2021-02-18 18:50:11 +01:00
|
|
|
|
2020-04-02 14:49:05 +02:00
|
|
|
// Cross-compilation settings:
|
CMake: iOS: Enable automatic provisioning updates
By default xcodebuild does not try create / download a provisioning
profile for a project if a valid one does not exist locally
in ~/Library/MobileDevice/Provisioning Profiles, even if the
Xcode CODE_SIGN_STYLE attribute is set to Automatic.
Starting with Xcode 9, xcodebuild accepts a new
-allowProvisioningUpdates option.
When passed, xcodebuild will request a new provisioning profile
from Apple's servers for the current project and use it during
the build. The provisioning profile is only needed when building
for a real device, not the simulator.
When building an iOS project with qmake, the option is embedded in the
wrapping Makefile generated by qmake, so Qt Creator can simply call
make (which it does).
For CMake, there is no wrapping Makefile, so we need to pass the new
option explicitly as an additional build tool argument.
There might be cases where automatic provisioning is not desired,
which is why there is now a new checkbox in the CMake build step
configuration widget. It's default value is 'enabled', to match
qmake's behavior.
As an implementation detail, isiOS had to be moved to a header file so
it's accessible to both the build configuration and the build step.
Fixes: QTCREATORBUG-26246
Change-Id: Ic80cd965ba095d0ff379e13ad2ffb8c298c9f7c4
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
2022-05-05 16:26:11 +02:00
|
|
|
if (!CMakeBuildConfiguration::isIos(k)) { // iOS handles this differently
|
2021-06-16 18:15:02 +02:00
|
|
|
const QString sysRoot = SysRootKitAspect::sysRoot(k).path();
|
2021-02-02 16:10:45 +01:00
|
|
|
if (!sysRoot.isEmpty()) {
|
2022-03-31 17:43:25 +02:00
|
|
|
cmd.addArg("-DCMAKE_SYSROOT:PATH=" + sysRoot);
|
2021-02-02 16:10:45 +01:00
|
|
|
if (ToolChain *tc = ToolChainKitAspect::cxxToolChain(k)) {
|
|
|
|
|
const QString targetTriple = tc->originalTargetTriple();
|
2022-01-26 11:21:00 +01:00
|
|
|
cmd.addArg("-DCMAKE_C_COMPILER_TARGET:STRING=" + targetTriple);
|
2022-03-31 09:54:11 +03:00
|
|
|
cmd.addArg("-DCMAKE_CXX_COMPILER_TARGET:STRING=" + targetTriple);
|
2021-02-02 16:10:45 +01:00
|
|
|
}
|
2020-04-02 14:49:05 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-26 11:21:00 +01:00
|
|
|
cmd.addArgs(CMakeConfigurationKitAspect::toArgumentsList(k));
|
|
|
|
|
cmd.addArgs(CMakeConfigurationKitAspect::additionalConfiguration(k), CommandLine::Raw);
|
2020-04-02 14:49:05 +02:00
|
|
|
|
2022-01-26 11:21:00 +01:00
|
|
|
return cmd;
|
2020-04-02 14:49:05 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-30 19:04:54 +02:00
|
|
|
static void addCMakeConfigurePresetToInitialArguments(QStringList &initialArguments,
|
|
|
|
|
const CMakeProject *project,
|
|
|
|
|
const Kit *k,
|
|
|
|
|
const Utils::Environment &env)
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const CMakeConfigItem presetItem = CMakeConfigurationKitAspect::cmakePresetConfigItem(k);
|
|
|
|
|
if (presetItem.isNull())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// Remove the -DQTC_CMAKE_PRESET argument, which is only used as a kit marker
|
|
|
|
|
const QString presetArgument = presetItem.toArgument();
|
|
|
|
|
const QString presetName = presetItem.expandedValue(k);
|
|
|
|
|
initialArguments.removeIf(
|
|
|
|
|
[presetArgument](const QString &item) { return item == presetArgument; });
|
|
|
|
|
|
|
|
|
|
PresetsDetails::ConfigurePreset configurePreset
|
|
|
|
|
= Utils::findOrDefault(project->presetsData().configurePresets,
|
|
|
|
|
[presetName](const PresetsDetails::ConfigurePreset &preset) {
|
|
|
|
|
return preset.name == presetName;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Add the command line arguments
|
|
|
|
|
if (configurePreset.warnings) {
|
|
|
|
|
if (configurePreset.warnings.value().dev) {
|
|
|
|
|
bool value = configurePreset.warnings.value().dev.value();
|
|
|
|
|
initialArguments.append(value ? QString("-Wdev") : QString("-Wno-dev"));
|
|
|
|
|
}
|
|
|
|
|
if (configurePreset.warnings.value().deprecated) {
|
|
|
|
|
bool value = configurePreset.warnings.value().deprecated.value();
|
|
|
|
|
initialArguments.append(value ? QString("-Wdeprecated") : QString("-Wno-deprecated"));
|
|
|
|
|
}
|
|
|
|
|
if (configurePreset.warnings.value().uninitialized
|
|
|
|
|
&& configurePreset.warnings.value().uninitialized.value())
|
|
|
|
|
initialArguments.append("--warn-uninitialized");
|
|
|
|
|
if (configurePreset.warnings.value().unusedCli
|
|
|
|
|
&& !configurePreset.warnings.value().unusedCli.value())
|
|
|
|
|
initialArguments.append(" --no-warn-unused-cli");
|
|
|
|
|
if (configurePreset.warnings.value().systemVars
|
|
|
|
|
&& configurePreset.warnings.value().systemVars.value())
|
|
|
|
|
initialArguments.append("--check-system-vars");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (configurePreset.errors) {
|
|
|
|
|
if (configurePreset.errors.value().dev) {
|
|
|
|
|
bool value = configurePreset.errors.value().dev.value();
|
|
|
|
|
initialArguments.append(value ? QString("-Werror=dev") : QString("-Wno-error=dev"));
|
|
|
|
|
}
|
|
|
|
|
if (configurePreset.errors.value().deprecated) {
|
|
|
|
|
bool value = configurePreset.errors.value().deprecated.value();
|
|
|
|
|
initialArguments.append(value ? QString("-Werror=deprecated")
|
|
|
|
|
: QString("-Wno-error=deprecated"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (configurePreset.debug) {
|
|
|
|
|
if (configurePreset.debug.value().find && configurePreset.debug.value().find.value())
|
|
|
|
|
initialArguments.append("--debug-find");
|
|
|
|
|
if (configurePreset.debug.value().tryCompile
|
|
|
|
|
&& configurePreset.debug.value().tryCompile.value())
|
|
|
|
|
initialArguments.append("--debug-trycompile");
|
|
|
|
|
if (configurePreset.debug.value().output && configurePreset.debug.value().output.value())
|
|
|
|
|
initialArguments.append("--debug-output");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Merge the presets cache variables
|
|
|
|
|
CMakeConfig cache;
|
|
|
|
|
if (configurePreset.cacheVariables)
|
|
|
|
|
cache = configurePreset.cacheVariables.value();
|
|
|
|
|
|
|
|
|
|
for (const CMakeConfigItem &presetItemRaw : cache) {
|
|
|
|
|
|
|
|
|
|
// Expand the CMakePresets Macros
|
|
|
|
|
CMakeConfigItem presetItem(presetItemRaw);
|
|
|
|
|
|
|
|
|
|
QString presetItemValue = QString::fromUtf8(presetItem.value);
|
|
|
|
|
CMakePresets::Macros::expand(configurePreset, env, project->projectDirectory(), presetItemValue);
|
|
|
|
|
presetItem.value = presetItemValue.toUtf8();
|
|
|
|
|
|
|
|
|
|
const QString presetItemArg = presetItem.toArgument();
|
|
|
|
|
const QString presetItemArgNoType = presetItemArg.left(presetItemArg.indexOf(":"));
|
|
|
|
|
|
|
|
|
|
auto it = std::find_if(initialArguments.begin(),
|
|
|
|
|
initialArguments.end(),
|
|
|
|
|
[presetItemArgNoType](const QString &arg) {
|
|
|
|
|
return arg.startsWith(presetItemArgNoType);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (it != initialArguments.end()) {
|
|
|
|
|
QString &arg = *it;
|
|
|
|
|
CMakeConfigItem argItem = CMakeConfigItem::fromString(arg.mid(2)); // skip -D
|
|
|
|
|
|
|
|
|
|
// For multi value path variables append the non Qt path
|
|
|
|
|
if (argItem.key == "CMAKE_PREFIX_PATH" || argItem.key == "CMAKE_FIND_ROOT_PATH") {
|
|
|
|
|
QStringList presetValueList = presetItem.expandedValue(k).split(";");
|
|
|
|
|
|
|
|
|
|
// Remove the expanded Qt path from the presets values
|
|
|
|
|
QString argItemExpandedValue = argItem.expandedValue(k);
|
|
|
|
|
presetValueList.removeIf([argItemExpandedValue](const QString &presetPath) {
|
|
|
|
|
QStringList argItemPaths = argItemExpandedValue.split(";");
|
|
|
|
|
for (const QString &argPath : argItemPaths) {
|
|
|
|
|
const FilePath argFilePath = FilePath::fromString(argPath);
|
|
|
|
|
const FilePath presetFilePath = FilePath::fromString(presetPath);
|
|
|
|
|
|
|
|
|
|
if (argFilePath == presetFilePath)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Add the presets values to the final argument
|
|
|
|
|
for (const QString &presetPath : presetValueList) {
|
|
|
|
|
argItem.value.append(";");
|
|
|
|
|
argItem.value.append(presetPath.toUtf8());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
arg = argItem.toArgument();
|
|
|
|
|
} else if (argItem.key == "CMAKE_C_COMPILER" || argItem.key == "CMAKE_CXX_COMPILER"
|
|
|
|
|
|| argItem.key == "QT_QMAKE_EXECUTABLE" || argItem.key == "QT_HOST_PATH"
|
|
|
|
|
|| argItem.key == "CMAKE_PROJECT_INCLUDE_BEFORE"
|
|
|
|
|
|| argItem.key == "CMAKE_TOOLCHAIN_FILE") {
|
|
|
|
|
const FilePath argFilePath = FilePath::fromString(argItem.expandedValue(k));
|
|
|
|
|
const FilePath presetFilePath = FilePath::fromUtf8(presetItem.value);
|
|
|
|
|
|
|
|
|
|
if (argFilePath != presetFilePath)
|
|
|
|
|
arg = presetItem.toArgument();
|
|
|
|
|
} else if (argItem.expandedValue(k) != QString::fromUtf8(presetItem.value)) {
|
|
|
|
|
arg = presetItem.toArgument();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
initialArguments.append(presetItem.toArgument());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-05 20:09:12 +02:00
|
|
|
static Utils::EnvironmentItems getEnvironmentItemsFromCMakeConfigurePreset(
|
|
|
|
|
const CMakeProject *project, const Kit *k)
|
2022-05-30 19:04:54 +02:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
Utils::EnvironmentItems envItems;
|
|
|
|
|
|
|
|
|
|
const CMakeConfigItem presetItem = CMakeConfigurationKitAspect::cmakePresetConfigItem(k);
|
|
|
|
|
if (presetItem.isNull())
|
|
|
|
|
return envItems;
|
|
|
|
|
|
|
|
|
|
const QString presetName = presetItem.expandedValue(k);
|
|
|
|
|
|
|
|
|
|
PresetsDetails::ConfigurePreset configurePreset
|
|
|
|
|
= Utils::findOrDefault(project->presetsData().configurePresets,
|
|
|
|
|
[presetName](const PresetsDetails::ConfigurePreset &preset) {
|
|
|
|
|
return preset.name == presetName;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
CMakePresets::Macros::expand(configurePreset, envItems, project->projectDirectory());
|
|
|
|
|
|
|
|
|
|
return envItems;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-05 20:09:12 +02:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-10 19:12:40 +02:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// CMakeBuildConfigurationPrivate:
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
class CMakeBuildConfigurationPrivate
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
Utils::Environment m_configureEnvironment;
|
|
|
|
|
Utils::EnvironmentItems m_userConfigureEnvironmentChanges;
|
|
|
|
|
bool m_clearSystemConfigureEnvironment = false;
|
|
|
|
|
};
|
|
|
|
|
|
2021-02-04 14:53:42 +01:00
|
|
|
} // namespace Internal
|
|
|
|
|
|
2020-04-02 14:49:05 +02:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// CMakeBuildConfiguration:
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
|
2022-08-10 19:12:40 +02:00
|
|
|
: BuildConfiguration(target, id), d(new Internal::CMakeBuildConfigurationPrivate())
|
2009-11-23 12:11:48 +01:00
|
|
|
{
|
2020-04-20 17:33:36 +02:00
|
|
|
m_buildSystem = new CMakeBuildSystem(this);
|
|
|
|
|
|
2020-03-24 11:01:40 +01:00
|
|
|
const auto buildDirAspect = aspect<BuildDirectoryAspect>();
|
|
|
|
|
buildDirAspect->setValueAcceptor(
|
2022-08-26 10:30:00 +02:00
|
|
|
[](const QString &oldDir, const QString &newDir) -> std::optional<QString> {
|
2020-03-24 11:01:40 +01:00
|
|
|
if (oldDir.isEmpty())
|
|
|
|
|
return newDir;
|
|
|
|
|
|
2020-11-25 17:56:03 +01:00
|
|
|
if (QDir(oldDir).exists("CMakeCache.txt") && !QDir(newDir).exists("CMakeCache.txt")) {
|
2021-06-24 13:23:36 +02:00
|
|
|
if (QMessageBox::information(
|
|
|
|
|
Core::ICore::dialogParent(),
|
|
|
|
|
tr("Changing Build Directory"),
|
|
|
|
|
tr("Change the build directory to \"%1\" and start with a "
|
|
|
|
|
"basic CMake configuration?")
|
|
|
|
|
.arg(newDir),
|
|
|
|
|
QMessageBox::Ok,
|
|
|
|
|
QMessageBox::Cancel)
|
2020-03-24 11:01:40 +01:00
|
|
|
== QMessageBox::Ok) {
|
|
|
|
|
return newDir;
|
|
|
|
|
}
|
2022-08-26 10:30:00 +02:00
|
|
|
return std::nullopt;
|
2020-03-24 11:01:40 +01:00
|
|
|
}
|
2020-06-25 11:19:15 +02:00
|
|
|
return newDir;
|
2020-03-24 11:01:40 +01:00
|
|
|
});
|
2020-03-16 10:24:35 +01:00
|
|
|
|
2020-08-11 20:38:38 +02:00
|
|
|
auto initialCMakeArgumentsAspect = addAspect<InitialCMakeArgumentsAspect>();
|
2021-12-28 21:42:29 +01:00
|
|
|
initialCMakeArgumentsAspect->setMacroExpanderProvider([this] { return macroExpander(); });
|
|
|
|
|
|
2022-02-03 11:24:56 +01:00
|
|
|
auto additionalCMakeArgumentsAspect = addAspect<AdditionalCMakeOptionsAspect>();
|
2021-12-28 21:42:29 +01:00
|
|
|
additionalCMakeArgumentsAspect->setMacroExpanderProvider([this] { return macroExpander(); });
|
|
|
|
|
|
2021-02-04 14:53:42 +01:00
|
|
|
macroExpander()->registerVariable(DEVELOPMENT_TEAM_FLAG,
|
|
|
|
|
tr("The CMake flag for the development team"),
|
|
|
|
|
[this] {
|
|
|
|
|
const CMakeConfig flags = signingFlags();
|
|
|
|
|
if (!flags.isEmpty())
|
|
|
|
|
return flags.first().toArgument();
|
|
|
|
|
return QString();
|
|
|
|
|
});
|
|
|
|
|
macroExpander()->registerVariable(PROVISIONING_PROFILE_FLAG,
|
|
|
|
|
tr("The CMake flag for the provisioning profile"),
|
|
|
|
|
[this] {
|
|
|
|
|
const CMakeConfig flags = signingFlags();
|
|
|
|
|
if (flags.size() > 1 && !flags.at(1).isUnset) {
|
|
|
|
|
return flags.at(1).toArgument();
|
|
|
|
|
}
|
|
|
|
|
return QString();
|
|
|
|
|
});
|
2020-04-02 14:49:05 +02:00
|
|
|
|
Add workarounds for running under Rosetta on macOS
When Qt Creator is built as an Intel binary, and runs on
an Apple Silicon (ARM) Mac, it will be run via the Rosetta
translation layer. This means any process spawned by QtC,
including qmake, CMake, and lldb, will launch as x86_64
binaries as well.
For qmake and CMake, this affects their default choice of
build architecture, resulting in x86_64 builds of user
applications. We want to produce native arm64 apps, even
if Qt Creator itself isn't one, so we explicitly detect
the situation, and if Qt has an arm64 slice, we default
to arm64 builds.
The logic of adding CONFIG+=x86_64 to the qmake step has
been disabled, as the assumption that a single qmake run
and build will produce only a single architecture does no
longer hold. The corresponding logic in Qt was removed
in 2015 (qtbase f58e95f098c8d78a5f2db7729606126fe093cbdf).
In the case of lldb, running it as an x86_64 binary fails
to attach to the running application. We work around this
by using the 'arch' tool to explicitly launch it as an
arm64 binary. This works for debugging both arm64 and
x86_64 applications.
Change-Id: I65cc0f600223990f25c76cef18d927895e551260
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
2021-06-22 00:11:58 +02:00
|
|
|
macroExpander()->registerVariable(CMAKE_OSX_ARCHITECTURES_FLAG,
|
|
|
|
|
tr("The CMake flag for the architecture on macOS"),
|
|
|
|
|
[target] {
|
|
|
|
|
if (HostOsInfo::isRunningUnderRosetta()) {
|
|
|
|
|
if (auto *qt = QtSupport::QtKitAspect::qtVersion(target->kit())) {
|
|
|
|
|
const Abis abis = qt->qtAbis();
|
|
|
|
|
for (const Abi &abi : abis) {
|
|
|
|
|
if (abi.architecture() == Abi::ArmArchitecture)
|
|
|
|
|
return QLatin1String("-DCMAKE_OSX_ARCHITECTURES=arm64");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return QLatin1String();
|
|
|
|
|
});
|
2022-05-18 11:56:01 +02:00
|
|
|
macroExpander()->registerVariable(QT_QML_DEBUG_FLAG,
|
|
|
|
|
tr("The CMake flag for QML debugging, if enabled"),
|
|
|
|
|
[this] {
|
|
|
|
|
if (aspect<QtSupport::QmlDebuggingAspect>()->value()
|
|
|
|
|
== TriState::Enabled) {
|
|
|
|
|
return QLatin1String(
|
|
|
|
|
"-DQT_QML_DEBUG");
|
|
|
|
|
}
|
|
|
|
|
return QLatin1String();
|
|
|
|
|
});
|
Add workarounds for running under Rosetta on macOS
When Qt Creator is built as an Intel binary, and runs on
an Apple Silicon (ARM) Mac, it will be run via the Rosetta
translation layer. This means any process spawned by QtC,
including qmake, CMake, and lldb, will launch as x86_64
binaries as well.
For qmake and CMake, this affects their default choice of
build architecture, resulting in x86_64 builds of user
applications. We want to produce native arm64 apps, even
if Qt Creator itself isn't one, so we explicitly detect
the situation, and if Qt has an arm64 slice, we default
to arm64 builds.
The logic of adding CONFIG+=x86_64 to the qmake step has
been disabled, as the assumption that a single qmake run
and build will produce only a single architecture does no
longer hold. The corresponding logic in Qt was removed
in 2015 (qtbase f58e95f098c8d78a5f2db7729606126fe093cbdf).
In the case of lldb, running it as an x86_64 binary fails
to attach to the running application. We work around this
by using the 'arch' tool to explicitly launch it as an
arm64 binary. This works for debugging both arm64 and
x86_64 applications.
Change-Id: I65cc0f600223990f25c76cef18d927895e551260
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
2021-06-22 00:11:58 +02:00
|
|
|
|
2020-12-02 19:16:40 +01:00
|
|
|
addAspect<SourceDirectoryAspect>();
|
2021-01-14 16:38:55 +01:00
|
|
|
addAspect<BuildTypeAspect>();
|
2022-04-13 15:53:36 +02:00
|
|
|
addAspect<QtSupport::QmlDebuggingAspect>(this);
|
2020-12-02 19:16:40 +01:00
|
|
|
|
2022-09-05 20:09:12 +02:00
|
|
|
setInitialBuildAndCleanSteps(target);
|
2019-12-06 17:32:07 +01:00
|
|
|
|
2019-12-06 18:42:11 +01:00
|
|
|
setInitializer([this, target](const BuildInfo &info) {
|
2020-04-02 14:49:05 +02:00
|
|
|
const Kit *k = target->kit();
|
2022-05-18 11:56:01 +02:00
|
|
|
const QtSupport::QtVersion *qt = QtSupport::QtKitAspect::qtVersion(k);
|
CMake: Add 'Profile' configuration
Get rid of the hardcoded QML Debugging for Debug & RelWithDebInfo from
the project template, because RelWithDebInfo is actually a good
configuration for doing releases (we use it for Qt Creator), and
enabling QML debugging for releases is a bad idea.
Instead enable QML Debugging in Qt Creator for the Debug configuration,
and add a 'Profile' configuration that is 'RelWithDebInfo + QML
Debugging'.
When importing a build, we only set the "QML debugging" option of the
build configuration, if it is enabled in the imported build, even if it
uses CMAKE_BUILD_TYPE=Debug .
One drawback: When not importing a build, but just setting the build
directory of a "Profile" or "Debug" configuration to an existing build,
Qt Creator asks if it should apply "-DCMAKE_CXX_FLAGS=-DQT_QML_DEBUG".
The user can choose not to, but then is asked the next time again, and
it is not obvious that the "QML debugging" option is responsible for
this.
That is somewhat orthogonal to this change though: Even without this
change, if the user changes the QML debugging option from "Leave at
Default" to "Enable", the same happens, and it is also not clear to the
user how to get rid of it. The user might not even have realized that
they changed the option (e.g. on platforms where the mouse wheel cycles
combo box values).
I think the correct solution is to 1. make clearer where the CMake flags
came from in that dialog, 2. allow the user to cancel a build from that
dialog, 3. allow the user to discard these changes (by changing the
setting) from that dialog. But that is for another patch.
Amends 3300182d405bffe062a0f2be900f35822a9e20b0
Amends 77fed0b0fdce2a93f465c20cd87c41900117dcda
Change-Id: I95de59473b67c5afd6a53ea7f49838dbaef770d4
Reviewed-by: Artem Sokolovskii <artem.sokolovskii@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
2022-05-18 10:40:31 +02:00
|
|
|
const QVariantMap extraInfoMap = info.extraInfo.value<QVariantMap>();
|
|
|
|
|
const QString buildType = extraInfoMap.contains(CMAKE_BUILD_TYPE)
|
|
|
|
|
? extraInfoMap.value(CMAKE_BUILD_TYPE).toString()
|
|
|
|
|
: info.typeName;
|
|
|
|
|
const TriState qmlDebugging = extraInfoMap.contains(Constants::QML_DEBUG_SETTING)
|
|
|
|
|
? TriState::fromVariant(
|
|
|
|
|
extraInfoMap.value(Constants::QML_DEBUG_SETTING))
|
|
|
|
|
: TriState::Default;
|
|
|
|
|
|
|
|
|
|
CommandLine cmd = defaultInitialCMakeCommand(k, buildType);
|
2022-05-02 16:58:26 +02:00
|
|
|
m_buildSystem->setIsMultiConfig(CMakeGeneratorKitAspect::isMultiConfigGenerator(k));
|
2019-12-09 13:54:57 +01:00
|
|
|
|
2020-04-02 14:49:05 +02:00
|
|
|
// Android magic:
|
2019-12-09 13:54:57 +01:00
|
|
|
if (DeviceTypeKitAspect::deviceTypeId(k) == Android::Constants::ANDROID_DEVICE_TYPE) {
|
2019-12-09 12:59:38 +01:00
|
|
|
buildSteps()->appendStep(Android::Constants::ANDROID_BUILD_APK_ID);
|
|
|
|
|
const auto &bs = buildSteps()->steps().constLast();
|
2022-01-26 11:21:00 +01:00
|
|
|
cmd.addArg("-DANDROID_NATIVE_API_LEVEL:STRING="
|
2021-06-16 18:15:02 +02:00
|
|
|
+ bs->data(Android::Constants::AndroidNdkPlatform).toString());
|
2019-12-09 12:59:38 +01:00
|
|
|
auto ndkLocation = bs->data(Android::Constants::NdkLocation).value<FilePath>();
|
2022-01-26 11:21:00 +01:00
|
|
|
cmd.addArg("-DANDROID_NDK:PATH=" + ndkLocation.path());
|
ProjectExplorer/all: Re-organize BuildSteps/{Deploy,Build}Config setup
This follow the rough pattern of recent *RunConfigurationFactory changes
for build and deploy configurations.
- Collapse the two lines of constructors similar to what
890c1906e6fb2ec did for RunConfigurations
* Deploy* was purely mechanical
* Build* ctors are split in connects() in the ctor body
to create "empty shell for clone" etc
and build step additions in initialize() functions which
are only used in the create() case.
-- Allows to collapse the shared 'ctor()' functions, too.
- Move FooBuildConfigurationFactory::create() implementations
to FooBuildConfiguration() constructor. That was a strange
and unneeded ping-pong between factories and objects, and
furthermore allows one level less of indirection (and for a
later, left out here, some reduction of the
FooBuildConfiguration interfaces that were only used to
accommodate the *Factory::create() functions.
- Most {Build,Deploy}Configuration{,Factory} classes had a canHandle(),
but there wasn't one in the base classses. Have one there.
- Most canHandle() functions were checking simple restrictions on
e.g. project or target types, specify those by setters in the
constructors instead and check them in the base canHandle()
- clone() is generally replaced by a creation of a "shell object"
and a fromMap(source->toMap()), implemented in the base, there
are two cases left for Android and Qbs that needed(?) some extra
polish
- generally use canHandle() in base implementation, instead
of doing that in all Derived::canFoo()
- as a result, canCreate/create/canClone/clone reimplementations
are not needed anymore, keep the base implementation for
now (could be inlined into their only users later), but
de-virtualize them.
- Combine Ios{Preset,DSym}BuildStepFactory. There was only one
'dsym' build step they could create.
- Split the 'mangled' id into the ProjectConfiguration subtype
specific constant identifier, and a QString extraId() bit.
Only maintain the mangled id in saved settings.
- Make ProjectConfiguration::m_id a constant member, adapt
all constructors of derived classe.
Not done in this patch:
- Finish possible cosmetic changes on top
- Add a way to specify restrictions to supported Qt versions
(used in Android/Ios), as the base implementation does not
depend on the qtsupport plugin
- Combine the QList<X> availableFoo() + createFoo(X) function
pairs to somthing like a direct
QList<struct { X; std::function<X()>; }> fooCreators()
to avoid e.g. the baseId.withSuffix() <-> id.suffixAfter(base)
pingpong
- Remove the *Factories from the global object pool
- Do something about priority(). Falling back to plain
qmake in android+qmake setup is not helpful.
Change-Id: I2be7d88d554c5aa8b7db8edf5b93278e1ae0112a
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
2017-11-29 12:28:40 +01:00
|
|
|
|
2022-02-07 13:09:21 +01:00
|
|
|
cmd.addArg("-DCMAKE_TOOLCHAIN_FILE:FILEPATH="
|
2021-06-16 18:15:02 +02:00
|
|
|
+ ndkLocation.pathAppended("build/cmake/android.toolchain.cmake").path());
|
2019-12-09 12:59:38 +01:00
|
|
|
|
2021-09-05 18:49:26 +03:00
|
|
|
auto androidAbis = bs->data(Android::Constants::AndroidMkSpecAbis).toStringList();
|
2019-12-09 12:59:38 +01:00
|
|
|
QString preferredAbi;
|
2020-07-23 15:48:56 +02:00
|
|
|
if (androidAbis.contains(ProjectExplorer::Constants::ANDROID_ABI_ARMEABI_V7A)) {
|
|
|
|
|
preferredAbi = ProjectExplorer::Constants::ANDROID_ABI_ARMEABI_V7A;
|
|
|
|
|
} else if (androidAbis.isEmpty()
|
|
|
|
|
|| androidAbis.contains(ProjectExplorer::Constants::ANDROID_ABI_ARM64_V8A)) {
|
|
|
|
|
preferredAbi = ProjectExplorer::Constants::ANDROID_ABI_ARM64_V8A;
|
2019-12-09 12:59:38 +01:00
|
|
|
} else {
|
|
|
|
|
preferredAbi = androidAbis.first();
|
|
|
|
|
}
|
2022-01-26 11:21:00 +01:00
|
|
|
cmd.addArg("-DANDROID_ABI:STRING=" + preferredAbi);
|
|
|
|
|
cmd.addArg("-DANDROID_STL:STRING=c++_shared");
|
|
|
|
|
cmd.addArg("-DCMAKE_FIND_ROOT_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}");
|
2020-09-18 18:29:03 +03:00
|
|
|
|
2020-11-05 14:21:12 +02:00
|
|
|
auto sdkLocation = bs->data(Android::Constants::SdkLocation).value<FilePath>();
|
2020-09-25 10:49:44 +03:00
|
|
|
|
2022-07-04 18:36:40 +02:00
|
|
|
if (qt && qt->qtVersion() >= QVersionNumber(6, 0, 0)) {
|
2021-09-07 12:51:02 +03:00
|
|
|
// Don't build apk under ALL target because Qt Creator will handle it
|
2022-07-04 18:36:40 +02:00
|
|
|
if (qt->qtVersion() >= QVersionNumber(6, 1, 0))
|
2022-01-26 11:21:00 +01:00
|
|
|
cmd.addArg("-DQT_NO_GLOBAL_APK_TARGET_PART_OF_ALL:BOOL=ON");
|
|
|
|
|
cmd.addArg("-DQT_HOST_PATH:PATH=%{Qt:QT_HOST_PREFIX}");
|
|
|
|
|
cmd.addArg("-DANDROID_SDK_ROOT:PATH=" + sdkLocation.path());
|
2020-11-05 14:21:12 +02:00
|
|
|
} else {
|
2022-01-26 11:21:00 +01:00
|
|
|
cmd.addArg("-DANDROID_SDK:PATH=" + sdkLocation.path());
|
2020-09-18 18:29:03 +03:00
|
|
|
}
|
2019-12-09 12:59:38 +01:00
|
|
|
}
|
|
|
|
|
|
Add workarounds for running under Rosetta on macOS
When Qt Creator is built as an Intel binary, and runs on
an Apple Silicon (ARM) Mac, it will be run via the Rosetta
translation layer. This means any process spawned by QtC,
including qmake, CMake, and lldb, will launch as x86_64
binaries as well.
For qmake and CMake, this affects their default choice of
build architecture, resulting in x86_64 builds of user
applications. We want to produce native arm64 apps, even
if Qt Creator itself isn't one, so we explicitly detect
the situation, and if Qt has an arm64 slice, we default
to arm64 builds.
The logic of adding CONFIG+=x86_64 to the qmake step has
been disabled, as the assumption that a single qmake run
and build will produce only a single architecture does no
longer hold. The corresponding logic in Qt was removed
in 2015 (qtbase f58e95f098c8d78a5f2db7729606126fe093cbdf).
In the case of lldb, running it as an x86_64 binary fails
to attach to the running application. We work around this
by using the 'arch' tool to explicitly launch it as an
arm64 binary. This works for debugging both arm64 and
x86_64 applications.
Change-Id: I65cc0f600223990f25c76cef18d927895e551260
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
2021-06-22 00:11:58 +02:00
|
|
|
const IDevice::ConstPtr device = DeviceKitAspect::device(k);
|
CMake: iOS: Enable automatic provisioning updates
By default xcodebuild does not try create / download a provisioning
profile for a project if a valid one does not exist locally
in ~/Library/MobileDevice/Provisioning Profiles, even if the
Xcode CODE_SIGN_STYLE attribute is set to Automatic.
Starting with Xcode 9, xcodebuild accepts a new
-allowProvisioningUpdates option.
When passed, xcodebuild will request a new provisioning profile
from Apple's servers for the current project and use it during
the build. The provisioning profile is only needed when building
for a real device, not the simulator.
When building an iOS project with qmake, the option is embedded in the
wrapping Makefile generated by qmake, so Qt Creator can simply call
make (which it does).
For CMake, there is no wrapping Makefile, so we need to pass the new
option explicitly as an additional build tool argument.
There might be cases where automatic provisioning is not desired,
which is why there is now a new checkbox in the CMake build step
configuration widget. It's default value is 'enabled', to match
qmake's behavior.
As an implementation detail, isiOS had to be moved to a header file so
it's accessible to both the build configuration and the build step.
Fixes: QTCREATORBUG-26246
Change-Id: Ic80cd965ba095d0ff379e13ad2ffb8c298c9f7c4
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
2022-05-05 16:26:11 +02:00
|
|
|
if (CMakeBuildConfiguration::isIos(k)) {
|
2022-07-04 18:36:40 +02:00
|
|
|
if (qt && qt->qtVersion().majorVersion() >= 6) {
|
2021-09-10 12:12:48 +02:00
|
|
|
// TODO it would be better if we could set
|
|
|
|
|
// CMAKE_SYSTEM_NAME=iOS and CMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=YES
|
|
|
|
|
// and build with "cmake --build . -- -arch <arch>" instead of setting the architecture
|
|
|
|
|
// and sysroot in the CMake configuration, but that currently doesn't work with Qt/CMake
|
|
|
|
|
// https://gitlab.kitware.com/cmake/cmake/-/issues/21276
|
|
|
|
|
const Id deviceType = DeviceTypeKitAspect::deviceTypeId(k);
|
|
|
|
|
// TODO the architectures are probably not correct with Apple Silicon in the mix...
|
|
|
|
|
const QString architecture = deviceType == Ios::Constants::IOS_DEVICE_TYPE
|
|
|
|
|
? QLatin1String("arm64")
|
|
|
|
|
: QLatin1String("x86_64");
|
|
|
|
|
const QString sysroot = deviceType == Ios::Constants::IOS_DEVICE_TYPE
|
|
|
|
|
? QLatin1String("iphoneos")
|
|
|
|
|
: QLatin1String("iphonesimulator");
|
2022-01-26 11:21:00 +01:00
|
|
|
cmd.addArg(CMAKE_QT6_TOOLCHAIN_FILE_ARG);
|
|
|
|
|
cmd.addArg("-DCMAKE_OSX_ARCHITECTURES:STRING=" + architecture);
|
|
|
|
|
cmd.addArg("-DCMAKE_OSX_SYSROOT:STRING=" + sysroot);
|
|
|
|
|
cmd.addArg("%{" + QLatin1String(DEVELOPMENT_TEAM_FLAG) + "}");
|
|
|
|
|
cmd.addArg("%{" + QLatin1String(PROVISIONING_PROFILE_FLAG) + "}");
|
2021-02-02 16:10:45 +01:00
|
|
|
}
|
2021-09-10 12:12:48 +02:00
|
|
|
} else if (device && device->osType() == Utils::OsTypeMac) {
|
2022-01-26 11:21:00 +01:00
|
|
|
cmd.addArg("%{" + QLatin1String(CMAKE_OSX_ARCHITECTURES_FLAG) + "}");
|
2021-02-02 16:10:45 +01:00
|
|
|
}
|
|
|
|
|
|
2021-12-01 13:46:58 +01:00
|
|
|
if (isWebAssembly(k) || isQnx(k) || isWindowsARM64(k)) {
|
2022-07-04 18:36:40 +02:00
|
|
|
if (qt && qt->qtVersion().majorVersion() >= 6)
|
2022-01-26 11:21:00 +01:00
|
|
|
cmd.addArg(CMAKE_QT6_TOOLCHAIN_FILE_ARG);
|
2021-03-23 18:33:42 +01:00
|
|
|
}
|
|
|
|
|
|
2019-12-06 17:32:07 +01:00
|
|
|
if (info.buildDirectory.isEmpty()) {
|
2019-12-09 12:59:38 +01:00
|
|
|
setBuildDirectory(shadowBuildDirectory(target->project()->projectFilePath(),
|
2019-12-09 13:54:57 +01:00
|
|
|
k,
|
2022-08-10 19:55:58 +02:00
|
|
|
info.typeName,
|
2019-12-06 17:32:07 +01:00
|
|
|
info.buildType));
|
2019-10-18 09:25:14 +03:00
|
|
|
}
|
2019-12-09 13:54:57 +01:00
|
|
|
|
CMake: Add 'Profile' configuration
Get rid of the hardcoded QML Debugging for Debug & RelWithDebInfo from
the project template, because RelWithDebInfo is actually a good
configuration for doing releases (we use it for Qt Creator), and
enabling QML debugging for releases is a bad idea.
Instead enable QML Debugging in Qt Creator for the Debug configuration,
and add a 'Profile' configuration that is 'RelWithDebInfo + QML
Debugging'.
When importing a build, we only set the "QML debugging" option of the
build configuration, if it is enabled in the imported build, even if it
uses CMAKE_BUILD_TYPE=Debug .
One drawback: When not importing a build, but just setting the build
directory of a "Profile" or "Debug" configuration to an existing build,
Qt Creator asks if it should apply "-DCMAKE_CXX_FLAGS=-DQT_QML_DEBUG".
The user can choose not to, but then is asked the next time again, and
it is not obvious that the "QML debugging" option is responsible for
this.
That is somewhat orthogonal to this change though: Even without this
change, if the user changes the QML debugging option from "Leave at
Default" to "Enable", the same happens, and it is also not clear to the
user how to get rid of it. The user might not even have realized that
they changed the option (e.g. on platforms where the mouse wheel cycles
combo box values).
I think the correct solution is to 1. make clearer where the CMake flags
came from in that dialog, 2. allow the user to cancel a build from that
dialog, 3. allow the user to discard these changes (by changing the
setting) from that dialog. But that is for another patch.
Amends 3300182d405bffe062a0f2be900f35822a9e20b0
Amends 77fed0b0fdce2a93f465c20cd87c41900117dcda
Change-Id: I95de59473b67c5afd6a53ea7f49838dbaef770d4
Reviewed-by: Artem Sokolovskii <artem.sokolovskii@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
2022-05-18 10:40:31 +02:00
|
|
|
if (extraInfoMap.contains(Constants::CMAKE_HOME_DIR))
|
|
|
|
|
setSourceDirectory(FilePath::fromVariant(extraInfoMap.value(Constants::CMAKE_HOME_DIR)));
|
|
|
|
|
|
|
|
|
|
aspect<QtSupport::QmlDebuggingAspect>()->setValue(qmlDebugging);
|
2020-12-02 19:16:40 +01:00
|
|
|
|
2022-05-18 11:56:01 +02:00
|
|
|
if (qt && qt->isQmlDebuggingSupported())
|
|
|
|
|
cmd.addArg("-DCMAKE_CXX_FLAGS_INIT:STRING=%{" + QLatin1String(QT_QML_DEBUG_FLAG) + "}");
|
|
|
|
|
|
2022-05-30 19:04:54 +02:00
|
|
|
CMakeProject *cmakeProject = static_cast<CMakeProject *>(target->project());
|
2022-09-05 20:09:12 +02:00
|
|
|
setUserConfigureEnvironmentChanges(getEnvironmentItemsFromCMakeConfigurePreset(cmakeProject, k));
|
2022-05-30 19:04:54 +02:00
|
|
|
|
|
|
|
|
QStringList initialCMakeArguments = cmd.splitArguments();
|
|
|
|
|
addCMakeConfigurePresetToInitialArguments(initialCMakeArguments,
|
|
|
|
|
cmakeProject,
|
|
|
|
|
k,
|
|
|
|
|
configureEnvironment());
|
|
|
|
|
m_buildSystem->setInitialCMakeArguments(initialCMakeArguments);
|
CMake: Add 'Profile' configuration
Get rid of the hardcoded QML Debugging for Debug & RelWithDebInfo from
the project template, because RelWithDebInfo is actually a good
configuration for doing releases (we use it for Qt Creator), and
enabling QML debugging for releases is a bad idea.
Instead enable QML Debugging in Qt Creator for the Debug configuration,
and add a 'Profile' configuration that is 'RelWithDebInfo + QML
Debugging'.
When importing a build, we only set the "QML debugging" option of the
build configuration, if it is enabled in the imported build, even if it
uses CMAKE_BUILD_TYPE=Debug .
One drawback: When not importing a build, but just setting the build
directory of a "Profile" or "Debug" configuration to an existing build,
Qt Creator asks if it should apply "-DCMAKE_CXX_FLAGS=-DQT_QML_DEBUG".
The user can choose not to, but then is asked the next time again, and
it is not obvious that the "QML debugging" option is responsible for
this.
That is somewhat orthogonal to this change though: Even without this
change, if the user changes the QML debugging option from "Leave at
Default" to "Enable", the same happens, and it is also not clear to the
user how to get rid of it. The user might not even have realized that
they changed the option (e.g. on platforms where the mouse wheel cycles
combo box values).
I think the correct solution is to 1. make clearer where the CMake flags
came from in that dialog, 2. allow the user to cancel a build from that
dialog, 3. allow the user to discard these changes (by changing the
setting) from that dialog. But that is for another patch.
Amends 3300182d405bffe062a0f2be900f35822a9e20b0
Amends 77fed0b0fdce2a93f465c20cd87c41900117dcda
Change-Id: I95de59473b67c5afd6a53ea7f49838dbaef770d4
Reviewed-by: Artem Sokolovskii <artem.sokolovskii@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
2022-05-18 10:40:31 +02:00
|
|
|
m_buildSystem->setCMakeBuildType(buildType);
|
2022-09-01 08:52:12 +02:00
|
|
|
updateAndEmitConfigureEnvironmentChanged();
|
2022-09-05 20:09:12 +02:00
|
|
|
|
|
|
|
|
setBuildPresetToBuildSteps(target);
|
2019-12-09 12:59:38 +01:00
|
|
|
});
|
|
|
|
|
}
|
2019-10-18 09:25:14 +03:00
|
|
|
|
2019-12-09 12:59:38 +01:00
|
|
|
CMakeBuildConfiguration::~CMakeBuildConfiguration()
|
|
|
|
|
{
|
|
|
|
|
delete m_buildSystem;
|
2022-08-10 19:12:40 +02:00
|
|
|
delete d;
|
2016-02-24 18:00:24 +01:00
|
|
|
}
|
|
|
|
|
|
2010-01-18 12:11:04 +01:00
|
|
|
QVariantMap CMakeBuildConfiguration::toMap() const
|
2009-12-08 12:21:11 +01:00
|
|
|
{
|
2021-02-12 16:15:26 +01:00
|
|
|
QVariantMap map(BuildConfiguration::toMap());
|
2022-08-10 19:12:40 +02:00
|
|
|
map.insert(QLatin1String(CLEAR_SYSTEM_ENVIRONMENT_KEY), d->m_clearSystemConfigureEnvironment);
|
|
|
|
|
map.insert(QLatin1String(USER_ENVIRONMENT_CHANGES_KEY), EnvironmentItem::toStringList(d->m_userConfigureEnvironmentChanges));
|
2010-01-18 12:11:04 +01:00
|
|
|
return map;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CMakeBuildConfiguration::fromMap(const QVariantMap &map)
|
|
|
|
|
{
|
2010-09-22 15:14:07 +02:00
|
|
|
if (!BuildConfiguration::fromMap(map))
|
|
|
|
|
return false;
|
|
|
|
|
|
2016-02-03 13:52:50 +01:00
|
|
|
const CMakeConfig conf
|
2016-04-08 14:11:57 +02:00
|
|
|
= Utils::filtered(Utils::transform(map.value(QLatin1String(CONFIGURATION_KEY)).toStringList(),
|
|
|
|
|
[](const QString &v) { return CMakeConfigItem::fromString(v); }),
|
|
|
|
|
[](const CMakeConfigItem &c) { return !c.isNull(); });
|
2016-02-03 13:52:50 +01:00
|
|
|
|
2020-04-02 14:49:05 +02:00
|
|
|
// TODO: Upgrade from Qt Creator < 4.13: Remove when no longer supported!
|
|
|
|
|
const QString buildTypeName = [this]() {
|
|
|
|
|
switch (buildType()) {
|
|
|
|
|
case Debug:
|
|
|
|
|
return QString("Debug");
|
|
|
|
|
case Profile:
|
|
|
|
|
return QString("RelWithDebInfo");
|
|
|
|
|
case Release:
|
|
|
|
|
return QString("Release");
|
|
|
|
|
case Unknown:
|
|
|
|
|
default:
|
|
|
|
|
return QString("");
|
|
|
|
|
}
|
|
|
|
|
}();
|
2022-05-02 18:02:37 +02:00
|
|
|
if (m_buildSystem->initialCMakeArguments().isEmpty()) {
|
2022-01-26 11:21:00 +01:00
|
|
|
CommandLine cmd = defaultInitialCMakeCommand(kit(), buildTypeName);
|
|
|
|
|
for (const CMakeConfigItem &item : conf)
|
|
|
|
|
cmd.addArg(item.toArgument(macroExpander()));
|
2022-05-02 18:02:37 +02:00
|
|
|
m_buildSystem->setInitialCMakeArguments(cmd.splitArguments());
|
2020-04-02 14:49:05 +02:00
|
|
|
}
|
2010-01-18 12:11:04 +01:00
|
|
|
|
2022-08-10 19:12:40 +02:00
|
|
|
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();
|
|
|
|
|
|
2010-09-22 15:14:07 +02:00
|
|
|
return true;
|
2009-11-23 12:11:48 +01:00
|
|
|
}
|
2009-11-23 13:29:45 +01:00
|
|
|
|
2019-05-28 13:49:26 +02:00
|
|
|
FilePath CMakeBuildConfiguration::shadowBuildDirectory(const FilePath &projectFilePath,
|
2016-03-01 14:12:35 +01:00
|
|
|
const Kit *k,
|
|
|
|
|
const QString &bcName,
|
|
|
|
|
BuildConfiguration::BuildType buildType)
|
|
|
|
|
{
|
|
|
|
|
if (projectFilePath.isEmpty())
|
2019-05-28 13:49:26 +02:00
|
|
|
return FilePath();
|
2016-03-01 14:12:35 +01:00
|
|
|
|
|
|
|
|
const QString projectName = projectFilePath.parentDir().fileName();
|
2021-06-25 19:17:05 +02:00
|
|
|
const FilePath projectDir = Project::projectDirectory(projectFilePath);
|
2022-06-03 13:32:49 +02:00
|
|
|
FilePath buildPath = buildDirectoryFromTemplate(projectDir, projectFilePath, projectName, k,
|
|
|
|
|
bcName, buildType, "cmake");
|
2021-01-14 16:38:55 +01:00
|
|
|
|
2021-08-24 08:34:32 +02:00
|
|
|
if (CMakeGeneratorKitAspect::isMultiConfigGenerator(k)) {
|
2022-08-04 15:00:24 +02:00
|
|
|
const QString path = buildPath.path();
|
|
|
|
|
buildPath = buildPath.withNewPath(path.left(path.lastIndexOf(QString("-%1").arg(bcName))));
|
2021-08-24 08:34:32 +02:00
|
|
|
}
|
2021-01-14 16:38:55 +01:00
|
|
|
|
2021-08-24 08:34:32 +02:00
|
|
|
return buildPath;
|
2016-03-01 14:12:35 +01:00
|
|
|
}
|
|
|
|
|
|
CMake: iOS: Enable automatic provisioning updates
By default xcodebuild does not try create / download a provisioning
profile for a project if a valid one does not exist locally
in ~/Library/MobileDevice/Provisioning Profiles, even if the
Xcode CODE_SIGN_STYLE attribute is set to Automatic.
Starting with Xcode 9, xcodebuild accepts a new
-allowProvisioningUpdates option.
When passed, xcodebuild will request a new provisioning profile
from Apple's servers for the current project and use it during
the build. The provisioning profile is only needed when building
for a real device, not the simulator.
When building an iOS project with qmake, the option is embedded in the
wrapping Makefile generated by qmake, so Qt Creator can simply call
make (which it does).
For CMake, there is no wrapping Makefile, so we need to pass the new
option explicitly as an additional build tool argument.
There might be cases where automatic provisioning is not desired,
which is why there is now a new checkbox in the CMake build step
configuration widget. It's default value is 'enabled', to match
qmake's behavior.
As an implementation detail, isiOS had to be moved to a header file so
it's accessible to both the build configuration and the build step.
Fixes: QTCREATORBUG-26246
Change-Id: Ic80cd965ba095d0ff379e13ad2ffb8c298c9f7c4
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
2022-05-05 16:26:11 +02:00
|
|
|
bool CMakeBuildConfiguration::isIos(const Kit *k)
|
|
|
|
|
{
|
|
|
|
|
const Id deviceType = DeviceTypeKitAspect::deviceTypeId(k);
|
|
|
|
|
return deviceType == Ios::Constants::IOS_DEVICE_TYPE
|
|
|
|
|
|| deviceType == Ios::Constants::IOS_SIMULATOR_TYPE;
|
|
|
|
|
}
|
|
|
|
|
|
CMake: Make QML debugging state reflect build system state
After parsing the CMake response, we make the configuration variables
table reflect the actual configuration in the build directory. It is one
of our "promises" that we do not break an existing build configuration,
to avoid unexpected rebuilds.
This was not quite true for the "QML debugging and profiling" setting.
When that setting and the actual build directory disagreed, the user
would get a dialog asking for running CMake with additional parameters,
and when running CMake via the button in projects mode or the menu, it
would just change these configuration parameters, potentially leading to
an unexpected complete rebuild of the application.
So, after parsing check if the actual CMake configuration matches our
QML debugging setting, and if not, change the setting to "Leave at
Default", to ensure that we don't mess with the build.
Fix the "Run CMake" button state (in the "Current Configuration") when
changing the QML debugging option, which should become bold, if the
CMake parameters change.
Amends 2577ce8ba1a69ad716c2fc2a5d0d5cc742c3c4cf and fixes the drawback
mentioned there, i.e. setting the build directory of a "Debug" build
configuration to an existing build directory with QML debugging
disabled, will now simply set the QML debugging option to "Leave at
Default" instead of forcing it to "Enabled".
Change-Id: Ie6d4875d59319687d94e44e459ca76038e5813c0
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
2022-06-07 10:18:34 +02:00
|
|
|
bool CMakeBuildConfiguration::hasQmlDebugging(const CMakeConfig &config)
|
|
|
|
|
{
|
|
|
|
|
// Determine QML debugging flags. This must match what we do in
|
|
|
|
|
// CMakeBuildSettingsWidget::getQmlDebugCxxFlags()
|
|
|
|
|
// such that in doubt we leave the QML Debugging setting at "Leave at default"
|
|
|
|
|
const QString cxxFlagsInit = config.stringValueOf("CMAKE_CXX_FLAGS_INIT");
|
|
|
|
|
const QString cxxFlags = config.stringValueOf("CMAKE_CXX_FLAGS");
|
|
|
|
|
return cxxFlagsInit.contains("-DQT_QML_DEBUG") && cxxFlags.contains("-DQT_QML_DEBUG");
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-14 15:18:25 +01:00
|
|
|
void CMakeBuildConfiguration::buildTarget(const QString &buildTarget)
|
|
|
|
|
{
|
2021-02-12 16:15:26 +01:00
|
|
|
auto cmBs = qobject_cast<CMakeBuildStep *>(findOrDefault(
|
2019-12-05 16:19:42 +01:00
|
|
|
buildSteps()->steps(),
|
2021-02-12 16:15:26 +01:00
|
|
|
[](const BuildStep *bs) {
|
2016-11-14 15:18:25 +01:00
|
|
|
return bs->id() == Constants::CMAKE_BUILD_STEP_ID;
|
|
|
|
|
}));
|
|
|
|
|
|
2020-06-02 19:37:25 +02:00
|
|
|
QStringList originalBuildTargets;
|
2016-11-14 15:18:25 +01:00
|
|
|
if (cmBs) {
|
2020-06-02 19:37:25 +02:00
|
|
|
originalBuildTargets = cmBs->buildTargets();
|
|
|
|
|
cmBs->setBuildTargets({buildTarget});
|
2016-11-14 15:18:25 +01:00
|
|
|
}
|
|
|
|
|
|
2019-12-05 16:19:42 +01:00
|
|
|
BuildManager::buildList(buildSteps());
|
2016-11-14 15:18:25 +01:00
|
|
|
|
|
|
|
|
if (cmBs)
|
2020-06-02 19:37:25 +02:00
|
|
|
cmBs->setBuildTargets(originalBuildTargets);
|
2016-11-14 15:18:25 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
CMakeConfig CMakeBuildSystem::configurationFromCMake() const
|
2016-02-24 18:00:24 +01:00
|
|
|
{
|
2017-09-28 11:32:39 +02:00
|
|
|
return m_configurationFromCMake;
|
|
|
|
|
}
|
2016-02-24 18:00:24 +01:00
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
CMakeConfig CMakeBuildSystem::configurationChanges() const
|
2017-09-28 11:32:39 +02:00
|
|
|
{
|
2021-02-04 16:22:40 +01:00
|
|
|
return m_configurationChanges;
|
2016-02-24 18:00:24 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
QStringList CMakeBuildSystem::configurationChangesArguments(bool initialParameters) const
|
2017-09-28 11:32:39 +02:00
|
|
|
{
|
2021-12-28 21:42:29 +01:00
|
|
|
const QList<CMakeConfigItem> filteredInitials
|
|
|
|
|
= Utils::filtered(m_configurationChanges, [initialParameters](const CMakeConfigItem &ci) {
|
|
|
|
|
return initialParameters ? ci.isInitial : !ci.isInitial;
|
|
|
|
|
});
|
|
|
|
|
return Utils::transform(filteredInitials, &CMakeConfigItem::toArgument);
|
2020-04-02 14:49:05 +02:00
|
|
|
}
|
2016-02-24 18:00:24 +01:00
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
QStringList CMakeBuildSystem::initialCMakeArguments() const
|
2020-04-02 14:49:05 +02:00
|
|
|
{
|
2022-05-02 18:02:37 +02:00
|
|
|
return buildConfiguration()->aspect<InitialCMakeArgumentsAspect>()->allValues();
|
2021-12-28 21:42:29 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
CMakeConfig CMakeBuildSystem::initialCMakeConfiguration() const
|
2021-12-28 21:42:29 +01:00
|
|
|
{
|
2022-05-02 18:02:37 +02:00
|
|
|
return buildConfiguration()->aspect<InitialCMakeArgumentsAspect>()->cmakeConfiguration();
|
2016-02-24 18:00:24 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
void CMakeBuildSystem::setConfigurationFromCMake(const CMakeConfig &config)
|
2020-04-02 14:49:05 +02:00
|
|
|
{
|
|
|
|
|
m_configurationFromCMake = config;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
void CMakeBuildSystem::setConfigurationChanges(const CMakeConfig &config)
|
2021-02-04 16:22:40 +01:00
|
|
|
{
|
|
|
|
|
qCDebug(cmakeBuildConfigurationLog)
|
|
|
|
|
<< "Configuration changes before:" << configurationChangesArguments();
|
|
|
|
|
|
|
|
|
|
m_configurationChanges = config;
|
|
|
|
|
|
|
|
|
|
qCDebug(cmakeBuildConfigurationLog)
|
|
|
|
|
<< "Configuration changes after:" << configurationChangesArguments();
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-02 14:49:05 +02:00
|
|
|
// FIXME: Run clean steps when a setting starting with "ANDROID_BUILD_ABI_" is changed.
|
|
|
|
|
// FIXME: Warn when kit settings are overridden by a project.
|
|
|
|
|
|
2022-04-25 13:40:05 +02:00
|
|
|
void CMakeBuildSystem::clearError(ForceEnabledChanged fec)
|
2017-03-01 12:52:24 +01:00
|
|
|
{
|
|
|
|
|
if (!m_error.isEmpty()) {
|
|
|
|
|
m_error.clear();
|
2017-04-07 11:15:26 +02:00
|
|
|
fec = ForceEnabledChanged::True;
|
2017-03-01 12:52:24 +01:00
|
|
|
}
|
2019-10-08 12:53:23 +02:00
|
|
|
if (fec == ForceEnabledChanged::True) {
|
|
|
|
|
qCDebug(cmakeBuildConfigurationLog) << "Emitting enabledChanged signal";
|
2022-04-25 13:40:05 +02:00
|
|
|
emit buildConfiguration()->enabledChanged();
|
2019-10-08 12:53:23 +02:00
|
|
|
}
|
2017-03-01 12:52:24 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
void CMakeBuildSystem::setInitialCMakeArguments(const QStringList &args)
|
2015-09-10 16:17:38 +02:00
|
|
|
{
|
2021-12-28 21:42:29 +01:00
|
|
|
QStringList additionalArguments;
|
2022-05-02 18:02:37 +02:00
|
|
|
buildConfiguration()->aspect<InitialCMakeArgumentsAspect>()->setAllValues(args.join('\n'), additionalArguments);
|
2021-12-28 21:42:29 +01:00
|
|
|
|
|
|
|
|
// Set the unknown additional arguments also for the "Current Configuration"
|
|
|
|
|
setAdditionalCMakeArguments(additionalArguments);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
QStringList CMakeBuildSystem::additionalCMakeArguments() const
|
2021-12-28 21:42:29 +01:00
|
|
|
{
|
2022-05-02 18:02:37 +02:00
|
|
|
return ProcessArgs::splitArgs(buildConfiguration()->aspect<AdditionalCMakeOptionsAspect>()->value());
|
2021-12-28 21:42:29 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
void CMakeBuildSystem::setAdditionalCMakeArguments(const QStringList &args)
|
2021-12-28 21:42:29 +01:00
|
|
|
{
|
|
|
|
|
const QStringList expandedAdditionalArguments = Utils::transform(args, [this](const QString &s) {
|
2022-05-02 18:02:37 +02:00
|
|
|
return buildConfiguration()->macroExpander()->expand(s);
|
2021-12-28 21:42:29 +01:00
|
|
|
});
|
|
|
|
|
const QStringList nonEmptyAdditionalArguments = Utils::filtered(expandedAdditionalArguments,
|
|
|
|
|
[](const QString &s) {
|
|
|
|
|
return !s.isEmpty();
|
|
|
|
|
});
|
2022-05-02 18:02:37 +02:00
|
|
|
buildConfiguration()->aspect<AdditionalCMakeOptionsAspect>()->setValue(
|
2021-12-28 21:42:29 +01:00
|
|
|
ProcessArgs::joinArgs(nonEmptyAdditionalArguments));
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
void CMakeBuildSystem::filterConfigArgumentsFromAdditionalCMakeArguments()
|
2021-12-28 21:42:29 +01:00
|
|
|
{
|
|
|
|
|
// 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
|
2022-02-03 11:24:56 +01:00
|
|
|
// in the addtional CMake options
|
2021-12-28 21:42:29 +01:00
|
|
|
const QStringList arguments = ProcessArgs::splitArgs(
|
2022-05-02 18:02:37 +02:00
|
|
|
buildConfiguration()->aspect<AdditionalCMakeOptionsAspect>()->value());
|
2022-02-03 11:24:56 +01:00
|
|
|
QStringList unknownOptions;
|
|
|
|
|
const CMakeConfig config = CMakeConfig::fromArguments(arguments, unknownOptions);
|
2021-12-28 21:42:29 +01:00
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
buildConfiguration()->aspect<AdditionalCMakeOptionsAspect>()->setValue(ProcessArgs::joinArgs(unknownOptions));
|
2015-09-10 16:17:38 +02:00
|
|
|
}
|
|
|
|
|
|
2022-04-25 13:40:05 +02:00
|
|
|
void CMakeBuildSystem::setError(const QString &message)
|
2016-02-11 16:33:15 +01:00
|
|
|
{
|
2019-10-08 12:53:23 +02:00
|
|
|
qCDebug(cmakeBuildConfigurationLog) << "Setting error to" << message;
|
|
|
|
|
QTC_ASSERT(!message.isEmpty(), return );
|
|
|
|
|
|
2017-07-18 16:48:02 +02:00
|
|
|
const QString oldMessage = m_error;
|
2017-03-01 12:52:24 +01:00
|
|
|
if (m_error != message)
|
2016-12-02 17:32:31 +01:00
|
|
|
m_error = message;
|
2019-10-08 12:53:23 +02:00
|
|
|
if (oldMessage.isEmpty() != !message.isEmpty()) {
|
|
|
|
|
qCDebug(cmakeBuildConfigurationLog) << "Emitting enabledChanged signal";
|
2022-04-25 13:40:05 +02:00
|
|
|
emit buildConfiguration()->enabledChanged();
|
2019-10-08 12:53:23 +02:00
|
|
|
}
|
2021-09-21 12:42:44 +02:00
|
|
|
TaskHub::addTask(BuildSystemTask(Task::TaskType::Error, message));
|
2022-04-25 14:03:03 +02:00
|
|
|
emit errorOccurred(m_error);
|
2016-02-11 16:33:15 +01:00
|
|
|
}
|
|
|
|
|
|
2022-04-25 13:40:05 +02:00
|
|
|
void CMakeBuildSystem::setWarning(const QString &message)
|
2016-05-12 17:23:03 +02:00
|
|
|
{
|
|
|
|
|
if (m_warning == message)
|
|
|
|
|
return;
|
|
|
|
|
m_warning = message;
|
2021-09-21 12:42:44 +02:00
|
|
|
TaskHub::addTask(BuildSystemTask(Task::TaskType::Warning, message));
|
2022-04-25 14:03:03 +02:00
|
|
|
emit warningOccurred(m_warning);
|
2016-05-12 17:23:03 +02:00
|
|
|
}
|
|
|
|
|
|
2022-04-25 13:40:05 +02:00
|
|
|
QString CMakeBuildSystem::error() const
|
2016-02-11 16:33:15 +01:00
|
|
|
{
|
|
|
|
|
return m_error;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-25 13:40:05 +02:00
|
|
|
QString CMakeBuildSystem::warning() const
|
2016-05-12 17:23:03 +02:00
|
|
|
{
|
|
|
|
|
return m_warning;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
NamedWidget *CMakeBuildConfiguration::createConfigWidget()
|
2009-11-26 14:43:27 +01:00
|
|
|
{
|
2022-05-02 18:02:37 +02:00
|
|
|
return new CMakeBuildSettingsWidget(m_buildSystem);
|
2009-11-26 14:43:27 +01:00
|
|
|
}
|
|
|
|
|
|
2021-02-04 14:53:42 +01:00
|
|
|
CMakeConfig CMakeBuildConfiguration::signingFlags() const
|
|
|
|
|
{
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-05 20:09:12 +02:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-07 18:17:24 +01:00
|
|
|
/*!
|
|
|
|
|
\class CMakeBuildConfigurationFactory
|
|
|
|
|
*/
|
|
|
|
|
|
ProjectExplorer/all: Re-organize BuildSteps/{Deploy,Build}Config setup
This follow the rough pattern of recent *RunConfigurationFactory changes
for build and deploy configurations.
- Collapse the two lines of constructors similar to what
890c1906e6fb2ec did for RunConfigurations
* Deploy* was purely mechanical
* Build* ctors are split in connects() in the ctor body
to create "empty shell for clone" etc
and build step additions in initialize() functions which
are only used in the create() case.
-- Allows to collapse the shared 'ctor()' functions, too.
- Move FooBuildConfigurationFactory::create() implementations
to FooBuildConfiguration() constructor. That was a strange
and unneeded ping-pong between factories and objects, and
furthermore allows one level less of indirection (and for a
later, left out here, some reduction of the
FooBuildConfiguration interfaces that were only used to
accommodate the *Factory::create() functions.
- Most {Build,Deploy}Configuration{,Factory} classes had a canHandle(),
but there wasn't one in the base classses. Have one there.
- Most canHandle() functions were checking simple restrictions on
e.g. project or target types, specify those by setters in the
constructors instead and check them in the base canHandle()
- clone() is generally replaced by a creation of a "shell object"
and a fromMap(source->toMap()), implemented in the base, there
are two cases left for Android and Qbs that needed(?) some extra
polish
- generally use canHandle() in base implementation, instead
of doing that in all Derived::canFoo()
- as a result, canCreate/create/canClone/clone reimplementations
are not needed anymore, keep the base implementation for
now (could be inlined into their only users later), but
de-virtualize them.
- Combine Ios{Preset,DSym}BuildStepFactory. There was only one
'dsym' build step they could create.
- Split the 'mangled' id into the ProjectConfiguration subtype
specific constant identifier, and a QString extraId() bit.
Only maintain the mangled id in saved settings.
- Make ProjectConfiguration::m_id a constant member, adapt
all constructors of derived classe.
Not done in this patch:
- Finish possible cosmetic changes on top
- Add a way to specify restrictions to supported Qt versions
(used in Android/Ios), as the base implementation does not
depend on the qtsupport plugin
- Combine the QList<X> availableFoo() + createFoo(X) function
pairs to somthing like a direct
QList<struct { X; std::function<X()>; }> fooCreators()
to avoid e.g. the baseId.withSuffix() <-> id.suffixAfter(base)
pingpong
- Remove the *Factories from the global object pool
- Do something about priority(). Falling back to plain
qmake in android+qmake setup is not helpful.
Change-Id: I2be7d88d554c5aa8b7db8edf5b93278e1ae0112a
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
2017-11-29 12:28:40 +01:00
|
|
|
CMakeBuildConfigurationFactory::CMakeBuildConfigurationFactory()
|
|
|
|
|
{
|
2021-02-04 14:53:42 +01:00
|
|
|
registerBuildConfiguration<CMakeBuildConfiguration>(Constants::CMAKE_BUILDCONFIGURATION_ID);
|
2018-05-04 16:52:21 +02:00
|
|
|
|
2020-04-07 14:44:22 +02:00
|
|
|
setSupportedProjectType(CMakeProjectManager::Constants::CMAKE_PROJECT_ID);
|
|
|
|
|
setSupportedProjectMimeTypeName(Constants::CMAKE_PROJECT_MIMETYPE);
|
2020-01-09 15:06:30 +01:00
|
|
|
|
2020-01-09 18:42:28 +01:00
|
|
|
setBuildGenerator([](const Kit *k, const FilePath &projectPath, bool forSetup) {
|
2020-01-09 15:06:30 +01:00
|
|
|
QList<BuildInfo> result;
|
|
|
|
|
|
|
|
|
|
FilePath path = forSetup ? Project::projectDirectory(projectPath) : projectPath;
|
|
|
|
|
|
|
|
|
|
for (int type = BuildTypeDebug; type != BuildTypeLast; ++type) {
|
2020-01-09 18:42:28 +01:00
|
|
|
BuildInfo info = createBuildInfo(BuildType(type));
|
2020-01-09 15:06:30 +01:00
|
|
|
if (forSetup) {
|
|
|
|
|
info.buildDirectory = CMakeBuildConfiguration::shadowBuildDirectory(projectPath,
|
|
|
|
|
k,
|
|
|
|
|
info.typeName,
|
|
|
|
|
info.buildType);
|
|
|
|
|
}
|
|
|
|
|
result << info;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
});
|
ProjectExplorer/all: Re-organize BuildSteps/{Deploy,Build}Config setup
This follow the rough pattern of recent *RunConfigurationFactory changes
for build and deploy configurations.
- Collapse the two lines of constructors similar to what
890c1906e6fb2ec did for RunConfigurations
* Deploy* was purely mechanical
* Build* ctors are split in connects() in the ctor body
to create "empty shell for clone" etc
and build step additions in initialize() functions which
are only used in the create() case.
-- Allows to collapse the shared 'ctor()' functions, too.
- Move FooBuildConfigurationFactory::create() implementations
to FooBuildConfiguration() constructor. That was a strange
and unneeded ping-pong between factories and objects, and
furthermore allows one level less of indirection (and for a
later, left out here, some reduction of the
FooBuildConfiguration interfaces that were only used to
accommodate the *Factory::create() functions.
- Most {Build,Deploy}Configuration{,Factory} classes had a canHandle(),
but there wasn't one in the base classses. Have one there.
- Most canHandle() functions were checking simple restrictions on
e.g. project or target types, specify those by setters in the
constructors instead and check them in the base canHandle()
- clone() is generally replaced by a creation of a "shell object"
and a fromMap(source->toMap()), implemented in the base, there
are two cases left for Android and Qbs that needed(?) some extra
polish
- generally use canHandle() in base implementation, instead
of doing that in all Derived::canFoo()
- as a result, canCreate/create/canClone/clone reimplementations
are not needed anymore, keep the base implementation for
now (could be inlined into their only users later), but
de-virtualize them.
- Combine Ios{Preset,DSym}BuildStepFactory. There was only one
'dsym' build step they could create.
- Split the 'mangled' id into the ProjectConfiguration subtype
specific constant identifier, and a QString extraId() bit.
Only maintain the mangled id in saved settings.
- Make ProjectConfiguration::m_id a constant member, adapt
all constructors of derived classe.
Not done in this patch:
- Finish possible cosmetic changes on top
- Add a way to specify restrictions to supported Qt versions
(used in Android/Ios), as the base implementation does not
depend on the qtsupport plugin
- Combine the QList<X> availableFoo() + createFoo(X) function
pairs to somthing like a direct
QList<struct { X; std::function<X()>; }> fooCreators()
to avoid e.g. the baseId.withSuffix() <-> id.suffixAfter(base)
pingpong
- Remove the *Factories from the global object pool
- Do something about priority(). Falling back to plain
qmake in android+qmake setup is not helpful.
Change-Id: I2be7d88d554c5aa8b7db8edf5b93278e1ae0112a
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
2017-11-29 12:28:40 +01:00
|
|
|
}
|
2010-01-07 18:17:24 +01:00
|
|
|
|
2019-08-05 16:35:07 +02:00
|
|
|
CMakeBuildConfigurationFactory::BuildType CMakeBuildConfigurationFactory::buildTypeFromByteArray(
|
|
|
|
|
const QByteArray &in)
|
2017-02-07 16:23:36 +01:00
|
|
|
{
|
|
|
|
|
const QByteArray bt = in.toLower();
|
|
|
|
|
if (bt == "debug")
|
|
|
|
|
return BuildTypeDebug;
|
|
|
|
|
if (bt == "release")
|
|
|
|
|
return BuildTypeRelease;
|
|
|
|
|
if (bt == "relwithdebinfo")
|
|
|
|
|
return BuildTypeRelWithDebInfo;
|
|
|
|
|
if (bt == "minsizerel")
|
|
|
|
|
return BuildTypeMinSizeRel;
|
|
|
|
|
return BuildTypeNone;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-05 16:35:07 +02:00
|
|
|
BuildConfiguration::BuildType CMakeBuildConfigurationFactory::cmakeBuildTypeToBuildType(
|
|
|
|
|
const CMakeBuildConfigurationFactory::BuildType &in)
|
2017-02-07 16:23:36 +01:00
|
|
|
{
|
CMake: Add 'Profile' configuration
Get rid of the hardcoded QML Debugging for Debug & RelWithDebInfo from
the project template, because RelWithDebInfo is actually a good
configuration for doing releases (we use it for Qt Creator), and
enabling QML debugging for releases is a bad idea.
Instead enable QML Debugging in Qt Creator for the Debug configuration,
and add a 'Profile' configuration that is 'RelWithDebInfo + QML
Debugging'.
When importing a build, we only set the "QML debugging" option of the
build configuration, if it is enabled in the imported build, even if it
uses CMAKE_BUILD_TYPE=Debug .
One drawback: When not importing a build, but just setting the build
directory of a "Profile" or "Debug" configuration to an existing build,
Qt Creator asks if it should apply "-DCMAKE_CXX_FLAGS=-DQT_QML_DEBUG".
The user can choose not to, but then is asked the next time again, and
it is not obvious that the "QML debugging" option is responsible for
this.
That is somewhat orthogonal to this change though: Even without this
change, if the user changes the QML debugging option from "Leave at
Default" to "Enable", the same happens, and it is also not clear to the
user how to get rid of it. The user might not even have realized that
they changed the option (e.g. on platforms where the mouse wheel cycles
combo box values).
I think the correct solution is to 1. make clearer where the CMake flags
came from in that dialog, 2. allow the user to cancel a build from that
dialog, 3. allow the user to discard these changes (by changing the
setting) from that dialog. But that is for another patch.
Amends 3300182d405bffe062a0f2be900f35822a9e20b0
Amends 77fed0b0fdce2a93f465c20cd87c41900117dcda
Change-Id: I95de59473b67c5afd6a53ea7f49838dbaef770d4
Reviewed-by: Artem Sokolovskii <artem.sokolovskii@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
2022-05-18 10:40:31 +02:00
|
|
|
return createBuildInfo(in).buildType;
|
2017-02-07 16:23:36 +01:00
|
|
|
}
|
|
|
|
|
|
2020-01-09 18:42:28 +01:00
|
|
|
BuildInfo CMakeBuildConfigurationFactory::createBuildInfo(BuildType buildType)
|
2013-07-22 15:53:57 +02:00
|
|
|
{
|
2020-01-09 18:42:28 +01:00
|
|
|
BuildInfo info;
|
2019-01-29 16:51:17 +01:00
|
|
|
|
2015-09-10 16:17:38 +02:00
|
|
|
switch (buildType) {
|
|
|
|
|
case BuildTypeNone:
|
2019-10-09 18:36:17 +02:00
|
|
|
info.typeName = "Build";
|
2020-01-09 17:32:51 +01:00
|
|
|
info.displayName = BuildConfiguration::tr("Build");
|
2019-10-09 18:36:17 +02:00
|
|
|
info.buildType = BuildConfiguration::Unknown;
|
2015-09-10 16:17:38 +02:00
|
|
|
break;
|
CMake: Add 'Profile' configuration
Get rid of the hardcoded QML Debugging for Debug & RelWithDebInfo from
the project template, because RelWithDebInfo is actually a good
configuration for doing releases (we use it for Qt Creator), and
enabling QML debugging for releases is a bad idea.
Instead enable QML Debugging in Qt Creator for the Debug configuration,
and add a 'Profile' configuration that is 'RelWithDebInfo + QML
Debugging'.
When importing a build, we only set the "QML debugging" option of the
build configuration, if it is enabled in the imported build, even if it
uses CMAKE_BUILD_TYPE=Debug .
One drawback: When not importing a build, but just setting the build
directory of a "Profile" or "Debug" configuration to an existing build,
Qt Creator asks if it should apply "-DCMAKE_CXX_FLAGS=-DQT_QML_DEBUG".
The user can choose not to, but then is asked the next time again, and
it is not obvious that the "QML debugging" option is responsible for
this.
That is somewhat orthogonal to this change though: Even without this
change, if the user changes the QML debugging option from "Leave at
Default" to "Enable", the same happens, and it is also not clear to the
user how to get rid of it. The user might not even have realized that
they changed the option (e.g. on platforms where the mouse wheel cycles
combo box values).
I think the correct solution is to 1. make clearer where the CMake flags
came from in that dialog, 2. allow the user to cancel a build from that
dialog, 3. allow the user to discard these changes (by changing the
setting) from that dialog. But that is for another patch.
Amends 3300182d405bffe062a0f2be900f35822a9e20b0
Amends 77fed0b0fdce2a93f465c20cd87c41900117dcda
Change-Id: I95de59473b67c5afd6a53ea7f49838dbaef770d4
Reviewed-by: Artem Sokolovskii <artem.sokolovskii@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
2022-05-18 10:40:31 +02:00
|
|
|
case BuildTypeDebug: {
|
2019-10-09 18:36:17 +02:00
|
|
|
info.typeName = "Debug";
|
2020-01-09 17:32:51 +01:00
|
|
|
info.displayName = BuildConfiguration::tr("Debug");
|
2019-01-29 16:51:17 +01:00
|
|
|
info.buildType = BuildConfiguration::Debug;
|
CMake: Add 'Profile' configuration
Get rid of the hardcoded QML Debugging for Debug & RelWithDebInfo from
the project template, because RelWithDebInfo is actually a good
configuration for doing releases (we use it for Qt Creator), and
enabling QML debugging for releases is a bad idea.
Instead enable QML Debugging in Qt Creator for the Debug configuration,
and add a 'Profile' configuration that is 'RelWithDebInfo + QML
Debugging'.
When importing a build, we only set the "QML debugging" option of the
build configuration, if it is enabled in the imported build, even if it
uses CMAKE_BUILD_TYPE=Debug .
One drawback: When not importing a build, but just setting the build
directory of a "Profile" or "Debug" configuration to an existing build,
Qt Creator asks if it should apply "-DCMAKE_CXX_FLAGS=-DQT_QML_DEBUG".
The user can choose not to, but then is asked the next time again, and
it is not obvious that the "QML debugging" option is responsible for
this.
That is somewhat orthogonal to this change though: Even without this
change, if the user changes the QML debugging option from "Leave at
Default" to "Enable", the same happens, and it is also not clear to the
user how to get rid of it. The user might not even have realized that
they changed the option (e.g. on platforms where the mouse wheel cycles
combo box values).
I think the correct solution is to 1. make clearer where the CMake flags
came from in that dialog, 2. allow the user to cancel a build from that
dialog, 3. allow the user to discard these changes (by changing the
setting) from that dialog. But that is for another patch.
Amends 3300182d405bffe062a0f2be900f35822a9e20b0
Amends 77fed0b0fdce2a93f465c20cd87c41900117dcda
Change-Id: I95de59473b67c5afd6a53ea7f49838dbaef770d4
Reviewed-by: Artem Sokolovskii <artem.sokolovskii@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
2022-05-18 10:40:31 +02:00
|
|
|
QVariantMap extraInfo;
|
|
|
|
|
// enable QML debugging by default
|
|
|
|
|
extraInfo.insert(Constants::QML_DEBUG_SETTING, TriState::Enabled.toVariant());
|
|
|
|
|
info.extraInfo = extraInfo;
|
2015-09-10 16:17:38 +02:00
|
|
|
break;
|
CMake: Add 'Profile' configuration
Get rid of the hardcoded QML Debugging for Debug & RelWithDebInfo from
the project template, because RelWithDebInfo is actually a good
configuration for doing releases (we use it for Qt Creator), and
enabling QML debugging for releases is a bad idea.
Instead enable QML Debugging in Qt Creator for the Debug configuration,
and add a 'Profile' configuration that is 'RelWithDebInfo + QML
Debugging'.
When importing a build, we only set the "QML debugging" option of the
build configuration, if it is enabled in the imported build, even if it
uses CMAKE_BUILD_TYPE=Debug .
One drawback: When not importing a build, but just setting the build
directory of a "Profile" or "Debug" configuration to an existing build,
Qt Creator asks if it should apply "-DCMAKE_CXX_FLAGS=-DQT_QML_DEBUG".
The user can choose not to, but then is asked the next time again, and
it is not obvious that the "QML debugging" option is responsible for
this.
That is somewhat orthogonal to this change though: Even without this
change, if the user changes the QML debugging option from "Leave at
Default" to "Enable", the same happens, and it is also not clear to the
user how to get rid of it. The user might not even have realized that
they changed the option (e.g. on platforms where the mouse wheel cycles
combo box values).
I think the correct solution is to 1. make clearer where the CMake flags
came from in that dialog, 2. allow the user to cancel a build from that
dialog, 3. allow the user to discard these changes (by changing the
setting) from that dialog. But that is for another patch.
Amends 3300182d405bffe062a0f2be900f35822a9e20b0
Amends 77fed0b0fdce2a93f465c20cd87c41900117dcda
Change-Id: I95de59473b67c5afd6a53ea7f49838dbaef770d4
Reviewed-by: Artem Sokolovskii <artem.sokolovskii@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
2022-05-18 10:40:31 +02:00
|
|
|
}
|
2015-09-10 16:17:38 +02:00
|
|
|
case BuildTypeRelease:
|
2019-10-09 18:36:17 +02:00
|
|
|
info.typeName = "Release";
|
2020-01-09 17:32:51 +01:00
|
|
|
info.displayName = BuildConfiguration::tr("Release");
|
2019-01-29 16:51:17 +01:00
|
|
|
info.buildType = BuildConfiguration::Release;
|
2015-09-10 16:17:38 +02:00
|
|
|
break;
|
|
|
|
|
case BuildTypeMinSizeRel:
|
2019-10-09 18:36:17 +02:00
|
|
|
info.typeName = "MinSizeRel";
|
2020-01-09 17:32:51 +01:00
|
|
|
info.displayName = CMakeBuildConfiguration::tr("Minimum Size Release");
|
2019-01-29 16:51:17 +01:00
|
|
|
info.buildType = BuildConfiguration::Release;
|
2015-09-10 16:17:38 +02:00
|
|
|
break;
|
|
|
|
|
case BuildTypeRelWithDebInfo:
|
2019-10-09 18:36:17 +02:00
|
|
|
info.typeName = "RelWithDebInfo";
|
2020-01-09 17:32:51 +01:00
|
|
|
info.displayName = CMakeBuildConfiguration::tr("Release with Debug Information");
|
2019-01-29 16:51:17 +01:00
|
|
|
info.buildType = BuildConfiguration::Profile;
|
2015-09-10 16:17:38 +02:00
|
|
|
break;
|
CMake: Add 'Profile' configuration
Get rid of the hardcoded QML Debugging for Debug & RelWithDebInfo from
the project template, because RelWithDebInfo is actually a good
configuration for doing releases (we use it for Qt Creator), and
enabling QML debugging for releases is a bad idea.
Instead enable QML Debugging in Qt Creator for the Debug configuration,
and add a 'Profile' configuration that is 'RelWithDebInfo + QML
Debugging'.
When importing a build, we only set the "QML debugging" option of the
build configuration, if it is enabled in the imported build, even if it
uses CMAKE_BUILD_TYPE=Debug .
One drawback: When not importing a build, but just setting the build
directory of a "Profile" or "Debug" configuration to an existing build,
Qt Creator asks if it should apply "-DCMAKE_CXX_FLAGS=-DQT_QML_DEBUG".
The user can choose not to, but then is asked the next time again, and
it is not obvious that the "QML debugging" option is responsible for
this.
That is somewhat orthogonal to this change though: Even without this
change, if the user changes the QML debugging option from "Leave at
Default" to "Enable", the same happens, and it is also not clear to the
user how to get rid of it. The user might not even have realized that
they changed the option (e.g. on platforms where the mouse wheel cycles
combo box values).
I think the correct solution is to 1. make clearer where the CMake flags
came from in that dialog, 2. allow the user to cancel a build from that
dialog, 3. allow the user to discard these changes (by changing the
setting) from that dialog. But that is for another patch.
Amends 3300182d405bffe062a0f2be900f35822a9e20b0
Amends 77fed0b0fdce2a93f465c20cd87c41900117dcda
Change-Id: I95de59473b67c5afd6a53ea7f49838dbaef770d4
Reviewed-by: Artem Sokolovskii <artem.sokolovskii@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
2022-05-18 10:40:31 +02:00
|
|
|
case BuildTypeProfile: {
|
|
|
|
|
info.typeName = "Profile";
|
|
|
|
|
info.displayName = CMakeBuildConfiguration::tr("Profile");
|
|
|
|
|
info.buildType = BuildConfiguration::Profile;
|
|
|
|
|
QVariantMap extraInfo;
|
|
|
|
|
// override CMake build type, which defaults to info.typeName
|
|
|
|
|
extraInfo.insert(CMAKE_BUILD_TYPE, "RelWithDebInfo");
|
|
|
|
|
// enable QML debugging by default
|
|
|
|
|
extraInfo.insert(Constants::QML_DEBUG_SETTING, TriState::Enabled.toVariant());
|
|
|
|
|
info.extraInfo = extraInfo;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-09-10 16:17:38 +02:00
|
|
|
default:
|
|
|
|
|
QTC_CHECK(false);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2013-07-22 15:53:57 +02:00
|
|
|
|
|
|
|
|
return info;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
BuildConfiguration::BuildType CMakeBuildConfiguration::buildType() const
|
2022-05-02 18:02:37 +02:00
|
|
|
{
|
|
|
|
|
return m_buildSystem->buildType();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BuildConfiguration::BuildType CMakeBuildSystem::buildType() const
|
2011-03-03 16:12:00 +01:00
|
|
|
{
|
2021-07-06 10:29:29 +02:00
|
|
|
QByteArray cmakeBuildTypeName = m_configurationFromCMake.valueOf("CMAKE_BUILD_TYPE");
|
2021-01-14 16:38:55 +01:00
|
|
|
if (cmakeBuildTypeName.isEmpty()) {
|
2021-07-06 10:29:29 +02:00
|
|
|
QByteArray cmakeCfgTypes = m_configurationFromCMake.valueOf("CMAKE_CONFIGURATION_TYPES");
|
2021-01-14 16:38:55 +01:00
|
|
|
if (!cmakeCfgTypes.isEmpty())
|
|
|
|
|
cmakeBuildTypeName = cmakeBuildType().toUtf8();
|
|
|
|
|
}
|
2011-03-03 16:12:00 +01:00
|
|
|
// Cover all common CMake build types
|
2017-02-07 16:23:36 +01:00
|
|
|
const CMakeBuildConfigurationFactory::BuildType cmakeBuildType
|
2019-08-05 16:39:00 +02:00
|
|
|
= CMakeBuildConfigurationFactory::buildTypeFromByteArray(cmakeBuildTypeName);
|
2017-02-07 16:23:36 +01:00
|
|
|
return CMakeBuildConfigurationFactory::cmakeBuildTypeToBuildType(cmakeBuildType);
|
2011-03-03 16:12:00 +01:00
|
|
|
}
|
2012-10-02 17:46:12 +02:00
|
|
|
|
2019-10-25 09:55:32 +02:00
|
|
|
BuildSystem *CMakeBuildConfiguration::buildSystem() const
|
|
|
|
|
{
|
|
|
|
|
return m_buildSystem;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-02 19:16:40 +01:00
|
|
|
void CMakeBuildConfiguration::setSourceDirectory(const FilePath &path)
|
|
|
|
|
{
|
2022-02-07 17:04:26 +01:00
|
|
|
aspect<SourceDirectoryAspect>()->setFilePath(path);
|
2020-12-02 19:16:40 +01:00
|
|
|
}
|
|
|
|
|
|
2021-02-12 16:15:26 +01:00
|
|
|
FilePath CMakeBuildConfiguration::sourceDirectory() const
|
2020-12-02 19:16:40 +01:00
|
|
|
{
|
2022-02-07 17:04:26 +01:00
|
|
|
return aspect<SourceDirectoryAspect>()->filePath();
|
2020-12-02 19:16:40 +01:00
|
|
|
}
|
|
|
|
|
|
2022-06-15 14:40:23 +02:00
|
|
|
void CMakeBuildConfiguration::addToEnvironment(Utils::Environment &env) const
|
|
|
|
|
{
|
|
|
|
|
CMakeSpecificSettings *settings = CMakeProjectPlugin::projectTypeSpecificSettings();
|
|
|
|
|
if (!settings->ninjaPath.filePath().isEmpty()) {
|
|
|
|
|
const Utils::FilePath ninja = settings->ninjaPath.filePath();
|
|
|
|
|
env.appendOrSetPath(ninja.isFile() ? ninja.parentDir() : ninja);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-10 19:12:40 +02:00
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
QString CMakeBuildSystem::cmakeBuildType() const
|
2021-01-14 16:38:55 +01:00
|
|
|
{
|
2021-12-28 21:42:29 +01:00
|
|
|
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;
|
|
|
|
|
});
|
2021-09-08 17:16:48 +02:00
|
|
|
if (it != config.end())
|
2022-05-02 18:02:37 +02:00
|
|
|
const_cast<CMakeBuildSystem*>(this)
|
2021-03-18 14:20:02 +01:00
|
|
|
->setCMakeBuildType(QString::fromUtf8(it->value));
|
2021-09-08 17:16:48 +02:00
|
|
|
};
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
if (!isMultiConfig())
|
2021-09-08 17:16:48 +02:00
|
|
|
setBuildTypeFromConfig(configurationChanges());
|
2021-03-18 14:20:02 +01:00
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
QString cmakeBuildType = buildConfiguration()->aspect<BuildTypeAspect>()->value();
|
2021-03-18 14:20:02 +01:00
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
const Utils::FilePath cmakeCacheTxt = buildConfiguration()->buildDirectory().pathAppended("CMakeCache.txt");
|
2022-05-05 15:51:11 +02:00
|
|
|
const bool hasCMakeCache = cmakeCacheTxt.exists();
|
2021-03-18 14:20:02 +01:00
|
|
|
CMakeConfig config;
|
|
|
|
|
|
|
|
|
|
if (cmakeBuildType == "Unknown") {
|
|
|
|
|
// The "Unknown" type is the case of loading of an existing project
|
|
|
|
|
// that doesn't have the "CMake.Build.Type" aspect saved
|
|
|
|
|
if (hasCMakeCache) {
|
|
|
|
|
QString errorMessage;
|
2022-05-05 15:51:11 +02:00
|
|
|
config = CMakeConfig::fromFile(cmakeCacheTxt, &errorMessage);
|
2021-03-18 14:20:02 +01:00
|
|
|
} else {
|
2021-12-28 21:42:29 +01:00
|
|
|
config = initialCMakeConfiguration();
|
2021-03-18 14:20:02 +01:00
|
|
|
}
|
|
|
|
|
} else if (!hasCMakeCache) {
|
2021-12-28 21:42:29 +01:00
|
|
|
config = initialCMakeConfiguration();
|
2021-03-18 14:20:02 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
if (!config.isEmpty() && !isMultiConfig())
|
2021-09-08 17:16:48 +02:00
|
|
|
setBuildTypeFromConfig(config);
|
2021-03-18 14:20:02 +01:00
|
|
|
|
|
|
|
|
return cmakeBuildType;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:02:37 +02:00
|
|
|
void CMakeBuildSystem::setCMakeBuildType(const QString &cmakeBuildType, bool quiet)
|
2021-03-18 14:20:02 +01:00
|
|
|
{
|
2022-05-02 18:02:37 +02:00
|
|
|
auto aspect = buildConfiguration()->aspect<BuildTypeAspect>();
|
2021-03-18 14:20:02 +01:00
|
|
|
if (quiet) {
|
2022-05-02 18:02:37 +02:00
|
|
|
aspect->setValueQuietly(cmakeBuildType);
|
|
|
|
|
aspect->update();
|
2021-03-18 14:20:02 +01:00
|
|
|
} else {
|
2022-05-02 18:02:37 +02:00
|
|
|
aspect->setValue(cmakeBuildType);
|
2021-03-18 14:20:02 +01:00
|
|
|
}
|
2021-01-14 16:38:55 +01:00
|
|
|
}
|
|
|
|
|
|
2021-02-04 14:53:42 +01:00
|
|
|
namespace Internal {
|
|
|
|
|
|
2020-04-02 14:49:05 +02:00
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
|
// - InitialCMakeParametersAspect:
|
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
|
|
2021-12-28 21:42:29 +01:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-03 11:24:56 +01:00
|
|
|
void InitialCMakeArgumentsAspect::setAllValues(const QString &values, QStringList &additionalOptions)
|
2021-12-28 21:42:29 +01:00
|
|
|
{
|
|
|
|
|
QStringList arguments = values.split('\n', Qt::SkipEmptyParts);
|
2022-03-02 14:29:15 +01:00
|
|
|
QString cmakeGenerator;
|
2021-12-28 21:42:29 +01:00
|
|
|
for (QString &arg: arguments) {
|
2022-02-22 18:16:24 +01:00
|
|
|
if (arg.startsWith("-G")) {
|
|
|
|
|
const QString strDash(" - ");
|
|
|
|
|
const int idxDash = arg.indexOf(strDash);
|
|
|
|
|
if (idxDash > 0) {
|
|
|
|
|
// -GCodeBlocks - Ninja
|
2022-03-02 14:29:15 +01:00
|
|
|
cmakeGenerator = "-DCMAKE_GENERATOR:STRING=" + arg.mid(idxDash + strDash.length());
|
2022-02-22 18:16:24 +01:00
|
|
|
|
2022-02-28 12:15:53 +01:00
|
|
|
arg = arg.left(idxDash);
|
2022-02-22 18:16:24 +01:00
|
|
|
arg.replace("-G", "-DCMAKE_EXTRA_GENERATOR:STRING=");
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
// -GNinja
|
|
|
|
|
arg.replace("-G", "-DCMAKE_GENERATOR:STRING=");
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-12-28 21:42:29 +01:00
|
|
|
if (arg.startsWith("-A"))
|
|
|
|
|
arg.replace("-A", "-DCMAKE_GENERATOR_PLATFORM:STRING=");
|
|
|
|
|
if (arg.startsWith("-T"))
|
|
|
|
|
arg.replace("-T", "-DCMAKE_GENERATOR_TOOLSET:STRING=");
|
|
|
|
|
}
|
2022-03-02 14:29:15 +01:00
|
|
|
if (!cmakeGenerator.isEmpty())
|
|
|
|
|
arguments.append(cmakeGenerator);
|
|
|
|
|
|
2022-02-03 11:24:56 +01:00
|
|
|
m_cmakeConfiguration = CMakeConfig::fromArguments(arguments, additionalOptions);
|
2022-01-27 12:36:21 +01:00
|
|
|
for (CMakeConfigItem &ci : m_cmakeConfiguration)
|
|
|
|
|
ci.isInitial = true;
|
2021-12-28 21:42:29 +01:00
|
|
|
|
2022-02-03 11:24:56 +01:00
|
|
|
// Display the unknown arguments in "Additional CMake Options"
|
|
|
|
|
const QString additionalOptionsValue = ProcessArgs::joinArgs(additionalOptions);
|
|
|
|
|
BaseAspect::setValueQuietly(additionalOptionsValue);
|
2021-12-28 21:42:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void InitialCMakeArgumentsAspect::setCMakeConfiguration(const CMakeConfig &config)
|
|
|
|
|
{
|
|
|
|
|
m_cmakeConfiguration = config;
|
2022-01-27 12:36:21 +01:00
|
|
|
for (CMakeConfigItem &ci : m_cmakeConfiguration)
|
|
|
|
|
ci.isInitial = true;
|
2021-12-28 21:42:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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());
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-02 14:49:05 +02:00
|
|
|
InitialCMakeArgumentsAspect::InitialCMakeArgumentsAspect()
|
|
|
|
|
{
|
|
|
|
|
setSettingsKey("CMake.Initial.Parameters");
|
2022-02-03 16:12:41 +01:00
|
|
|
setLabelText(tr("Additional CMake <a href=\"options\">options</a>:"));
|
2021-12-28 21:42:29 +01:00
|
|
|
setDisplayStyle(LineEditDisplay);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------
|
2022-02-03 11:24:56 +01:00
|
|
|
// - AdditionalCMakeOptionsAspect:
|
2021-12-28 21:42:29 +01:00
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
|
|
2022-02-03 11:24:56 +01:00
|
|
|
AdditionalCMakeOptionsAspect::AdditionalCMakeOptionsAspect()
|
2021-12-28 21:42:29 +01:00
|
|
|
{
|
2022-02-03 11:24:56 +01:00
|
|
|
setSettingsKey("CMake.Additional.Options");
|
2022-02-03 16:12:41 +01:00
|
|
|
setLabelText(tr("Additional CMake <a href=\"options\">options</a>:"));
|
2021-12-28 21:42:29 +01:00
|
|
|
setDisplayStyle(LineEditDisplay);
|
2020-04-02 14:49:05 +02:00
|
|
|
}
|
|
|
|
|
|
2020-12-02 19:16:40 +01:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// SourceDirectoryAspect:
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
SourceDirectoryAspect::SourceDirectoryAspect()
|
|
|
|
|
{
|
|
|
|
|
// Will not be displayed, only persisted
|
|
|
|
|
setSettingsKey("CMake.Source.Directory");
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-14 16:38:55 +01:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// BuildTypeAspect:
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
BuildTypeAspect::BuildTypeAspect()
|
|
|
|
|
{
|
CMake: Add 'Profile' configuration
Get rid of the hardcoded QML Debugging for Debug & RelWithDebInfo from
the project template, because RelWithDebInfo is actually a good
configuration for doing releases (we use it for Qt Creator), and
enabling QML debugging for releases is a bad idea.
Instead enable QML Debugging in Qt Creator for the Debug configuration,
and add a 'Profile' configuration that is 'RelWithDebInfo + QML
Debugging'.
When importing a build, we only set the "QML debugging" option of the
build configuration, if it is enabled in the imported build, even if it
uses CMAKE_BUILD_TYPE=Debug .
One drawback: When not importing a build, but just setting the build
directory of a "Profile" or "Debug" configuration to an existing build,
Qt Creator asks if it should apply "-DCMAKE_CXX_FLAGS=-DQT_QML_DEBUG".
The user can choose not to, but then is asked the next time again, and
it is not obvious that the "QML debugging" option is responsible for
this.
That is somewhat orthogonal to this change though: Even without this
change, if the user changes the QML debugging option from "Leave at
Default" to "Enable", the same happens, and it is also not clear to the
user how to get rid of it. The user might not even have realized that
they changed the option (e.g. on platforms where the mouse wheel cycles
combo box values).
I think the correct solution is to 1. make clearer where the CMake flags
came from in that dialog, 2. allow the user to cancel a build from that
dialog, 3. allow the user to discard these changes (by changing the
setting) from that dialog. But that is for another patch.
Amends 3300182d405bffe062a0f2be900f35822a9e20b0
Amends 77fed0b0fdce2a93f465c20cd87c41900117dcda
Change-Id: I95de59473b67c5afd6a53ea7f49838dbaef770d4
Reviewed-by: Artem Sokolovskii <artem.sokolovskii@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
2022-05-18 10:40:31 +02:00
|
|
|
setSettingsKey(CMAKE_BUILD_TYPE);
|
2021-03-18 14:20:02 +01:00
|
|
|
setLabelText(tr("Build type:"));
|
|
|
|
|
setDisplayStyle(LineEditDisplay);
|
|
|
|
|
setDefaultValue("Unknown");
|
2021-01-14 16:38:55 +01:00
|
|
|
}
|
|
|
|
|
|
2014-10-22 09:16:55 +02:00
|
|
|
} // namespace Internal
|
|
|
|
|
} // namespace CMakeProjectManager
|