CMakePM: Make "Build type" aspect visible

For single configuration projects if you change the build type
aspect you will change the CMAKE_BUILD_TYPE variable.

When switching the build directory the existing CMAKE_BUILD_TYPE
will be set as build type aspect.

Fixes: QTCREATORBUG-25451
Change-Id: I13519e95c316c556cc1348fba6121637d2fd4275
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Cristian Adam
2021-03-18 14:20:02 +01:00
parent 8eaf24a694
commit 637d45c66a
6 changed files with 77 additions and 18 deletions

View File

@@ -640,7 +640,7 @@ void StringAspect::setValue(const QString &val)
void StringAspect::fromMap(const QVariantMap &map) void StringAspect::fromMap(const QVariantMap &map)
{ {
if (!settingsKey().isEmpty()) if (!settingsKey().isEmpty())
BaseAspect::setValueQuietly(map.value(settingsKey())); BaseAspect::setValueQuietly(map.value(settingsKey(), defaultValue()));
if (d->m_checker) if (d->m_checker)
d->m_checker->fromMap(map); d->m_checker->fromMap(map);
} }

View File

@@ -303,7 +303,7 @@ public:
signals: signals:
void checkedChanged(); void checkedChanged();
private: protected:
void update(); void update();
std::unique_ptr<Internal::StringAspectPrivate> d; std::unique_ptr<Internal::StringAspectPrivate> d;

View File

@@ -76,16 +76,6 @@ BuildDirParameters::BuildDirParameters(CMakeBuildConfiguration *bc)
buildDirectory = bc->buildDirectory(); buildDirectory = bc->buildDirectory();
cmakeBuildType = bc->cmakeBuildType(); cmakeBuildType = bc->cmakeBuildType();
if (cmakeBuildType.isEmpty()) {
// The empty build type might be just a case of loading of an existing project
// that doesn't have the "CMake.Build.Type" aspect saved
const CMakeConfig config = CMakeConfigItem::itemsFromArguments(initialCMakeArguments);
if (!config.isEmpty()) {
cmakeBuildType = QString::fromLatin1(CMakeConfigItem::valueOf("CMAKE_BUILD_TYPE", config));
if (!cmakeBuildType.isEmpty())
bc->setCMakeBuildType(cmakeBuildType);
}
}
environment = bc->environment(); environment = bc->environment();
// Disable distributed building for configuration runs. CMake does not do those in parallel, // Disable distributed building for configuration runs. CMake does not do those in parallel,

View File

@@ -189,6 +189,17 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
buildDirAspect->addToLayout(aspectWidgetBuilder); buildDirAspect->addToLayout(aspectWidgetBuilder);
aspectWidgetBuilder.finishRow(); aspectWidgetBuilder.finishRow();
initialCMakeAspect->addToLayout(aspectWidgetBuilder); initialCMakeAspect->addToLayout(aspectWidgetBuilder);
aspectWidgetBuilder.finishRow();
auto buildTypeAspect = bc->aspect<BuildTypeAspect>();
connect(buildTypeAspect, &BaseAspect::changed, this, [this, buildTypeAspect]() {
if (!m_buildConfiguration->isMultiConfig()) {
CMakeConfig config;
config << CMakeConfigItem("CMAKE_BUILD_TYPE", buildTypeAspect->value().toUtf8());
m_configModel->setBatchEditConfiguration(config);
}
});
buildTypeAspect->addToLayout(aspectWidgetBuilder);
mainLayout->addWidget(aspectWidget, row, 0, 1, -1); mainLayout->addWidget(aspectWidget, row, 0, 1, -1);
++row; ++row;
@@ -1257,13 +1268,57 @@ FilePath CMakeBuildConfiguration::sourceDirectory() const
QString CMakeBuildConfiguration::cmakeBuildType() const QString CMakeBuildConfiguration::cmakeBuildType() const
{ {
return aspect<BuildTypeAspect>()->value(); if (!isMultiConfig()) {
auto configChanges = configurationChanges();
auto it = std::find_if(configChanges.begin(), configChanges.end(),
[](const CMakeConfigItem &item) { return item.key == "CMAKE_BUILD_TYPE";});
if (it != configChanges.end())
const_cast<CMakeBuildConfiguration*>(this)
->setCMakeBuildType(QString::fromUtf8(it->value));
} }
void CMakeBuildConfiguration::setCMakeBuildType(const QString &cmakeBuildType) QString cmakeBuildType = aspect<BuildTypeAspect>()->value();
const Utils::FilePath cmakeCacheTxt = buildDirectory().pathAppended("CMakeCache.txt");
const bool hasCMakeCache = QFile::exists(cmakeCacheTxt.toString());
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;
config = CMakeBuildSystem::parseCMakeCacheDotTxt(cmakeCacheTxt, &errorMessage);
} else {
config = CMakeConfigItem::itemsFromArguments(initialCMakeArguments());
}
} else if (!hasCMakeCache) {
config = CMakeConfigItem::itemsFromArguments(initialCMakeArguments());
}
if (!config.isEmpty()) {
cmakeBuildType = QString::fromUtf8(CMakeConfigItem::valueOf("CMAKE_BUILD_TYPE", config));
const_cast<CMakeBuildConfiguration*>(this)
->setCMakeBuildType(cmakeBuildType);
}
return cmakeBuildType;
}
void CMakeBuildConfiguration::setCMakeBuildType(const QString &cmakeBuildType, bool quiet)
{ {
if (quiet) {
aspect<BuildTypeAspect>()->setValueQuietly(cmakeBuildType);
aspect<BuildTypeAspect>()->update();
} else {
aspect<BuildTypeAspect>()->setValue(cmakeBuildType); aspect<BuildTypeAspect>()->setValue(cmakeBuildType);
} }
}
bool CMakeBuildConfiguration::isMultiConfig() const
{
return m_buildSystem->isMultiConfig();
}
namespace Internal { namespace Internal {
@@ -1293,6 +1348,9 @@ SourceDirectoryAspect::SourceDirectoryAspect()
BuildTypeAspect::BuildTypeAspect() BuildTypeAspect::BuildTypeAspect()
{ {
setSettingsKey("CMake.Build.Type"); setSettingsKey("CMake.Build.Type");
setLabelText(tr("Build type:"));
setDisplayStyle(LineEditDisplay);
setDefaultValue("Unknown");
} }
} // namespace Internal } // namespace Internal

View File

@@ -75,7 +75,9 @@ public:
Utils::FilePath sourceDirectory() const; Utils::FilePath sourceDirectory() const;
QString cmakeBuildType() const; QString cmakeBuildType() const;
void setCMakeBuildType(const QString &cmakeBuildType); void setCMakeBuildType(const QString &cmakeBuildType, bool quiet = false);
bool isMultiConfig() const;
signals: signals:
void errorOccurred(const QString &message); void errorOccurred(const QString &message);
@@ -163,6 +165,7 @@ class BuildTypeAspect final : public Utils::StringAspect
public: public:
BuildTypeAspect(); BuildTypeAspect();
using Utils::StringAspect::update;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -820,12 +820,20 @@ void CMakeBuildSystem::wireUpConnections()
// No CMakeCache? Run with initial arguments! // No CMakeCache? Run with initial arguments!
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to build directory change"; qCDebug(cmakeBuildSystemLog) << "Requesting parse due to build directory change";
const BuildDirParameters parameters(cmakeBuildConfiguration()); const BuildDirParameters parameters(cmakeBuildConfiguration());
const bool hasCMakeCache = QFile::exists( const FilePath cmakeCacheTxt = parameters.buildDirectory.pathAppended("CMakeCache.txt");
(parameters.buildDirectory / "CMakeCache.txt").toString()); const bool hasCMakeCache = QFile::exists(cmakeCacheTxt.toString());
const auto options = ReparseParameters( const auto options = ReparseParameters(
hasCMakeCache hasCMakeCache
? REPARSE_DEFAULT ? REPARSE_DEFAULT
: (REPARSE_FORCE_INITIAL_CONFIGURATION | REPARSE_FORCE_CMAKE_RUN)); : (REPARSE_FORCE_INITIAL_CONFIGURATION | REPARSE_FORCE_CMAKE_RUN));
if (hasCMakeCache) {
QString errorMessage;
const CMakeConfig config = CMakeBuildSystem::parseCMakeCacheDotTxt(cmakeCacheTxt, &errorMessage);
if (!config.isEmpty() && errorMessage.isEmpty()) {
QByteArray cmakeBuildTypeName = CMakeConfigItem::valueOf("CMAKE_BUILD_TYPE", config);
cmakeBuildConfiguration()->setCMakeBuildType(QString::fromUtf8(cmakeBuildTypeName), true);
}
}
setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()), options); setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()), options);
}); });