forked from qt-creator/qt-creator
CMakeProjectManager: Use CMAKE_HOME_DIRECTORY as source directory
The CMakeCache.txt file has CMAKE_HOME_DIRECTORY pointing to the project source directory used to configure the project. When importing a cmake build the CMAKE_HOME_DIRECTORY from CMakeCache.txt might not point to the same CMakeLists.txt that was opened as a project. qt-cmake-standalone-test from Qt6 uses a CMake template project which does a add_subdirectory with the test source directory, which will not work if opened standalone. Normally this is a user error though, so ask the user if this was intended, before actually importing the build. Task-number: QTBUG-88776 Change-Id: Ifdd5e1d1cb8a1ef9955d22493eba3a1a55dc689f Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "cmakebuildconfiguration.h"
|
||||
#include "cmakekitinformation.h"
|
||||
#include "cmakeprojectconstants.h"
|
||||
#include "cmakeprojectplugin.h"
|
||||
#include "cmakespecificsettings.h"
|
||||
#include "cmaketoolmanager.h"
|
||||
@@ -67,7 +68,9 @@ BuildDirParameters::BuildDirParameters(CMakeBuildConfiguration *bc)
|
||||
|
||||
projectName = p->displayName();
|
||||
|
||||
sourceDirectory = p->projectDirectory();
|
||||
sourceDirectory = bc->sourceDirectory();
|
||||
if (sourceDirectory.isEmpty())
|
||||
sourceDirectory = p->projectDirectory();
|
||||
buildDirectory = bc->buildDirectory();
|
||||
|
||||
environment = bc->environment();
|
||||
|
||||
@@ -129,6 +129,8 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Utils::Id id)
|
||||
auto initialCMakeArgumentsAspect = addAspect<InitialCMakeArgumentsAspect>();
|
||||
initialCMakeArgumentsAspect->setMacroExpanderProvider([this]{ return macroExpander(); });
|
||||
|
||||
addAspect<SourceDirectoryAspect>();
|
||||
|
||||
appendInitialBuildStep(Constants::CMAKE_BUILD_STEP_ID);
|
||||
appendInitialCleanStep(Constants::CMAKE_BUILD_STEP_ID);
|
||||
|
||||
@@ -190,6 +192,11 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Utils::Id id)
|
||||
info.buildType));
|
||||
}
|
||||
|
||||
if (info.extraInfo.isValid()) {
|
||||
setSourceDirectory(FilePath::fromVariant(
|
||||
info.extraInfo.value<QVariantMap>().value(Constants::CMAKE_HOME_DIR)));
|
||||
}
|
||||
|
||||
setInitialCMakeArguments(initialArgs);
|
||||
});
|
||||
|
||||
@@ -486,6 +493,16 @@ void CMakeBuildConfiguration::runCMakeWithExtraArguments()
|
||||
m_buildSystem->runCMakeWithExtraArguments();
|
||||
}
|
||||
|
||||
void CMakeBuildConfiguration::setSourceDirectory(const FilePath &path)
|
||||
{
|
||||
aspect<SourceDirectoryAspect>()->setValue(path.toString());
|
||||
}
|
||||
|
||||
Utils::FilePath CMakeBuildConfiguration::sourceDirectory() const
|
||||
{
|
||||
return Utils::FilePath::fromString(aspect<SourceDirectoryAspect>()->value());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// - InitialCMakeParametersAspect:
|
||||
// ----------------------------------------------------------------------
|
||||
@@ -497,5 +514,14 @@ InitialCMakeArgumentsAspect::InitialCMakeArgumentsAspect()
|
||||
setDisplayStyle(TextEditDisplay);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// SourceDirectoryAspect:
|
||||
// -----------------------------------------------------------------------------
|
||||
SourceDirectoryAspect::SourceDirectoryAspect()
|
||||
{
|
||||
// Will not be displayed, only persisted
|
||||
setSettingsKey("CMake.Source.Directory");
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace CMakeProjectManager
|
||||
|
||||
@@ -67,6 +67,9 @@ public:
|
||||
|
||||
void runCMakeWithExtraArguments();
|
||||
|
||||
void setSourceDirectory(const Utils::FilePath& path);
|
||||
Utils::FilePath sourceDirectory() const;
|
||||
|
||||
signals:
|
||||
void errorOccurred(const QString &message);
|
||||
void warningOccurred(const QString &message);
|
||||
@@ -133,5 +136,13 @@ public:
|
||||
InitialCMakeArgumentsAspect();
|
||||
};
|
||||
|
||||
class SourceDirectoryAspect final : public Utils::StringAspect
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SourceDirectoryAspect();
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace CMakeProjectManager
|
||||
|
||||
@@ -37,6 +37,7 @@ const char RESCAN_PROJECT[] = "CMakeProject.RescanProject";
|
||||
const char RUN_CMAKE_CONTEXT_MENU[] = "CMakeProject.RunCMakeContextMenu";
|
||||
const char BUILD_FILE_CONTEXT_MENU[] = "CMakeProject.BuildFileContextMenu";
|
||||
const char BUILD_FILE[] = "CMakeProject.BuildFile";
|
||||
const char CMAKE_HOME_DIR[] = "CMakeProject.HomeDirectory";
|
||||
|
||||
// Project
|
||||
const char CMAKE_PROJECT_ID[] = "CMakeProjectManager.CMakeProject";
|
||||
|
||||
@@ -28,8 +28,11 @@
|
||||
#include "cmakebuildconfiguration.h"
|
||||
#include "cmakebuildsystem.h"
|
||||
#include "cmakekitinformation.h"
|
||||
#include "cmakeprojectconstants.h"
|
||||
#include "cmaketoolmanager.h"
|
||||
|
||||
#include <coreplugin/messagemanager.h>
|
||||
|
||||
#include <projectexplorer/buildinfo.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
@@ -58,6 +61,7 @@ struct DirectoryData
|
||||
// Project Stuff:
|
||||
QByteArray cmakeBuildType;
|
||||
FilePath buildDirectory;
|
||||
FilePath cmakeHomeDirectory;
|
||||
|
||||
// Kit Stuff
|
||||
FilePath cmakeBinary;
|
||||
@@ -266,7 +270,8 @@ static QVector<ToolChainDescription> extractToolChainsFromCache(const CMakeConfi
|
||||
return result;
|
||||
}
|
||||
|
||||
QList<void *> CMakeProjectImporter::examineDirectory(const FilePath &importPath) const
|
||||
QList<void *> CMakeProjectImporter::examineDirectory(const FilePath &importPath,
|
||||
QString *warningMessage) const
|
||||
{
|
||||
qCInfo(cmInputLog) << "Examining directory:" << importPath.toUserOutput();
|
||||
const FilePath cacheFile = importPath.pathAppended("CMakeCache.txt");
|
||||
@@ -282,18 +287,22 @@ QList<void *> CMakeProjectImporter::examineDirectory(const FilePath &importPath)
|
||||
qCDebug(cmInputLog) << "Failed to read configuration from" << cacheFile << errorMessage;
|
||||
return { };
|
||||
}
|
||||
const auto homeDir = FilePath::fromUserInput(
|
||||
QString::fromUtf8(
|
||||
CMakeConfigItem::valueOf("CMAKE_HOME_DIRECTORY", config)))
|
||||
.canonicalPath();
|
||||
auto data = std::make_unique<DirectoryData>();
|
||||
|
||||
data->cmakeHomeDirectory = FilePath::fromUserInput(
|
||||
QString::fromUtf8(
|
||||
CMakeConfigItem::valueOf("CMAKE_HOME_DIRECTORY", config)))
|
||||
.canonicalPath();
|
||||
const FilePath canonicalProjectDirectory = projectDirectory().canonicalPath();
|
||||
if (homeDir != canonicalProjectDirectory) {
|
||||
qCDebug(cmInputLog) << "Wrong source directory:" << homeDir.toUserOutput()
|
||||
<< "expected:" << canonicalProjectDirectory.toUserOutput();
|
||||
return { };
|
||||
if (data->cmakeHomeDirectory != canonicalProjectDirectory) {
|
||||
*warningMessage = tr("Unexpected source directory \"%1\", expected \"%2\". "
|
||||
"This can be correct in some situations, for example when "
|
||||
"importing a standalone Qt test, but usually this is an error. "
|
||||
"Import the build anyway?")
|
||||
.arg(data->cmakeHomeDirectory.toUserOutput(),
|
||||
canonicalProjectDirectory.toUserOutput());
|
||||
}
|
||||
|
||||
auto data = std::make_unique<DirectoryData>();
|
||||
data->buildDirectory = importPath;
|
||||
data->cmakeBuildType = CMakeConfigItem::valueOf("CMAKE_BUILD_TYPE", config);
|
||||
|
||||
@@ -395,6 +404,10 @@ const QList<BuildInfo> CMakeProjectImporter::buildInfoList(void *directoryData)
|
||||
info.buildDirectory = data->buildDirectory;
|
||||
info.displayName = info.typeName;
|
||||
|
||||
QVariantMap config;
|
||||
config.insert(Constants::CMAKE_HOME_DIR, data->cmakeHomeDirectory.toString());
|
||||
info.extraInfo = config;
|
||||
|
||||
qCDebug(cmInputLog) << "BuildInfo configured.";
|
||||
return {info};
|
||||
}
|
||||
|
||||
@@ -41,7 +41,8 @@ public:
|
||||
QStringList importCandidates() final;
|
||||
|
||||
private:
|
||||
QList<void *> examineDirectory(const Utils::FilePath &importPath) const final;
|
||||
QList<void *> examineDirectory(const Utils::FilePath &importPath,
|
||||
QString *warningMessage) const final;
|
||||
bool matchKit(void *directoryData, const ProjectExplorer::Kit *k) const final;
|
||||
ProjectExplorer::Kit *createKit(void *directoryData) const final;
|
||||
const QList<ProjectExplorer::BuildInfo> buildInfoList(void *directoryData) const final;
|
||||
|
||||
@@ -44,8 +44,10 @@ QStringList MesonProjectImporter::importCandidates()
|
||||
return {};
|
||||
}
|
||||
|
||||
QList<void *> MesonProjectImporter::examineDirectory(const Utils::FilePath &importPath) const
|
||||
QList<void *> MesonProjectImporter::examineDirectory(const Utils::FilePath &importPath,
|
||||
QString *warningMessage) const
|
||||
{
|
||||
Q_UNUSED(warningMessage)
|
||||
//TODO, this can be done later
|
||||
qCDebug(mInputLog()) << "examining build directory" << importPath.toUserOutput();
|
||||
QList<void *> data;
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
|
||||
private:
|
||||
// importPath is an existing directory at this point!
|
||||
QList<void *> examineDirectory(const Utils::FilePath &importPath) const final;
|
||||
QList<void *> examineDirectory(const Utils::FilePath &importPath, QString *warningMessage) const final;
|
||||
// will get one of the results from examineDirectory
|
||||
bool matchKit(void *directoryData, const ProjectExplorer::Kit *k) const final;
|
||||
// will get one of the results from examineDirectory
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
#include <QLoggingCategory>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QString>
|
||||
|
||||
namespace ProjectExplorer {
|
||||
@@ -108,12 +109,28 @@ const QList<BuildInfo> ProjectImporter::import(const Utils::FilePath &importPath
|
||||
.arg(importPath.toUserOutput(), projectFilePath().toUserOutput()));
|
||||
};
|
||||
qCDebug(log) << "Examining directory" << absoluteImportPath.toString();
|
||||
QList<void *> dataList = examineDirectory(absoluteImportPath);
|
||||
QString warningMessage;
|
||||
QList<void *> dataList = examineDirectory(absoluteImportPath, &warningMessage);
|
||||
if (dataList.isEmpty()) {
|
||||
qCDebug(log) << "Nothing to import found in" << absoluteImportPath.toString();
|
||||
handleFailure();
|
||||
return result;
|
||||
}
|
||||
if (!warningMessage.isEmpty()) {
|
||||
qCDebug(log) << "Warning when examining" << absoluteImportPath.toString();
|
||||
// we should ask user before importing
|
||||
if (silent)
|
||||
return result;
|
||||
QMessageBox dialog(Core::ICore::dialogParent());
|
||||
dialog.setWindowTitle(tr("Import Warning"));
|
||||
dialog.setText(warningMessage);
|
||||
dialog.setIcon(QMessageBox::Warning);
|
||||
QPushButton *acceptButton = dialog.addButton(tr("Import Build"), QMessageBox::AcceptRole);
|
||||
dialog.addButton(QMessageBox::Cancel);
|
||||
dialog.exec();
|
||||
if (dialog.clickedButton() != acceptButton)
|
||||
return result;
|
||||
}
|
||||
|
||||
qCDebug(log) << "Looking for kits";
|
||||
foreach (void *data, dataList) {
|
||||
|
||||
@@ -86,7 +86,8 @@ protected:
|
||||
};
|
||||
|
||||
// importPath is an existing directory at this point!
|
||||
virtual QList<void *> examineDirectory(const Utils::FilePath &importPath) const = 0;
|
||||
virtual QList<void *> examineDirectory(const Utils::FilePath &importPath,
|
||||
QString *warningMessage) const = 0;
|
||||
// will get one of the results from examineDirectory
|
||||
virtual bool matchKit(void *directoryData, const Kit *k) const = 0;
|
||||
// will get one of the results from examineDirectory
|
||||
|
||||
@@ -134,8 +134,10 @@ QStringList QbsProjectImporter::importCandidates()
|
||||
return candidates;
|
||||
}
|
||||
|
||||
QList<void *> QbsProjectImporter::examineDirectory(const FilePath &importPath) const
|
||||
QList<void *> QbsProjectImporter::examineDirectory(const FilePath &importPath,
|
||||
QString *warningMessage) const
|
||||
{
|
||||
Q_UNUSED(warningMessage)
|
||||
qCDebug(qbsPmLog) << "examining build directory" << importPath.toUserOutput();
|
||||
QList<void *> data;
|
||||
const FilePath bgFilePath = importPath.pathAppended(importPath.fileName() + ".bg");
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
|
||||
private:
|
||||
QStringList importCandidates() override;
|
||||
QList<void *> examineDirectory(const Utils::FilePath &importPath) const override;
|
||||
QList<void *> examineDirectory(const Utils::FilePath &importPath, QString *warningMessage) const override;
|
||||
bool matchKit(void *directoryData, const ProjectExplorer::Kit *k) const override;
|
||||
ProjectExplorer::Kit *createKit(void *directoryData) const override;
|
||||
const QList<ProjectExplorer::BuildInfo> buildInfoList(void *directoryData) const override;
|
||||
|
||||
@@ -110,8 +110,10 @@ QStringList QmakeProjectImporter::importCandidates()
|
||||
return candidates;
|
||||
}
|
||||
|
||||
QList<void *> QmakeProjectImporter::examineDirectory(const FilePath &importPath) const
|
||||
QList<void *> QmakeProjectImporter::examineDirectory(const FilePath &importPath,
|
||||
QString *warningMessage) const
|
||||
{
|
||||
Q_UNUSED(warningMessage)
|
||||
QList<void *> result;
|
||||
const QLoggingCategory &logs = MakeFileParse::logging();
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
QStringList importCandidates() final;
|
||||
|
||||
private:
|
||||
QList<void *> examineDirectory(const Utils::FilePath &importPath) const final;
|
||||
QList<void *> examineDirectory(const Utils::FilePath &importPath, QString *warningMessage) const final;
|
||||
bool matchKit(void *directoryData, const ProjectExplorer::Kit *k) const final;
|
||||
ProjectExplorer::Kit *createKit(void *directoryData) const final;
|
||||
const QList<ProjectExplorer::BuildInfo> buildInfoList(void *directoryData) const final;
|
||||
|
||||
@@ -177,7 +177,8 @@ public:
|
||||
bool allDeleted() const { return m_deletedTestData.count() == m_testData.count();}
|
||||
|
||||
protected:
|
||||
QList<void *> examineDirectory(const Utils::FilePath &importPath) const override;
|
||||
QList<void *> examineDirectory(const Utils::FilePath &importPath,
|
||||
QString *warningMessage) const override;
|
||||
bool matchKit(void *directoryData, const Kit *k) const override;
|
||||
Kit *createKit(void *directoryData) const override;
|
||||
const QList<BuildInfo> buildInfoList(void *directoryData) const override;
|
||||
@@ -196,8 +197,10 @@ QStringList TestQtProjectImporter::importCandidates()
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
QList<void *> TestQtProjectImporter::examineDirectory(const Utils::FilePath &importPath) const
|
||||
QList<void *> TestQtProjectImporter::examineDirectory(const Utils::FilePath &importPath,
|
||||
QString *warningMessage) const
|
||||
{
|
||||
Q_UNUSED(warningMessage)
|
||||
m_path = importPath;
|
||||
|
||||
assert(m_deletedTestData.isEmpty());
|
||||
|
||||
Reference in New Issue
Block a user