ProjectExplorer: Collect and remember non-functional toolchains

It's not unusual for the toolchain auto-detection procedure to encounter
binaries that turn out not to be valid toolchains only after running
them, either because they are genuinely broken or because their names
match a compiler name pattern, but they are not actually compilers.
Until now, we would re-run such executables on every start of Qt
Creator, potentially delaying start-up unnecessarily.
Now we store them in the settings and do not try to run them again.
For now, the collection of bad toolchains is done for GCC only. Follow-
up patches will add support for more toolchain types.

Change-Id: Icfa28de523737bdd88af3a2bfa8b947326c1bc70
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2022-01-18 15:42:02 +01:00
parent 5c98d40901
commit 16ef8b6253
6 changed files with 129 additions and 5 deletions

View File

@@ -39,6 +39,8 @@
#include <QFileInfo>
#include <QUuid>
#include <utility>
using namespace Utils;
static const char ID_KEY[] = "ProjectExplorer.ToolChain.Id";
@@ -652,4 +654,62 @@ ToolchainDetector::ToolchainDetector(const Toolchains &alreadyKnown, const IDevi
: alreadyKnown(alreadyKnown), device(device)
{}
BadToolchain::BadToolchain(const Utils::FilePath &filePath)
: BadToolchain(filePath, filePath.symLinkTarget(), filePath.lastModified())
{}
BadToolchain::BadToolchain(const Utils::FilePath &filePath, const Utils::FilePath &symlinkTarget,
const QDateTime &timestamp)
: filePath(filePath), symlinkTarget(symlinkTarget), timestamp(timestamp)
{}
static QString badToolchainFilePathKey() { return {"FilePath"}; }
static QString badToolchainSymlinkTargetKey() { return {"TargetFilePath"}; }
static QString badToolchainTimestampKey() { return {"Timestamp"}; }
QVariantMap BadToolchain::toMap() const
{
return {
std::make_pair(badToolchainFilePathKey(), filePath.toVariant()),
std::make_pair(badToolchainSymlinkTargetKey(), symlinkTarget.toVariant()),
std::make_pair(badToolchainTimestampKey(), timestamp.toMSecsSinceEpoch()),
};
}
BadToolchain BadToolchain::fromMap(const QVariantMap &map)
{
return {
FilePath::fromVariant(map.value(badToolchainFilePathKey())),
FilePath::fromVariant(map.value(badToolchainSymlinkTargetKey())),
QDateTime::fromMSecsSinceEpoch(map.value(badToolchainTimestampKey()).toLongLong())
};
}
BadToolchains::BadToolchains(const QList<BadToolchain> &toolchains)
: toolchains(Utils::filtered(toolchains, [](const BadToolchain &badTc) {
return badTc.filePath.lastModified() == badTc.timestamp
&& badTc.filePath.symLinkTarget() == badTc.symlinkTarget;
}))
{}
bool BadToolchains::isBadToolchain(const FilePath &toolchain) const
{
return Utils::contains(toolchains, [toolchain](const BadToolchain &badTc) {
return badTc.filePath == toolchain.absoluteFilePath()
|| badTc.symlinkTarget == toolchain.absoluteFilePath();
});
}
QVariant BadToolchains::toVariant() const
{
return Utils::transform<QVariantList>(toolchains, &BadToolchain::toMap);
}
BadToolchains BadToolchains::fromVariant(const QVariant &v)
{
return Utils::transform<QList<BadToolchain>>(v.toList(),
[](const QVariant &e) { return BadToolchain::fromMap(e.toMap()); });
}
} // namespace ProjectExplorer