QtSupport: Cache Qt Version information

Change-Id: Iabdd4f880e492fe5ab7ee6d633c8f1f70b4c2cb8
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Marcus Tillmanns
2023-09-04 12:58:19 +02:00
parent 19aeb45abd
commit 640a4f0c9c
5 changed files with 145 additions and 30 deletions

View File

@@ -116,9 +116,9 @@ Store QnxQtVersion::toMap() const
return result; return result;
} }
void QnxQtVersion::fromMap(const Store &map, const FilePath &) void QnxQtVersion::fromMap(const Store &map, const FilePath &, bool forceRefreshCache)
{ {
QtVersion::fromMap(map); QtVersion::fromMap(map, {}, forceRefreshCache);
setSdpPath(FilePath::fromSettings(map.value(SDP_PATH_KEY))); setSdpPath(FilePath::fromSettings(map.value(SDP_PATH_KEY)));
} }

View File

@@ -28,7 +28,9 @@ public:
QString cpuDir() const; QString cpuDir() const;
Utils::Store toMap() const override; Utils::Store toMap() const override;
void fromMap(const Utils::Store &map, const Utils::FilePath &filePath) override; void fromMap(const Utils::Store &map,
const Utils::FilePath &filePath,
bool forceRefreshCache) override;
ProjectExplorer::Abis detectQtAbis() const override; ProjectExplorer::Abis detectQtAbis() const override;

View File

@@ -33,6 +33,7 @@
#include <utils/fileinprojectfinder.h> #include <utils/fileinprojectfinder.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/macroexpander.h> #include <utils/macroexpander.h>
#include <utils/persistentcachestore.h>
#include <utils/process.h> #include <utils/process.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/stringutils.h> #include <utils/stringutils.h>
@@ -76,6 +77,9 @@ const char MKSPEC_VALUE_NAMESPACE[] = "QT_NAMESPACE";
class QtVersionData class QtVersionData
{ {
public: public:
// Update version if you add data members!
static const int version = 1;
bool installed = true; bool installed = true;
bool hasExamples = false; bool hasExamples = false;
bool hasDemos = false; bool hasDemos = false;
@@ -111,6 +115,102 @@ public:
Utils::FilePath hostPrefixPath; Utils::FilePath hostPrefixPath;
Abis qtAbis; Abis qtAbis;
QHash<ProKey, ProString> versionInfo;
bool versionInfoUpToDate = false;
static QHash<ProKey, ProString> fromVariantMap(const QVariantMap &map)
{
QHash<ProKey, ProString> result;
for (auto it = map.constBegin(); it != map.constEnd(); ++it)
result.insert(ProKey(it.key()), ProString(it.value().toString()));
return result;
}
static QVariantMap toVariantMap(const QHash<ProKey, ProString> &map)
{
QVariantMap result;
for (auto it = map.constBegin(); it != map.constEnd(); ++it)
result.insert(it.key().toQString(), it.value().toQString());
return result;
}
Store toMap()
{
Store result;
result.insert("CacheDataVersion", version);
result.insert("Installed", installed);
result.insert("HasExamples", hasExamples);
result.insert("HasDemos", hasDemos);
result.insert("HasDocumentation", hasDocumentation);
result.insert("HasQtAbis", hasQtAbis);
result.insert("VersionInfoUpToDate", versionInfoUpToDate);
unexpandedDisplayName.toMap(result, "UnexpandedDisplayName");
result.insert("QtVersionString", qtVersionString);
result.insert("SourcePath", sourcePath.toSettings());
result.insert("QtSources", qtSources.toSettings());
result.insert("Prefix", prefix.toSettings());
result.insert("BinPath", binPath.toSettings());
result.insert("LibExecPath", libExecPath.toSettings());
result.insert("ConfigurationPath", configurationPath.toSettings());
result.insert("DataPath", dataPath.toSettings());
result.insert("DemosPath", demosPath.toSettings());
result.insert("DocsPath", docsPath.toSettings());
result.insert("ExamplesPath", examplesPath.toSettings());
result.insert("HeaderPath", headerPath.toSettings());
result.insert("ImportsPath", importsPath.toSettings());
result.insert("LibraryPath", libraryPath.toSettings());
result.insert("PluginPath", pluginPath.toSettings());
result.insert("QmlPath", qmlPath.toSettings());
result.insert("TranslationsPath", translationsPath.toSettings());
result.insert("HostBinPath", hostBinPath.toSettings());
result.insert("HostLibexecPath", hostLibexecPath.toSettings());
result.insert("HostDataPath", hostDataPath.toSettings());
result.insert("HostPrefixPath", hostPrefixPath.toSettings());
result.insert("QtAbis", Utils::transform(qtAbis, &Abi::toString));
result.insert("VersionInfo", toVariantMap(versionInfo));
return result;
}
void fromMap(Store map)
{
if (map.value("CacheDataVersion").toInt() < version)
return;
installed = map.value("Installed").toBool();
hasExamples = map.value("HasExamples").toBool();
hasDemos = map.value("HasDemos").toBool();
hasDocumentation = map.value("HasDocumentation").toBool();
hasQtAbis = map.value("HasQtAbis").toBool();
versionInfoUpToDate = map.value("VersionInfoUpToDate", false).toBool();
unexpandedDisplayName.fromMap(map, "UnexpandedDisplayName");
qtVersionString = map.value("QtVersionString").toString();
sourcePath = FilePath::fromSettings(map.value("SourcePath"));
qtSources = FilePath::fromSettings(map.value("QtSources"));
prefix = FilePath::fromSettings(map.value("Prefix"));
binPath = FilePath::fromSettings(map.value("BinPath"));
libExecPath = FilePath::fromSettings(map.value("LibExecPath"));
configurationPath = FilePath::fromSettings(map.value("ConfigurationPath"));
dataPath = FilePath::fromSettings(map.value("DataPath"));
demosPath = FilePath::fromSettings(map.value("DemosPath"));
docsPath = FilePath::fromSettings(map.value("DocsPath"));
examplesPath = FilePath::fromSettings(map.value("ExamplesPath"));
headerPath = FilePath::fromSettings(map.value("HeaderPath"));
importsPath = FilePath::fromSettings(map.value("ImportsPath"));
libraryPath = FilePath::fromSettings(map.value("LibraryPath"));
pluginPath = FilePath::fromSettings(map.value("PluginPath"));
qmlPath = FilePath::fromSettings(map.value("QmlPath"));
translationsPath = FilePath::fromSettings(map.value("TranslationsPath"));
hostBinPath = FilePath::fromSettings(map.value("HostBinPath"));
hostLibexecPath = FilePath::fromSettings(map.value("HostLibexecPath"));
hostDataPath = FilePath::fromSettings(map.value("HostDataPath"));
hostPrefixPath = FilePath::fromSettings(map.value("HostPrefixPath"));
qtAbis = Utils::transform(map.value("QtAbis").toStringList(), &Abi::fromString);
versionInfo = fromVariantMap(map.value("VersionInfo").toMap());
}
}; };
// -------------------------------------------------------------------- // --------------------------------------------------------------------
@@ -211,7 +311,6 @@ public:
bool m_defaultConfigIsDebug = true; bool m_defaultConfigIsDebug = true;
bool m_defaultConfigIsDebugAndRelease = true; bool m_defaultConfigIsDebugAndRelease = true;
bool m_frameworkBuild = false; bool m_frameworkBuild = false;
bool m_versionInfoUpToDate = false;
bool m_qmakeIsExecutable = true; bool m_qmakeIsExecutable = true;
QString m_detectionSource; QString m_detectionSource;
@@ -222,8 +321,6 @@ public:
QHash<QString, QString> m_mkspecValues; QHash<QString, QString> m_mkspecValues;
QHash<ProKey, ProString> m_versionInfo;
FilePath m_qmakeCommand; FilePath m_qmakeCommand;
FilePath m_rccPath; FilePath m_rccPath;
@@ -585,8 +682,8 @@ FilePath QtVersion::mkspecsPath() const
{ {
const FilePath result = hostDataPath(); const FilePath result = hostDataPath();
if (result.isEmpty()) if (result.isEmpty())
return FilePath::fromUserInput(QtVersionPrivate::qmakeProperty( return FilePath::fromUserInput(
d->m_versionInfo, "QMAKE_MKSPECS")); QtVersionPrivate::qmakeProperty(d->m_data.versionInfo, "QMAKE_MKSPECS"));
return result.pathAppended("mkspecs"); return result.pathAppended("mkspecs");
} }
@@ -640,7 +737,7 @@ bool QtVersion::hasReleaseBuild() const
return !d->m_defaultConfigIsDebug || d->m_defaultConfigIsDebugAndRelease; return !d->m_defaultConfigIsDebug || d->m_defaultConfigIsDebugAndRelease;
} }
void QtVersion::fromMap(const Store &map, const FilePath &filePath) void QtVersion::fromMap(const Store &map, const FilePath &filePath, bool forceRefreshCache)
{ {
d->m_id = map.value(Constants::QTVERSIONID).toInt(); d->m_id = map.value(Constants::QTVERSIONID).toInt();
if (d->m_id == -1) // this happens on adding from installer, see updateFromInstaller => get a new unique id if (d->m_id == -1) // this happens on adding from installer, see updateFromInstaller => get a new unique id
@@ -667,15 +764,21 @@ void QtVersion::fromMap(const Store &map, const FilePath &filePath)
} }
d->m_qmakeCommand = filePath.resolvePath(d->m_qmakeCommand); d->m_qmakeCommand = filePath.resolvePath(d->m_qmakeCommand);
d->m_data.qtSources = FilePath::fromSettings(map.value(QTVERSIONSOURCEPATH)); const expected_str<Utils::Store> persistentStore = PersistentCacheStore::byKey(
"QtVersionData" + d->m_qmakeCommand.toString().toUtf8());
// Handle ABIs provided by the SDKTool: if (persistentStore && !forceRefreshCache) {
// Note: Creator does not write these settings itself, so it has to come from the SDKTool! d->m_data.fromMap(*persistentStore);
d->m_data.qtAbis = Utils::transform<Abis>(map.value(QTVERSION_ABIS).toStringList(), } else {
&Abi::fromString); d->m_data.qtSources = FilePath::fromSettings(map.value(QTVERSIONSOURCEPATH));
d->m_data.qtAbis = Utils::filtered(d->m_data.qtAbis, &Abi::isValid);
d->m_data.hasQtAbis = !d->m_data.qtAbis.isEmpty();
// Handle ABIs provided by the SDKTool:
// Note: Creator does not write these settings itself, so it has to come from the SDKTool!
d->m_data.qtAbis = Utils::transform<Abis>(map.value(QTVERSION_ABIS).toStringList(),
&Abi::fromString);
d->m_data.qtAbis = Utils::filtered(d->m_data.qtAbis, &Abi::isValid);
d->m_data.hasQtAbis = !d->m_data.qtAbis.isEmpty();
}
updateDefaultDisplayName(); updateDefaultDisplayName();
// Clear the cached qmlscene command, it might not match the restored path anymore. // Clear the cached qmlscene command, it might not match the restored path anymore.
@@ -694,6 +797,11 @@ Store QtVersion::toMap() const
result.insert(QTVERSION_OVERRIDE_FEATURES, Utils::Id::toStringList(d->m_overrideFeatures)); result.insert(QTVERSION_OVERRIDE_FEATURES, Utils::Id::toStringList(d->m_overrideFeatures));
result.insert(QTVERSIONQMAKEPATH, qmakeFilePath().toSettings()); result.insert(QTVERSIONQMAKEPATH, qmakeFilePath().toSettings());
if (d->m_data.versionInfoUpToDate)
PersistentCacheStore::write("QtVersionData" + d->m_qmakeCommand.toString().toUtf8(),
d->m_data.toMap());
return result; return result;
} }
@@ -738,8 +846,8 @@ QStringList QtVersion::warningReason() const
QStringList ret; QStringList ret;
if (qtAbis().isEmpty()) if (qtAbis().isEmpty())
ret << Tr::tr("ABI detection failed: Make sure to use a matching compiler when building."); ret << Tr::tr("ABI detection failed: Make sure to use a matching compiler when building.");
if (d->m_versionInfo.value(ProKey("QT_INSTALL_PREFIX/get")) if (d->m_data.versionInfo.value(ProKey("QT_INSTALL_PREFIX/get"))
!= d->m_versionInfo.value(ProKey("QT_INSTALL_PREFIX"))) { != d->m_data.versionInfo.value(ProKey("QT_INSTALL_PREFIX"))) {
ret << Tr::tr("Non-installed -prefix build - for internal development only."); ret << Tr::tr("Non-installed -prefix build - for internal development only.");
} }
return ret; return ret;
@@ -919,7 +1027,7 @@ FilePath QtVersion::sourcePath() const
{ {
if (d->m_data.sourcePath.isEmpty()) { if (d->m_data.sourcePath.isEmpty()) {
d->updateVersionInfo(); d->updateVersionInfo();
d->m_data.sourcePath = QtVersionPrivate::sourcePath(d->m_versionInfo); d->m_data.sourcePath = QtVersionPrivate::sourcePath(d->m_data.versionInfo);
} }
return d->m_data.sourcePath; return d->m_data.sourcePath;
} }
@@ -1232,19 +1340,19 @@ QVersionNumber QtVersion::qtVersion() const
void QtVersionPrivate::updateVersionInfo() void QtVersionPrivate::updateVersionInfo()
{ {
if (m_versionInfoUpToDate || !m_qmakeIsExecutable || m_isUpdating) if (m_data.versionInfoUpToDate || !m_qmakeIsExecutable || m_isUpdating)
return; return;
m_isUpdating = true; m_isUpdating = true;
// extract data from qmake executable // extract data from qmake executable
m_versionInfo.clear(); m_data.versionInfo.clear();
m_data.installed = true; m_data.installed = true;
m_data.hasExamples = false; m_data.hasExamples = false;
m_data.hasDocumentation = false; m_data.hasDocumentation = false;
QString error; QString error;
if (!queryQMakeVariables(m_qmakeCommand, q->qmakeRunEnvironment(), &m_versionInfo, &error)) { if (!queryQMakeVariables(m_qmakeCommand, q->qmakeRunEnvironment(), &m_data.versionInfo, &error)) {
m_qmakeIsExecutable = false; m_qmakeIsExecutable = false;
qWarning("Cannot update Qt version information from %s: %s.", qWarning("Cannot update Qt version information from %s: %s.",
qPrintable(m_qmakeCommand.displayName()), qPrintable(error)); qPrintable(m_qmakeCommand.displayName()), qPrintable(error));
@@ -1297,13 +1405,16 @@ void QtVersionPrivate::updateVersionInfo()
m_data.qtVersionString = qmakeProperty("QT_VERSION"); m_data.qtVersionString = qmakeProperty("QT_VERSION");
m_isUpdating = false; m_isUpdating = false;
m_versionInfoUpToDate = true; m_data.versionInfoUpToDate = true;
PersistentCacheStore::write("QtVersionData" + m_qmakeCommand.toString().toUtf8(),
m_data.toMap());
} }
QHash<ProKey,ProString> QtVersionPrivate::versionInfo() QHash<ProKey,ProString> QtVersionPrivate::versionInfo()
{ {
updateVersionInfo(); updateVersionInfo();
return m_versionInfo; return m_data.versionInfo;
} }
QString QtVersionPrivate::qmakeProperty(const QHash<ProKey, ProString> &versionInfo, QString QtVersionPrivate::qmakeProperty(const QHash<ProKey, ProString> &versionInfo,
@@ -1765,7 +1876,7 @@ QString QtVersionPrivate::qmakeProperty(const QByteArray &name,
QtVersionPrivate::PropertyVariant variant) QtVersionPrivate::PropertyVariant variant)
{ {
updateVersionInfo(); updateVersionInfo();
return qmakeProperty(m_versionInfo, name, variant); return qmakeProperty(m_data.versionInfo, name, variant);
} }
FilePath QtVersionPrivate::mkspecDirectoryFromVersionInfo(const QHash<ProKey, ProString> &versionInfo, FilePath QtVersionPrivate::mkspecDirectoryFromVersionInfo(const QHash<ProKey, ProString> &versionInfo,
@@ -2340,13 +2451,13 @@ QtVersion *QtVersionFactory::create() const
return version; return version;
} }
QtVersion *QtVersion::clone() const QtVersion *QtVersion::clone(bool forceRefreshCache) const
{ {
for (QtVersionFactory *factory : std::as_const(g_qtVersionFactories)) { for (QtVersionFactory *factory : std::as_const(g_qtVersionFactories)) {
if (factory->m_supportedType == d->m_type) { if (factory->m_supportedType == d->m_type) {
QtVersion *version = factory->create(); QtVersion *version = factory->create();
QTC_ASSERT(version, return nullptr); QTC_ASSERT(version, return nullptr);
version->fromMap(toMap()); version->fromMap(toMap(), {}, forceRefreshCache);
return version; return version;
} }
} }

View File

@@ -49,7 +49,9 @@ public:
virtual ~QtVersion(); virtual ~QtVersion();
virtual void fromMap(const Utils::Store &map, const Utils::FilePath &filePath = {}); virtual void fromMap(const Utils::Store &map,
const Utils::FilePath &filePath = {},
bool forceRefreshCache = false);
virtual bool equals(QtVersion *other); virtual bool equals(QtVersion *other);
bool isAutodetected() const; bool isAutodetected() const;
@@ -221,7 +223,7 @@ private:
friend class Internal::QtOptionsPageWidget; friend class Internal::QtOptionsPageWidget;
void setId(int id); void setId(int id);
QtVersion *clone() const; QtVersion *clone(bool forceRefreshCache = false) const;
Internal::QtVersionPrivate *d = nullptr; Internal::QtVersionPrivate *d = nullptr;
}; };

View File

@@ -599,7 +599,7 @@ void QtOptionsPageWidget::updateQtVersions(const QList<int> &additions, const QL
// Add changed/added items: // Add changed/added items:
for (int a : std::as_const(toAdd)) { for (int a : std::as_const(toAdd)) {
QtVersion *version = QtVersionManager::version(a)->clone(); QtVersion *version = QtVersionManager::version(a)->clone(true);
auto *item = new QtVersionItem(version); auto *item = new QtVersionItem(version);
// Insert in the right place: // Insert in the right place: