Commit 859bf2c5 authored by Tobias Hunger's avatar Tobias Hunger

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: default avatarTim Jenssen <tim.jenssen@theqtcompany.com>
parent d7caae5f
This diff is collapsed.
......@@ -23,38 +23,94 @@
**
****************************************************************************/
#pragma once
#ifndef CMAKE_BUILDDIRMANAGER_H
#define CMAKE_BUILDDIRMANAGER_H
#include <projectexplorer/kitconfigwidget.h>
#include "cmakecbpparser.h"
#include "cmakeconfigitem.h"
QT_BEGIN_NAMESPACE
class QLineEdit;
QT_END_NAMESPACE
#include <projectexplorer/task.h>
#include <utils/environment.h>
#include <utils/qtcprocess.h>
#include <utils/fileutils.h>
#include <QByteArray>
#include <QObject>
#include <QSet>
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 CMakePreloadCacheKitConfigWidget : public ProjectExplorer::KitConfigWidget
class BuildDirManager : public QObject
{
Q_OBJECT
public:
CMakePreloadCacheKitConfigWidget(ProjectExplorer::Kit *k, const ProjectExplorer::KitInformation *ki);
~CMakePreloadCacheKitConfigWidget() override;
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();
QWidget *mainWidget() const override;
QString displayName() const override;
QString toolTip() const override;
bool isProjectFile(const Utils::FileName &fileName) const;
QString projectName() const;
QList<CMakeBuildTarget> buildTargets() const;
QList<ProjectExplorer::FileNode *> files() const;
void makeReadOnly() override;
void refresh() override;
signals:
void parsingStarted() const;
void dataAvailable() const;
void errorOccured(const QString &err) const;
private:
void preloadFileWasChanged(const QString &text);
void extractData();
QLineEdit *m_lineEdit = nullptr;
bool m_ignoreChange = false;
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<Utils::FileName> m_watchedFiles;
QString m_projectName;
QList<CMakeBuildTarget> m_buildTargets;
QFileSystemWatcher *m_watcher;
QList<ProjectExplorer::FileNode *> m_files;
// For error reporting:
ProjectExplorer::Task m_toReport;
};
} // namespace Internal
} // namespace CMakeProjectManager
#endif // CMAKE_BUILDDIRMANAGER_H
......@@ -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<CMakeBuildConfiguration *>(source);
auto old = static_cast<CMakeBuildConfiguration *>(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);
......
......@@ -26,15 +26,13 @@
#include "cmakebuildsettingswidget.h"
#include "cmakeproject.h"
#include "cmakebuildconfiguration.h"
#include "cmakebuildinfo.h"
#include "cmakeopenprojectwizard.h"
#include "cmakeprojectmanager.h"
#include <coreplugin/icore.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/target.h>
#include <utils/detailswidget.h>
#include <utils/pathchooser.h>
#include <QFormLayout>
......@@ -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<CMakeProject *>(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<CMakeProject *>(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<CMakeProject *>(m_buildConfiguration->target()->project());
project->parseCMakeLists();
}
}
} // namespace Internal
} // namespace CMakeProjectManager
......@@ -27,9 +27,6 @@
#include <projectexplorer/namedwidget.h>
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;
};
......
......@@ -98,7 +98,7 @@ void CMakeBuildStep::ctor()
setDefaultDisplayName(tr("Make"));
connect(target(), &Target::kitChanged, this, &CMakeBuildStep::cmakeCommandChanged);
connect(static_cast<CMakeProject *>(project()), &CMakeProject::buildTargetsChanged,
connect(static_cast<CMakeProject *>(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);
}
......
......@@ -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]() {
......
/****************************************************************************
**
** 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 <utils/environment.h>
#include <utils/wizard.h>
#include <utils/qtcprocess.h>
#include <projectexplorer/target.h>
#include <projectexplorer/project.h>
#include <QPushButton>
#include <QComboBox>
#include <QLineEdit>
#include <QLabel>
#include <QPlainTextEdit>
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
/****************************************************************************
**
** 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 <projectexplorer/kit.h>
#include <QLineEdit>
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.<br>"
"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
/****************************************************************************
**
** 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 <utils/qtcassert.h>
#include <projectexplorer/task.h>
#include <projectexplorer/kit.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <QDebug>
using namespace ProjectExplorer;
namespace CMakeProjectManager {
CMakePreloadCacheKitInformation::CMakePreloadCacheKitInformation()
{
setObjectName(QLatin1String("CMakePreloadCacheKitInformation"));
setId(CMakePreloadCacheKitInformation::id());
setPriority(18000);
}