diff --git a/src/plugins/cmakeprojectmanager/builddirparameters.cpp b/src/plugins/cmakeprojectmanager/builddirparameters.cpp index e240f7ec239..131ad540018 100644 --- a/src/plugins/cmakeprojectmanager/builddirparameters.cpp +++ b/src/plugins/cmakeprojectmanager/builddirparameters.cpp @@ -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(); diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 6b396a2aadb..114b93739ab 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -129,6 +129,8 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Utils::Id id) auto initialCMakeArgumentsAspect = addAspect(); initialCMakeArgumentsAspect->setMacroExpanderProvider([this]{ return macroExpander(); }); + addAspect(); + 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().value(Constants::CMAKE_HOME_DIR))); + } + setInitialCMakeArguments(initialArgs); }); @@ -486,6 +493,16 @@ void CMakeBuildConfiguration::runCMakeWithExtraArguments() m_buildSystem->runCMakeWithExtraArguments(); } +void CMakeBuildConfiguration::setSourceDirectory(const FilePath &path) +{ + aspect()->setValue(path.toString()); +} + +Utils::FilePath CMakeBuildConfiguration::sourceDirectory() const +{ + return Utils::FilePath::fromString(aspect()->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 diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h index e85102e121a..256e2c022c9 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h @@ -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 diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h b/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h index a59ac48c09d..b7d46e8dafc 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h +++ b/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h @@ -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"; diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp index 1bd4ff4f894..5b89c3866dd 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp @@ -28,8 +28,11 @@ #include "cmakebuildconfiguration.h" #include "cmakebuildsystem.h" #include "cmakekitinformation.h" +#include "cmakeprojectconstants.h" #include "cmaketoolmanager.h" +#include + #include #include #include @@ -58,6 +61,7 @@ struct DirectoryData // Project Stuff: QByteArray cmakeBuildType; FilePath buildDirectory; + FilePath cmakeHomeDirectory; // Kit Stuff FilePath cmakeBinary; @@ -266,7 +270,8 @@ static QVector extractToolChainsFromCache(const CMakeConfi return result; } -QList CMakeProjectImporter::examineDirectory(const FilePath &importPath) const +QList 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 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(); + + 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(); data->buildDirectory = importPath; data->cmakeBuildType = CMakeConfigItem::valueOf("CMAKE_BUILD_TYPE", config); @@ -395,6 +404,10 @@ const QList 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}; } diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.h b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.h index fa1f4e4df7d..7479e624a80 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.h +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.h @@ -41,7 +41,8 @@ public: QStringList importCandidates() final; private: - QList examineDirectory(const Utils::FilePath &importPath) const final; + QList 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 buildInfoList(void *directoryData) const final; diff --git a/src/plugins/mesonprojectmanager/project/mesonprojectimporter.cpp b/src/plugins/mesonprojectmanager/project/mesonprojectimporter.cpp index 5b00db82380..5b7f5ed0e0d 100644 --- a/src/plugins/mesonprojectmanager/project/mesonprojectimporter.cpp +++ b/src/plugins/mesonprojectmanager/project/mesonprojectimporter.cpp @@ -44,8 +44,10 @@ QStringList MesonProjectImporter::importCandidates() return {}; } -QList MesonProjectImporter::examineDirectory(const Utils::FilePath &importPath) const +QList 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 data; diff --git a/src/plugins/mesonprojectmanager/project/mesonprojectimporter.h b/src/plugins/mesonprojectmanager/project/mesonprojectimporter.h index af40bf68264..ac33927860e 100644 --- a/src/plugins/mesonprojectmanager/project/mesonprojectimporter.h +++ b/src/plugins/mesonprojectmanager/project/mesonprojectimporter.h @@ -43,7 +43,7 @@ public: private: // importPath is an existing directory at this point! - QList examineDirectory(const Utils::FilePath &importPath) const final; + QList 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 diff --git a/src/plugins/projectexplorer/projectimporter.cpp b/src/plugins/projectexplorer/projectimporter.cpp index 73fe4d1c0b2..932d4d6e427 100644 --- a/src/plugins/projectexplorer/projectimporter.cpp +++ b/src/plugins/projectexplorer/projectimporter.cpp @@ -42,6 +42,7 @@ #include #include +#include #include namespace ProjectExplorer { @@ -108,12 +109,28 @@ const QList ProjectImporter::import(const Utils::FilePath &importPath .arg(importPath.toUserOutput(), projectFilePath().toUserOutput())); }; qCDebug(log) << "Examining directory" << absoluteImportPath.toString(); - QList dataList = examineDirectory(absoluteImportPath); + QString warningMessage; + QList 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) { diff --git a/src/plugins/projectexplorer/projectimporter.h b/src/plugins/projectexplorer/projectimporter.h index 84603611209..b50f0bd888b 100644 --- a/src/plugins/projectexplorer/projectimporter.h +++ b/src/plugins/projectexplorer/projectimporter.h @@ -86,7 +86,8 @@ protected: }; // importPath is an existing directory at this point! - virtual QList examineDirectory(const Utils::FilePath &importPath) const = 0; + virtual QList 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 diff --git a/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp b/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp index 06f98121691..16c44e8782a 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp +++ b/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp @@ -134,8 +134,10 @@ QStringList QbsProjectImporter::importCandidates() return candidates; } -QList QbsProjectImporter::examineDirectory(const FilePath &importPath) const +QList QbsProjectImporter::examineDirectory(const FilePath &importPath, + QString *warningMessage) const { + Q_UNUSED(warningMessage) qCDebug(qbsPmLog) << "examining build directory" << importPath.toUserOutput(); QList data; const FilePath bgFilePath = importPath.pathAppended(importPath.fileName() + ".bg"); diff --git a/src/plugins/qbsprojectmanager/qbsprojectimporter.h b/src/plugins/qbsprojectmanager/qbsprojectimporter.h index 49fba42f28b..7578fc0f6f7 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectimporter.h +++ b/src/plugins/qbsprojectmanager/qbsprojectimporter.h @@ -39,7 +39,7 @@ public: private: QStringList importCandidates() override; - QList examineDirectory(const Utils::FilePath &importPath) const override; + QList 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 buildInfoList(void *directoryData) const override; diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp index 3fec5661f11..bbeeb4bea60 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp @@ -110,8 +110,10 @@ QStringList QmakeProjectImporter::importCandidates() return candidates; } -QList QmakeProjectImporter::examineDirectory(const FilePath &importPath) const +QList QmakeProjectImporter::examineDirectory(const FilePath &importPath, + QString *warningMessage) const { + Q_UNUSED(warningMessage) QList result; const QLoggingCategory &logs = MakeFileParse::logging(); diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.h b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.h index 8e48311f549..0d97f09b1f2 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.h +++ b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.h @@ -41,7 +41,7 @@ public: QStringList importCandidates() final; private: - QList examineDirectory(const Utils::FilePath &importPath) const final; + QList 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 buildInfoList(void *directoryData) const final; diff --git a/src/plugins/qtsupport/qtprojectimporter.cpp b/src/plugins/qtsupport/qtprojectimporter.cpp index 65d6336ed82..4749271091c 100644 --- a/src/plugins/qtsupport/qtprojectimporter.cpp +++ b/src/plugins/qtsupport/qtprojectimporter.cpp @@ -177,7 +177,8 @@ public: bool allDeleted() const { return m_deletedTestData.count() == m_testData.count();} protected: - QList examineDirectory(const Utils::FilePath &importPath) const override; + QList 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 buildInfoList(void *directoryData) const override; @@ -196,8 +197,10 @@ QStringList TestQtProjectImporter::importCandidates() return QStringList(); } -QList TestQtProjectImporter::examineDirectory(const Utils::FilePath &importPath) const +QList TestQtProjectImporter::examineDirectory(const Utils::FilePath &importPath, + QString *warningMessage) const { + Q_UNUSED(warningMessage) m_path = importPath; assert(m_deletedTestData.isEmpty());