Debugger: Fix automatic source mapping for Qt

- The QtVersion::sourcePath() was wrong because QT_INSTALL_PREFIX/src
  doesn't return the right path. Work around by checking if sources are
  found, and otherwise trying the location that we know the installers
  to put them.
- Pass the sourcePath along to the debugger run control, and use that
  instead of looking for qmake in the PATH (which fails because it is
  not in PATH).

Fixes: QTCREATORBUG-28950
Change-Id: Iffa262d6c87dbc979c449d43cd4a85e1320bcd37
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Eike Ziller
2023-06-15 11:38:21 +02:00
parent 6f6f6d3f97
commit 562c5774e3
4 changed files with 24 additions and 36 deletions

View File

@@ -157,6 +157,7 @@ public:
Utils::FilePath debugInfoLocation; // Gdb "set-debug-file-directory".
QStringList debugSourceLocation; // Gdb "directory"
QString qtPackageSourceLocation;
Utils::FilePath qtSourceLocation;
bool isSnapshot = false; // Set if created internally.
ProjectExplorer::Abi toolChainAbi;

View File

@@ -863,8 +863,10 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm
m_runParameters.debugger = DebuggerKitAspect::runnable(kit);
m_runParameters.cppEngineType = DebuggerKitAspect::engineType(kit);
if (QtSupport::QtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(kit))
if (QtSupport::QtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(kit)) {
m_runParameters.qtPackageSourceLocation = qtVersion->qtPackageSourcePath().toString();
m_runParameters.qtSourceLocation = qtVersion->sourcePath();
}
if (auto aspect = runControl->aspect<DebuggerRunConfigurationAspect>()) {
if (!aspect->useCppDebugger)

View File

@@ -415,47 +415,18 @@ void DebuggerSourcePathMappingWidget::slotEditTargetFieldChanged()
}
}
// Find Qt installation by running qmake
static QString findQtInstallPath(const FilePath &qmakePath)
{
if (qmakePath.isEmpty())
return QString();
Process proc;
proc.setCommand({qmakePath, {"-query", "QT_INSTALL_HEADERS"}});
proc.start();
if (!proc.waitForFinished()) {
qWarning("%s: Timeout running '%s'.", Q_FUNC_INFO, qPrintable(qmakePath.toString()));
return QString();
}
if (proc.exitStatus() != QProcess::NormalExit) {
qWarning("%s: '%s' crashed.", Q_FUNC_INFO, qPrintable(qmakePath.toString()));
return QString();
}
const QByteArray ba = proc.readAllRawStandardOutput().trimmed();
QDir dir(QString::fromLocal8Bit(ba));
if (dir.exists() && dir.cdUp())
return dir.absolutePath();
return QString();
}
/* Merge settings for an installed Qt (unless another setting is already in the map. */
SourcePathMap mergePlatformQtPath(const DebuggerRunParameters &sp, const SourcePathMap &in)
{
const FilePath qmake = BuildableHelperLibrary::findSystemQt(sp.inferior.environment);
// FIXME: Get this from the profile?
// We could query the QtVersion for this information directly, but then we
// will need to add a dependency on QtSupport to the debugger.
//
// The profile could also get a function to extract the required information from
// its information to avoid this dependency (as we do for the environment).
const QString qtInstallPath = findQtInstallPath(qmake);
if (qtInstallPath.isEmpty())
static const QString qglobal = "qtbase/src/corelib/global/qglobal.h";
const FilePath sourceLocation = sp.qtSourceLocation;
if (!(sourceLocation / qglobal).exists())
return in;
SourcePathMap rc = in;
for (const QString &buildPath : qtBuildPaths()) {
if (!rc.contains(buildPath)) // Do not overwrite user settings.
rc.insert(buildPath, qtInstallPath + "/../Src");
rc.insert(buildPath, sourceLocation.path());
}
return rc;
}

View File

@@ -1861,9 +1861,23 @@ FilePath QtVersionPrivate::mkspecFromVersionInfo(const QHash<ProKey, ProString>
FilePath QtVersionPrivate::sourcePath(const QHash<ProKey, ProString> &versionInfo)
{
const QString qt5Source = qmakeProperty(versionInfo, "QT_INSTALL_PREFIX/src");
if (!qt5Source.isEmpty())
return FilePath::fromString(QFileInfo(qt5Source).canonicalFilePath());
if (!qt5Source.isEmpty()) {
// Can be wrong for the Qt installers :/
// Check if we actually find sources, otherwise try what the online installer does.
const auto source = FilePath::fromString(QFileInfo(qt5Source).canonicalFilePath());
static const QString qglobal = "qtbase/src/corelib/global/qglobal.h";
if (!(source / qglobal).exists()) {
const auto install = FilePath::fromString(
qmakeProperty(versionInfo, "QT_INSTALL_PREFIX"))
.canonicalPath();
const FilePath otherSource = install / ".." / "Src";
if ((otherSource / qglobal).exists())
return otherSource.cleanPath();
}
return source;
}
// TODO The .qmake.cache workaround doesn't work anymore since Qt is built with CMake
const QString installData = qmakeProperty(versionInfo, "QT_INSTALL_PREFIX");
QString sourcePath = installData;
QFile qmakeCache(installData + "/.qmake.cache");