diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index 8ddf9e33d8d..f38da1fc0ec 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -1335,4 +1336,90 @@ MakeInstallCommand CMakeBuildSystem::makeInstallCommand(const FilePath &installR return cmd; } +QList> CMakeBuildSystem::generators() const +{ + if (!buildConfiguration()) + return {}; + const CMakeTool * const cmakeTool + = CMakeKitAspect::cmakeTool(buildConfiguration()->target()->kit()); + if (!cmakeTool) + return {}; + QList> result; + const QList &generators = cmakeTool->supportedGenerators(); + for (const CMakeTool::Generator &generator : generators) { + result << qMakePair(Id::fromSetting(generator.name), + Tr::tr("%1 (via cmake)").arg(generator.name)); + for (const QString &extraGenerator : generator.extraGenerators) { + const QString displayName = extraGenerator + " - " + generator.name; + result << qMakePair(Id::fromSetting(displayName), + Tr::tr("%1 (via cmake)").arg(displayName)); + } + } + return result; +} + +void CMakeBuildSystem::runGenerator(Utils::Id id) +{ + QTC_ASSERT(cmakeBuildConfiguration(), return); + const auto showError = [](const QString &detail) { + Core::MessageManager::writeDisrupting(Tr::tr("cmake generator failed: %1.").arg(detail)); + }; + const CMakeTool * const cmakeTool + = CMakeKitAspect::cmakeTool(buildConfiguration()->target()->kit()); + if (!cmakeTool) { + showError(Tr::tr("Kit does not have a cmake binary set")); + return; + } + const QString generator = id.toSetting().toString(); + const FilePath outDir = buildConfiguration()->buildDirectory() + / ("qtc_" + FileUtils::fileSystemFriendlyName(generator)); + if (!outDir.ensureWritableDir()) { + showError(Tr::tr("Cannot create output directory \"%1\"").arg(outDir.toString())); + return; + } + CommandLine cmdLine(cmakeTool->cmakeExecutable(), {"-S", buildConfiguration()->target() + ->project()->projectDirectory().toUserOutput(), "-G", generator}); + if (!cmdLine.executable().isExecutableFile()) { + showError(Tr::tr("No valid cmake executable")); + return; + } + const auto itemFilter = [](const CMakeConfigItem &item) { + return !item.isNull() + && item.type != CMakeConfigItem::STATIC + && item.type != CMakeConfigItem::INTERNAL + && !item.key.contains("GENERATOR"); + }; + QList configItems = Utils::filtered(m_configurationChanges.toList(), + itemFilter); + const QList initialConfigItems + = Utils::filtered(initialCMakeConfiguration().toList(), itemFilter); + for (const CMakeConfigItem &item : std::as_const(initialConfigItems)) { + if (!Utils::contains(configItems, [&item](const CMakeConfigItem &existingItem) { + return existingItem.key == item.key; + })) { + configItems << item; + } + } + for (const CMakeConfigItem &item : std::as_const(configItems)) + cmdLine.addArg(item.toArgument(buildConfiguration()->macroExpander())); + if (const auto optionsAspect = buildConfiguration()->aspect(); + optionsAspect && !optionsAspect->value().isEmpty()) { + cmdLine.addArgs(optionsAspect->value(), CommandLine::Raw); + } + const auto proc = new QtcProcess(this); + connect(proc, &QtcProcess::done, proc, &QtcProcess::deleteLater); + connect(proc, &QtcProcess::readyReadStandardOutput, this, [proc] { + Core::MessageManager::writeFlashing(QString::fromLocal8Bit(proc->readAllStandardOutput())); + }); + connect(proc, &QtcProcess::readyReadStandardError, this, [proc] { + Core::MessageManager::writeDisrupting(QString::fromLocal8Bit(proc->readAllStandardError())); + }); + proc->setWorkingDirectory(outDir); + proc->setEnvironment(buildConfiguration()->environment()); + proc->setCommand(cmdLine); + Core::MessageManager::writeFlashing(Tr::tr("Running in %1: %2") + .arg(outDir.toUserOutput(), cmdLine.toUserOutput())); + proc->start(); +} + } // CMakeProjectManager::Internal diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h index 71119986509..54bcf20dacc 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h @@ -120,6 +120,9 @@ signals: void warningOccurred(const QString &message); private: + QList> generators() const override; + void runGenerator(Utils::Id id) override; + enum ForceEnabledChanged { False, True }; void clearError(ForceEnabledChanged fec = ForceEnabledChanged::False);