From 196b0da08add8b36a118481314bd10a3a3dd78e0 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Thu, 17 Oct 2019 15:20:23 +0200 Subject: [PATCH] CMake: Write creators settings into build directory Write a file qtcsettings.cmake into the build directory. This file contains all applicable CMake configuration settings that creator wants to set. Use "cmake -C qtcsettings.cmake .." to reconfigure on the command line to make use of this file. Change-Id: I4a69d082c50bb66e60b4eec1b3155df53e00734d Reviewed-by: Cristian Adam Reviewed-by: Tobias Hunger --- .../cmakeprojectmanager/builddirmanager.cpp | 24 +++++++++++++++ .../cmakeprojectmanager/builddirmanager.h | 1 + .../cmakeprojectmanager/cmakeconfigitem.cpp | 30 +++++++++++++++++++ .../cmakeprojectmanager/cmakeconfigitem.h | 2 ++ .../cmakeprojectmanager/cmakeprocess.cpp | 7 ----- .../cmakeprojectmanager/cmakeprocess.h | 2 -- .../cmakeprojectmanager/fileapireader.cpp | 4 +-- .../cmakeprojectmanager/tealeafreader.cpp | 3 +- 8 files changed, 61 insertions(+), 12 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp index 73402574cc9..aa0caae7ecb 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp +++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp @@ -231,6 +231,28 @@ bool BuildDirManager::hasConfigChanged() return mustReparse || kcit != targetConfig.constEnd(); } +void BuildDirManager::writeConfigurationIntoBuildDirectory(const Utils::MacroExpander *expander) +{ + QTC_ASSERT(expander, return ); + + const FilePath buildDir = workDirectory(m_parameters); + QTC_ASSERT(buildDir.exists(), return ); + + const FilePath settingsFile = buildDir.pathAppended("qtcsettings.cmake"); + + QByteArray contents; + contents.append("# This file is managed by Qt Creator, do not edit!\n\n"); + contents.append( + transform(m_parameters.configuration, + [expander](const CMakeConfigItem &item) { return item.toCMakeSetLine(expander); }) + .join('\n') + .toUtf8()); + + QFile file(settingsFile.toString()); + QTC_ASSERT(file.open(QFile::WriteOnly | QFile::Truncate), return ); + file.write(contents); +} + bool BuildDirManager::isParsing() const { return m_reader && m_reader->isParsing(); @@ -358,6 +380,8 @@ void BuildDirManager::parse() } } + writeConfigurationIntoBuildDirectory(m_parameters.expander); + qCDebug(cmakeBuildDirManagerLog) << "Asking reader to parse"; m_reader->parse(reparseParameters & REPARSE_FORCE_CMAKE_RUN, reparseParameters & REPARSE_FORCE_CONFIGURATION); diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.h b/src/plugins/cmakeprojectmanager/builddirmanager.h index 91233b79a8f..d3537104cc7 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.h +++ b/src/plugins/cmakeprojectmanager/builddirmanager.h @@ -127,6 +127,7 @@ private: bool hasConfigChanged(); + void writeConfigurationIntoBuildDirectory(const Utils::MacroExpander *expander); void becameDirty(); diff --git a/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp b/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp index e63641cf287..777184f0a60 100644 --- a/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp @@ -149,6 +149,24 @@ CMakeConfigItem::Type CMakeConfigItem::typeStringToType(const QByteArray &type) return CMakeConfigItem::INTERNAL; } +QString CMakeConfigItem::typeToTypeString(const CMakeConfigItem::Type t) +{ + switch (t) { + case CMakeProjectManager::CMakeConfigItem::FILEPATH: + return "FILEPATH"; + case CMakeProjectManager::CMakeConfigItem::PATH: + return "PATH"; + case CMakeProjectManager::CMakeConfigItem::STRING: + return "STRING"; + case CMakeProjectManager::CMakeConfigItem::INTERNAL: + return "INTERNAL"; + case CMakeProjectManager::CMakeConfigItem::STATIC: + return "STATIC"; + case CMakeConfigItem::BOOL: + return "BOOL"; + } +} + Utils::optional CMakeConfigItem::toBool(const QByteArray &value) { // Taken from CMakes if() documentation: @@ -367,6 +385,18 @@ QString CMakeConfigItem::toArgument(const Utils::MacroExpander *expander) const return "-D" + toString(expander); } +QString CMakeConfigItem::toCMakeSetLine(const Utils::MacroExpander *expander) const +{ + if (isUnset) { + return QString("unset(\"%1\" CACHE)").arg(QString::fromUtf8(key)); + } + return QString("set(\"%1\" \"%2\" CACHE \"%3\" \"%4\" FORCE)") + .arg(QString::fromUtf8(key)) + .arg(expandedValue(expander)) + .arg(typeToTypeString(type)) + .arg(QString::fromUtf8(documentation)); +} + bool CMakeConfigItem::operator==(const CMakeConfigItem &o) const { // type, isAdvanced and documentation do not matter for a match! diff --git a/src/plugins/cmakeprojectmanager/cmakeconfigitem.h b/src/plugins/cmakeprojectmanager/cmakeconfigitem.h index 8b5fce8eb7f..15dae12a9c0 100644 --- a/src/plugins/cmakeprojectmanager/cmakeconfigitem.h +++ b/src/plugins/cmakeprojectmanager/cmakeconfigitem.h @@ -54,6 +54,7 @@ public: const QList &input); static QStringList cmakeSplitValue(const QString &in, bool keepEmpty = false); static Type typeStringToType(const QByteArray &typeString); + static QString typeToTypeString(const Type t); static Utils::optional toBool(const QByteArray &value); bool isNull() const { return key.isEmpty(); } @@ -65,6 +66,7 @@ public: static QList itemsFromFile(const Utils::FilePath &input, QString *errorMessage); QString toString(const Utils::MacroExpander *expander = nullptr) const; QString toArgument(const Utils::MacroExpander *expander = nullptr) const; + QString toCMakeSetLine(const Utils::MacroExpander *expander = nullptr) const; bool operator==(const CMakeConfigItem &o) const; diff --git a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp index 45b7b119eeb..8575e61cb34 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp @@ -84,13 +84,6 @@ CMakeProcess::~CMakeProcess() } } -QStringList CMakeProcess::toArguments(const CMakeConfig &config, - const Utils::MacroExpander *expander) { - return Utils::transform(config, [expander](const CMakeConfigItem &i) -> QString { - return i.toArgument(expander); - }); -} - void CMakeProcess::run(const BuildDirParameters ¶meters, const QStringList &arguments) { QTC_ASSERT(!m_process && !m_parser && !m_future, return); diff --git a/src/plugins/cmakeprojectmanager/cmakeprocess.h b/src/plugins/cmakeprojectmanager/cmakeprocess.h index 9675822435a..6d03d1ab832 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprocess.h +++ b/src/plugins/cmakeprojectmanager/cmakeprocess.h @@ -47,8 +47,6 @@ public: CMakeProcess(const CMakeProcess&) = delete; ~CMakeProcess(); - static QStringList toArguments(const CMakeConfig &config, const Utils::MacroExpander *expander); - void run(const BuildDirParameters ¶meters, const QStringList &arguments); QProcess::ProcessState state() const; diff --git a/src/plugins/cmakeprojectmanager/fileapireader.cpp b/src/plugins/cmakeprojectmanager/fileapireader.cpp index 47cccc74c5e..f15711f766b 100644 --- a/src/plugins/cmakeprojectmanager/fileapireader.cpp +++ b/src/plugins/cmakeprojectmanager/fileapireader.cpp @@ -131,8 +131,8 @@ void FileApiReader::parse(bool forceCMakeRun, bool forceConfiguration) if (forceConfiguration) { // Initial create: qCDebug(cmakeFileApiMode) << "FileApiReader: Starting CMake with forced configuration."; - startCMakeState( - CMakeProcess::toArguments(m_parameters.configuration, m_parameters.expander)); + const FilePath path = m_parameters.buildDirectory.pathAppended("qtcsettings.cmake"); + startCMakeState(QStringList({QString("-C"), path.toUserOutput()})); // Keep m_isParsing enabled! return; } diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.cpp b/src/plugins/cmakeprojectmanager/tealeafreader.cpp index b611f12c65b..a0fba9ca60f 100644 --- a/src/plugins/cmakeprojectmanager/tealeafreader.cpp +++ b/src/plugins/cmakeprojectmanager/tealeafreader.cpp @@ -133,7 +133,8 @@ void TeaLeafReader::parse(bool forceCMakeRun, bool forceConfiguration) const QFileInfo cbpFileFi = cbpFile.isEmpty() ? QFileInfo() : QFileInfo(cbpFile); if (!cbpFileFi.exists() || forceConfiguration) { // Initial create: - startCMake(CMakeProcess::toArguments(m_parameters.configuration, m_parameters.expander)); + const FilePath path = m_parameters.buildDirectory.pathAppended("qtcsettings.cmake"); + startCMake(QStringList({QString("-C"), path.toUserOutput()})); return; }