From 859bf2c5ce58b8f453b33397c748ca6b061b7ca1 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 20 Jan 2016 12:19:16 +0100 Subject: [PATCH] CMake: Do not run a cmake wizard all the time Do not push the cmake running straight into the face of the user. Do it in the background instead. This needs some follow-up patches to become really useful. Change-Id: I3457178b33e3f14bdeac25005a773d17abb73b65 Reviewed-by: Tim Jenssen --- .../cmakeprojectmanager/builddirmanager.cpp | 332 +++++++++ .../cmakeprojectmanager/builddirmanager.h | 116 ++++ .../cmakebuildconfiguration.cpp | 5 +- .../cmakebuildsettingswidget.cpp | 61 +- .../cmakebuildsettingswidget.h | 8 - .../cmakeprojectmanager/cmakebuildstep.cpp | 4 +- .../cmakeprojectmanager/cmakeeditor.cpp | 6 +- .../cmakeopenprojectwizard.cpp | 630 ------------------ .../cmakeopenprojectwizard.h | 194 ------ .../cmakepreloadcachekitconfigwidget.cpp | 86 --- .../cmakepreloadcachekitconfigwidget.h | 60 -- .../cmakepreloadcachekitinformation.cpp | 99 --- .../cmakepreloadcachekitinformation.h | 54 -- .../cmakeprojectmanager/cmakeproject.cpp | 282 +++----- .../cmakeprojectmanager/cmakeproject.h | 22 +- .../cmakeprojectmanager.cpp | 13 +- .../cmakeprojectmanager/cmakeprojectmanager.h | 2 +- .../cmakeprojectmanager.pro | 18 +- .../cmakeprojectmanager.qbs | 10 +- .../cmakeprojectplugin.cpp | 2 - .../cmakeprojectmanager/generatorinfo.cpp | 159 ----- .../cmakeprojectmanager/generatorinfo.h | 64 -- 22 files changed, 598 insertions(+), 1629 deletions(-) create mode 100644 src/plugins/cmakeprojectmanager/builddirmanager.cpp create mode 100644 src/plugins/cmakeprojectmanager/builddirmanager.h delete mode 100644 src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp delete mode 100644 src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h delete mode 100644 src/plugins/cmakeprojectmanager/cmakepreloadcachekitconfigwidget.cpp delete mode 100644 src/plugins/cmakeprojectmanager/cmakepreloadcachekitconfigwidget.h delete mode 100644 src/plugins/cmakeprojectmanager/cmakepreloadcachekitinformation.cpp delete mode 100644 src/plugins/cmakeprojectmanager/cmakepreloadcachekitinformation.h delete mode 100644 src/plugins/cmakeprojectmanager/generatorinfo.cpp delete mode 100644 src/plugins/cmakeprojectmanager/generatorinfo.h diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp new file mode 100644 index 00000000000..d9f085cee00 --- /dev/null +++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp @@ -0,0 +1,332 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "builddirmanager.h" +#include "cmakekitinformation.h" +#include "cmakeprojectmanager.h" +#include "cmaketool.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +// -------------------------------------------------------------------- +// Helper: +// -------------------------------------------------------------------- + +namespace CMakeProjectManager { +namespace Internal { + +static QStringList toArguments(const CMakeConfig &config) { + return Utils::transform(config, [](const CMakeConfigItem &i) -> QString { + QString a = QString::fromLatin1("-D"); + a.append(QString::fromUtf8(i.key)); + switch (i.type) { + case CMakeConfigItem::FILEPATH: + a.append(QLatin1String(":FILEPATH=")); + break; + case CMakeConfigItem::PATH: + a.append(QLatin1String(":PATH=")); + break; + case CMakeConfigItem::BOOL: + a.append(QLatin1String(":BOOL=")); + break; + case CMakeConfigItem::STRING: + a.append(QLatin1String(":STRING=")); + break; + case CMakeConfigItem::INTERNAL: + a.append(QLatin1String(":INTERNAL=")); + break; + } + a.append(QString::fromUtf8(i.value)); + + return a; + }); +} + +// -------------------------------------------------------------------- +// BuildDirManager: +// -------------------------------------------------------------------- + +BuildDirManager::BuildDirManager(const Utils::FileName &sourceDir, const ProjectExplorer::Kit *k, + const CMakeConfig &inputConfig, const Utils::Environment &env, + const Utils::FileName &buildDir) : + m_sourceDir(sourceDir), + m_buildDir(buildDir), + m_kit(k), + m_environment(env), + m_inputConfig(inputConfig), + m_watcher(new QFileSystemWatcher(this)) +{ + QTC_CHECK(!sourceDir.isEmpty()); + m_projectName = m_sourceDir.fileName(); + if (m_buildDir.isEmpty()) { + m_tempDir = new QTemporaryDir(QLatin1String("cmake-tmp-XXXXXX")); + m_buildDir = Utils::FileName::fromString(m_tempDir->path()); + } + QTC_CHECK(!m_buildDir.isEmpty()); + QTC_CHECK(k); + + connect(m_watcher, &QFileSystemWatcher::fileChanged, this, [this]() { + if (!isBusy()) + forceReparse(); + }); + + QTimer::singleShot(0, this, &BuildDirManager::parse); +} + +BuildDirManager::~BuildDirManager() +{ + delete m_tempDir; +} + +bool BuildDirManager::isBusy() const +{ + if (m_cmakeProcess) + return m_cmakeProcess->state() != QProcess::NotRunning; + return false; +} + +void BuildDirManager::forceReparse() +{ + CMakeTool *tool = CMakeKitInformation::cmakeTool(m_kit); + const QString generator = CMakeGeneratorKitInformation::generator(m_kit); + + QTC_ASSERT(tool, return); + QTC_ASSERT(!generator.isEmpty(), return); + + startCMake(tool, generator, m_inputConfig); +} + +void BuildDirManager::parse() +{ + CMakeTool *tool = CMakeKitInformation::cmakeTool(m_kit); + const QString generator = CMakeGeneratorKitInformation::generator(m_kit); + + QTC_ASSERT(tool, return); + QTC_ASSERT(!generator.isEmpty(), return); + + // Pop up a dialog asking the user to rerun cmake + QString cbpFile = CMakeManager::findCbpFile(QDir(m_buildDir.toString())); + QFileInfo cbpFileFi(cbpFile); + + if (!cbpFileFi.exists()) { + // Initial create: + startCMake(tool, generator, m_inputConfig); + return; + } + + const bool mustUpdate + = Utils::anyOf(m_watchedFiles, [&cbpFileFi](const Utils::FileName &f) { + return f.toFileInfo().lastModified() > cbpFileFi.lastModified(); + }); + if (mustUpdate) { + startCMake(tool, generator, CMakeConfig()); + } else { + extractData(); + emit dataAvailable(); + } +} + +bool BuildDirManager::isProjectFile(const Utils::FileName &fileName) const +{ + return m_watchedFiles.contains(fileName); +} + +QString BuildDirManager::projectName() const +{ + return m_projectName; +} + +QList BuildDirManager::buildTargets() const +{ + return m_buildTargets; +} + +QList BuildDirManager::files() const +{ + return m_files; +} + +void BuildDirManager::extractData() +{ + const Utils::FileName topCMake + = Utils::FileName::fromString(m_sourceDir.toString() + QLatin1String("/CMakeLists.txt")); + + m_projectName = m_sourceDir.fileName(); + m_buildTargets.clear(); + m_watchedFiles.clear(); + m_files.clear(); + m_files.append(new ProjectExplorer::FileNode(topCMake, ProjectExplorer::ProjectFileType, false)); + m_watchedFiles.insert(topCMake); + + foreach (const QString &file, m_watcher->files()) + m_watcher->removePath(file); + + // Find cbp file + QString cbpFile = CMakeManager::findCbpFile(m_buildDir.toString()); + if (cbpFile.isEmpty()) + return; + + m_watcher->addPath(cbpFile); + + // setFolderName + CMakeCbpParser cbpparser; + // Parsing + if (!cbpparser.parseCbpFile(m_kit, cbpFile, m_sourceDir.toString())) + return; + + m_projectName = cbpparser.projectName(); + + m_files = cbpparser.fileList(); + QSet projectFiles; + if (cbpparser.hasCMakeFiles()) { + m_files.append(cbpparser.cmakeFileList()); + foreach (const ProjectExplorer::FileNode *node, cbpparser.cmakeFileList()) + projectFiles.insert(node->filePath()); + } else { + m_files.append(new ProjectExplorer::FileNode(topCMake, ProjectExplorer::ProjectFileType, false)); + projectFiles.insert(topCMake); + } + + m_watchedFiles = projectFiles; + foreach (const Utils::FileName &f, m_watchedFiles) + m_watcher->addPath(f.toString()); + + m_buildTargets = cbpparser.buildTargets(); +} + +void BuildDirManager::startCMake(CMakeTool *tool, const QString &generator, + const CMakeConfig &config) +{ + QTC_ASSERT(tool && tool->isValid(), return); + QTC_ASSERT(!m_cmakeProcess, return); + + // Make sure m_buildDir exists: + const QString buildDirStr = m_buildDir.toString(); + QDir bDir = QDir(buildDirStr); + bDir.mkpath(buildDirStr); + + // Always use the sourceDir: If we are triggered because the build directory is getting deleted + // then we are racing against CMakeCache.txt also getting deleted. + const QString srcDir = m_sourceDir.toString(); + + m_cmakeProcess = new Utils::QtcProcess(this); + m_cmakeProcess->setProcessChannelMode(QProcess::MergedChannels); + m_cmakeProcess->setWorkingDirectory(buildDirStr); + m_cmakeProcess->setEnvironment(m_environment); + + connect(m_cmakeProcess, &QProcess::readyReadStandardOutput, + this, &BuildDirManager::processCMakeOutput); + connect(m_cmakeProcess, static_cast(&QProcess::finished), + this, &BuildDirManager::cmakeFinished); + + QString args; + Utils::QtcProcess::addArg(&args, srcDir); + if (!generator.isEmpty()) + Utils::QtcProcess::addArg(&args, QString::fromLatin1("-G%1").arg(generator)); + Utils::QtcProcess::addArgs(&args, toArguments(config)); + + // Clear task cache: + ProjectExplorer::TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM); + m_toReport.clear(); + + m_cmakeProcess->setCommand(tool->cmakeExecutable().toString(), args); + m_cmakeProcess->start(); + emit parsingStarted(); +} + +void BuildDirManager::cmakeFinished(int code, QProcess::ExitStatus status) +{ + QTC_ASSERT(m_cmakeProcess, return); + + // process rest of the output: + while (m_cmakeProcess->canReadLine()) + processOutputLine(Utils::SynchronousProcess::normalizeNewlines(QString::fromLocal8Bit(m_cmakeProcess->readLine()))); + QString rest = Utils::SynchronousProcess::normalizeNewlines(QString::fromLocal8Bit(m_cmakeProcess->readAllStandardOutput())); + if (!rest.isEmpty()) + processOutputLine(rest); + + QTC_CHECK(m_cmakeProcess->readAllStandardOutput().isEmpty()); + + if (!m_toReport.description.isEmpty()) + ProjectExplorer::TaskHub::addTask(m_toReport); + m_toReport.clear(); + + m_cmakeProcess->deleteLater(); + m_cmakeProcess = nullptr; + + extractData(); // try even if cmake failed... + + if (status != QProcess::NormalExit) + Core::MessageManager::write(tr("*** cmake process crashed!")); + else if (code != 0) + Core::MessageManager::write(tr("*** cmake process exited with exit code %s.").arg(code)); + emit dataAvailable(); +} + +void BuildDirManager::processCMakeOutput() +{ + QTC_ASSERT(m_cmakeProcess, return); + while (m_cmakeProcess->canReadLine()) + processOutputLine(QString::fromLocal8Bit(m_cmakeProcess->readLine())); +} + +void BuildDirManager::processOutputLine(const QString &l) +{ + QString line = Utils::SynchronousProcess::normalizeNewlines(l); + while (line.endsWith(QLatin1Char('\n'))) + line.chop(1); + Core::MessageManager::write(line); + + // Check for errors: + if (m_toReport.type == ProjectExplorer::Task::Unknown) { + m_toReport.category = ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM; + } else { + if (line.startsWith(QStringLiteral(" ")) || line.isEmpty()) { + m_toReport.description.append(QStringLiteral("\n") + line); + } else { + ProjectExplorer::TaskHub::addTask(m_toReport); + m_toReport.clear(); + } + } +} + +} // namespace Internal +} // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.h b/src/plugins/cmakeprojectmanager/builddirmanager.h new file mode 100644 index 00000000000..9e7648b1f26 --- /dev/null +++ b/src/plugins/cmakeprojectmanager/builddirmanager.h @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#ifndef CMAKE_BUILDDIRMANAGER_H +#define CMAKE_BUILDDIRMANAGER_H + +#include "cmakecbpparser.h" +#include "cmakeconfigitem.h" + +#include + +#include +#include +#include + +#include +#include +#include + +QT_FORWARD_DECLARE_CLASS(QTemporaryDir); +QT_FORWARD_DECLARE_CLASS(QFileSystemWatcher); + +namespace ProjectExplorer { +class FileNode; +class Kit; +} // namespace ProjectExplorer + +namespace CMakeProjectManager { + +class CMakeTool; + +namespace Internal { + +class BuildDirManager : public QObject +{ + Q_OBJECT + +public: + BuildDirManager(const Utils::FileName &sourceDir, const ProjectExplorer::Kit *k, + const CMakeConfig &inputConfig, const Utils::Environment &env, + const Utils::FileName &buildDir); + ~BuildDirManager() override; + + const ProjectExplorer::Kit *kit() const { return m_kit; } + const Utils::FileName buildDirectory() const { return m_buildDir; } + const Utils::FileName sourceDirectory() const { return m_sourceDir; } + bool isBusy() const; + + void parse(); + void forceReparse(); + + bool isProjectFile(const Utils::FileName &fileName) const; + QString projectName() const; + QList buildTargets() const; + QList files() const; + +signals: + void parsingStarted() const; + void dataAvailable() const; + void errorOccured(const QString &err) const; + +private: + void extractData(); + + void startCMake(CMakeTool *tool, const QString &generator, const CMakeConfig &config); + + void cmakeFinished(int code, QProcess::ExitStatus status); + void processCMakeOutput(); + + void processOutputLine(const QString &line); + + const Utils::FileName m_sourceDir; + Utils::FileName m_buildDir; + const ProjectExplorer::Kit *const m_kit; + Utils::Environment m_environment; + CMakeConfig m_inputConfig; + + QTemporaryDir *m_tempDir = nullptr; + Utils::QtcProcess *m_cmakeProcess = nullptr; + + QSet m_watchedFiles; + QString m_projectName; + QList m_buildTargets; + QFileSystemWatcher *m_watcher; + QList m_files; + + // For error reporting: + ProjectExplorer::Task m_toReport; +}; + +} // namespace Internal +} // namespace CMakeProjectManager + +#endif // CMAKE_BUILDDIRMANAGER_H diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 56bbc2fcbea..48306a0dbec 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -27,7 +27,6 @@ #include "cmakebuildinfo.h" #include "cmakebuildstep.h" -#include "cmakeopenprojectwizard.h" #include "cmakeproject.h" #include "cmakeprojectconstants.h" #include "cmakebuildsettingswidget.h" @@ -230,7 +229,7 @@ CMakeBuildConfiguration *CMakeBuildConfigurationFactory::clone(ProjectExplorer:: { if (!canClone(parent, source)) return 0; - CMakeBuildConfiguration *old = static_cast(source); + auto old = static_cast(source); return new CMakeBuildConfiguration(parent, old); } @@ -264,7 +263,7 @@ CMakeBuildInfo *CMakeBuildConfigurationFactory::createBuildInfo(const ProjectExp const QString &sourceDir, BuildType buildType) const { - CMakeBuildInfo *info = new CMakeBuildInfo(this); + auto info = new CMakeBuildInfo(this); info->kitId = k->id(); info->environment = Environment::systemEnvironment(); k->addToEnvironment(info->environment); diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp index db31e153e52..06696847b60 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp @@ -26,15 +26,13 @@ #include "cmakebuildsettingswidget.h" #include "cmakeproject.h" #include "cmakebuildconfiguration.h" -#include "cmakebuildinfo.h" -#include "cmakeopenprojectwizard.h" -#include "cmakeprojectmanager.h" #include #include #include #include +#include #include @@ -42,8 +40,7 @@ namespace CMakeProjectManager { namespace Internal { CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc) : - m_pathLineEdit(new QLineEdit), - m_changeButton(new QPushButton) + m_buildConfiguration(bc) { auto vbox = new QVBoxLayout(this); vbox->setMargin(0); @@ -58,55 +55,19 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc) fl->setMargin(0); fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); - auto runCmakeButton = new QPushButton(tr("Run CMake...")); - connect(runCmakeButton, &QAbstractButton::clicked, this, &CMakeBuildSettingsWidget::runCMake); - fl->addRow(tr("Reconfigure project:"), runCmakeButton); + auto project = static_cast(bc->target()->project()); + auto buildDirChooser = new Utils::PathChooser; + buildDirChooser->setBaseFileName(project->projectDirectory()); + buildDirChooser->setFileName(bc->buildDirectory()); + connect(buildDirChooser, &Utils::PathChooser::rawPathChanged, this, + [this, project](const QString &path) { + project->changeBuildDirectory(m_buildConfiguration, path); + }); - m_pathLineEdit->setReadOnly(true); - - auto hbox = new QHBoxLayout(); - hbox->addWidget(m_pathLineEdit); - - m_changeButton->setText(tr("&Change")); - connect(m_changeButton, &QAbstractButton::clicked, this, - &CMakeBuildSettingsWidget::openChangeBuildDirectoryDialog); - hbox->addWidget(m_changeButton); - - fl->addRow(tr("Build directory:"), hbox); - - m_buildConfiguration = bc; - m_pathLineEdit->setText(m_buildConfiguration->rawBuildDirectory().toString()); - if (m_buildConfiguration->buildDirectory() == bc->target()->project()->projectDirectory()) - m_changeButton->setEnabled(false); - else - m_changeButton->setEnabled(true); + fl->addRow(tr("Build directory:"), buildDirChooser); setDisplayName(tr("CMake")); } -void CMakeBuildSettingsWidget::openChangeBuildDirectoryDialog() -{ - CMakeBuildInfo info(m_buildConfiguration); - CMakeOpenProjectWizard copw(Core::ICore::mainWindow(), CMakeOpenProjectWizard::ChangeDirectory, - &info); - if (copw.exec() == QDialog::Accepted) { - auto project = static_cast(m_buildConfiguration->target()->project()); - project->changeBuildDirectory(m_buildConfiguration, copw.buildDirectory()); - m_pathLineEdit->setText(m_buildConfiguration->rawBuildDirectory().toString()); - } -} - -void CMakeBuildSettingsWidget::runCMake() -{ - if (!ProjectExplorer::ProjectExplorerPlugin::saveModifiedFiles()) - return; - CMakeBuildInfo info(m_buildConfiguration); - CMakeOpenProjectWizard copw(Core::ICore::mainWindow(), CMakeOpenProjectWizard::WantToUpdate, - &info); - if (copw.exec() == QDialog::Accepted) { - auto project = static_cast(m_buildConfiguration->target()->project()); - project->parseCMakeLists(); - } -} } // namespace Internal } // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.h b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.h index edc7cb77ae5..cca63741077 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.h @@ -27,9 +27,6 @@ #include -QT_FORWARD_DECLARE_CLASS(QLineEdit) -QT_FORWARD_DECLARE_CLASS(QPushButton) - namespace CMakeProjectManager { namespace Internal { @@ -42,11 +39,6 @@ public: CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc); private: - void openChangeBuildDirectoryDialog(); - void runCMake(); - - QLineEdit *m_pathLineEdit; - QPushButton *m_changeButton; CMakeBuildConfiguration *m_buildConfiguration = 0; }; diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp index 49207c7d8d2..5de059b24ea 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp @@ -98,7 +98,7 @@ void CMakeBuildStep::ctor() setDefaultDisplayName(tr("Make")); connect(target(), &Target::kitChanged, this, &CMakeBuildStep::cmakeCommandChanged); - connect(static_cast(project()), &CMakeProject::buildTargetsChanged, + connect(static_cast(project()), &CMakeProject::buildDirectoryDataAvailable, this, &CMakeBuildStep::buildTargetsChanged); } @@ -401,7 +401,7 @@ CMakeBuildStepConfigWidget::CMakeBuildStepConfigWidget(CMakeBuildStep *buildStep connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged, this, &CMakeBuildStepConfigWidget::updateDetails); - connect(pro, &CMakeProject::buildTargetsChanged, this, &CMakeBuildStepConfigWidget::buildTargetsChanged); + connect(pro, &CMakeProject::buildDirectoryDataAvailable, this, &CMakeBuildStepConfigWidget::buildTargetsChanged); connect(m_buildStep, &CMakeBuildStep::targetsToBuildChanged, this, &CMakeBuildStepConfigWidget::selectedBuildTargetsChanged); connect(pro, &CMakeProject::environmentChanged, this, &CMakeBuildStepConfigWidget::updateDetails); } diff --git a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp index 3fdde95596f..df2fefe7ca0 100644 --- a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp @@ -73,10 +73,10 @@ void CMakeEditor::finalizeInitialization() if (!document->isModified()) return; InfoBar *infoBar = document->infoBar(); - Id infoRunCmake("CMakeEditor.RunCMake"); - if (!infoBar->canInfoBeAdded(infoRunCmake)) + Id infoRunCMake("CMakeEditor.RunCMake"); + if (!infoBar->canInfoBeAdded(infoRunCMake)) return; - InfoBarEntry info(infoRunCmake, + InfoBarEntry info(infoRunCMake, tr("Changes to cmake files are shown in the project tree after building."), InfoBarEntry::GlobalSuppressionEnabled); info.setCustomButtonInfo(tr("Build now"), [document]() { diff --git a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp deleted file mode 100644 index faecf75cae6..00000000000 --- a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp +++ /dev/null @@ -1,630 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "cmakeprojectconstants.h" -#include "cmakeopenprojectwizard.h" -#include "cmakeprojectmanager.h" -#include "cmaketoolmanager.h" -#include "cmakebuildconfiguration.h" -#include "cmakebuildinfo.h" -#include "cmakekitinformation.h" -#include "cmaketool.h" -#include "generatorinfo.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace CMakeProjectManager; -using namespace CMakeProjectManager::Internal; -using namespace ProjectExplorer; - -/////// -// Page Flow: -// Start (No .user file) -// | -// |---> In Source Build --> Page: Tell the user about that -// |--> Already existing cbp file (and new enough) --> Page: Ready to load the project -// |--> Page: Ask for cmd options, run generator -// |---> No in source Build --> Page: Ask the user for the build directory -// |--> Already existing cbp file (and new enough) --> Page: Ready to load the project -// |--> Page: Ask for cmd options, run generator - - -////////////// -/// CMakeOpenProjectWizard -////////////// -CMakeOpenProjectWizard::CMakeOpenProjectWizard(QWidget *parent, - CMakeOpenProjectWizard::Mode mode, - const CMakeBuildInfo *info) : - Utils::Wizard(parent), - m_sourceDirectory(info->sourceDirectory), - m_environment(info->environment), - m_kit(KitManager::find(info->kitId)) -{ - CMakeRunPage::Mode rmode; - if (mode == CMakeOpenProjectWizard::NeedToCreate) - rmode = CMakeRunPage::Recreate; - else if (mode == CMakeOpenProjectWizard::WantToUpdate) - rmode = CMakeRunPage::WantToUpdate; - else if (mode == CMakeOpenProjectWizard::NeedToUpdate) - rmode = CMakeRunPage::NeedToUpdate; - else - rmode = CMakeRunPage::ChangeDirectory; - - if (mode == CMakeOpenProjectWizard::ChangeDirectory) { - m_buildDirectory = info->buildDirectory.toString(); - addPage(new ShadowBuildPage(this, true)); - } - - if (CMakeToolManager::cmakeTools().isEmpty()) - addPage(new NoCMakePage(this)); - - addPage(new CMakeRunPage(this, rmode, info->buildDirectory.toString(), info->arguments, - m_kit->displayName(), info->displayName)); - - setWindowTitle(tr("CMake Wizard")); -} - -bool CMakeOpenProjectWizard::hasInSourceBuild() const -{ - return QFileInfo::exists(m_sourceDirectory + QLatin1String("/CMakeCache.txt")); -} - -bool CMakeOpenProjectWizard::compatibleKitExist() const -{ - bool preferNinja = CMakeManager::preferNinja(); - const QList kitList = KitManager::kits(); - - foreach (Kit *k, kitList) { - CMakeTool *cmake = CMakeKitInformation::cmakeTool(k); - if (!cmake) - continue; - - bool hasCodeBlocksGenerator = cmake->hasCodeBlocksMsvcGenerator(); - bool hasNinjaGenerator = cmake->hasCodeBlocksNinjaGenerator(); - - // OfferNinja and ForceNinja differ in what they return - // but not whether the list is empty or not, which is what we - // are interested in here - QList infos = GeneratorInfo::generatorInfosFor(k, hasNinjaGenerator, - preferNinja, - hasCodeBlocksGenerator); - if (!infos.isEmpty()) - return true; - } - return false; -} - -bool CMakeOpenProjectWizard::existsUpToDateXmlFile() const -{ - QString cbpFile = CMakeManager::findCbpFile(QDir(buildDirectory())); - if (!cbpFile.isEmpty()) { - // We already have a cbp file - QFileInfo cbpFileInfo(cbpFile); - QFileInfo cmakeListsFileInfo(sourceDirectory() + QLatin1String("/CMakeLists.txt")); - - if (cbpFileInfo.lastModified() > cmakeListsFileInfo.lastModified()) - return true; - } - return false; -} - -QString CMakeOpenProjectWizard::buildDirectory() const -{ - return m_buildDirectory; -} - -QString CMakeOpenProjectWizard::sourceDirectory() const -{ - return m_sourceDirectory; -} - -void CMakeOpenProjectWizard::setBuildDirectory(const QString &directory) -{ - m_buildDirectory = directory; -} - -QString CMakeOpenProjectWizard::arguments() const -{ - return m_arguments; -} - -void CMakeOpenProjectWizard::setArguments(const QString &args) -{ - m_arguments = args; -} - -Utils::Environment CMakeOpenProjectWizard::environment() const -{ - return m_environment; -} - -Kit *CMakeOpenProjectWizard::kit() const -{ - return m_kit; -} - -void CMakeOpenProjectWizard::setKit(Kit *kit) -{ - m_kit = kit; -} - -////// -// NoKitPage -///// - -NoKitPage::NoKitPage(CMakeOpenProjectWizard *cmakeWizard) - : QWizardPage(cmakeWizard), m_cmakeWizard(cmakeWizard) -{ - auto layout = new QVBoxLayout; - setLayout(layout); - - m_descriptionLabel = new QLabel(this); - m_descriptionLabel->setWordWrap(true); - layout->addWidget(m_descriptionLabel); - - m_optionsButton = new QPushButton; - m_optionsButton->setText(Core::ICore::msgShowOptionsDialog()); - - connect(m_optionsButton, &QAbstractButton::clicked, this, &NoKitPage::showOptions); - - auto hbox = new QHBoxLayout; - hbox->addWidget(m_optionsButton); - hbox->addStretch(); - - layout->addLayout(hbox); - - setTitle(tr("Check Kits")); - - connect(KitManager::instance(), &KitManager::kitsChanged, this, &NoKitPage::kitsChanged); - - kitsChanged(); -} - -void NoKitPage::kitsChanged() -{ - if (isComplete()) { - m_descriptionLabel->setText(tr("There are compatible kits.")); - m_optionsButton->setVisible(false); - } else { - m_descriptionLabel->setText(tr("Qt Creator has no kits that are suitable for CMake projects. Please configure a kit.")); - m_optionsButton->setVisible(true); - } - emit completeChanged(); -} - -bool NoKitPage::isComplete() const -{ - return m_cmakeWizard->compatibleKitExist(); -} - -void NoKitPage::initializePage() -{ - //if the NoCMakePage was added, we need to recheck if kits exist - kitsChanged(); -} - -void NoKitPage::showOptions() -{ - Core::ICore::showOptionsDialog(ProjectExplorer::Constants::KITS_SETTINGS_PAGE_ID, this); -} - -InSourceBuildPage::InSourceBuildPage(CMakeOpenProjectWizard *cmakeWizard) - : QWizardPage(cmakeWizard), m_cmakeWizard(cmakeWizard) -{ - setLayout(new QVBoxLayout); - auto label = new QLabel(this); - label->setWordWrap(true); - label->setText(tr("Qt Creator has detected an in-source-build in %1 " - "which prevents shadow builds. Qt Creator will not allow you to change the build directory. " - "If you want a shadow build, clean your source directory and re-open the project.") - .arg(m_cmakeWizard->buildDirectory())); - layout()->addWidget(label); - setTitle(tr("Build Location")); -} - -ShadowBuildPage::ShadowBuildPage(CMakeOpenProjectWizard *cmakeWizard, bool change) - : QWizardPage(cmakeWizard), m_cmakeWizard(cmakeWizard) -{ - auto fl = new QFormLayout; - this->setLayout(fl); - - auto label = new QLabel(this); - label->setWordWrap(true); - if (change) - label->setText(tr("Please enter the directory in which you want to build your project.") + QLatin1Char(' ')); - else - label->setText(tr("Please enter the directory in which you want to build your project. " - "Qt Creator recommends to not use the source directory for building. " - "This ensures that the source directory remains clean and enables multiple builds " - "with different settings.")); - fl->addRow(label); - m_pc = new Utils::PathChooser(this); - m_pc->setBaseDirectory(m_cmakeWizard->sourceDirectory()); - m_pc->setPath(m_cmakeWizard->buildDirectory()); - m_pc->setExpectedKind(Utils::PathChooser::Directory); - m_pc->setHistoryCompleter(QLatin1String("Cmake.BuildDir.History")); - connect(m_pc, &Utils::PathChooser::rawPathChanged, this, &ShadowBuildPage::buildDirectoryChanged); - fl->addRow(tr("Build directory:"), m_pc); - setTitle(tr("Build Location")); -} - -void ShadowBuildPage::buildDirectoryChanged() -{ - m_cmakeWizard->setBuildDirectory(m_pc->path()); -} - -////// -// NoCMakePage -///// - -NoCMakePage::NoCMakePage(CMakeOpenProjectWizard *cmakeWizard) : QWizardPage(cmakeWizard) -{ - auto layout = new QVBoxLayout; - setLayout(layout); - - m_descriptionLabel = new QLabel(this); - m_descriptionLabel->setWordWrap(true); - layout->addWidget(m_descriptionLabel); - - m_optionsButton = new QPushButton; - m_optionsButton->setText(Core::ICore::msgShowOptionsDialog()); - - connect(m_optionsButton, &QAbstractButton::clicked, this, &NoCMakePage::showOptions); - - auto hbox = new QHBoxLayout; - hbox->addWidget(m_optionsButton); - hbox->addStretch(); - - layout->addLayout(hbox); - - setTitle(tr("Check CMake Tools")); - - connect(CMakeToolManager::instance(), &CMakeToolManager::cmakeToolsChanged, - this, &NoCMakePage::cmakeToolsChanged); - - cmakeToolsChanged(); -} - -void NoCMakePage::cmakeToolsChanged() -{ - if (isComplete()) { - m_descriptionLabel->setText(tr("There are CMake Tools registered.")); - m_optionsButton->setVisible(false); - } else { - m_descriptionLabel->setText(tr("Qt Creator has no CMake Tools that are required for CMake projects. Please configure at least one.")); - m_optionsButton->setVisible(true); - } - emit completeChanged(); -} - -bool NoCMakePage::isComplete() const -{ - return !CMakeToolManager::cmakeTools().isEmpty(); -} - -void NoCMakePage::showOptions() -{ - Core::ICore::showOptionsDialog(Constants::CMAKE_SETTINGSPAGE_ID, this); -} - -CMakeRunPage::CMakeRunPage(CMakeOpenProjectWizard *cmakeWizard, Mode mode, - const QString &buildDirectory, const QString &initialArguments, - const QString &kitName, const QString &buildConfigurationName) : - QWizardPage(cmakeWizard), - m_cmakeWizard(cmakeWizard), - m_descriptionLabel(new QLabel(this)), - m_argumentsLineEdit(new Utils::FancyLineEdit(this)), - m_generatorComboBox(new QComboBox(this)), - m_generatorExtraText(new QLabel(this)), - m_runCMake(new QPushButton(this)), - m_output(new QPlainTextEdit(this)), - m_exitCodeLabel(new QLabel(this)), - m_continueCheckBox(new QCheckBox(this)), - m_mode(mode), - m_buildDirectory(buildDirectory), - m_kitName(kitName), - m_buildConfigurationName(buildConfigurationName) -{ - auto fl = new QFormLayout; - fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); - setLayout(fl); - // Description Label - m_descriptionLabel->setWordWrap(true); - - fl->addRow(m_descriptionLabel); - - // Run CMake Line (with arguments) - m_argumentsLineEdit->setHistoryCompleter(QLatin1String("CMakeArgumentsLineEdit")); - m_argumentsLineEdit->selectAll(); - - connect(m_argumentsLineEdit, &QLineEdit::returnPressed, this, &CMakeRunPage::runCMake); - fl->addRow(tr("Arguments:"), m_argumentsLineEdit); - fl->addRow(tr("Generator:"), m_generatorComboBox); - fl->addRow(m_generatorExtraText); - - m_runCMake->setText(tr("Run CMake")); - connect(m_runCMake, &QAbstractButton::clicked, this, &CMakeRunPage::runCMake); - - auto hbox2 = new QHBoxLayout; - hbox2->addStretch(10); - hbox2->addWidget(m_runCMake); - fl->addRow(hbox2); - - // Bottom output window - m_output->setReadOnly(true); - // set smaller minimum size to avoid vanishing descriptions if all of the - // above is shown and the dialog not vertically resizing to fit stuff in (Mac) - m_output->setMinimumHeight(15); - QFont f(TextEditor::FontSettings::defaultFixedFontFamily()); - f.setStyleHint(QFont::TypeWriter); - m_output->setFont(f); - QSizePolicy pl = m_output->sizePolicy(); - pl.setVerticalStretch(1); - m_output->setSizePolicy(pl); - fl->addRow(m_output); - - m_exitCodeLabel->setVisible(false); - fl->addRow(m_exitCodeLabel); - - m_continueCheckBox->setVisible(false); - m_continueCheckBox->setText(tr("Open project with errors.")); - connect(m_continueCheckBox, &QCheckBox::toggled, this, &CMakeRunPage::completeChanged); - fl->addRow(m_continueCheckBox); - - setTitle(tr("Run CMake")); - setMinimumSize(600, 400); - - m_argumentsLineEdit->setText(initialArguments); -} - -QByteArray CMakeRunPage::cachedGeneratorFromFile(const QString &cache) -{ - QFile fi(cache); - if (fi.exists()) { - // Cache exists, then read it... - if (fi.open(QIODevice::ReadOnly | QIODevice::Text)) { - while (!fi.atEnd()) { - QByteArray line = fi.readLine(); - if (line.startsWith("CMAKE_GENERATOR:INTERNAL=")) { - int splitpos = line.indexOf('='); - if (splitpos != -1) { - QByteArray cachedGenerator = line.mid(splitpos + 1).trimmed(); - if (!cachedGenerator.isEmpty()) - return cachedGenerator; - } - } - } - } - } - return QByteArray(); -} - -void CMakeRunPage::initializePage() -{ - if (m_mode == CMakeRunPage::NeedToUpdate) { - m_descriptionLabel->setText(tr("The build directory \"%1\" for build configuration \"%2\" " - "for target \"%3\" contains an outdated .cbp file. Qt " - "Creator needs to update this file by running CMake. " - "You can add command line arguments below. Note that " - "CMake remembers command line arguments from the " - "previous runs.") - .arg(QDir::toNativeSeparators(m_buildDirectory)) - .arg(m_buildConfigurationName) - .arg(m_kitName)); - } else if (m_mode == CMakeRunPage::Recreate) { - m_descriptionLabel->setText(tr("The directory \"%1\" specified in build configuration \"%2\", " - "for target \"%3\" does not contain a .cbp file. " - "Qt Creator needs to recreate this file by running CMake. " - "Some projects require command line arguments to " - "the initial CMake call. Note that CMake remembers command " - "line arguments from the previous runs.") - .arg(QDir::toNativeSeparators(m_buildDirectory)) - .arg(m_buildConfigurationName) - .arg(m_kitName)); - } else if (m_mode == CMakeRunPage::ChangeDirectory) { - m_buildDirectory = m_cmakeWizard->buildDirectory(); - m_descriptionLabel->setText(tr("Qt Creator needs to run CMake in the new build directory. " - "Some projects require command line arguments to the " - "initial CMake call.")); - } else if (m_mode == CMakeRunPage::WantToUpdate) { - m_descriptionLabel->setText(tr("Refreshing the .cbp file in \"%1\" for build configuration \"%2\" " - "for target \"%3\".") - .arg(QDir::toNativeSeparators(m_buildDirectory)) - .arg(m_buildConfigurationName) - .arg(m_kitName)); - } - - // Build the list of generators/toolchains we want to offer - m_generatorComboBox->clear(); - - bool preferNinja = CMakeManager::preferNinja(); - - QList infos; - CMakeTool *cmake = CMakeKitInformation::cmakeTool(m_cmakeWizard->kit()); - if (cmake) { - // Note: We don't compare the actually cached generator to what is set in the buildconfiguration - // We assume that the buildconfiguration is correct - infos = GeneratorInfo::generatorInfosFor(m_cmakeWizard->kit(), true, preferNinja, true); - } - foreach (const GeneratorInfo &info, infos) - m_generatorComboBox->addItem(info.displayName(), qVariantFromValue(info)); - -} - -bool CMakeRunPage::validatePage() -{ - int index = m_generatorComboBox->currentIndex(); - if (index == -1) - return false; - GeneratorInfo generatorInfo = m_generatorComboBox->itemData(index).value(); - m_cmakeWizard->setKit(generatorInfo.kit()); - return QWizardPage::validatePage(); -} - -void CMakeRunPage::runCMake() -{ - QTC_ASSERT(!m_cmakeProcess, return); - m_haveCbpFile = false; - - Utils::Environment env = m_cmakeWizard->environment(); - int index = m_generatorComboBox->currentIndex(); - - if (index == -1) { - m_output->appendPlainText(tr("No generator selected.")); - return; - } - GeneratorInfo generatorInfo = m_generatorComboBox->itemData(index).value(); - m_cmakeWizard->setKit(generatorInfo.kit()); - - m_runCMake->setEnabled(false); - m_argumentsLineEdit->setEnabled(false); - m_generatorComboBox->setEnabled(false); - - m_output->clear(); - - CMakeTool *cmake = CMakeKitInformation::cmakeTool(generatorInfo.kit()); - if (cmake && cmake->isValid()) { - m_cmakeProcess = new Utils::QtcProcess(); - connect(m_cmakeProcess, &QProcess::readyReadStandardOutput, - this, &CMakeRunPage::cmakeReadyReadStandardOutput); - connect(m_cmakeProcess, &QProcess::readyReadStandardError, - this, &CMakeRunPage::cmakeReadyReadStandardError); - connect(m_cmakeProcess, static_cast(&QProcess::finished), - this, &CMakeRunPage::cmakeFinished); - - QString arguments = m_argumentsLineEdit->text(); - - Utils::QtcProcess::addArg(&arguments, QString::fromLatin1(generatorInfo.generatorArgument())); - const QString preloadCache = generatorInfo.preLoadCacheFileArgument(); - if (!preloadCache.isEmpty()) - Utils::QtcProcess::addArg(&arguments, preloadCache); - m_output->appendHtml(tr("Running: '%1' with arguments '%2' in '%3'.
") - .arg(cmake->cmakeExecutable().toUserOutput()) - .arg(arguments) - .arg(QDir::toNativeSeparators(m_buildDirectory))); - CMakeManager::createXmlFile(m_cmakeProcess, cmake->cmakeExecutable().toString(), - arguments, m_cmakeWizard->sourceDirectory(), - m_buildDirectory, env); - } else { - m_runCMake->setEnabled(true); - m_argumentsLineEdit->setEnabled(true); - m_generatorComboBox->setEnabled(true); - m_output->appendPlainText(tr("Selected kit has no valid CMake executable specified.")); - } -} - -static QColor mix_colors(const QColor &a, const QColor &b) -{ - return QColor((a.red() + 2 * b.red()) / 3, (a.green() + 2 * b.green()) / 3, - (a.blue() + 2* b.blue()) / 3, (a.alpha() + 2 * b.alpha()) / 3); -} - -void CMakeRunPage::cmakeReadyReadStandardOutput() -{ - QTextCursor cursor(m_output->document()); - cursor.movePosition(QTextCursor::End); - QTextCharFormat tf; - - QFont font = m_output->font(); - tf.setFont(font); - tf.setForeground(m_output->palette().color(QPalette::Text)); - - cursor.insertText(QString::fromLocal8Bit(m_cmakeProcess->readAllStandardOutput()), tf); -} - -void CMakeRunPage::cmakeReadyReadStandardError() -{ - QTextCursor cursor(m_output->document()); - cursor.movePosition(QTextCursor::End); - QTextCharFormat tf; - - QFont font = m_output->font(); - QFont boldFont = font; - boldFont.setBold(true); - tf.setFont(boldFont); - tf.setForeground(mix_colors(m_output->palette().color(QPalette::Text), QColor(Qt::red))); - - cursor.insertText(QString::fromLocal8Bit(m_cmakeProcess->readAllStandardError()), tf); -} - -void CMakeRunPage::cmakeFinished() -{ - m_runCMake->setEnabled(true); - m_argumentsLineEdit->setEnabled(true); - m_generatorComboBox->setEnabled(true); - - if (m_cmakeProcess->exitCode() != 0) { - m_exitCodeLabel->setVisible(true); - m_exitCodeLabel->setText(tr("CMake exited with errors. Please check CMake output.")); - static_cast(m_argumentsLineEdit->completer())->removeHistoryItem(0); - m_haveCbpFile = false; - m_continueCheckBox->setVisible(true); - } else { - m_exitCodeLabel->setVisible(false); - m_continueCheckBox->setVisible(false); - m_haveCbpFile = true; - } - m_cmakeProcess->deleteLater(); - m_cmakeProcess = 0; - m_cmakeWizard->setArguments(m_argumentsLineEdit->text()); - emit completeChanged(); -} - -void CMakeRunPage::cleanupPage() -{ - m_output->clear(); - m_haveCbpFile = false; - m_exitCodeLabel->setVisible(false); - emit completeChanged(); -} - -bool CMakeRunPage::isComplete() const -{ - int index = m_generatorComboBox->currentIndex(); - return index != -1 && (m_haveCbpFile || m_continueCheckBox->isChecked()); -} diff --git a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h deleted file mode 100644 index 1aace5004b0..00000000000 --- a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h +++ /dev/null @@ -1,194 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "cmakebuildconfiguration.h" -#include "cmakebuildinfo.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE -class QCheckBox; -QT_END_NAMESPACE - -namespace Utils { -class FancyLineEdit; -class PathChooser; -} - -namespace ProjectExplorer { class Kit; } - -namespace CMakeProjectManager { -namespace Internal { - -class CMakeManager; - -class CMakeOpenProjectWizard : public Utils::Wizard -{ - Q_OBJECT -public: - enum Mode { - Nothing, - NeedToCreate, - NeedToUpdate, - WantToUpdate, - ChangeDirectory - }; - - /// used to update if we have already a .user file - /// recreates or updates the cbp file - /// Also used to change the build directory of one buildconfiguration or create a new buildconfiguration - CMakeOpenProjectWizard(QWidget *parent, Mode mode, const CMakeBuildInfo *info); - - QString buildDirectory() const; - QString sourceDirectory() const; - void setBuildDirectory(const QString &directory); - QString arguments() const; - void setArguments(const QString &args); - Utils::Environment environment() const; - ProjectExplorer::Kit *kit() const; - void setKit(ProjectExplorer::Kit *kit); - bool existsUpToDateXmlFile() const; - bool compatibleKitExist() const; - -private: - bool hasInSourceBuild() const; - QString m_buildDirectory; - QString m_sourceDirectory; - QString m_arguments; - Utils::Environment m_environment; - ProjectExplorer::Kit *m_kit; -}; - -class NoKitPage : public QWizardPage -{ - Q_OBJECT -public: - NoKitPage(CMakeOpenProjectWizard *cmakeWizard); - bool isComplete() const override; - void initializePage() override; - -private: - void kitsChanged(); - void showOptions(); - - QLabel *m_descriptionLabel; - QPushButton *m_optionsButton; - CMakeOpenProjectWizard *m_cmakeWizard; -}; - -class InSourceBuildPage : public QWizardPage -{ - Q_OBJECT -public: - InSourceBuildPage(CMakeOpenProjectWizard *cmakeWizard); - -private: - CMakeOpenProjectWizard *m_cmakeWizard; -}; - -class ShadowBuildPage : public QWizardPage -{ - Q_OBJECT -public: - explicit ShadowBuildPage(CMakeOpenProjectWizard *cmakeWizard, bool change = false); - -private: - void buildDirectoryChanged(); - - CMakeOpenProjectWizard *m_cmakeWizard; - Utils::PathChooser *m_pc; -}; - -class NoCMakePage : public QWizardPage -{ - Q_OBJECT -public: - NoCMakePage(CMakeOpenProjectWizard *cmakeWizard); - bool isComplete() const override; - -private: - void cmakeToolsChanged(); - void showOptions(); - - QLabel *m_descriptionLabel; - QPushButton *m_optionsButton; -}; - -class CMakeRunPage : public QWizardPage -{ - Q_OBJECT -public: - enum Mode { NeedToUpdate, Recreate, ChangeDirectory, WantToUpdate }; - explicit CMakeRunPage(CMakeOpenProjectWizard *cmakeWizard, Mode mode, - const QString &buildDirectory, - const QString &initialArguments, - const QString &kitName, - const QString &buildConfigurationName); - - void initializePage() override; - bool validatePage() override; - void cleanupPage() override; - bool isComplete() const override; - -private: - void runCMake(); - void cmakeFinished(); - void cmakeReadyReadStandardOutput(); - void cmakeReadyReadStandardError(); - - QByteArray cachedGeneratorFromFile(const QString &cache); - - CMakeOpenProjectWizard *m_cmakeWizard; - QLabel *m_descriptionLabel; - Utils::FancyLineEdit *m_argumentsLineEdit; - QComboBox *m_generatorComboBox; - QLabel *m_generatorExtraText; - QPushButton *m_runCMake; - QPlainTextEdit *m_output; - QLabel *m_exitCodeLabel; - QCheckBox *m_continueCheckBox; - Utils::QtcProcess *m_cmakeProcess = 0; - bool m_haveCbpFile = false; - Mode m_mode; - QString m_buildDirectory; - QString m_kitName; - QString m_buildConfigurationName; -}; - -} // namespace Internal -} // namespace CMakeProjectManager - diff --git a/src/plugins/cmakeprojectmanager/cmakepreloadcachekitconfigwidget.cpp b/src/plugins/cmakeprojectmanager/cmakepreloadcachekitconfigwidget.cpp deleted file mode 100644 index e015d0a0def..00000000000 --- a/src/plugins/cmakeprojectmanager/cmakepreloadcachekitconfigwidget.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "cmakepreloadcachekitconfigwidget.h" -#include "cmakepreloadcachekitinformation.h" - -#include - -#include - -namespace CMakeProjectManager { -namespace Internal { - -CMakePreloadCacheKitConfigWidget::CMakePreloadCacheKitConfigWidget(ProjectExplorer::Kit *k, const ProjectExplorer::KitInformation *ki) : - ProjectExplorer::KitConfigWidget(k, ki), - m_lineEdit(new QLineEdit) -{ - refresh(); - m_lineEdit->setToolTip(toolTip()); - connect(m_lineEdit, &QLineEdit::textEdited, - this, &CMakePreloadCacheKitConfigWidget::preloadFileWasChanged); -} - -CMakePreloadCacheKitConfigWidget::~CMakePreloadCacheKitConfigWidget() -{ - delete m_lineEdit; -} - -QWidget *CMakePreloadCacheKitConfigWidget::mainWidget() const -{ - return m_lineEdit; -} - -QString CMakePreloadCacheKitConfigWidget::displayName() const -{ - return tr("CMake preload file:"); -} - -QString CMakePreloadCacheKitConfigWidget::toolTip() const -{ - return tr("The preload cache file to use when running cmake on the project.
" - "This setting is ignored when using other build systems."); -} - -void CMakePreloadCacheKitConfigWidget::makeReadOnly() -{ - m_lineEdit->setEnabled(false); -} - -void CMakePreloadCacheKitConfigWidget::refresh() -{ - if (!m_ignoreChange) - m_lineEdit->setText(CMakePreloadCacheKitInformation::preloadCacheFile(m_kit).toUserOutput()); -} - -void CMakePreloadCacheKitConfigWidget::preloadFileWasChanged(const QString &text) -{ - m_ignoreChange = true; - m_kit->setValue(CMakePreloadCacheKitInformation::id(), text); - m_ignoreChange = false; -} - -} // namespace Internal -} // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/cmakepreloadcachekitconfigwidget.h b/src/plugins/cmakeprojectmanager/cmakepreloadcachekitconfigwidget.h deleted file mode 100644 index ae99615fd67..00000000000 --- a/src/plugins/cmakeprojectmanager/cmakepreloadcachekitconfigwidget.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include - -QT_BEGIN_NAMESPACE -class QLineEdit; -QT_END_NAMESPACE - -namespace CMakeProjectManager { -namespace Internal { - -class CMakePreloadCacheKitConfigWidget : public ProjectExplorer::KitConfigWidget -{ - Q_OBJECT - -public: - CMakePreloadCacheKitConfigWidget(ProjectExplorer::Kit *k, const ProjectExplorer::KitInformation *ki); - ~CMakePreloadCacheKitConfigWidget() override; - - QWidget *mainWidget() const override; - QString displayName() const override; - QString toolTip() const override; - - void makeReadOnly() override; - void refresh() override; - -private: - void preloadFileWasChanged(const QString &text); - - QLineEdit *m_lineEdit = nullptr; - bool m_ignoreChange = false; -}; - -} // namespace Internal -} // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/cmakepreloadcachekitinformation.cpp b/src/plugins/cmakeprojectmanager/cmakepreloadcachekitinformation.cpp deleted file mode 100644 index b459eebfb4d..00000000000 --- a/src/plugins/cmakeprojectmanager/cmakepreloadcachekitinformation.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "cmakepreloadcachekitinformation.h" -#include "cmakepreloadcachekitconfigwidget.h" -#include "cmaketoolmanager.h" -#include "cmaketool.h" - -#include -#include -#include -#include - -#include - -using namespace ProjectExplorer; - -namespace CMakeProjectManager { - -CMakePreloadCacheKitInformation::CMakePreloadCacheKitInformation() -{ - setObjectName(QLatin1String("CMakePreloadCacheKitInformation")); - setId(CMakePreloadCacheKitInformation::id()); - setPriority(18000); -} - -Core::Id CMakePreloadCacheKitInformation::id() -{ - return "CMakeProjectManager.CMakePreloadCacheKitInformation"; -} - -QVariant CMakePreloadCacheKitInformation::defaultValue(const Kit *) const -{ - return QString(); -} - -QList CMakePreloadCacheKitInformation::validate(const Kit *k) const -{ - Q_UNUSED(k); - return QList(); -} - -void CMakePreloadCacheKitInformation::setup(Kit *k) -{ - Q_UNUSED(k); -} - -void CMakePreloadCacheKitInformation::fix(Kit *k) -{ - Q_UNUSED(k); -} - -KitInformation::ItemList CMakePreloadCacheKitInformation::toUserOutput(const Kit *k) const -{ - return ItemList() << qMakePair(tr("CMake Preload"), k->value(id()).toString()); -} - -KitConfigWidget *CMakePreloadCacheKitInformation::createConfigWidget(Kit *k) const -{ - return new Internal::CMakePreloadCacheKitConfigWidget(k, this); -} - -void CMakePreloadCacheKitInformation::setPreloadCacheFile(Kit *k, const Utils::FileName &preload) -{ - if (!k) - return; - k->setValue(CMakePreloadCacheKitInformation::id(), preload.toString()); -} - -Utils::FileName CMakePreloadCacheKitInformation::preloadCacheFile(const Kit *k) -{ - if (!k) - return Utils::FileName(); - return Utils::FileName::fromString(k->value(CMakePreloadCacheKitInformation::id()).toString()); -} - -} // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/cmakepreloadcachekitinformation.h b/src/plugins/cmakeprojectmanager/cmakepreloadcachekitinformation.h deleted file mode 100644 index 58438a14838..00000000000 --- a/src/plugins/cmakeprojectmanager/cmakepreloadcachekitinformation.h +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "cmake_global.h" - -#include - -namespace CMakeProjectManager { - -class CMAKE_EXPORT CMakePreloadCacheKitInformation : public ProjectExplorer::KitInformation -{ - Q_OBJECT -public: - CMakePreloadCacheKitInformation(); - - static Core::Id id(); - - // KitInformation interface - QVariant defaultValue(const ProjectExplorer::Kit *) const override; - QList validate(const ProjectExplorer::Kit *k) const override; - void setup(ProjectExplorer::Kit *k) override; - void fix(ProjectExplorer::Kit *k) override; - ItemList toUserOutput(const ProjectExplorer::Kit *k) const override; - ProjectExplorer::KitConfigWidget *createConfigWidget(ProjectExplorer::Kit *k) const override; - - static void setPreloadCacheFile(ProjectExplorer::Kit *k, const Utils::FileName &preload); - static Utils::FileName preloadCacheFile(const ProjectExplorer::Kit *k); -}; - -} // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index ec8df0716de..d5fa23491ab 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -25,47 +25,45 @@ #include "cmakeproject.h" +#include "builddirmanager.h" #include "cmakebuildconfiguration.h" #include "cmakebuildstep.h" #include "cmakekitinformation.h" #include "cmakeprojectconstants.h" #include "cmakeprojectnodes.h" #include "cmakerunconfiguration.h" -#include "cmakeopenprojectwizard.h" -#include "cmakecbpparser.h" #include "cmakefile.h" #include "cmakeprojectmanager.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include +#include +#include +#include #include #include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include #include -#include -#include -#include -#include #include #include +#include using namespace CMakeProjectManager; using namespace CMakeProjectManager::Internal; @@ -74,7 +72,6 @@ using namespace Utils; // QtCreator CMake Generator wishlist: // Which make targets we need to build to get all executables -// What is the make we need to call // What is the actual compiler executable // DEFINES @@ -84,8 +81,7 @@ using namespace Utils; /*! \class CMakeProject */ -CMakeProject::CMakeProject(CMakeManager *manager, const FileName &fileName) : - m_watcher(new QFileSystemWatcher(this)) +CMakeProject::CMakeProject(CMakeManager *manager, const FileName &fileName) { setId(Constants::CMAKEPROJECT_ID); setProjectManager(manager); @@ -96,56 +92,59 @@ CMakeProject::CMakeProject(CMakeManager *manager, const FileName &fileName) : rootProjectNode()->setDisplayName(fileName.parentDir().fileName()); - connect(this, &CMakeProject::buildTargetsChanged, this, &CMakeProject::updateRunConfigurations); - connect(m_watcher, &QFileSystemWatcher::fileChanged, this, &CMakeProject::fileChanged); + connect(this, &CMakeProject::buildDirectoryDataAvailable, this, &CMakeProject::updateRunConfigurations); + connect(this, &Project::activeTargetChanged, this, &CMakeProject::activeTargetHasChanged); + connect(this, &CMakeProject::environmentChanged, this, [this]() { + BuildConfiguration *bc = nullptr; + if (activeTarget()) + bc = activeTarget()->activeBuildConfiguration(); + changeActiveBuildConfiguration(bc); // Does a clean reset of the builddirmanager + }); + + connect(this, &Project::addedTarget, this, [this](Target *t) { + connect(t, &Target::kitChanged, this, &CMakeProject::handleKitChanges); + }); } CMakeProject::~CMakeProject() { + setRootProjectNode(nullptr); m_codeModelFuture.cancel(); -} - -void CMakeProject::fileChanged(const QString &fileName) -{ - Q_UNUSED(fileName) - - parseCMakeLists(); + delete m_buildDirManager; } void CMakeProject::changeActiveBuildConfiguration(ProjectExplorer::BuildConfiguration *bc) { - if (!bc) - return; + if (m_buildDirManager) { + m_buildDirManager->disconnect(); + m_buildDirManager->deleteLater(); + } + m_buildDirManager = nullptr; - CMakeBuildConfiguration *cmakebc = static_cast(bc); + Kit *k = nullptr; + CMakeConfig config; + Utils::FileName buildDir; - // Pop up a dialog asking the user to rerun cmake - QString cbpFile = CMakeManager::findCbpFile(QDir(bc->buildDirectory().toString())); - QFileInfo cbpFileFi(cbpFile); - CMakeOpenProjectWizard::Mode mode = CMakeOpenProjectWizard::Nothing; - if (!cbpFileFi.exists()) { - mode = CMakeOpenProjectWizard::NeedToCreate; + CMakeBuildConfiguration *cmakebc = qobject_cast(bc); + if (!cmakebc) { + k = KitManager::defaultKit(); + config = CMakeConfigurationKitInformation::configuration(k); } else { - foreach (const FileName &file, m_watchedFiles) { - if (file.toFileInfo().lastModified() > cbpFileFi.lastModified()) { - mode = CMakeOpenProjectWizard::NeedToUpdate; - break; - } - } + k = cmakebc->target()->kit(); + // FIXME: Fill config with data from cmakebc! + buildDir = cmakebc->buildDirectory(); } - - if (mode != CMakeOpenProjectWizard::Nothing) { - CMakeBuildInfo info(cmakebc); - CMakeOpenProjectWizard copw(Core::ICore::mainWindow(), mode, &info); - if (copw.exec() == QDialog::Accepted) - cmakebc->setInitialArguments(QString()); + if (k) { + m_buildDirManager = new Internal::BuildDirManager(projectDirectory(), k, config, + cmakebc->environment(), buildDir); + connect(m_buildDirManager, &BuildDirManager::parsingStarted, + this, &CMakeProject::parsingStarted); + connect(m_buildDirManager, &BuildDirManager::dataAvailable, + this, &CMakeProject::parseCMakeOutput); } - - // reparse - parseCMakeLists(); } -void CMakeProject::activeTargetWasChanged(Target *target) +void CMakeProject::activeTargetHasChanged(Target *target) { if (m_activeTarget) { disconnect(m_activeTarget, &Target::activeBuildConfigurationChanged, @@ -165,7 +164,16 @@ void CMakeProject::activeTargetWasChanged(Target *target) void CMakeProject::changeBuildDirectory(CMakeBuildConfiguration *bc, const QString &newBuildDirectory) { bc->setBuildDirectory(FileName::fromString(newBuildDirectory)); - parseCMakeLists(); + if (activeTarget() && activeTarget()->activeBuildConfiguration() == bc) + changeActiveBuildConfiguration(bc); +} + +void CMakeProject::handleKitChanges() +{ + const Target *t = qobject_cast(sender()); + if (t && t != activeTarget()) + return; + changeActiveBuildConfiguration(t->activeBuildConfiguration()); // force proper refresh } QStringList CMakeProject::getCXXFlagsFor(const CMakeBuildTarget &buildTarget, QByteArray *cachedBuildNinja) @@ -238,88 +246,30 @@ QStringList CMakeProject::getCXXFlagsFor(const CMakeBuildTarget &buildTarget, QB return QStringList(); } -bool CMakeProject::parseCMakeLists() +void CMakeProject::parseCMakeOutput() { - QTC_ASSERT(activeTarget() && activeTarget()->activeBuildConfiguration(), return false); + QTC_ASSERT(m_buildDirManager, return); + QTC_ASSERT(activeTarget() && activeTarget()->activeBuildConfiguration(), return); - CMakeBuildConfiguration *activeBC = static_cast(activeTarget()->activeBuildConfiguration()); foreach (Core::IDocument *document, Core::DocumentModel::openedDocuments()) if (isProjectFile(document->filePath())) document->infoBar()->removeInfo("CMakeEditor.RunCMake"); - // Find cbp file - QString cbpFile = CMakeManager::findCbpFile(activeBC->buildDirectory().toString()); + auto activeBC = static_cast(activeTarget()->activeBuildConfiguration()); - if (cbpFile.isEmpty()) { - emit buildTargetsChanged(); - return false; - } + rootProjectNode()->setDisplayName(m_buildDirManager->projectName()); - Kit *k = activeTarget()->kit(); - - // setFolderName - rootProjectNode()->setDisplayName(QFileInfo(cbpFile).completeBaseName()); - CMakeCbpParser cbpparser; - // Parsing - //qDebug()<<"Parsing file "<files()) - if (file != cbpFile) - m_watcher->removePath(file); - - // how can we ensure that it is completely written? - m_watcher->addPath(cbpFile); - - rootProjectNode()->setDisplayName(cbpparser.projectName()); - - //qDebug()<<"Building Tree"; - QList fileList = cbpparser.fileList(); - QSet projectFiles; - if (cbpparser.hasCMakeFiles()) { - fileList.append(cbpparser.cmakeFileList()); - foreach (const ProjectExplorer::FileNode *node, cbpparser.cmakeFileList()) - projectFiles.insert(node->filePath()); - } else { - // Manually add the CMakeLists.txt file - FileName cmakeListTxt = projectDirectory().appendPath(QLatin1String("CMakeLists.txt")); - bool generated = false; - fileList.append(new ProjectExplorer::FileNode(cmakeListTxt, ProjectExplorer::ProjectFileType, generated)); - projectFiles.insert(cmakeListTxt); - } - - m_watchedFiles = projectFiles; - - m_files.clear(); - foreach (ProjectExplorer::FileNode *fn, fileList) - m_files.append(fn->filePath().toString()); - m_files.sort(); - - buildTree(static_cast(rootProjectNode()), fileList); - - //qDebug()<<"Adding Targets"; - m_buildTargets = cbpparser.buildTargets(); -// qDebug()<<"Printing targets"; -// foreach (CMakeBuildTarget ct, m_buildTargets) { -// qDebug()<(rootProjectNode()), m_buildDirManager->files()); updateApplicationAndDeploymentTargets(); createUiCodeModelSupport(); - ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(k); + ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(m_buildDirManager->kit()); if (!tc) { - emit buildTargetsChanged(); + emit buildDirectoryDataAvailable(activeBC); emit fileListChanged(); - return true; + return; } CppTools::CppModelManager *modelmanager = CppTools::CppModelManager::instance(); @@ -327,7 +277,7 @@ bool CMakeProject::parseCMakeLists() CppTools::ProjectPartBuilder ppBuilder(pinfo); CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt; - if (QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k)) { + if (QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(m_buildDirManager->kit())) { if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0)) activeQtVersion = CppTools::ProjectPart::Qt4; else @@ -337,7 +287,7 @@ bool CMakeProject::parseCMakeLists() ppBuilder.setQtVersion(activeQtVersion); QByteArray cachedBuildNinja; - foreach (const CMakeBuildTarget &cbt, m_buildTargets) { + foreach (const CMakeBuildTarget &cbt, buildTargets()) { // This explicitly adds -I. to the include paths QStringList includePaths = cbt.includeFiles; includePaths += projectDirectory().toString(); @@ -358,12 +308,10 @@ bool CMakeProject::parseCMakeLists() m_codeModelFuture = modelmanager->updateProjectInfo(pinfo); emit displayNameChanged(); - emit buildTargetsChanged(); + emit buildDirectoryDataAvailable(activeBC); emit fileListChanged(); emit activeBC->emitBuildTypeChanged(); - - return true; } bool CMakeProject::needsConfiguration() const @@ -386,30 +334,45 @@ bool CMakeProject::supportsKit(Kit *k, QString *errorMessage) const return true; } +void CMakeProject::runCMake() +{ + if (m_buildDirManager && !m_buildDirManager->isBusy()) + m_buildDirManager->forceReparse(); +} + +bool CMakeProject::isParsing() const +{ + return m_buildDirManager && m_buildDirManager->isBusy(); +} + bool CMakeProject::isProjectFile(const FileName &fileName) { - return m_watchedFiles.contains(fileName); + if (!m_buildDirManager) + return false; + return m_buildDirManager->isProjectFile(fileName); } QList CMakeProject::buildTargets() const { - return m_buildTargets; + if (!m_buildDirManager) + return QList(); + return m_buildDirManager->buildTargets(); } QStringList CMakeProject::buildTargetTitles(bool runnable) const { const QList targets - = runnable ? Utils::filtered(m_buildTargets, + = runnable ? Utils::filtered(buildTargets(), [](const CMakeBuildTarget &ct) { return !ct.executable.isEmpty() && ct.targetType == ExecutableType; }) - : m_buildTargets; + : buildTargets(); return Utils::transform(targets, [](const CMakeBuildTarget &ct) { return ct.title; }); } bool CMakeProject::hasBuildTarget(const QString &title) const { - return Utils::anyOf(m_buildTargets, [title](const CMakeBuildTarget &ct) { return ct.title == title; }); + return Utils::anyOf(buildTargets(), [title](const CMakeBuildTarget &ct) { return ct.title == title; }); } void CMakeProject::gatherFileNodes(ProjectExplorer::FolderNode *parent, QList &list) @@ -442,7 +405,6 @@ void CMakeProject::buildTree(CMakeProjectNode *rootNode, QListpath(); // Get relative path to rootNode QString parentDir = fn->filePath().toFileInfo().absolutePath(); ProjectExplorer::FolderNode *folder = findOrCreateFolder(rootNode, parentDir); @@ -452,7 +414,6 @@ void CMakeProject::buildTree(CMakeProjectNode *rootNode, QListparentFolderNode(); -// qDebug()<<"removed"<path(); parent->removeFileNodes(QList() << fn); // Check for empty parent while (parent->subFolderNodes().isEmpty() && parent->fileNodes().isEmpty()) { @@ -514,44 +475,13 @@ Project::RestoreResult CMakeProject::fromMap(const QVariantMap &map, QString *er if (result != RestoreResult::Ok) return result; - bool hasUserFile = activeTarget(); - if (!hasUserFile) { - // Nothing to do, the target setup page will show up - } else { - // We have a user file, but we could still be missing the cbp file - // or simply run createXml with the saved settings - CMakeBuildConfiguration *activeBC = qobject_cast(activeTarget()->activeBuildConfiguration()); - if (!activeBC) { - *errorMessage = tr("Internal Error: No build configuration found in settings file."); - return RestoreResult::Error; - } - QString cbpFile = CMakeManager::findCbpFile(QDir(activeBC->buildDirectory().toString())); - QFileInfo cbpFileFi(cbpFile); - - CMakeOpenProjectWizard::Mode mode = CMakeOpenProjectWizard::Nothing; - if (!cbpFileFi.exists()) - mode = CMakeOpenProjectWizard::NeedToCreate; - else if (cbpFileFi.lastModified() < projectFilePath().toFileInfo().lastModified()) - mode = CMakeOpenProjectWizard::NeedToUpdate; - - if (mode != CMakeOpenProjectWizard::Nothing) { - CMakeBuildInfo info(activeBC); - CMakeOpenProjectWizard copw(Core::ICore::mainWindow(), mode, &info); - if (copw.exec() != QDialog::Accepted) - return RestoreResult::UserAbort; - else - activeBC->setInitialArguments(QString()); - } - } - - parseCMakeLists(); - m_activeTarget = activeTarget(); - if (m_activeTarget) + if (m_activeTarget) { connect(m_activeTarget, &Target::activeBuildConfigurationChanged, this, &CMakeProject::changeActiveBuildConfiguration); - connect(this, &Project::activeTargetChanged, - this, &CMakeProject::activeTargetWasChanged); + if (BuildConfiguration *bc = m_activeTarget->activeBuildConfiguration()) + changeActiveBuildConfiguration(bc); + } return RestoreResult::Ok; } @@ -568,7 +498,7 @@ bool CMakeProject::setupTarget(Target *t) CMakeBuildTarget CMakeProject::buildTargetForTitle(const QString &title) { - foreach (const CMakeBuildTarget &ct, m_buildTargets) + foreach (const CMakeBuildTarget &ct, buildTargets()) if (ct.title == title) return ct; return CMakeBuildTarget(); @@ -672,7 +602,7 @@ void CMakeProject::updateApplicationAndDeploymentTargets() BuildTargetInfoList appTargetList; DeploymentData deploymentData; - foreach (const CMakeBuildTarget &ct, m_buildTargets) { + foreach (const CMakeBuildTarget &ct, buildTargets()) { if (ct.executable.isEmpty()) continue; diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h index 5fc7f6f0111..24c75319e69 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.h +++ b/src/plugins/cmakeprojectmanager/cmakeproject.h @@ -49,12 +49,13 @@ QT_END_NAMESPACE namespace CMakeProjectManager { namespace Internal { +class BuildDirManager; class CMakeFile; class CMakeBuildSettingsWidget; class CMakeBuildConfiguration; class CMakeProjectNode; class CMakeManager; -} +} // namespace Internal enum TargetType { ExecutableType = 0, @@ -103,17 +104,19 @@ public: bool isProjectFile(const Utils::FileName &fileName); - bool parseCMakeLists(); - bool needsConfiguration() const override; - bool requiresTargetPanel() const override; bool supportsKit(ProjectExplorer::Kit *k, QString *errorMessage = 0) const override; + void runCMake(); + bool isParsing() const; + signals: + /// emitted when parsing starts: + void parsingStarted(); /// emitted after parsing - void buildTargetsChanged(); + void buildDirectoryDataAvailable(ProjectExplorer::BuildConfiguration *bc); protected: RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override; @@ -123,8 +126,10 @@ protected: void changeBuildDirectory(Internal::CMakeBuildConfiguration *bc, const QString &newBuildDirectory); private: - void fileChanged(const QString &fileName); - void activeTargetWasChanged(ProjectExplorer::Target *target); + void handleKitChanges(); + void parseCMakeOutput(); + + void activeTargetHasChanged(ProjectExplorer::Target *target); void changeActiveBuildConfiguration(ProjectExplorer::BuildConfiguration*); void updateRunConfigurations(); @@ -139,12 +144,11 @@ private: QStringList getCXXFlagsFor(const CMakeBuildTarget &buildTarget, QByteArray *cachedBuildNinja); ProjectExplorer::Target *m_activeTarget = 0; + Internal::BuildDirManager *m_buildDirManager = 0; // TODO probably need a CMake specific node structure QStringList m_files; QList m_buildTargets; - QFileSystemWatcher *m_watcher; - QSet m_watchedFiles; QFuture m_codeModelFuture; }; diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp index 231912b7829..98893345e55 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp @@ -24,7 +24,6 @@ ****************************************************************************/ #include "cmakeprojectmanager.h" -#include "cmakeopenprojectwizard.h" #include "cmakeprojectconstants.h" #include "cmakeproject.h" #include "cmakesettingspage.h" @@ -39,11 +38,14 @@ #include #include #include +#include +#include #include #include #include +#include using namespace ProjectExplorer; using namespace CMakeProjectManager::Internal; @@ -103,14 +105,7 @@ void CMakeManager::runCMake(Project *project) if (!ProjectExplorerPlugin::saveModifiedFiles()) return; - CMakeBuildConfiguration *bc - = static_cast(cmakeProject->activeTarget()->activeBuildConfiguration()); - - CMakeBuildInfo info(bc); - - CMakeOpenProjectWizard copw(Core::ICore::mainWindow(), CMakeOpenProjectWizard::WantToUpdate, &info); - if (copw.exec() == QDialog::Accepted) - cmakeProject->parseCMakeLists(); + cmakeProject->runCMake(); } Project *CMakeManager::openProject(const QString &fileName, QString *errorString) diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h index f8d7c983695..eccf1dd90bb 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h @@ -36,7 +36,7 @@ namespace ProjectExplorer { class Node; } namespace Utils { class Environment; class QtcProcess; -} +} // namespace Utils namespace CMakeProjectManager { namespace Internal { diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro index d777ca2870e..577fb88e15b 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro @@ -1,7 +1,8 @@ DEFINES += CMAKEPROJECTMANAGER_LIBRARY include(../../qtcreatorplugin.pri) -HEADERS = cmakebuildinfo.h \ +HEADERS = builddirmanager.h \ + cmakebuildinfo.h \ cmakebuildstep.h \ cmakeconfigitem.h \ cmakeproject.h \ @@ -10,14 +11,12 @@ HEADERS = cmakebuildinfo.h \ cmakeprojectconstants.h \ cmakeprojectnodes.h \ cmakerunconfiguration.h \ - cmakeopenprojectwizard.h \ cmakebuildconfiguration.h \ cmakeeditor.h \ cmakelocatorfilter.h \ cmakefilecompletionassist.h \ cmaketool.h \ cmakeparser.h \ - generatorinfo.h \ cmakesettingspage.h \ cmaketoolmanager.h \ cmake_global.h \ @@ -27,25 +26,22 @@ HEADERS = cmakebuildinfo.h \ cmakefile.h \ cmakebuildsettingswidget.h \ cmakeindenter.h \ - cmakeautocompleter.h \ - cmakepreloadcachekitinformation.h \ - cmakepreloadcachekitconfigwidget.h + cmakeautocompleter.h -SOURCES = cmakebuildstep.cpp \ +SOURCES = builddirmanager.cpp \ + cmakebuildstep.cpp \ cmakeconfigitem.cpp \ cmakeproject.cpp \ cmakeprojectplugin.cpp \ cmakeprojectmanager.cpp \ cmakeprojectnodes.cpp \ cmakerunconfiguration.cpp \ - cmakeopenprojectwizard.cpp \ cmakebuildconfiguration.cpp \ cmakeeditor.cpp \ cmakelocatorfilter.cpp \ cmakefilecompletionassist.cpp \ cmaketool.cpp \ cmakeparser.cpp \ - generatorinfo.cpp \ cmakesettingspage.cpp \ cmaketoolmanager.cpp \ cmakekitinformation.cpp \ @@ -54,8 +50,6 @@ SOURCES = cmakebuildstep.cpp \ cmakefile.cpp \ cmakebuildsettingswidget.cpp \ cmakeindenter.cpp \ - cmakeautocompleter.cpp \ - cmakepreloadcachekitinformation.cpp \ - cmakepreloadcachekitconfigwidget.cpp + cmakeautocompleter.cpp RESOURCES += cmakeproject.qrc diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs index 92d739ae9a2..3dabc68db52 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs @@ -17,6 +17,8 @@ QtcPlugin { ] files: [ + "builddirmanager.cpp", + "builddirmanager.h", "cmake_global.h", "cmakebuildconfiguration.cpp", "cmakebuildconfiguration.h", @@ -41,14 +43,8 @@ QtcPlugin { "cmakekitinformation.cpp", "cmakelocatorfilter.cpp", "cmakelocatorfilter.h", - "cmakeopenprojectwizard.cpp", - "cmakeopenprojectwizard.h", "cmakeparser.cpp", "cmakeparser.h", - "cmakepreloadcachekitconfigwidget.cpp", - "cmakepreloadcachekitconfigwidget.h", - "cmakepreloadcachekitinformation.cpp", - "cmakepreloadcachekitinformation.h", "cmakeproject.cpp", "cmakeproject.h", "cmakeproject.qrc", @@ -67,8 +63,6 @@ QtcPlugin { "cmaketoolmanager.h", "cmakesettingspage.h", "cmakesettingspage.cpp", - "generatorinfo.h", - "generatorinfo.cpp", "cmakeindenter.h", "cmakeindenter.cpp", "cmakeautocompleter.h", diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp index fd529b53742..1da3cce40de 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp @@ -35,7 +35,6 @@ #include "cmakesettingspage.h" #include "cmaketoolmanager.h" #include "cmakekitinformation.h" -#include "cmakepreloadcachekitinformation.h" #include #include @@ -59,7 +58,6 @@ bool CMakeProjectPlugin::initialize(const QStringList & /*arguments*/, QString * ProjectExplorer::KitManager::registerKitInformation(new CMakeKitInformation); ProjectExplorer::KitManager::registerKitInformation(new CMakeGeneratorKitInformation); - ProjectExplorer::KitManager::registerKitInformation(new CMakePreloadCacheKitInformation); ProjectExplorer::KitManager::registerKitInformation(new CMakeConfigurationKitInformation); return true; diff --git a/src/plugins/cmakeprojectmanager/generatorinfo.cpp b/src/plugins/cmakeprojectmanager/generatorinfo.cpp deleted file mode 100644 index 3bb85152b89..00000000000 --- a/src/plugins/cmakeprojectmanager/generatorinfo.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "generatorinfo.h" - -#include -#include -#include -#include - -#include -#include -#include -#include "cmakepreloadcachekitinformation.h" - -namespace CMakeProjectManager { -namespace Internal { - -static bool isMsvcFlavor(const ProjectExplorer::Abi &abi) { - switch (abi.osFlavor()) { - case ProjectExplorer::Abi::WindowsMsvc2005Flavor: - case ProjectExplorer::Abi::WindowsMsvc2008Flavor: - case ProjectExplorer::Abi::WindowsMsvc2010Flavor: - case ProjectExplorer::Abi::WindowsMsvc2012Flavor: - case ProjectExplorer::Abi::WindowsMsvc2013Flavor: - case ProjectExplorer::Abi::WindowsMsvc2015Flavor: - return true; - default: - return false; - } -} - -GeneratorInfo::GeneratorInfo(ProjectExplorer::Kit *kit, bool ninja) : m_kit(kit), m_isNinja(ninja) -{ } - -ProjectExplorer::Kit *GeneratorInfo::kit() const -{ - return m_kit; -} - -QByteArray GeneratorInfo::generator() const -{ - if (!m_kit) - return QByteArray(); - ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(m_kit); - ProjectExplorer::Abi targetAbi = tc->targetAbi(); - if (m_isNinja) { - return "Ninja"; - } else if (targetAbi.os() == ProjectExplorer::Abi::WindowsOS) { - if (isMsvcFlavor(targetAbi)) { - return "NMake Makefiles"; - } else if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) { - if (Utils::HostOsInfo::isWindowsHost()) - return "MinGW Makefiles"; - else - return "Unix Makefiles"; - } - } - return "Unix Makefiles"; -} - -QByteArray GeneratorInfo::generatorArgument() const -{ - QByteArray tmp = generator(); - if (tmp.isEmpty()) - return tmp; - return QByteArray("-GCodeBlocks - ") + tmp; -} - -QString GeneratorInfo::preLoadCacheFileArgument() const -{ - const QString tmp = CMakePreloadCacheKitInformation::preloadCacheFile(m_kit).toUserOutput(); - return tmp.isEmpty() ? QString() : QString::fromLatin1("-C") + tmp; -} - -QString GeneratorInfo::displayName() const -{ - if (!m_kit) - return QString(); - if (m_isNinja) - return tr("Ninja (%1)").arg(m_kit->displayName()); - ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(m_kit); - ProjectExplorer::Abi targetAbi = tc->targetAbi(); - if (targetAbi.os() == ProjectExplorer::Abi::WindowsOS) { - if (isMsvcFlavor(targetAbi)) { - return tr("NMake Generator (%1)").arg(m_kit->displayName()); - } else if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) { - if (Utils::HostOsInfo::isWindowsHost()) - return tr("MinGW Generator (%1)").arg(m_kit->displayName()); - else - return tr("Unix Generator (%1)").arg(m_kit->displayName()); - } - } else { - // Non windows - return tr("Unix Generator (%1)").arg(m_kit->displayName()); - } - return QString(); -} - -QList GeneratorInfo::generatorInfosFor(ProjectExplorer::Kit *k, bool hasNinja, - bool preferNinja, bool hasCodeBlocks) -{ - QList results; - ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(k); - if (!tc) - return results; - Core::Id deviceType = ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(k); - if (deviceType != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE - && deviceType != BareMetal::Constants::BareMetalOsType - && deviceType != RemoteLinux::Constants::GenericLinuxOsType - && deviceType != Qnx::Constants::QNX_QNX_OS_TYPE) - return results; - ProjectExplorer::Abi targetAbi = tc->targetAbi(); - if (targetAbi.os() == ProjectExplorer::Abi::WindowsOS) { - if (isMsvcFlavor(targetAbi)) { - if (hasCodeBlocks) - results << GeneratorInfo(k); - } else if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) { - results << GeneratorInfo(k); - } - } else { - // Non windows - results << GeneratorInfo(k); - } - - if (hasNinja) { - if (preferNinja) - results.prepend(GeneratorInfo(k, true)); - else - results.append(GeneratorInfo(k, true)); - } - - return results; -} - -} // namespace Internal -} // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/generatorinfo.h b/src/plugins/cmakeprojectmanager/generatorinfo.h deleted file mode 100644 index 2f87ef02d5d..00000000000 --- a/src/plugins/cmakeprojectmanager/generatorinfo.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "cmakeprojectmanager.h" - -#include - -#include -#include - -namespace CMakeProjectManager { -namespace Internal { - -class GeneratorInfo -{ - Q_DECLARE_TR_FUNCTIONS(CMakeProjectManager::Internal::GeneratorInfo) -public: - static QList generatorInfosFor(ProjectExplorer::Kit *k, bool hasNinja, - bool preferNinja, bool hasCodeBlocks); - GeneratorInfo() = default; - - ProjectExplorer::Kit *kit() const; - bool isNinja() const; - QString displayName() const; - QByteArray generatorArgument() const; - QByteArray generator() const; - QString preLoadCacheFileArgument() const; - -private: - explicit GeneratorInfo(ProjectExplorer::Kit *kit, bool ninja = false); - - ProjectExplorer::Kit *m_kit = 0; - bool m_isNinja = false; -}; - -} // namespace Internal -} // namespace CMakeProjectManager - -Q_DECLARE_METATYPE(CMakeProjectManager::Internal::GeneratorInfo) -