forked from qt-creator/qt-creator
Docker: Provide a means to select search paths for auto-detection
A combobox in the device dialog to select between the (docker image's) system path and a semicolon-separated set of user defined paths. Use it for cmake and gdb detection; qmake and toolchains currently missing. Change-Id: I3c478ca914a1bf02dcb69ebcb9ea6e358d24aaf9 Reviewed-by: David Schulz <david.schulz@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -180,15 +180,14 @@ void CMakeToolManager::updateDocumentation()
|
|||||||
Core::HelpManager::registerDocumentation(docs);
|
Core::HelpManager::registerDocumentation(docs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeToolManager::autoDetectCMakeForDevice(const FilePath &deviceRoot,
|
void CMakeToolManager::autoDetectCMakeForDevice(const FilePaths &searchPaths,
|
||||||
const QString &detectionSource,
|
const QString &detectionSource,
|
||||||
QString *logMessage)
|
QString *logMessage)
|
||||||
{
|
{
|
||||||
QStringList messages{tr("Searching CMake binaries...")};
|
QStringList messages{tr("Searching CMake binaries...")};
|
||||||
const FilePaths candidates = {deviceRoot.withNewPath("cmake")};
|
for (const FilePath &path : searchPaths) {
|
||||||
for (const FilePath &candidate : candidates) {
|
const FilePath cmake = path.pathAppended("cmake").withExecutableSuffix();
|
||||||
const FilePath cmake = candidate.searchInPath();
|
if (cmake.isExecutableFile()) {
|
||||||
if (!cmake.isEmpty()) {
|
|
||||||
registerCMakeByPath(cmake, detectionSource);
|
registerCMakeByPath(cmake, detectionSource);
|
||||||
messages.append(tr("Found \"%1\"").arg(cmake.toUserOutput()));
|
messages.append(tr("Found \"%1\"").arg(cmake.toUserOutput()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public:
|
|||||||
static void updateDocumentation();
|
static void updateDocumentation();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void autoDetectCMakeForDevice(const Utils::FilePath &deviceRoot,
|
void autoDetectCMakeForDevice(const Utils::FilePaths &searchPaths,
|
||||||
const QString &detectionSource,
|
const QString &detectionSource,
|
||||||
QString *logMessage);
|
QString *logMessage);
|
||||||
void registerCMakeByPath(const Utils::FilePath &cmakePath,
|
void registerCMakeByPath(const Utils::FilePath &cmakePath,
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ public:
|
|||||||
QVariant registerDebugger(const DebuggerItem &item);
|
QVariant registerDebugger(const DebuggerItem &item);
|
||||||
void readDebuggers(const FilePath &fileName, bool isSystem);
|
void readDebuggers(const FilePath &fileName, bool isSystem);
|
||||||
void autoDetectCdbDebuggers();
|
void autoDetectCdbDebuggers();
|
||||||
void autoDetectGdbOrLldbDebuggers(const FilePath &deviceRoot,
|
void autoDetectGdbOrLldbDebuggers(const FilePaths &searchPaths,
|
||||||
const QString &detectionSource,
|
const QString &detectionSource,
|
||||||
QString *logMessage = nullptr);
|
QString *logMessage = nullptr);
|
||||||
void autoDetectUvscDebuggers();
|
void autoDetectUvscDebuggers();
|
||||||
@@ -724,7 +724,7 @@ static Utils::FilePaths searchGdbPathsFromRegistry()
|
|||||||
return searchPaths;
|
return searchPaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerItemManagerPrivate::autoDetectGdbOrLldbDebuggers(const FilePath &deviceRoot,
|
void DebuggerItemManagerPrivate::autoDetectGdbOrLldbDebuggers(const FilePaths &searchPaths,
|
||||||
const QString &detectionSource,
|
const QString &detectionSource,
|
||||||
QString *logMessage)
|
QString *logMessage)
|
||||||
{
|
{
|
||||||
@@ -752,7 +752,10 @@ void DebuggerItemManagerPrivate::autoDetectGdbOrLldbDebuggers(const FilePath &de
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
IDevice::ConstPtr device = DeviceManager::deviceForPath(deviceRoot);
|
if (searchPaths.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
IDevice::ConstPtr device = DeviceManager::deviceForPath(searchPaths.front());
|
||||||
QTC_ASSERT(device, return);
|
QTC_ASSERT(device, return);
|
||||||
|
|
||||||
FilePaths suspects;
|
FilePaths suspects;
|
||||||
@@ -773,15 +776,14 @@ void DebuggerItemManagerPrivate::autoDetectGdbOrLldbDebuggers(const FilePath &de
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePaths paths = device->systemEnvironment().path();
|
FilePaths paths = searchPaths;
|
||||||
if (!deviceRoot.needsDevice())
|
if (!searchPaths.front().needsDevice())
|
||||||
paths.append(searchGdbPathsFromRegistry());
|
paths.append(searchGdbPathsFromRegistry());
|
||||||
|
|
||||||
paths = Utils::filteredUnique(paths);
|
paths = Utils::filteredUnique(paths);
|
||||||
|
|
||||||
for (const FilePath &path : paths) {
|
for (const FilePath &path : paths) {
|
||||||
const FilePath globalPath = path.onDevice(deviceRoot);
|
suspects.append(device->directoryEntries(path, filters, QDir::Files | QDir::Executable));
|
||||||
suspects.append(device->directoryEntries(globalPath, filters, QDir::Files | QDir::Executable));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList logMessages{tr("Searching debuggers...")};
|
QStringList logMessages{tr("Searching debuggers...")};
|
||||||
@@ -1044,11 +1046,11 @@ void DebuggerItemManager::deregisterDebugger(const QVariant &id)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerItemManager::autoDetectDebuggersForDevice(const FilePath &deviceRoot,
|
void DebuggerItemManager::autoDetectDebuggersForDevice(const FilePaths &searchPaths,
|
||||||
const QString &detectionSource,
|
const QString &detectionSource,
|
||||||
QString *logMessage)
|
QString *logMessage)
|
||||||
{
|
{
|
||||||
d->autoDetectGdbOrLldbDebuggers(deviceRoot, detectionSource, logMessage);
|
d->autoDetectGdbOrLldbDebuggers(searchPaths, detectionSource, logMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerItemManager::removeDetectedDebuggers(const QString &detectionSource,
|
void DebuggerItemManager::removeDetectedDebuggers(const QString &detectionSource,
|
||||||
|
|||||||
@@ -28,13 +28,13 @@
|
|||||||
#include "debugger_global.h"
|
#include "debugger_global.h"
|
||||||
#include "debuggerconstants.h"
|
#include "debuggerconstants.h"
|
||||||
|
|
||||||
|
#include <utils/filepath.h>
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
|
||||||
namespace Utils { class FilePath; }
|
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
|
|
||||||
class DebuggerItem;
|
class DebuggerItem;
|
||||||
@@ -52,7 +52,7 @@ public:
|
|||||||
static QVariant registerDebugger(const DebuggerItem &item);
|
static QVariant registerDebugger(const DebuggerItem &item);
|
||||||
static void deregisterDebugger(const QVariant &id);
|
static void deregisterDebugger(const QVariant &id);
|
||||||
|
|
||||||
static void autoDetectDebuggersForDevice(const Utils::FilePath &deviceRoot,
|
static void autoDetectDebuggersForDevice(const Utils::FilePaths &searchPaths,
|
||||||
const QString &detectionSource,
|
const QString &detectionSource,
|
||||||
QString *logMessage);
|
QString *logMessage);
|
||||||
static void removeDetectedDebuggers(const QString &detectionSource, QString *logMessage);
|
static void removeDetectedDebuggers(const QString &detectionSource, QString *logMessage);
|
||||||
|
|||||||
@@ -1748,11 +1748,11 @@ void DebuggerPlugin::getEnginesState(QByteArray *json) const
|
|||||||
*json = QJsonDocument(QJsonObject::fromVariantMap(result)).toJson();
|
*json = QJsonDocument(QJsonObject::fromVariantMap(result)).toJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerPlugin::autoDetectDebuggersForDevice(const FilePath &deviceRoot,
|
void DebuggerPlugin::autoDetectDebuggersForDevice(const FilePaths &searchPaths,
|
||||||
const QString &detectionSource,
|
const QString &detectionSource,
|
||||||
QString *logMessage)
|
QString *logMessage)
|
||||||
{
|
{
|
||||||
dd->m_debuggerItemManager.autoDetectDebuggersForDevice(deviceRoot, detectionSource, logMessage);
|
dd->m_debuggerItemManager.autoDetectDebuggersForDevice(searchPaths, detectionSource, logMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerPlugin::removeDetectedDebuggers(const QString &detectionSource, QString *logMessage)
|
void DebuggerPlugin::removeDetectedDebuggers(const QString &detectionSource, QString *logMessage)
|
||||||
|
|||||||
@@ -26,10 +26,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "debugger_global.h"
|
#include "debugger_global.h"
|
||||||
|
|
||||||
#include <extensionsystem/iplugin.h>
|
#include <extensionsystem/iplugin.h>
|
||||||
|
#include <utils/filepath.h>
|
||||||
|
|
||||||
namespace ProjectExplorer { class RunControl; }
|
namespace ProjectExplorer { class RunControl; }
|
||||||
namespace Utils { class FilePath; }
|
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -59,7 +60,7 @@ private:
|
|||||||
Q_SLOT void getEnginesState(QByteArray *json) const;
|
Q_SLOT void getEnginesState(QByteArray *json) const;
|
||||||
|
|
||||||
// Called from DockerDevice
|
// Called from DockerDevice
|
||||||
Q_SLOT void autoDetectDebuggersForDevice(const Utils::FilePath &deviceRoot,
|
Q_SLOT void autoDetectDebuggersForDevice(const Utils::FilePaths &searchPaths,
|
||||||
const QString &detectionId,
|
const QString &detectionId,
|
||||||
QString *logMessage);
|
QString *logMessage);
|
||||||
Q_SLOT void removeDetectedDebuggers(const QString &detectionId, QString *logMessage);
|
Q_SLOT void removeDetectedDebuggers(const QString &detectionId, QString *logMessage);
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
|
#include <QComboBox>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
@@ -262,6 +263,10 @@ public:
|
|||||||
void undoAutoDetect() const;
|
void undoAutoDetect() const;
|
||||||
void listAutoDetected() const;
|
void listAutoDetected() const;
|
||||||
|
|
||||||
|
void setSharedId(const QString &sharedId) { m_sharedId = sharedId; }
|
||||||
|
void setSearchPaths(const FilePaths &searchPaths) { m_searchPaths = searchPaths; }
|
||||||
|
|
||||||
|
private:
|
||||||
QList<BaseQtVersion *> autoDetectQtVersions() const;
|
QList<BaseQtVersion *> autoDetectQtVersions() const;
|
||||||
QList<ToolChain *> autoDetectToolChains();
|
QList<ToolChain *> autoDetectToolChains();
|
||||||
void autoDetectCMake();
|
void autoDetectCMake();
|
||||||
@@ -270,6 +275,7 @@ public:
|
|||||||
KitDetector *q;
|
KitDetector *q;
|
||||||
IDevice::ConstPtr m_device;
|
IDevice::ConstPtr m_device;
|
||||||
QString m_sharedId;
|
QString m_sharedId;
|
||||||
|
FilePaths m_searchPaths;
|
||||||
};
|
};
|
||||||
|
|
||||||
KitDetector::KitDetector(const IDevice::ConstPtr &device)
|
KitDetector::KitDetector(const IDevice::ConstPtr &device)
|
||||||
@@ -281,21 +287,22 @@ KitDetector::~KitDetector()
|
|||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KitDetector::autoDetect(const QString &sharedId) const
|
void KitDetector::autoDetect(const QString &sharedId, const FilePaths &searchPaths) const
|
||||||
{
|
{
|
||||||
d->m_sharedId = sharedId;
|
d->setSharedId(sharedId);
|
||||||
|
d->setSearchPaths(searchPaths);
|
||||||
d->autoDetect();
|
d->autoDetect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KitDetector::undoAutoDetect(const QString &sharedId) const
|
void KitDetector::undoAutoDetect(const QString &sharedId) const
|
||||||
{
|
{
|
||||||
d->m_sharedId = sharedId;
|
d->setSharedId(sharedId);
|
||||||
d->undoAutoDetect();
|
d->undoAutoDetect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KitDetector::listAutoDetected(const QString &sharedId) const
|
void KitDetector::listAutoDetected(const QString &sharedId) const
|
||||||
{
|
{
|
||||||
d->m_sharedId = sharedId;
|
d->setSharedId(sharedId);
|
||||||
d->listAutoDetected();
|
d->listAutoDetected();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,10 +422,35 @@ public:
|
|||||||
auto undoAutoDetectButton = new QPushButton(tr("Remove Auto-Detected Kit Items"));
|
auto undoAutoDetectButton = new QPushButton(tr("Remove Auto-Detected Kit Items"));
|
||||||
auto listAutoDetectedButton = new QPushButton(tr("List Auto-Detected Kit Items"));
|
auto listAutoDetectedButton = new QPushButton(tr("List Auto-Detected Kit Items"));
|
||||||
|
|
||||||
connect(autoDetectButton, &QPushButton::clicked, this, [this, logView, id = data.id(), dockerDevice] {
|
auto searchDirsComboBox = new QComboBox;
|
||||||
|
searchDirsComboBox->addItem(tr("Search in PATH"));
|
||||||
|
searchDirsComboBox->addItem(tr("Search in selected directories"));
|
||||||
|
|
||||||
|
auto searchDirsLineEdit = new QLineEdit;
|
||||||
|
searchDirsLineEdit->setText("/usr/bin;/opt");
|
||||||
|
searchDirsLineEdit->setToolTip(
|
||||||
|
tr("Select the paths in the Docker image that should be scanned for Kit entries"));
|
||||||
|
|
||||||
|
auto searchPaths = [this, searchDirsComboBox, searchDirsLineEdit, dockerDevice] {
|
||||||
|
FilePaths paths;
|
||||||
|
if (searchDirsComboBox->currentIndex() == 0) {
|
||||||
|
paths = dockerDevice->systemEnvironment().path();
|
||||||
|
} else {
|
||||||
|
for (const QString &path : searchDirsLineEdit->text().split(';'))
|
||||||
|
paths.append(FilePath::fromString(path.trimmed()));
|
||||||
|
}
|
||||||
|
paths = Utils::transform(paths, [dockerDevice](const FilePath &path) {
|
||||||
|
return dockerDevice->mapToGlobalPath(path);
|
||||||
|
});
|
||||||
|
return paths;
|
||||||
|
};
|
||||||
|
|
||||||
|
connect(autoDetectButton, &QPushButton::clicked, this,
|
||||||
|
[this, logView, id = data.id(), dockerDevice, searchPaths] {
|
||||||
logView->clear();
|
logView->clear();
|
||||||
dockerDevice->tryCreateLocalFileAccess();
|
dockerDevice->tryCreateLocalFileAccess();
|
||||||
m_kitItemDetector.autoDetect(id);
|
|
||||||
|
m_kitItemDetector.autoDetect(id, searchPaths());
|
||||||
|
|
||||||
if (DockerPlugin::isDaemonRunning().value_or(false) == false)
|
if (DockerPlugin::isDaemonRunning().value_or(false) == false)
|
||||||
logView->append(tr("Docker daemon appears to be not running."));
|
logView->append(tr("Docker daemon appears to be not running."));
|
||||||
@@ -451,11 +483,27 @@ public:
|
|||||||
}, Break(),
|
}, Break(),
|
||||||
Column {
|
Column {
|
||||||
Space(20),
|
Space(20),
|
||||||
Row { autoDetectButton, undoAutoDetectButton, listAutoDetectedButton, Stretch() },
|
Row {
|
||||||
|
searchDirsComboBox,
|
||||||
|
searchDirsLineEdit
|
||||||
|
},
|
||||||
|
Row {
|
||||||
|
autoDetectButton,
|
||||||
|
undoAutoDetectButton,
|
||||||
|
listAutoDetectedButton,
|
||||||
|
Stretch(),
|
||||||
|
},
|
||||||
new QLabel(tr("Detection log:")),
|
new QLabel(tr("Detection log:")),
|
||||||
logView
|
logView
|
||||||
}
|
}
|
||||||
}.attachTo(this);
|
}.attachTo(this);
|
||||||
|
|
||||||
|
searchDirsLineEdit->setVisible(false);
|
||||||
|
auto updateDirectoriesLineEdit = [this, searchDirsLineEdit](int index) {
|
||||||
|
searchDirsLineEdit->setVisible(index == 1);
|
||||||
|
};
|
||||||
|
QObject::connect(searchDirsComboBox, qOverload<int>(&QComboBox::activated),
|
||||||
|
this, updateDirectoriesLineEdit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateDeviceFromUi() final {}
|
void updateDeviceFromUi() final {}
|
||||||
@@ -658,7 +706,7 @@ QList<BaseQtVersion *> KitDetectorPrivate::autoDetectQtVersions() const
|
|||||||
emit q->logOutput('\n' + tr("Searching Qt installations..."));
|
emit q->logOutput('\n' + tr("Searching Qt installations..."));
|
||||||
for (const QString &candidate : candidates) {
|
for (const QString &candidate : candidates) {
|
||||||
emit q->logOutput(tr("Searching for %1 executable...").arg(candidate));
|
emit q->logOutput(tr("Searching for %1 executable...").arg(candidate));
|
||||||
const FilePath qmake = m_device->searchExecutableInPath(candidate);
|
const FilePath qmake = m_device->searchExecutable(candidate, m_searchPaths);
|
||||||
if (qmake.isEmpty())
|
if (qmake.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
BaseQtVersion *qtVersion = QtVersionFactory::createQtVersionFromQMakePath(qmake, false, m_sharedId, &error);
|
BaseQtVersion *qtVersion = QtVersionFactory::createQtVersionFromQMakePath(qmake, false, m_sharedId, &error);
|
||||||
@@ -703,11 +751,10 @@ void KitDetectorPrivate::autoDetectCMake()
|
|||||||
if (!cmakeManager)
|
if (!cmakeManager)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const FilePath deviceRoot = m_device->mapToGlobalPath({});
|
|
||||||
QString logMessage;
|
QString logMessage;
|
||||||
const bool res = QMetaObject::invokeMethod(cmakeManager,
|
const bool res = QMetaObject::invokeMethod(cmakeManager,
|
||||||
"autoDetectCMakeForDevice",
|
"autoDetectCMakeForDevice",
|
||||||
Q_ARG(Utils::FilePath, deviceRoot),
|
Q_ARG(Utils::FilePaths, m_searchPaths),
|
||||||
Q_ARG(QString, m_sharedId),
|
Q_ARG(QString, m_sharedId),
|
||||||
Q_ARG(QString *, &logMessage));
|
Q_ARG(QString *, &logMessage));
|
||||||
QTC_CHECK(res);
|
QTC_CHECK(res);
|
||||||
@@ -720,11 +767,10 @@ void KitDetectorPrivate::autoDetectDebugger()
|
|||||||
if (!debuggerPlugin)
|
if (!debuggerPlugin)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const FilePath deviceRoot = m_device->mapToGlobalPath({});
|
|
||||||
QString logMessage;
|
QString logMessage;
|
||||||
const bool res = QMetaObject::invokeMethod(debuggerPlugin,
|
const bool res = QMetaObject::invokeMethod(debuggerPlugin,
|
||||||
"autoDetectDebuggersForDevice",
|
"autoDetectDebuggersForDevice",
|
||||||
Q_ARG(Utils::FilePath, deviceRoot),
|
Q_ARG(Utils::FilePaths, m_searchPaths),
|
||||||
Q_ARG(QString, m_sharedId),
|
Q_ARG(QString, m_sharedId),
|
||||||
Q_ARG(QString *, &logMessage));
|
Q_ARG(QString *, &logMessage));
|
||||||
QTC_CHECK(res);
|
QTC_CHECK(res);
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ public:
|
|||||||
explicit KitDetector(const ProjectExplorer::IDevice::ConstPtr &device);
|
explicit KitDetector(const ProjectExplorer::IDevice::ConstPtr &device);
|
||||||
~KitDetector() override;
|
~KitDetector() override;
|
||||||
|
|
||||||
void autoDetect(const QString &sharedId) const;
|
void autoDetect(const QString &sharedId, const Utils::FilePaths &selectedPaths) const;
|
||||||
void undoAutoDetect(const QString &sharedId) const;
|
void undoAutoDetect(const QString &sharedId) const;
|
||||||
void listAutoDetected(const QString &sharedId) const;
|
void listAutoDetected(const QString &sharedId) const;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user