From 264313ec90e7eaf3797833d715d3c4aa1e40d60b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20K=C3=BCmmel?= <syntheticpp@gmx.net> Date: Tue, 2 Oct 2012 17:46:12 +0200 Subject: [PATCH] CMake: add Ninja support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cmake wizard proposes also ninja if ninja support is available Ninja must be in PATH, but it is only called once, so it doesn't hurt. Task-number: QTCREATORBUG-7720 Reviewed-by: Daniel Teske <daniel.teske@digia.com> Change-Id: If3c9c7ae55e6990fa16b031fc2998a8d8d9ed17a Reviewed-by: Peter Kümmel <syntheticpp@gmx.net> Reviewed-by: Yuchen Deng <loaden@gmail.com> Reviewed-by: Tobias Hunger <tobias.hunger@digia.com> --- .../cmakebuildconfiguration.cpp | 21 ++++- .../cmakebuildconfiguration.h | 7 ++ .../cmakeopenprojectwizard.cpp | 77 ++++++++++++---- .../cmakeopenprojectwizard.h | 10 ++- .../cmakeprojectmanager/cmakeproject.cpp | 8 +- .../cmakeprojectmanager.cpp | 20 ++++- .../cmakeprojectmanager/cmakeprojectmanager.h | 3 + src/plugins/cmakeprojectmanager/makestep.cpp | 87 +++++++++++++++++-- src/plugins/cmakeprojectmanager/makestep.h | 17 ++++ 9 files changed, 212 insertions(+), 38 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index ac933cb48b0..d18e3e8fd35 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -55,7 +55,7 @@ const char BUILD_DIRECTORY_KEY[] = "CMakeProjectManager.CMakeBuildConfiguration. } // namespace CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent) : - BuildConfiguration(parent, Core::Id(CMAKE_BC_ID)) + BuildConfiguration(parent, Core::Id(CMAKE_BC_ID)), m_useNinja(false) { m_buildDirectory = static_cast<CMakeProject *>(parent->project())->defaultBuildDirectory(); } @@ -64,7 +64,8 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent CMakeBuildConfiguration *source) : BuildConfiguration(parent, source), m_buildDirectory(source->m_buildDirectory), - m_msvcVersion(source->m_msvcVersion) + m_msvcVersion(source->m_msvcVersion), + m_useNinja(false) { Q_ASSERT(parent); cloneSteps(source); @@ -87,6 +88,19 @@ bool CMakeBuildConfiguration::fromMap(const QVariantMap &map) return true; } +bool CMakeBuildConfiguration::useNinja() const +{ + return m_useNinja; +} + +void CMakeBuildConfiguration::setUseNinja(bool useNninja) +{ + if (m_useNinja != useNninja) { + m_useNinja = useNninja; + emit useNinjaChanged(m_useNinja); + } +} + CMakeBuildConfiguration::~CMakeBuildConfiguration() { } @@ -202,7 +216,7 @@ CMakeBuildConfiguration *CMakeBuildConfigurationFactory::create(ProjectExplorer: CMakeOpenProjectWizard copw(project->projectManager(), project->projectDirectory(), bc->buildDirectory(), - bc->environment()); + bc); if (copw.exec() != QDialog::Accepted) { delete bc; return 0; @@ -284,3 +298,4 @@ ProjectExplorer::BuildConfiguration::BuildType CMakeBuildConfiguration::buildTyp return Unknown; } + diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h index 655e1b3b9dc..e264e6090f7 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h @@ -65,6 +65,12 @@ public: BuildType buildType() const; + bool useNinja() const; + void setUseNinja(bool); + +signals: + void useNinjaChanged(bool); + protected: CMakeBuildConfiguration(ProjectExplorer::Target *parent, CMakeBuildConfiguration *source); virtual bool fromMap(const QVariantMap &map); @@ -72,6 +78,7 @@ protected: private: QString m_buildDirectory; QString m_msvcVersion; + bool m_useNinja; }; class CMakeBuildConfigurationFactory : public ProjectExplorer::IBuildConfigurationFactory diff --git a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp index 433f5fc61c9..de167758545 100644 --- a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp @@ -30,6 +30,7 @@ #include "cmakeopenprojectwizard.h" #include "cmakeprojectmanager.h" +#include "cmakebuildconfiguration.h" #include <coreplugin/icore.h> #include <utils/pathchooser.h> @@ -63,11 +64,37 @@ using namespace CMakeProjectManager::Internal; // |--> Already existing cbp file (and new enough) --> Page: Ready to load the project // |--> Page: Ask for cmd options, run generator -CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, const Utils::Environment &env) + +namespace CMakeProjectManager { +namespace Internal { + + class GeneratorInfo + { + public: + GeneratorInfo() + : m_kit(0), m_isNinja(false) {} + explicit GeneratorInfo(ProjectExplorer::Kit *kit, bool ninja = false) + : m_kit(kit), m_isNinja(ninja) {} + + ProjectExplorer::Kit *kit() const { return m_kit; } + bool isNinja() const { return m_isNinja; } + + private: + ProjectExplorer::Kit *m_kit; + bool m_isNinja; + }; + +} +} + +Q_DECLARE_METATYPE(CMakeProjectManager::Internal::GeneratorInfo); + + +CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, CMakeBuildConfiguration *bc) : m_cmakeManager(cmakeManager), m_sourceDirectory(sourceDirectory), m_creatingCbpFiles(false), - m_environment(env) + m_buildConfiguration(bc) { int startid; if (hasInSourceBuild()) { @@ -95,11 +122,11 @@ CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, const QString &buildDirectory, CMakeOpenProjectWizard::Mode mode, - const Utils::Environment &env) + CMakeBuildConfiguration *bc) : m_cmakeManager(cmakeManager), m_sourceDirectory(sourceDirectory), m_creatingCbpFiles(true), - m_environment(env) + m_buildConfiguration(bc) { CMakeRunPage::Mode rmode; @@ -115,11 +142,11 @@ CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, const QString &oldBuildDirectory, - const Utils::Environment &env) + CMakeBuildConfiguration *bc) : m_cmakeManager(cmakeManager), m_sourceDirectory(sourceDirectory), m_creatingCbpFiles(true), - m_environment(env) + m_buildConfiguration(bc) { m_buildDirectory = oldBuildDirectory; addPage(new ShadowBuildPage(this, true)); @@ -201,9 +228,13 @@ void CMakeOpenProjectWizard::setArguments(const QString &args) Utils::Environment CMakeOpenProjectWizard::environment() const { - return m_environment; + return m_buildConfiguration->environment(); } +CMakeBuildConfiguration *CMakeOpenProjectWizard::buildConfiguration() const +{ + return m_buildConfiguration; +} InSourceBuildPage::InSourceBuildPage(CMakeOpenProjectWizard *cmakeWizard) : QWizardPage(cmakeWizard), m_cmakeWizard(cmakeWizard) @@ -409,8 +440,6 @@ void CMakeRunPage::initializePage() ProjectExplorer::KitManager::instance()->kits(); foreach (ProjectExplorer::Kit *k, kitList) { - QVariant kitVariant = qVariantFromValue(static_cast<void *>(k)); - ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(k); if (!tc) continue; @@ -421,22 +450,24 @@ void CMakeRunPage::initializePage() || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2010Flavor || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2012Flavor) { if (hasCodeBlocksGenerator && (cachedGenerator.isEmpty() || cachedGenerator == "NMake Makefiles")) - m_generatorComboBox->addItem(tr("NMake Generator (%1)").arg(k->displayName()), kitVariant); + m_generatorComboBox->addItem(tr("NMake Generator (%1)").arg(k->displayName()), qVariantFromValue(GeneratorInfo(k))); } else if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) { #ifdef Q_OS_WIN if (cachedGenerator.isEmpty() || cachedGenerator == "MinGW Makefiles") - m_generatorComboBox->addItem(tr("MinGW Generator (%1)").arg(k->displayName()), kitVariant); + m_generatorComboBox->addItem(tr("MinGW Generator (%1)").arg(k->displayName()), qVariantFromValue(GeneratorInfo(k))); #else if (cachedGenerator.isEmpty() || cachedGenerator == "Unix Makefiles") - m_generatorComboBox->addItem(tr("Unix Generator (%1)").arg(k->displayName()), kitVariant); + m_generatorComboBox->addItem(tr("Unix Generator (%1)").arg(k->displayName()), qVariantFromValue(GeneratorInfo(k))); #endif - } } else { // Non windows if (cachedGenerator.isEmpty() || cachedGenerator == "Unix Makefiles") - m_generatorComboBox->addItem(tr("Unix Generator (%1)").arg(k->displayName()), kitVariant); + m_generatorComboBox->addItem(tr("Unix Generator (%1)").arg(k->displayName()), qVariantFromValue(GeneratorInfo(k))); } + if (m_cmakeWizard->cmakeManager()->hasCodeBlocksNinjaGenerator() && + (cachedGenerator.isEmpty() || cachedGenerator == "Ninja")) + m_generatorComboBox->addItem(tr("Ninja (%1)").arg(k->displayName()), qVariantFromValue(GeneratorInfo(k, true))); } } @@ -449,8 +480,11 @@ void CMakeRunPage::runCMake() int index = m_generatorComboBox->currentIndex(); ProjectExplorer::Kit *k = 0; - if (index >= 0) - k = static_cast<ProjectExplorer::Kit *>(m_generatorComboBox->itemData(index).value<void *>()); + GeneratorInfo generatorInfo; + if (index >= 0) { + generatorInfo = m_generatorComboBox->itemData(index).value<GeneratorInfo>(); + k = generatorInfo.kit(); + } if (!k) { m_output->appendPlainText(tr("No generator selected.")); return; @@ -464,15 +498,20 @@ void CMakeRunPage::runCMake() CMakeManager *cmakeManager = m_cmakeWizard->cmakeManager(); QString generator = QLatin1String("-GCodeBlocks - Unix Makefiles"); - if (tc->targetAbi().os() == ProjectExplorer::Abi::WindowsOS) { - if (tc->targetAbi().osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) + if (generatorInfo.isNinja()) { + m_cmakeWizard->buildConfiguration()->setUseNinja(true); + generator = "-GCodeBlocks - Ninja"; + } else if (tc->targetAbi().os() == ProjectExplorer::Abi::WindowsOS) { + m_cmakeWizard->buildConfiguration()->setUseNinja(false); + if (tc->targetAbi().osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) { #ifdef Q_OS_WIN generator = QLatin1String("-GCodeBlocks - MinGW Makefiles"); #else generator = QLatin1String("-GCodeBlocks - Unix Makefiles"); #endif - else + } else { generator = QLatin1String("-GCodeBlocks - NMake Makefiles"); + } } Utils::Environment env = m_cmakeWizard->environment(); diff --git a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h index 7c3781f1a2c..9b2c629259a 100644 --- a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h +++ b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h @@ -54,6 +54,7 @@ namespace CMakeProjectManager { namespace Internal { class CMakeManager; +class CMakeBuildConfiguration; class CMakeOpenProjectWizard : public Utils::Wizard { @@ -73,14 +74,14 @@ public: }; // used at importing a project without a .user file - CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, const Utils::Environment &env); + CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, CMakeBuildConfiguration *bc); /// used to update if we have already a .user file /// recreates or updates the cbp file - CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, const QString &buildDirectory, Mode mode, const Utils::Environment &env); + CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, const QString &buildDirectory, Mode mode, CMakeBuildConfiguration *bc); /// used to change the build directory of one buildconfiguration /// shows a page for selecting a directory /// then the run cmake page - CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, const QString &oldBuildDirectory, const Utils::Environment &env); + CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, const QString &oldBuildDirectory, CMakeBuildConfiguration *bc); virtual int nextId() const; QString buildDirectory() const; @@ -90,6 +91,7 @@ public: QString arguments() const; void setArguments(const QString &args); Utils::Environment environment() const; + CMakeBuildConfiguration *buildConfiguration() const; bool existsUpToDateXmlFile() const; private: @@ -100,7 +102,7 @@ private: QString m_sourceDirectory; QString m_arguments; bool m_creatingCbpFiles; - Utils::Environment m_environment; + CMakeBuildConfiguration *m_buildConfiguration; }; class InSourceBuildPage : public QWizardPage diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index b536af7c821..e33c7deef48 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -166,7 +166,7 @@ void CMakeProject::changeActiveBuildConfiguration(ProjectExplorer::BuildConfigur sourceFileInfo.absolutePath(), cmakebc->buildDirectory(), mode, - cmakebc->environment()); + cmakebc); copw.exec(); } // reparse @@ -555,7 +555,7 @@ bool CMakeProject::fromMap(const QVariantMap &map) sourceFileInfo.absolutePath(), activeBC->buildDirectory(), mode, - activeBC->environment()); + activeBC); if (copw.exec() != QDialog::Accepted) return false; } @@ -906,7 +906,7 @@ void CMakeBuildSettingsWidget::openChangeBuildDirectoryDialog() CMakeOpenProjectWizard copw(project->projectManager(), project->projectDirectory(), m_buildConfiguration->buildDirectory(), - m_buildConfiguration->environment()); + m_buildConfiguration); if (copw.exec() == QDialog::Accepted) { project->changeBuildDirectory(m_buildConfiguration, copw.buildDirectory()); m_pathLineEdit->setText(m_buildConfiguration->buildDirectory()); @@ -921,7 +921,7 @@ void CMakeBuildSettingsWidget::runCMake() project->projectDirectory(), m_buildConfiguration->buildDirectory(), CMakeOpenProjectWizard::WantToUpdate, - m_buildConfiguration->environment()); + m_buildConfiguration); if (copw.exec() == QDialog::Accepted) project->parseCMakeLists(); } diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp index 6fe9cbb8056..98ee2ea3822 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp @@ -123,7 +123,7 @@ void CMakeManager::runCMake(ProjectExplorer::Project *project) cmakeProject->projectDirectory(), bc->buildDirectory(), CMakeOpenProjectWizard::WantToUpdate, - bc->environment()); + bc); if (copw.exec() == QDialog::Accepted) cmakeProject->parseCMakeLists(); } @@ -160,6 +160,11 @@ bool CMakeManager::hasCodeBlocksMsvcGenerator() const return m_settingsPage->hasCodeBlocksMsvcGenerator(); } +bool CMakeManager::hasCodeBlocksNinjaGenerator() const +{ + return m_settingsPage->hasCodeBlocksNinjaGenerator(); +} + // need to refactor this out // we probably want the process instead of this function // cmakeproject then could even run the cmake process in the background, adding the files afterwards @@ -253,6 +258,8 @@ CMakeSettingsPage::CMakeSettingsPage() m_pathCmake.process = 0; m_userCmake.hasCodeBlocksMsvcGenerator = false; m_pathCmake.hasCodeBlocksMsvcGenerator = false; + m_userCmake.hasCodeBlocksNinjaGenerator = false; + m_pathCmake.hasCodeBlocksNinjaGenerator = false; QSettings *settings = Core::ICore::settings(); settings->beginGroup(QLatin1String("CMakeSettings")); m_userCmake.executable = settings->value(QLatin1String("cmakeExecutable")).toString(); @@ -297,6 +304,7 @@ void CMakeSettingsPage::cmakeFinished(CMakeValidator *cmakeValidator) const versionRegexp.indexIn(response); //m_supportsQtCreator = response.contains(QLatin1String("QtCreator")); + cmakeValidator->hasCodeBlocksNinjaGenerator = response.contains(QLatin1String("CodeBlocks - Ninja")); cmakeValidator->hasCodeBlocksMsvcGenerator = response.contains(QLatin1String("CodeBlocks - NMake Makefiles")); cmakeValidator->version = versionRegexp.cap(1); if (!(versionRegexp.capturedTexts().size() > 3)) @@ -426,3 +434,13 @@ bool CMakeSettingsPage::hasCodeBlocksMsvcGenerator() const else return m_pathCmake.hasCodeBlocksMsvcGenerator; } + +bool CMakeSettingsPage::hasCodeBlocksNinjaGenerator() const +{ + if (!isCMakeExecutableValid()) + return false; + if (m_userCmake.state == CMakeValidator::VALID) + return m_userCmake.hasCodeBlocksNinjaGenerator; + else + return m_pathCmake.hasCodeBlocksNinjaGenerator; +} diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h index 071963ac67f..0f52093e2a9 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h @@ -78,6 +78,7 @@ public: const Utils::Environment &env, const QString &generator); bool hasCodeBlocksMsvcGenerator() const; + bool hasCodeBlocksNinjaGenerator() const; static QString findCbpFile(const QDir &); static QString findDumperLibrary(const Utils::Environment &env); @@ -101,6 +102,7 @@ struct CMakeValidator STATE state; QProcess *process; bool hasCodeBlocksMsvcGenerator; + bool hasCodeBlocksNinjaGenerator; QString version; QString executable; }; @@ -121,6 +123,7 @@ public: void setCMakeExecutable(const QString &executable); bool isCMakeExecutableValid() const; bool hasCodeBlocksMsvcGenerator() const; + bool hasCodeBlocksNinjaGenerator() const; private slots: void userCmakeFinished(); diff --git a/src/plugins/cmakeprojectmanager/makestep.cpp b/src/plugins/cmakeprojectmanager/makestep.cpp index ee3ebde7e9b..7c9bcd4b40f 100644 --- a/src/plugins/cmakeprojectmanager/makestep.cpp +++ b/src/plugins/cmakeprojectmanager/makestep.cpp @@ -63,6 +63,7 @@ const char MS_ID[] = "CMakeProjectManager.MakeStep"; const char CLEAN_KEY[] = "CMakeProjectManager.MakeStep.Clean"; const char BUILD_TARGETS_KEY[] = "CMakeProjectManager.MakeStep.BuildTargets"; const char ADDITIONAL_ARGUMENTS_KEY[] = "CMakeProjectManager.MakeStep.AdditionalArguments"; +const char USE_NINJA_KEY[] = "CMakeProjectManager.MakeStep.UseNinja"; } MakeStep::MakeStep(BuildStepList *bsl) : @@ -92,8 +93,24 @@ MakeStep::MakeStep(BuildStepList *bsl, MakeStep *bs) : void MakeStep::ctor() { m_percentProgress = QRegExp("^\\[\\s*(\\d*)%\\]"); + m_useNinja = false; + m_ninjaProgress = QRegExp ("^\\[\\s*(\\d*)/\\s*(\\d*)"); + m_ninjaProgressString = QLatin1String("[%s/%t "); // ninja: [33/100 //: Default display name for the cmake make step. setDefaultDisplayName(tr("Make")); + + BuildConfiguration *bc = cmakeBuildConfiguration(); + if (bc) { + m_activeConfiguration = 0; + connect(bc, SIGNAL(useNinjaChanged(bool)), this, SLOT(setUseNinja(bool))); + } else { + // That means the step is in the deploylist, so we listen to the active build config + // changed signal and react to the activeBuildConfigurationChanged() signal of the buildconfiguration + m_activeConfiguration = targetsActiveBuildConfiguration(); + connect (target(), SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)), + this, SLOT(activeBuildConfigurationChanged())); + activeBuildConfigurationChanged(); + } } MakeStep::~MakeStep() @@ -105,6 +122,24 @@ CMakeBuildConfiguration *MakeStep::cmakeBuildConfiguration() const return static_cast<CMakeBuildConfiguration *>(buildConfiguration()); } +CMakeBuildConfiguration *MakeStep::targetsActiveBuildConfiguration() const +{ + return static_cast<CMakeBuildConfiguration *>(target()->activeBuildConfiguration()); +} + +void MakeStep::activeBuildConfigurationChanged() +{ + if (m_activeConfiguration) + disconnect(m_activeConfiguration, SIGNAL(useNinjaChanged(bool)), this, SLOT(setUseNinja(bool))); + + m_activeConfiguration = targetsActiveBuildConfiguration(); + + if (m_activeConfiguration) { + connect(m_activeConfiguration, SIGNAL(useNinjaChanged(bool)), this, SLOT(setUseNinja(bool))); + setUseNinja(m_activeConfiguration->useNinja()); + } +} + void MakeStep::setClean(bool clean) { m_clean = clean; @@ -116,6 +151,7 @@ QVariantMap MakeStep::toMap() const map.insert(QLatin1String(CLEAN_KEY), m_clean); map.insert(QLatin1String(BUILD_TARGETS_KEY), m_buildTargets); map.insert(QLatin1String(ADDITIONAL_ARGUMENTS_KEY), m_additionalArguments); + map.insert(QLatin1String(USE_NINJA_KEY), m_useNinja); return map; } @@ -124,6 +160,7 @@ bool MakeStep::fromMap(const QVariantMap &map) m_clean = map.value(QLatin1String(CLEAN_KEY)).toBool(); m_buildTargets = map.value(QLatin1String(BUILD_TARGETS_KEY)).toStringList(); m_additionalArguments = map.value(QLatin1String(ADDITIONAL_ARGUMENTS_KEY)).toString(); + m_useNinja = map.value(QLatin1String(USE_NINJA_KEY)).toBool(); return BuildStep::fromMap(map); } @@ -151,12 +188,16 @@ bool MakeStep::init() ProcessParameters *pp = processParameters(); pp->setMacroExpander(bc->macroExpander()); - pp->setEnvironment(bc->environment()); + if (m_useNinja) { + Utils::Environment env = bc->environment(); + if (!env.value(QLatin1String("NINJA_STATUS")).startsWith(m_ninjaProgressString)) + env.set(QLatin1String("NINJA_STATUS"), m_ninjaProgressString + QLatin1String("%o/sec] ")); + pp->setEnvironment(env); + } else { + pp->setEnvironment(bc->environment()); + } pp->setWorkingDirectory(bc->buildDirectory()); - if (tc) - pp->setCommand(tc->makeCommand(bc->environment())); - else - pp->setCommand(QLatin1String("make")); + pp->setCommand(makeCommand(tc, bc->environment())); pp->setArguments(arguments); setOutputParser(new ProjectExplorer::GnuMakeParser()); @@ -209,8 +250,21 @@ void MakeStep::stdOutput(const QString &line) int percent = m_percentProgress.cap(1).toInt(&ok);; if (ok) m_futureInterface->setProgressValue(percent); + } else if (m_ninjaProgress.indexIn(line) != -1) { + bool ok = false; + int done = m_ninjaProgress.cap(1).toInt(&ok); + if (ok) { + int all = m_ninjaProgress.cap(2).toInt(&ok); + if (ok && all != 0) { + int percent = 100.0 * done/all; + m_futureInterface->setProgressValue(percent); + } + } } - AbstractProcessStep::stdOutput(line); + if (m_useNinja) + AbstractProcessStep::stdError(line); + else + AbstractProcessStep::stdOutput(line); } QStringList MakeStep::buildTargets() const @@ -253,6 +307,24 @@ void MakeStep::setAdditionalArguments(const QString &list) m_additionalArguments = list; } +QString MakeStep::makeCommand(ProjectExplorer::ToolChain *tc, const Utils::Environment &env) const +{ + if (m_useNinja) + return QLatin1String("ninja"); + if (tc) + return tc->makeCommand(env); + + return QLatin1String("make"); +} + +void MakeStep::setUseNinja(bool useNinja) +{ + if (m_useNinja != useNinja) { + m_useNinja = useNinja; + emit makeCommandChanged(); + } +} + // // MakeStepConfigWidget // @@ -291,6 +363,7 @@ MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep) connect(pro, SIGNAL(buildTargetsChanged()), this, SLOT(buildTargetsChanged())); connect(pro, SIGNAL(environmentChanged()), this, SLOT(updateDetails())); + connect(m_makeStep, SIGNAL(makeCommandChanged()), this, SLOT(updateDetails())); } void MakeStepConfigWidget::additionalArgumentsEdited() @@ -344,7 +417,7 @@ void MakeStepConfigWidget::updateDetails() param.setMacroExpander(bc->macroExpander()); param.setEnvironment(bc->environment()); param.setWorkingDirectory(bc->buildDirectory()); - param.setCommand(tc->makeCommand(bc->environment())); + param.setCommand(m_makeStep->makeCommand(tc, bc->environment())); param.setArguments(arguments); m_summaryText = param.summary(displayName()); } else { diff --git a/src/plugins/cmakeprojectmanager/makestep.h b/src/plugins/cmakeprojectmanager/makestep.h index b8342705e1a..d3c6a73c482 100644 --- a/src/plugins/cmakeprojectmanager/makestep.h +++ b/src/plugins/cmakeprojectmanager/makestep.h @@ -39,6 +39,10 @@ class QListWidget; class QListWidgetItem; QT_END_NAMESPACE +namespace ProjectExplorer { +class ToolChain; +} + namespace CMakeProjectManager { namespace Internal { @@ -72,10 +76,18 @@ public: QString additionalArguments() const; void setAdditionalArguments(const QString &list); + QString makeCommand(ProjectExplorer::ToolChain *tc, const Utils::Environment &env) const; + void setClean(bool clean); QVariantMap toMap() const; +public slots: + void setUseNinja(bool); + void activeBuildConfigurationChanged(); + +signals: + void makeCommandChanged(); protected: MakeStep(ProjectExplorer::BuildStepList *bsl, MakeStep *bs); @@ -88,13 +100,18 @@ protected: private: void ctor(); + CMakeBuildConfiguration *targetsActiveBuildConfiguration() const; bool m_clean; QRegExp m_percentProgress; + QRegExp m_ninjaProgress; + QString m_ninjaProgressString; QFutureInterface<bool> *m_futureInterface; QStringList m_buildTargets; QString m_additionalArguments; QList<ProjectExplorer::Task> m_tasks; + bool m_useNinja; + CMakeBuildConfiguration *m_activeConfiguration; }; class MakeStepConfigWidget :public ProjectExplorer::BuildStepConfigWidget -- GitLab