diff --git a/src/plugins/autotest/gtest/gtesttreeitem.cpp b/src/plugins/autotest/gtest/gtesttreeitem.cpp index b9308a4e737..f41afacf7a4 100644 --- a/src/plugins/autotest/gtest/gtesttreeitem.cpp +++ b/src/plugins/autotest/gtest/gtesttreeitem.cpp @@ -295,7 +295,7 @@ QSet GTestTreeItem::internalTargets() const const auto projectInfo = cppMM->projectInfo(ProjectExplorer::SessionManager::startupProject()); for (const CppTools::ProjectPart::Ptr projectPart : projectInfo.projectParts()) { if (projectPart->projectFile == proFile()) - result.insert(projectPart->buildSystemTarget); + result.insert(projectPart->buildSystemTarget + '|' + projectPart->projectFile); } return result; } diff --git a/src/plugins/autotest/quick/quicktesttreeitem.cpp b/src/plugins/autotest/quick/quicktesttreeitem.cpp index c4de28c6915..8edff98f4a3 100644 --- a/src/plugins/autotest/quick/quicktesttreeitem.cpp +++ b/src/plugins/autotest/quick/quicktesttreeitem.cpp @@ -321,7 +321,7 @@ QSet QuickTestTreeItem::internalTargets() const const auto projectInfo = cppMM->projectInfo(ProjectExplorer::SessionManager::startupProject()); for (const CppTools::ProjectPart::Ptr projectPart : projectInfo.projectParts()) { if (projectPart->projectFile == proFile()) { - result.insert(projectPart->buildSystemTarget); + result.insert(projectPart->buildSystemTarget + '|' + projectPart->projectFile); break; } } diff --git a/src/plugins/autotest/testconfiguration.cpp b/src/plugins/autotest/testconfiguration.cpp index 8440348d7d2..7fe89b3ca3a 100644 --- a/src/plugins/autotest/testconfiguration.cpp +++ b/src/plugins/autotest/testconfiguration.cpp @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -61,6 +62,13 @@ static bool isLocal(RunConfiguration *runConfiguration) return DeviceTypeKitInformation::deviceTypeId(kit) == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE; } +static QString ensureExeEnding(const QString& file) +{ + if (!Utils::HostOsInfo::isWindowsHost() || file.isEmpty() || file.toLower().endsWith(".exe")) + return file; + return Utils::HostOsInfo::withExecutableSuffix(file); +} + void TestConfiguration::completeTestInformation(int runMode) { QTC_ASSERT(!m_projectFile.isEmpty(), return); @@ -82,44 +90,65 @@ void TestConfiguration::completeTestInformation(int runMode) const QStringList targWithProjectFile = b.split('|'); if (targWithProjectFile.size() != 2) // some build targets might miss the project file return false; - return targWithProjectFile.at(0) == bti.targetName + return !bti.targetFilePath.isEmpty() && targWithProjectFile.at(0) == bti.targetName && targWithProjectFile.at(1).startsWith(bti.projectFilePath.toString()); }); }); - QString executable = targetInfo.targetFilePath.toString(); // empty if BTI default created - if (Utils::HostOsInfo::isWindowsHost() && !executable.isEmpty() - && !executable.toLower().endsWith(".exe")) { - executable = Utils::HostOsInfo::withExecutableSuffix(executable); + QTC_CHECK(!targetInfo.targetFilePath.isEmpty()); // empty if BTI default created + const QString localExecutable = ensureExeEnding(targetInfo.targetFilePath.toString()); + + QString buildBase; + if (auto buildConfig = target->activeBuildConfiguration()) { + buildBase = buildConfig->buildDirectory().toString(); + const QString projBase = project->projectDirectory().toString(); + if (m_projectFile.startsWith(projBase)) + m_buildDir = QFileInfo(buildBase + m_projectFile.mid(projBase.length())).absolutePath(); } + // deployment information should get taken into account, but it pretty much seems as if + // each build system uses it differently + const DeploymentData &deployData = target->deploymentData(); + const DeployableFile deploy = deployData.deployableForLocalFile(localExecutable); + // we might have a deployable executable + const QString deployedExecutable = ensureExeEnding((deploy.isValid() && deploy.isExecutable()) + ? QDir::cleanPath(deploy.remoteFilePath()) : localExecutable); + for (RunConfiguration *runConfig : target->runConfigurations()) { if (!isLocal(runConfig)) // TODO add device support continue; - const QString bst = runConfig->buildSystemTarget() + '|' + m_projectFile; - if (buildSystemTargets.contains(bst)) { - Runnable runnable = runConfig->runnable(); - if (!runnable.is()) - continue; - StandardRunnable stdRunnable = runnable.as(); - // TODO this might pick up the wrong executable - m_executableFile = stdRunnable.executable; - if (Utils::HostOsInfo::isWindowsHost() && !m_executableFile.isEmpty() - && !m_executableFile.toLower().endsWith(".exe")) { - m_executableFile = Utils::HostOsInfo::withExecutableSuffix(m_executableFile); - } + Runnable runnable = runConfig->runnable(); + if (!runnable.is()) + continue; + StandardRunnable stdRunnable = runnable.as(); + // not the best approach - but depending on the build system and whether the executables + // are going to get installed or not we have to soften the condition... + const QString ¤tExecutable = ensureExeEnding(stdRunnable.executable); + const QString currentBST = runConfig->buildSystemTarget() + '|'; + const bool isQbs = runConfig->id().toString().startsWith("Qbs.RunConfiguration:"); // BAD! + if ((localExecutable == currentExecutable) + || (deployedExecutable == currentExecutable) + || (isQbs && Utils::anyOf(buildSystemTargets, [currentBST] (const QString &b) { + return b.startsWith(currentBST); + }))) { + m_executableFile = currentExecutable; m_displayName = runConfig->displayName(); m_workingDir = Utils::FileUtils::normalizePathName(stdRunnable.workingDirectory); m_environment = stdRunnable.environment; m_project = project; if (runMode == TestRunner::Debug) m_runConfig = new TestRunConfiguration(runConfig->target(), this); - if (m_executableFile == executable) // we can find a better runConfig if no match - break; + break; } } + // RunConfiguration for this target could be explicitly removed or not created at all - if (m_displayName.isEmpty() && !executable.isEmpty()) { + // or we might have end up using the (wrong) path of a locally installed executable + // for this case try the original executable path of the BuildTargetInfo (the executable + // before installation) to have at least something to execute + if (m_executableFile.isEmpty() && !localExecutable.isEmpty()) + m_executableFile = localExecutable; + if (m_displayName.isEmpty() && !m_executableFile.isEmpty()) { // we failed to find a valid runconfiguration - but we've got the executable already if (auto rc = target->activeRunConfiguration()) { if (isLocal(rc)) { // FIXME for now only Desktop support @@ -127,7 +156,6 @@ void TestConfiguration::completeTestInformation(int runMode) if (runnable.is()) { StandardRunnable stdRunnable = runnable.as(); m_environment = stdRunnable.environment; - m_executableFile = executable; m_project = project; m_guessedConfiguration = true; m_guessedFrom = rc->displayName(); @@ -138,15 +166,8 @@ void TestConfiguration::completeTestInformation(int runMode) } } - if (auto buildConfig = target->activeBuildConfiguration()) { - const QString buildBase = buildConfig->buildDirectory().toString(); - const QString projBase = project->projectDirectory().toString(); - if (m_projectFile.startsWith(projBase)) - m_buildDir = QFileInfo(buildBase + m_projectFile.mid(projBase.length())).absolutePath(); - } - if (m_displayName.isEmpty()) // happens e.g. when guessing the TestConfiguration or error - m_displayName = buildSystemTargets.isEmpty() ? "unknown" : (*buildSystemTargets.begin()).split('|').first(); + m_displayName = (*buildSystemTargets.begin()).split('|').first(); } /** diff --git a/src/plugins/autotest/testtreeitem.cpp b/src/plugins/autotest/testtreeitem.cpp index 3bfa4400c5e..60b58ca85db 100644 --- a/src/plugins/autotest/testtreeitem.cpp +++ b/src/plugins/autotest/testtreeitem.cpp @@ -291,7 +291,7 @@ QSet TestTreeItem::internalTargets() const const QList projectParts = cppMM->projectPart(filePath()); QSet targets; for (const CppTools::ProjectPart::Ptr part : projectParts) - targets.insert(part->buildSystemTarget); + targets.insert(part->buildSystemTarget + '|' + part->projectFile); return targets; } diff --git a/src/plugins/cmakeprojectmanager/servermodereader.cpp b/src/plugins/cmakeprojectmanager/servermodereader.cpp index b2aefc76ceb..bcb0fbed42e 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.cpp +++ b/src/plugins/cmakeprojectmanager/servermodereader.cpp @@ -333,7 +333,7 @@ void ServerModeReader::updateCodeModel(CppTools::RawProjectParts &rpps) CppTools::RawProjectPart rpp; rpp.setProjectFileLocation(fg->target->sourceDirectory.toString() + "/CMakeLists.txt"); - rpp.setBuildSystemTarget(fg->target->name + '|' + rpp.projectFile); + rpp.setBuildSystemTarget(fg->target->name); rpp.setDisplayName(fg->target->name + QString::number(counter)); rpp.setDefines(defineArg.toUtf8()); rpp.setIncludePaths(includes); diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.cpp b/src/plugins/cmakeprojectmanager/tealeafreader.cpp index 025cb934e25..eed99dad19c 100644 --- a/src/plugins/cmakeprojectmanager/tealeafreader.cpp +++ b/src/plugins/cmakeprojectmanager/tealeafreader.cpp @@ -373,7 +373,7 @@ void TeaLeafReader::updateCodeModel(CppTools::RawProjectParts &rpps) includePaths += m_parameters.buildDirectory.toString(); CppTools::RawProjectPart rpp; rpp.setProjectFileLocation(cbt.sourceDirectory.toString() + "/CMakeLists.txt"); - rpp.setBuildSystemTarget(cbt.title + '|' + rpp.projectFile); + rpp.setBuildSystemTarget(cbt.title); rpp.setIncludePaths(includePaths); CppTools::RawProjectPartFlags cProjectFlags; diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 166c386570b..1685b32e876 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -1001,7 +1001,7 @@ void QbsProject::updateCppCodeModel() rpp.setDisplayName(grp.name()); rpp.setProjectFileLocation(grp.location().filePath(), grp.location().line(), grp.location().column()); - rpp.setBuildSystemTarget(prd.name() + '|' + rpp.projectFile); + rpp.setBuildSystemTarget(prd.name()); QHash filePathToSourceArtifact; bool hasCFiles = false; diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 806e500e572..c241189d9e1 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -287,7 +287,7 @@ void QmakeProject::updateCppCodeModel() CppTools::RawProjectPart rpp; rpp.setDisplayName(pro->displayName()); rpp.setProjectFileLocation(pro->filePath().toString()); - rpp.setBuildSystemTarget(pro->targetInformation().target + '|' + rpp.projectFile); + rpp.setBuildSystemTarget(pro->targetInformation().target); // TODO: Handle QMAKE_CFLAGS rpp.setFlagsForCxx({cxxToolChain, pro->variableValue(Variable::CppFlags)}); rpp.setDefines(pro->cxxDefines());