diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index 829c28be152..8be4716a838 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -7,16 +7,17 @@ #include "cmakeprojectconstants.h" #include "cmakeprojectimporter.h" #include "cmakeprojectmanagertr.h" -#include "cmaketool.h" #include #include +#include #include #include #include #include #include #include +#include using namespace ProjectExplorer; using namespace Utils; @@ -237,4 +238,17 @@ ProjectExplorer::DeploymentKnowledge CMakeProject::deploymentKnowledge() const : DeploymentKnowledge::Bad; } +void CMakeProject::configureAsExampleProject(ProjectExplorer::Kit *kit) +{ + QList infoList; + const QList kits(kit != nullptr ? QList({kit}) : KitManager::kits()); + for (Kit *k : kits) { + if (QtSupport::QtKitAspect::qtVersion(k) != nullptr) { + if (auto factory = BuildConfigurationFactory::find(k, projectFilePath())) + infoList << factory->allAvailableSetups(k, projectFilePath()); + } + } + setup(infoList); +} + } // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h index 2885b9eb4b1..09154615013 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.h +++ b/src/plugins/cmakeprojectmanager/cmakeproject.h @@ -36,6 +36,8 @@ protected: private: ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override; + void configureAsExampleProject(ProjectExplorer::Kit *kit) override; + Internal::PresetsData combinePresets(Internal::PresetsData &cmakePresetsData, Internal::PresetsData &cmakeUserPresetsData); void setupBuildPresets(Internal::PresetsData &presetsData); diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index 84f5363cd11..e62d65c0f89 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -869,6 +869,13 @@ const Node *Project::nodeForFilePath(const FilePath &filePath, return nullptr; } +FilePaths Project::binariesForSourceFile(const Utils::FilePath &sourceFile) const +{ + Q_UNUSED(sourceFile); + // TODO: QTCREATORBUG-28815 + return {}; +} + void Project::setProjectLanguages(Context language) { if (d->m_projectLanguages == language) @@ -1482,6 +1489,76 @@ void ProjectExplorerPlugin::testProject_multipleBuildConfigs() ProjectManager::closeAllProjects(); // QTCREATORBUG-25655 } +void ProjectExplorerPlugin::testSourceToBinaryMapping() +{ + // Find suitable kit. + Kit * const kit = findOr(KitManager::kits(), nullptr, [](const Kit *k) { + return k->isValid(); + }); + if (!kit) + QSKIP("The test requires at least one valid kit."); + + // Copy project from qrc. + QTemporaryDir * const tempDir = TemporaryDirectory::masterTemporaryDirectory(); + QVERIFY(tempDir->isValid()); + const FilePath projectDir = FilePath::fromString(tempDir->path() + "/multi-target-project"); + if (!projectDir.exists()) { + const auto result = FilePath(":/projectexplorer/testdata/multi-target-project") + .copyRecursively(projectDir); + QVERIFY2(result, qPrintable(result.error())); + const QFileInfoList files = QDir(projectDir.toString()).entryInfoList(QDir::Files); + for (const QFileInfo &f : files) + QFile(f.absoluteFilePath()).setPermissions(f.permissions() | QFile::WriteUser); + } + + // Load Project. + QFETCH(QString, projectFileName); + const auto theProject = openProject(projectDir.pathAppended(projectFileName)); + if (theProject.errorMessage().contains("text/")) { + QSKIP("This test requires the presence of the qmake/cmake/qbs project managers " + "to be fully functional"); + } + + QVERIFY2(theProject, qPrintable(theProject.errorMessage())); + theProject.project()->configureAsExampleProject(kit); + QCOMPARE(theProject.project()->targets().size(), 1); + Target * const target = theProject.project()->activeTarget(); + QVERIFY(target); + BuildSystem * const bs = target->buildSystem(); + QVERIFY(bs); + QCOMPARE(bs, target->activeBuildConfiguration()->buildSystem()); + if (bs->isWaitingForParse() || bs->isParsing()) { + QSignalSpy parsingFinishedSpy(bs, &BuildSystem::parsingFinished); + QVERIFY(parsingFinishedSpy.wait(10000)); + } + QVERIFY(!bs->isWaitingForParse() && !bs->isParsing()); + + // Build project. + BuildManager::buildProjectWithoutDependencies(theProject.project()); + if (BuildManager::isBuilding()) { + QSignalSpy buildingFinishedSpy(BuildManager::instance(), &BuildManager::buildQueueFinished); + QVERIFY(buildingFinishedSpy.wait(10000)); + } + QVERIFY(!BuildManager::isBuilding()); + + // Check mapping + const auto binariesForSource = [&](const QString &fileName) { + return theProject.project()->binariesForSourceFile(projectDir.pathAppended(fileName)); + }; + QEXPECT_FAIL(0, "QTCREATORBUG-28815", Abort); + QCOMPARE(binariesForSource("multi-target-project-main.cpp").size(), 1); + QCOMPARE(binariesForSource("multi-target-project-lib.cpp").size(), 1); + QCOMPARE(binariesForSource("multi-target-project-shared.h").size(), 2); +} + +void ProjectExplorerPlugin::testSourceToBinaryMapping_data() +{ + QTest::addColumn("projectFileName"); + QTest::addRow("cmake") << "CMakeLists.txt"; + QTest::addRow("qbs") << "multi-target-project.qbs"; + QTest::addRow("qmake") << "multi-target-project.pro"; +} + #endif // WITH_TESTS } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index ebf38a688d4..d753048aff5 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -110,6 +110,7 @@ public: bool isKnownFile(const Utils::FilePath &filename) const; const Node *nodeForFilePath(const Utils::FilePath &filePath, const NodeMatcher &extraMatcher = {}) const; + Utils::FilePaths binariesForSourceFile(const Utils::FilePath &sourceFile) const; virtual QVariantMap toMap() const; diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h index baa8bb83a6b..e5f91bd334d 100644 --- a/src/plugins/projectexplorer/projectexplorer.h +++ b/src/plugins/projectexplorer/projectexplorer.h @@ -261,6 +261,9 @@ private slots: void testProject_projectTree(); void testProject_multipleBuildConfigs(); + void testSourceToBinaryMapping(); + void testSourceToBinaryMapping_data(); + void testSessionSwitch(); #endif // WITH_TESTS }; diff --git a/src/plugins/projectexplorer/projectexplorer.qrc b/src/plugins/projectexplorer/projectexplorer.qrc index ececb0854b3..0cc88e3331a 100644 --- a/src/plugins/projectexplorer/projectexplorer.qrc +++ b/src/plugins/projectexplorer/projectexplorer.qrc @@ -86,5 +86,13 @@ images/settingscategory_cpp@2x.png images/importasproject.png images/importasproject@2x.png + testdata/multi-target-project/CMakeLists.txt + testdata/multi-target-project/multi-target-project-app.pro + testdata/multi-target-project/multi-target-project-lib.cpp + testdata/multi-target-project/multi-target-project-lib.pro + testdata/multi-target-project/multi-target-project-main.cpp + testdata/multi-target-project/multi-target-project-shared.h + testdata/multi-target-project/multi-target-project.pro + testdata/multi-target-project/multi-target-project.qbs diff --git a/src/plugins/projectexplorer/testdata/multi-target-project/CMakeLists.txt b/src/plugins/projectexplorer/testdata/multi-target-project/CMakeLists.txt new file mode 100644 index 00000000000..5313539cd79 --- /dev/null +++ b/src/plugins/projectexplorer/testdata/multi-target-project/CMakeLists.txt @@ -0,0 +1,3 @@ +project(multi-target-project) +add_executable(multi-target-project-app multi-target-project-main.cpp multi-target-project-shared.h) +add_library(multi-target-project-lib STATIC multi-target-project-lib.cpp multi-target-project-shared.h) diff --git a/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project-app.pro b/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project-app.pro new file mode 100644 index 00000000000..96870c05c1f --- /dev/null +++ b/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project-app.pro @@ -0,0 +1,4 @@ +TARGET = app +CONFIG -= qt +SOURCES = multi-target-project-main.cpp +HEADERS = multi-target-project-shared.h diff --git a/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project-lib.cpp b/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project-lib.cpp new file mode 100644 index 00000000000..9b7a34861c7 --- /dev/null +++ b/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project-lib.cpp @@ -0,0 +1,6 @@ +#include "multi-target-project-shared.h" + +int increaseNumber() +{ + return getNumber() + 1; +} diff --git a/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project-lib.pro b/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project-lib.pro new file mode 100644 index 00000000000..42571540519 --- /dev/null +++ b/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project-lib.pro @@ -0,0 +1,4 @@ +TEMPLATE = lib +CONFIG += static +SOURCES = multi-target-project-lib.cpp +HEADERS = multi-target-project-shared.h diff --git a/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project-main.cpp b/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project-main.cpp new file mode 100644 index 00000000000..306400b3502 --- /dev/null +++ b/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project-main.cpp @@ -0,0 +1,6 @@ +#include "multi-target-project-shared.h" + +int main() +{ + return getNumber(); +} diff --git a/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project-shared.h b/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project-shared.h new file mode 100644 index 00000000000..9f839e82d02 --- /dev/null +++ b/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project-shared.h @@ -0,0 +1,3 @@ +#pragma once + +inline int getNumber() { return 5; } diff --git a/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project.pro b/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project.pro new file mode 100644 index 00000000000..5e6289d7b26 --- /dev/null +++ b/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs +app.file = multi-target-project-app.pro +lib.file = multi-target-project-lib.pro +SUBDIRS = app lib diff --git a/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project.qbs b/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project.qbs new file mode 100644 index 00000000000..079ac82c955 --- /dev/null +++ b/src/plugins/projectexplorer/testdata/multi-target-project/multi-target-project.qbs @@ -0,0 +1,10 @@ +Project { + CppApplication { + name: "app" + files: ["multi-target-project-main.cpp", "multi-target-project-shared.h"] + } + StaticLibrary { + Depends { name: "cpp" } + files: ["multi-target-project-lib.cpp", "multi-target-project-shared.h"] + } +}