CMake: Store CMake project configuration in CMakeBuildConfiguration

Store CMakeConfig in CMakeBuildConfiguration instead of the list of
initialArguments.

Update initialArguments to a list of settings on load.

Change-Id: If58fc38296a4627f40062dd407e684c8a9477f6e
Reviewed-by: Tim Jenssen <tim.jenssen@theqtcompany.com>
This commit is contained in:
Tobias Hunger
2016-02-03 13:52:50 +01:00
parent 28e4306865
commit 744008ccf0
4 changed files with 82 additions and 25 deletions

View File

@@ -27,6 +27,7 @@
#include "cmakebuildinfo.h" #include "cmakebuildinfo.h"
#include "cmakebuildstep.h" #include "cmakebuildstep.h"
#include "cmakekitinformation.h"
#include "cmakeproject.h" #include "cmakeproject.h"
#include "cmakeprojectconstants.h" #include "cmakeprojectconstants.h"
#include "cmakebuildsettingswidget.h" #include "cmakebuildsettingswidget.h"
@@ -41,9 +42,12 @@
#include <projectexplorer/projectmacroexpander.h> #include <projectexplorer/projectmacroexpander.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <utils/algorithm.h>
#include <utils/mimetypes/mimedatabase.h> #include <utils/mimetypes/mimedatabase.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <QHash>
#include <QInputDialog> #include <QInputDialog>
using namespace ProjectExplorer; using namespace ProjectExplorer;
@@ -52,7 +56,8 @@ using namespace Utils;
namespace CMakeProjectManager { namespace CMakeProjectManager {
namespace Internal { namespace Internal {
const char INITIAL_ARGUMENTS[] = "CMakeProjectManager.CMakeBuildConfiguration.InitialArgument"; const char INITIAL_ARGUMENTS[] = "CMakeProjectManager.CMakeBuildConfiguration.InitialArgument"; // Obsolete since QtC 3.7
const char CONFIGURATION_KEY[] = "CMake.Configuration";
static FileName shadowBuildDirectory(const FileName &projectFilePath, const Kit *k, static FileName shadowBuildDirectory(const FileName &projectFilePath, const Kit *k,
const QString &bcName, BuildConfiguration::BuildType buildType) const QString &bcName, BuildConfiguration::BuildType buildType)
@@ -79,7 +84,7 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent
CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent, CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent,
CMakeBuildConfiguration *source) : CMakeBuildConfiguration *source) :
BuildConfiguration(parent, source), BuildConfiguration(parent, source),
m_initialArguments(source->m_initialArguments) m_configuration(source->m_configuration)
{ {
Q_ASSERT(parent); Q_ASSERT(parent);
cloneSteps(source); cloneSteps(source);
@@ -88,7 +93,9 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent
QVariantMap CMakeBuildConfiguration::toMap() const QVariantMap CMakeBuildConfiguration::toMap() const
{ {
QVariantMap map(ProjectExplorer::BuildConfiguration::toMap()); QVariantMap map(ProjectExplorer::BuildConfiguration::toMap());
map.insert(QLatin1String(INITIAL_ARGUMENTS), m_initialArguments); const QStringList config
= Utils::transform(m_configuration, [](const CMakeConfigItem &i) { return i.toString(); });
map.insert(QLatin1String(CONFIGURATION_KEY), config);
return map; return map;
} }
@@ -97,7 +104,27 @@ bool CMakeBuildConfiguration::fromMap(const QVariantMap &map)
if (!BuildConfiguration::fromMap(map)) if (!BuildConfiguration::fromMap(map))
return false; return false;
m_initialArguments = map.value(QLatin1String(INITIAL_ARGUMENTS)).toString(); const CMakeConfig conf
= Utils::transform(map.value(QLatin1String(CONFIGURATION_KEY)).toStringList(),
[](const QString &v) { return CMakeConfigItem::fromString(v); });
// Legacy (pre QtC 3.7):
const QStringList args = QtcProcess::splitArgs(map.value(QLatin1String(INITIAL_ARGUMENTS)).toString());
CMakeConfig legacyConf;
bool nextIsConfig = false;
foreach (const QString &a, args) {
if (a == QLatin1String("-D")) {
nextIsConfig = true;
continue;
}
if (!a.startsWith(QLatin1String("-D")))
continue;
legacyConf << CMakeConfigItem::fromString(nextIsConfig ? a : a.mid(2));
nextIsConfig = false;
}
// End Legacy
setCMakeConfiguration(legacyConf + conf);
return true; return true;
} }
@@ -107,14 +134,30 @@ void CMakeBuildConfiguration::emitBuildTypeChanged()
emit buildTypeChanged(); emit buildTypeChanged();
} }
void CMakeBuildConfiguration::setInitialArguments(const QString &arguments) static CMakeConfig removeDuplicates(const CMakeConfig &config)
{ {
m_initialArguments = arguments; CMakeConfig result;
// Remove duplicates (last value wins):
QSet<QByteArray> knownKeys;
for (int i = config.count() - 1; i >= 0; --i) {
const CMakeConfigItem &item = config.at(i);
if (knownKeys.contains(item.key))
continue;
result.append(item);
knownKeys.insert(item.key);
}
Utils::sort(result, CMakeConfigItem::sortOperator());
return result;
} }
QString CMakeBuildConfiguration::initialArguments() const void CMakeBuildConfiguration::setCMakeConfiguration(const CMakeConfig &config)
{ {
return m_initialArguments; m_configuration = removeDuplicates(config);
}
CMakeConfig CMakeBuildConfiguration::cmakeConfiguration() const
{
return m_configuration;
} }
ProjectExplorer::NamedWidget *CMakeBuildConfiguration::createConfigWidget() ProjectExplorer::NamedWidget *CMakeBuildConfiguration::createConfigWidget()
@@ -128,8 +171,7 @@ ProjectExplorer::NamedWidget *CMakeBuildConfiguration::createConfigWidget()
CMakeBuildConfigurationFactory::CMakeBuildConfigurationFactory(QObject *parent) : CMakeBuildConfigurationFactory::CMakeBuildConfigurationFactory(QObject *parent) :
ProjectExplorer::IBuildConfigurationFactory(parent) ProjectExplorer::IBuildConfigurationFactory(parent)
{ { }
}
int CMakeBuildConfigurationFactory::priority(const ProjectExplorer::Target *parent) const int CMakeBuildConfigurationFactory::priority(const ProjectExplorer::Target *parent) const
{ {
@@ -209,7 +251,7 @@ ProjectExplorer::BuildConfiguration *CMakeBuildConfigurationFactory::create(Proj
cleanStep->setBuildTarget(CMakeBuildStep::cleanTarget(), true); cleanStep->setBuildTarget(CMakeBuildStep::cleanTarget(), true);
bc->setBuildDirectory(copy.buildDirectory); bc->setBuildDirectory(copy.buildDirectory);
bc->setInitialArguments(copy.arguments); bc->setCMakeConfiguration(copy.configuration);
// Default to all // Default to all
if (project->hasBuildTarget(QLatin1String("all"))) if (project->hasBuildTarget(QLatin1String("all")))
@@ -265,30 +307,31 @@ CMakeBuildInfo *CMakeBuildConfigurationFactory::createBuildInfo(const ProjectExp
{ {
auto info = new CMakeBuildInfo(this); auto info = new CMakeBuildInfo(this);
info->kitId = k->id(); info->kitId = k->id();
info->environment = Environment::systemEnvironment();
k->addToEnvironment(info->environment);
info->sourceDirectory = sourceDir; info->sourceDirectory = sourceDir;
info->configuration = CMakeConfigurationKitInformation::configuration(k);
CMakeConfigItem buildTypeItem;
switch (buildType) { switch (buildType) {
case BuildTypeNone: case BuildTypeNone:
info->typeName = tr("Build"); info->typeName = tr("Build");
break; break;
case BuildTypeDebug: case BuildTypeDebug:
info->arguments = QLatin1String("-DCMAKE_BUILD_TYPE=Debug"); buildTypeItem = { CMakeConfigItem("CMAKE_BUILD_TYPE", "Debug") };
info->typeName = tr("Debug"); info->typeName = tr("Debug");
info->buildType = BuildConfiguration::Debug; info->buildType = BuildConfiguration::Debug;
break; break;
case BuildTypeRelease: case BuildTypeRelease:
info->arguments = QLatin1String("-DCMAKE_BUILD_TYPE=Release"); buildTypeItem = { CMakeConfigItem("CMAKE_BUILD_TYPE", "Release") };
info->typeName = tr("Release"); info->typeName = tr("Release");
info->buildType = BuildConfiguration::Release; info->buildType = BuildConfiguration::Release;
break; break;
case BuildTypeMinSizeRel: case BuildTypeMinSizeRel:
info->arguments = QLatin1String("-DCMAKE_BUILD_TYPE=MinSizeRel"); buildTypeItem = { CMakeConfigItem("CMAKE_BUILD_TYPE", "MinSizeRel") };
info->typeName = tr("Minimum Size Release"); info->typeName = tr("Minimum Size Release");
info->buildType = BuildConfiguration::Release; info->buildType = BuildConfiguration::Release;
break; break;
case BuildTypeRelWithDebInfo: case BuildTypeRelWithDebInfo:
info->arguments = QLatin1String("-DCMAKE_BUILD_TYPE=RelWithDebInfo"); buildTypeItem = { CMakeConfigItem("CMAKE_BUILD_TYPE", "RelWithDebInfo") };
info->typeName = tr("Release with Debug Information"); info->typeName = tr("Release with Debug Information");
info->buildType = BuildConfiguration::Profile; info->buildType = BuildConfiguration::Profile;
break; break;
@@ -297,6 +340,9 @@ CMakeBuildInfo *CMakeBuildConfigurationFactory::createBuildInfo(const ProjectExp
break; break;
} }
if (!buildTypeItem.isNull())
info->configuration.append(buildTypeItem);
return info; return info;
} }

View File

@@ -25,6 +25,8 @@
#pragma once #pragma once
#include "cmakeconfigitem.h"
#include <projectexplorer/buildconfiguration.h> #include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/abi.h> #include <projectexplorer/abi.h>
@@ -54,8 +56,8 @@ public:
void emitBuildTypeChanged(); void emitBuildTypeChanged();
void setInitialArguments(const QString &arguments); void setCMakeConfiguration(const CMakeConfig &config);
QString initialArguments() const; CMakeConfig cmakeConfiguration() const;
protected: protected:
CMakeBuildConfiguration(ProjectExplorer::Target *parent, CMakeBuildConfiguration *source); CMakeBuildConfiguration(ProjectExplorer::Target *parent, CMakeBuildConfiguration *source);
@@ -63,6 +65,7 @@ protected:
private: private:
QString m_initialArguments; QString m_initialArguments;
CMakeConfig m_configuration;
friend class CMakeProjectManager::CMakeProject; friend class CMakeProjectManager::CMakeProject;
}; };

View File

@@ -26,6 +26,7 @@
#pragma once #pragma once
#include "cmakebuildconfiguration.h" #include "cmakebuildconfiguration.h"
#include "cmakeconfigitem.h"
#include <projectexplorer/buildinfo.h> #include <projectexplorer/buildinfo.h>
#include <projectexplorer/kit.h> #include <projectexplorer/kit.h>
@@ -48,16 +49,14 @@ public:
displayName = bc->displayName(); displayName = bc->displayName();
buildDirectory = bc->buildDirectory(); buildDirectory = bc->buildDirectory();
kitId = bc->target()->kit()->id(); kitId = bc->target()->kit()->id();
environment = bc->environment();
QTC_ASSERT(bc->target()->project(), return); QTC_ASSERT(bc->target()->project(), return);
sourceDirectory = bc->target()->project()->projectDirectory().toString(); sourceDirectory = bc->target()->project()->projectDirectory().toString();
arguments = bc->initialArguments(); configuration = bc->cmakeConfiguration();
} }
Utils::Environment environment;
QString sourceDirectory; QString sourceDirectory;
QString arguments; CMakeConfig configuration;
}; };
} // namespace CMakeProjectManager } // namespace CMakeProjectManager

View File

@@ -129,7 +129,7 @@ void CMakeProject::changeActiveBuildConfiguration(ProjectExplorer::BuildConfigur
config = CMakeConfigurationKitInformation::configuration(k); config = CMakeConfigurationKitInformation::configuration(k);
} else { } else {
k = cmakebc->target()->kit(); k = cmakebc->target()->kit();
// FIXME: Fill config with data from cmakebc! config = cmakebc->cmakeConfiguration();
buildDir = cmakebc->buildDirectory(); buildDir = cmakebc->buildDirectory();
} }
if (k) { if (k) {
@@ -378,7 +378,7 @@ void CMakeProject::setCurrentCMakeConfiguration(const QList<ConfigModel::DataIte
if (!m_buildDirManager || m_buildDirManager->isBusy()) if (!m_buildDirManager || m_buildDirManager->isBusy())
return; return;
const CMakeConfig config = Utils::transform(items, [](const ConfigModel::DataItem &i) { const CMakeConfig newConfig = Utils::transform(items, [](const ConfigModel::DataItem &i) {
CMakeConfigItem ni; CMakeConfigItem ni;
ni.key = i.key.toUtf8(); ni.key = i.key.toUtf8();
ni.value = i.value.toUtf8(); ni.value = i.value.toUtf8();
@@ -405,6 +405,15 @@ void CMakeProject::setCurrentCMakeConfiguration(const QList<ConfigModel::DataIte
return ni; return ni;
}); });
// There is a buildDirManager, so there must also be an active BC:
QTC_ASSERT(activeTarget(), return);
QTC_ASSERT(activeTarget()->activeBuildConfiguration(), return);
auto bc = static_cast<CMakeBuildConfiguration *>(activeTarget()->activeBuildConfiguration());
QTC_ASSERT(bc, return);
const CMakeConfig config = bc->cmakeConfiguration() + newConfig;
bc->setCMakeConfiguration(config);
m_buildDirManager->setInputConfiguration(config); m_buildDirManager->setInputConfiguration(config);
} }