Commit 4acb1627 authored by Tobias Hunger's avatar Tobias Hunger

CMake: Enable switching between different temporary CMake configurations

This got broken when moving the BuildDirManager from the BuildConfiguration
into the Project itself.

As a side-effect this patch also fixes the persisting of cmake state.

Task-number: QTCREATORBUG-19075
Change-Id: I1fc696097b09f5285e67f20885eb1fa27504990b
Reviewed-by: default avatarhjk <hjk@qt.io>
Reviewed-by: Tim Jenssen's avatarTim Jenssen <tim.jenssen@qt.io>
parent 79226a66
......@@ -66,6 +66,7 @@ Utils::FileName BuildDirManager::workDirectory(const BuildDirParameters &paramet
const Utils::FileName bdir = parameters.buildDirectory;
const CMakeTool *cmake = parameters.cmakeTool;
if (bdir.exists()) {
m_buildDirToTempDir.erase(bdir);
return bdir;
} else {
if (cmake && cmake->autoCreateBuildDirectory()) {
......@@ -74,14 +75,19 @@ Utils::FileName BuildDirManager::workDirectory(const BuildDirParameters &paramet
return bdir;
}
}
if (!m_tempDir) {
m_tempDir.reset(new Utils::TemporaryDirectory("qtc-cmake-XXXXXXXX"));
if (!m_tempDir->isValid()) {
auto tmpDirIt = m_buildDirToTempDir.find(bdir);
if (tmpDirIt == m_buildDirToTempDir.end()) {
auto ret = m_buildDirToTempDir.emplace(std::make_pair(bdir, std::make_unique<Utils::TemporaryDirectory>("qtc-cmake-XXXXXXXX")));
QTC_ASSERT(ret.second, return bdir);
tmpDirIt = ret.first;
if (!tmpDirIt->second->isValid()) {
emitErrorOccured(tr("Failed to create temporary directory \"%1\".")
.arg(QDir::toNativeSeparators(m_tempDir->path())));
.arg(QDir::toNativeSeparators(tmpDirIt->second->path())));
return bdir;
}
}
return Utils::FileName::fromString(m_tempDir->path());
return Utils::FileName::fromString(tmpDirIt->second->path());
}
void BuildDirManager::emitDataAvailable()
......@@ -198,14 +204,20 @@ void BuildDirManager::setParametersAndRequestParse(const BuildDirParameters &par
BuildDirReader *old = m_reader.get();
m_parameters = parameters;
m_parameters.buildDirectory = workDirectory(parameters);
m_parameters.workDirectory = workDirectory(parameters);
updateReaderType(m_parameters,
[this, old, newReaderReparseOptions, existingReaderReparseOptions]() {
if (old != m_reader.get())
emit requestReparse(newReaderReparseOptions);
else
emit requestReparse(existingReaderReparseOptions);
int options = REPARSE_DEFAULT;
if (old != m_reader.get()) {
options = newReaderReparseOptions;
} else {
if (!QFileInfo::exists(m_parameters.workDirectory.toString() + "/CMakeCache.txt"))
options = newReaderReparseOptions;
else
options = existingReaderReparseOptions;
}
emit requestReparse(options);
});
}
......@@ -239,16 +251,17 @@ bool BuildDirManager::persistCMakeState()
{
QTC_ASSERT(m_parameters.isValid(), return false);
if (!m_tempDir)
if (m_parameters.workDirectory == m_parameters.buildDirectory)
return false;
const Utils::FileName buildDir = m_parameters.buildDirectory;
QDir dir(buildDir.toString());
dir.mkpath(buildDir.toString());
m_tempDir.reset(nullptr);
emit requestReparse(REPARSE_URGENT | REPARSE_FORCE_CONFIGURATION | REPARSE_CHECK_CONFIGURATION);
BuildDirParameters newParameters = m_parameters;
newParameters.workDirectory.clear();
setParametersAndRequestParse(newParameters, REPARSE_URGENT | REPARSE_FORCE_CONFIGURATION | REPARSE_CHECK_CONFIGURATION,
REPARSE_FAIL);
return true;
}
......@@ -291,8 +304,8 @@ void BuildDirManager::clearCache()
QTC_ASSERT(m_parameters.isValid(), return);
QTC_ASSERT(!m_isHandlingError, return);
auto cmakeCache = workDirectory(m_parameters).appendPath("CMakeCache.txt");
auto cmakeFiles = workDirectory(m_parameters).appendPath("CMakeFiles");
auto cmakeCache = m_parameters.workDirectory.appendPath("CMakeCache.txt");
auto cmakeFiles = m_parameters.workDirectory.appendPath("CMakeFiles");
const bool mustCleanUp = cmakeCache.exists() || cmakeFiles.exists();
if (!mustCleanUp)
......@@ -367,7 +380,7 @@ bool BuildDirManager::checkConfiguration()
{
QTC_ASSERT(m_parameters.isValid(), return false);
if (m_tempDir) // always throw away changes in the tmpdir!
if (m_parameters.workDirectory != m_parameters.buildDirectory) // always throw away changes in the tmpdir!
return false;
const CMakeConfig cache = m_parameters.buildConfiguration->configurationFromCMake();
......
......@@ -40,6 +40,7 @@
#include <functional>
#include <memory>
#include <unordered_map>
namespace ProjectExplorer { class FileNode; }
......@@ -112,7 +113,7 @@ private:
void becameDirty();
BuildDirParameters m_parameters;
mutable std::unique_ptr<Utils::TemporaryDirectory> m_tempDir = nullptr;
mutable std::unordered_map<Utils::FileName, std::unique_ptr<Utils::TemporaryDirectory>> m_buildDirToTempDir;
mutable std::unique_ptr<BuildDirReader> m_reader;
mutable bool m_isHandlingError = false;
};
......
......@@ -52,6 +52,7 @@ public:
Utils::FileName sourceDirectory;
Utils::FileName buildDirectory;
Utils::FileName workDirectory; // either buildDirectory or a QTemporaryDirectory!
Utils::Environment environment;
CMakeTool *cmakeTool = nullptr;
......
......@@ -160,11 +160,11 @@ CMakeProject::CMakeProject(const FileName &fileName) : Project(Constants::CMAKEM
return;
// Build configuration has switched:
// * Error out if the reader updates, can not happen since all BCs share a target/kit.
// * Check configuration if reader changes due to it not existing yet:-)
// * run cmake without configuration arguments if the reader stays
m_buildDirManager.setParametersAndRequestParse(
BuildDirParameters(bc),
BuildDirManager::REPARSE_FAIL,
BuildDirManager::REPARSE_CHECK_CONFIGURATION,
BuildDirManager::REPARSE_CHECK_CONFIGURATION);
});
......
......@@ -26,11 +26,11 @@
#pragma once
#include "cmake_global.h"
#include "builddirmanager.h"
#include "cmakebuildtarget.h"
#include "cmakeprojectimporter.h"
#include "treescanner.h"
#include "builddirmanager.h"
#include <projectexplorer/extracompiler.h>
#include <projectexplorer/projectmacro.h>
......
......@@ -104,7 +104,7 @@ void ServerModeReader::setParameters(const BuildDirParameters &p)
BuildDirReader::setParameters(p);
if (!m_cmakeServer) {
m_cmakeServer.reset(new ServerMode(p.environment,
p.sourceDirectory, p.buildDirectory,
p.sourceDirectory, p.workDirectory,
p.cmakeTool->cmakeExecutable(),
p.generator, p.extraGenerator, p.platform, p.toolset,
true, 1));
......@@ -155,7 +155,7 @@ bool ServerModeReader::isCompatible(const BuildDirParameters &p)
&& p.platform == m_parameters.platform
&& p.toolset == m_parameters.toolset
&& p.sourceDirectory == m_parameters.sourceDirectory
&& p.buildDirectory == m_parameters.buildDirectory;
&& p.workDirectory == m_parameters.workDirectory;
}
void ServerModeReader::resetData()
......
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