AutoTest: Avoid guessing run configuration

Base the selection of the run configuration on the executable
we have gotten already from the BuildTargetInfo and take
deployment information into account.

This also reverts cce1e130 partially and avoids
stuffing unrelated information into the buildsystemtarget.

Change-Id: I3de6e910a5fd1092d428ec4afc33c4ca62daaa25
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
Christian Stenger
2017-07-12 15:53:31 +02:00
parent b50d5a4b0b
commit 27cb331b4b
8 changed files with 57 additions and 36 deletions

View File

@@ -295,7 +295,7 @@ QSet<QString> 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;
}

View File

@@ -321,7 +321,7 @@ QSet<QString> 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;
}
}

View File

@@ -33,6 +33,7 @@
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/buildtargetinfo.h>
#include <projectexplorer/deploymentdata.h>
#include <projectexplorer/environmentaspect.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/runnables.h>
@@ -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<StandardRunnable>())
continue;
StandardRunnable stdRunnable = runnable.as<StandardRunnable>();
// 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);
}
// 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 &currentExecutable = 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;
}
}
// 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>()) {
StandardRunnable stdRunnable = runnable.as<StandardRunnable>();
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();
}
/**

View File

@@ -291,7 +291,7 @@ QSet<QString> TestTreeItem::internalTargets() const
const QList<CppTools::ProjectPart::Ptr> projectParts = cppMM->projectPart(filePath());
QSet<QString> targets;
for (const CppTools::ProjectPart::Ptr part : projectParts)
targets.insert(part->buildSystemTarget);
targets.insert(part->buildSystemTarget + '|' + part->projectFile);
return targets;
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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<QString, qbs::ArtifactData> filePathToSourceArtifact;
bool hasCFiles = false;

View File

@@ -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());