Commit 8fb3105e authored by Tobias Hunger's avatar Tobias Hunger

CMake: Add option to auto-create build directories

Add an option to CMakeTools to force auto-creation of build directories.
This does lead to cmake cluttering up the file system with directories, but
does not force users to go through the oftentimes long configuration process
twice (once in a temporary directory and once in the real location).

Task-number: QTCREATORBUG-16794
Change-Id: I68d92fc58638ad0a0a7622b7ef1621e055c9f2a7
Reviewed-by: Riitta-Leena Miettinen's avatarLeena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Tim Jenssen's avatarTim Jenssen <tim.jenssen@qt.io>
parent ab1d1dae
......@@ -44,6 +44,7 @@
#include <utils/fileutils.h>
#include <utils/qtcassert.h>
#include <QDir>
#include <QMessageBox>
#include <QPushButton>
#include <QSet>
......@@ -72,12 +73,22 @@ BuildDirManager::~BuildDirManager() = default;
const Utils::FileName BuildDirManager::workDirectory() const
{
const Utils::FileName bdir = m_buildConfiguration->buildDirectory();
if (bdir.exists())
const CMakeTool *cmake = CMakeKitInformation::cmakeTool(m_buildConfiguration->target()->kit());
if (bdir.exists()) {
return bdir;
} else {
if (cmake && cmake->autoCreateBuildDirectory()) {
if (!QDir().mkpath(bdir.toString()))
emitErrorOccured(tr("Failed to create build directory \"%1\".").arg(bdir.toUserOutput()));
return bdir;
}
}
if (!m_tempDir) {
m_tempDir.reset(new Utils::TemporaryDirectory("qtc-cmake-XXXXXXXX"));
if (!m_tempDir->isValid())
emitErrorOccured(tr("Failed to create temporary directory \"%1\".").arg(m_tempDir->path()));
if (!m_tempDir->isValid()) {
emitErrorOccured(tr("Failed to create temporary directory \"%1\".")
.arg(QDir::toNativeSeparators(m_tempDir->path())));
}
}
return Utils::FileName::fromString(m_tempDir->path());
}
......
......@@ -66,13 +66,13 @@ public:
CMakeToolTreeItem *cmakeToolItem(const Core::Id &id) const;
CMakeToolTreeItem *cmakeToolItem(const QModelIndex &index) const;
QModelIndex addCMakeTool(const QString &name, const FileName &executable, const bool autoRun, const bool isAutoDetected);
QModelIndex addCMakeTool(const QString &name, const FileName &executable, const bool autoRun, const bool autoCreate, const bool isAutoDetected);
void addCMakeTool(const CMakeTool *item, bool changed);
TreeItem *autoGroupItem() const;
TreeItem *manualGroupItem() const;
void reevaluateChangedFlag(CMakeToolTreeItem *item) const;
void updateCMakeTool(const Core::Id &id, const QString &displayName, const FileName &executable,
bool autoRun);
bool autoRun, bool autoCreate);
void removeCMakeTool(const Core::Id &id);
void apply();
......@@ -95,16 +95,18 @@ public:
m_name(item->displayName()),
m_executable(item->cmakeExecutable()),
m_isAutoRun(item->isAutoRun()),
m_autoCreateBuildDirectory(item->autoCreateBuildDirectory()),
m_autodetected(item->isAutoDetected()),
m_changed(changed)
{}
CMakeToolTreeItem(const QString &name, const Utils::FileName &executable,
bool autoRun, bool autodetected) :
bool autoRun, bool autoCreate, bool autodetected) :
m_id(Core::Id::fromString(QUuid::createUuid().toString())),
m_name(name),
m_executable(executable),
m_isAutoRun(autoRun),
m_autoCreateBuildDirectory(autoCreate),
m_autodetected(autodetected),
m_changed(true)
{}
......@@ -143,6 +145,7 @@ public:
QString m_name;
FileName m_executable;
bool m_isAutoRun = true;
bool m_autoCreateBuildDirectory = false;
bool m_autodetected = false;
bool m_changed = true;
};
......@@ -166,9 +169,10 @@ CMakeToolItemModel::CMakeToolItemModel()
}
QModelIndex CMakeToolItemModel::addCMakeTool(const QString &name, const FileName &executable,
const bool autoRun, const bool isAutoDetected)
const bool autoRun, const bool autoCreate,
const bool isAutoDetected)
{
CMakeToolTreeItem *item = new CMakeToolTreeItem(name, executable, autoRun, isAutoDetected);
CMakeToolTreeItem *item = new CMakeToolTreeItem(name, executable, autoRun, autoCreate, isAutoDetected);
if (isAutoDetected)
autoGroupItem()->appendChild(item);
else
......@@ -219,7 +223,8 @@ void CMakeToolItemModel::reevaluateChangedFlag(CMakeToolTreeItem *item) const
}
void CMakeToolItemModel::updateCMakeTool(const Core::Id &id, const QString &displayName,
const FileName &executable, bool autoRun)
const FileName &executable, bool autoRun,
bool autoCreate)
{
CMakeToolTreeItem *treeItem = cmakeToolItem(id);
QTC_ASSERT(treeItem, return);
......@@ -227,6 +232,7 @@ void CMakeToolItemModel::updateCMakeTool(const Core::Id &id, const QString &disp
treeItem->m_name = displayName;
treeItem->m_executable = executable;
treeItem->m_isAutoRun = autoRun;
treeItem->m_autoCreateBuildDirectory = autoCreate;
reevaluateChangedFlag(treeItem);
}
......@@ -262,6 +268,7 @@ void CMakeToolItemModel::apply()
cmake->setDisplayName(item->m_name);
cmake->setCMakeExecutable(item->m_executable);
cmake->setAutorun(item->m_isAutoRun);
cmake->setAutoCreateBuildDirectory(item->m_autoCreateBuildDirectory);
} else {
toRegister.append(item);
}
......@@ -329,6 +336,7 @@ private:
CMakeToolItemModel *m_model;
QLineEdit *m_displayNameLineEdit;
QCheckBox *m_autoRunCheckBox;
QCheckBox *m_autoCreateBuildDirectoryCheckBox;
PathChooser *m_binaryChooser;
Core::Id m_id;
bool m_loadingItem;
......@@ -349,11 +357,16 @@ CMakeToolItemConfigWidget::CMakeToolItemConfigWidget(CMakeToolItemModel *model)
m_autoRunCheckBox->setText(tr("Autorun CMake"));
m_autoRunCheckBox->setToolTip(tr("Automatically run CMake after changes to CMake project files."));
m_autoCreateBuildDirectoryCheckBox = new QCheckBox;
m_autoCreateBuildDirectoryCheckBox->setText(tr("Auto-create build directories"));
m_autoCreateBuildDirectoryCheckBox->setToolTip(tr("Automatically create build directories for CMake projects."));
QFormLayout *formLayout = new QFormLayout(this);
formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
formLayout->addRow(new QLabel(tr("Name:")), m_displayNameLineEdit);
formLayout->addRow(new QLabel(tr("Path:")), m_binaryChooser);
formLayout->addRow(m_autoRunCheckBox);
formLayout->addRow(m_autoCreateBuildDirectoryCheckBox);
connect(m_binaryChooser, &PathChooser::rawPathChanged,
this, &CMakeToolItemConfigWidget::store);
......@@ -361,13 +374,16 @@ CMakeToolItemConfigWidget::CMakeToolItemConfigWidget(CMakeToolItemModel *model)
this, &CMakeToolItemConfigWidget::store);
connect(m_autoRunCheckBox, &QCheckBox::toggled,
this, &CMakeToolItemConfigWidget::store);
connect(m_autoCreateBuildDirectoryCheckBox, &QCheckBox::toggled,
this, &CMakeToolItemConfigWidget::store);
}
void CMakeToolItemConfigWidget::store() const
{
if (!m_loadingItem && m_id.isValid())
m_model->updateCMakeTool(m_id, m_displayNameLineEdit->text(), m_binaryChooser->fileName(),
m_autoRunCheckBox->checkState() == Qt::Checked);
m_autoRunCheckBox->checkState() == Qt::Checked,
m_autoCreateBuildDirectoryCheckBox->checkState() == Qt::Checked);
}
void CMakeToolItemConfigWidget::load(const CMakeToolTreeItem *item)
......@@ -387,6 +403,7 @@ void CMakeToolItemConfigWidget::load(const CMakeToolTreeItem *item)
m_binaryChooser->setFileName(item->m_executable);
m_autoRunCheckBox->setChecked(item->m_isAutoRun);
m_autoCreateBuildDirectoryCheckBox->setChecked(item->m_autoCreateBuildDirectory);
m_id = item->m_id;
m_loadingItem = false;
......@@ -492,7 +509,8 @@ void CMakeToolConfigWidget::cloneCMakeTool()
QModelIndex newItem = m_model.addCMakeTool(tr("Clone of %1").arg(m_currentItem->m_name),
m_currentItem->m_executable,
m_currentItem->m_isAutoRun, false);
m_currentItem->m_isAutoRun,
m_currentItem->m_autoCreateBuildDirectory, false);
m_cmakeToolsView->setCurrentIndex(newItem);
}
......@@ -500,7 +518,7 @@ void CMakeToolConfigWidget::cloneCMakeTool()
void CMakeToolConfigWidget::addCMakeTool()
{
QModelIndex newItem = m_model.addCMakeTool(m_model.uniqueDisplayName(tr("New CMake")),
FileName(), true, false);
FileName(), true, false, false);
m_cmakeToolsView->setCurrentIndex(newItem);
}
......
......@@ -46,6 +46,7 @@ const char CMAKE_INFORMATION_ID[] = "Id";
const char CMAKE_INFORMATION_COMMAND[] = "Binary";
const char CMAKE_INFORMATION_DISPLAYNAME[] = "DisplayName";
const char CMAKE_INFORMATION_AUTORUN[] = "AutoRun";
const char CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY[] = "AutoCreateBuildDirectory";
const char CMAKE_INFORMATION_AUTODETECTED[] = "AutoDetected";
......@@ -68,6 +69,7 @@ CMakeTool::CMakeTool(const QVariantMap &map, bool fromSdk) : m_isAutoDetected(fr
m_id = Core::Id::fromSetting(map.value(CMAKE_INFORMATION_ID));
m_displayName = map.value(CMAKE_INFORMATION_DISPLAYNAME).toString();
m_isAutoRun = map.value(CMAKE_INFORMATION_AUTORUN, true).toBool();
m_autoCreateBuildDirectory = map.value(CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY, false).toBool();
//loading a CMakeTool from SDK is always autodetection
if (!fromSdk)
......@@ -102,6 +104,15 @@ void CMakeTool::setAutorun(bool autoRun)
CMakeToolManager::notifyAboutUpdate(this);
}
void CMakeTool::setAutoCreateBuildDirectory(bool autoBuildDir)
{
if (m_autoCreateBuildDirectory == autoBuildDir)
return;
m_autoCreateBuildDirectory = autoBuildDir;
CMakeToolManager::notifyAboutUpdate(this);
}
bool CMakeTool::isValid() const
{
if (!m_id.isValid())
......@@ -142,6 +153,7 @@ QVariantMap CMakeTool::toMap() const
data.insert(CMAKE_INFORMATION_ID, m_id.toSetting());
data.insert(CMAKE_INFORMATION_COMMAND, m_executable.toString());
data.insert(CMAKE_INFORMATION_AUTORUN, m_isAutoRun);
data.insert(CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY, m_autoCreateBuildDirectory);
data.insert(CMAKE_INFORMATION_AUTODETECTED, m_isAutoDetected);
return data;
}
......@@ -162,6 +174,11 @@ bool CMakeTool::isAutoRun() const
return m_isAutoRun;
}
bool CMakeTool::autoCreateBuildDirectory() const
{
return m_autoCreateBuildDirectory;
}
QList<CMakeTool::Generator> CMakeTool::supportedGenerators() const
{
readInformation(QueryType::GENERATORS);
......
......@@ -90,9 +90,11 @@ public:
void setCMakeExecutable(const Utils::FileName &executable);
void setAutorun(bool autoRun);
void setAutoCreateBuildDirectory(bool autoBuildDir);
Utils::FileName cmakeExecutable() const;
bool isAutoRun() const;
bool autoCreateBuildDirectory() const;
QList<Generator> supportedGenerators() const;
TextEditor::Keywords keywords();
bool hasServerMode() const;
......@@ -127,6 +129,7 @@ private:
bool m_isAutoRun = true;
bool m_isAutoDetected = false;
bool m_autoCreateBuildDirectory = false;
mutable bool m_didAttemptToRun = false;
mutable bool m_didRun = false;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment