From 562c5774e3faabaad58f5d36a4487bb0397369bd Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 15 Jun 2023 11:38:21 +0200 Subject: [PATCH] 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: Reviewed-by: David Schulz --- src/plugins/debugger/debuggerengine.h | 1 + src/plugins/debugger/debuggerruncontrol.cpp | 4 +- .../debuggersourcepathmappingwidget.cpp | 37 ++----------------- src/plugins/qtsupport/baseqtversion.cpp | 18 ++++++++- 4 files changed, 24 insertions(+), 36 deletions(-) diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 783fa9b9f17..cc6baf32d28 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -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; diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index e3feb04e393..ed4a34f3067 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -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()) { if (!aspect->useCppDebugger) diff --git a/src/plugins/debugger/debuggersourcepathmappingwidget.cpp b/src/plugins/debugger/debuggersourcepathmappingwidget.cpp index 9d3af533bcc..0c98ba174b0 100644 --- a/src/plugins/debugger/debuggersourcepathmappingwidget.cpp +++ b/src/plugins/debugger/debuggersourcepathmappingwidget.cpp @@ -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; } diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index d6f2efacefc..dfc85ec0c77 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -1861,9 +1861,23 @@ FilePath QtVersionPrivate::mkspecFromVersionInfo(const QHash FilePath QtVersionPrivate::sourcePath(const QHash &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");