qt.conf: add private "merge_qt_conf" option

This is meant to allow the buildsystem to add additional paths (for e.g.
QML imports) while still allowing the application to pick up the paths
where e.g. Qt's plugins are located – without having to query qtpaths or
the build system to locate them first, and to then also add them to
qt.conf.
QLibraryInfo::paths will return a list containing any values provided in
qt.conf, followed by the value that would have been provided if there
were no qt.conf file.
If no value is provided at all for a given key in qt.conf,
QLibraryInfo::path will behave as if no qt.conf file was provided,
instead of using LocationInfo::defaultValue.

For now, this is considered to be internal only, and won't be
documented.

Change-Id: Ic74c66b5cbde605b43336cd88c3f909999381f46
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
This commit is contained in:
Fabian Kosmale 2024-05-15 17:14:13 +02:00
parent 59b7e143a9
commit 5573ca3599
4 changed files with 44 additions and 4 deletions

View File

@ -566,6 +566,17 @@ static QString normalizePath(QString ret)
return QDir::fromNativeSeparators(ret);
};
static bool keepQtBuildDefaults()
{
#if QT_CONFIG(settings)
QSettings *config = QLibraryInfoPrivate::configuration();
Q_ASSERT(config != nullptr);
return config->value("Config/MergeQtConf", false).toBool();
#else
return false;
#endif
}
#if QT_CONFIG(settings)
static QVariant libraryPathToValue(QLibraryInfo::LibraryPath loc)
{
@ -575,21 +586,26 @@ static QVariant libraryPathToValue(QLibraryInfo::LibraryPath loc)
return value;
QSettings *config = QLibraryInfoPrivate::configuration();
Q_ASSERT(config != nullptr);
// if keepQtBuildDefaults returns true,
// we only consider explicit values listed in qt.conf
QVariant defaultValue = keepQtBuildDefaults()
? QVariant()
: QVariant(li.defaultValue);
config->beginGroup("Paths"_L1);
auto cleanup = qScopeGuard([&]() { config->endGroup(); });
if (li.fallbackKey.isNull()) {
value = config->value(li.key, li.defaultValue);
value = config->value(li.key, defaultValue);
} else {
value = config->value(li.key);
if (!value.isValid())
value = config->value(li.fallbackKey, li.defaultValue);
value = config->value(li.fallbackKey, defaultValue);
}
return value;
}
#endif // settings
QStringList QLibraryInfoPrivate::paths(QLibraryInfo::LibraryPath p,
QLibraryInfoPrivate::UsageMode usageMode)
UsageMode usageMode)
{
const QLibraryInfo::LibraryPath loc = p;
QList<QString> ret;
@ -611,7 +627,7 @@ QStringList QLibraryInfoPrivate::paths(QLibraryInfo::LibraryPath p,
}
#endif // settings
if (!fromConf) {
if (!fromConf || keepQtBuildDefaults()) {
QString noConfResult;
if (loc == QLibraryInfo::PrefixPath) {
noConfResult = getPrefix(usageMode);

View File

@ -20,4 +20,5 @@ qt_add_resources(tst_qlibraryinfo "qtconffiles"
empty.qt.conf
partial.qt.conf
list.qt.conf
merge.qt.conf
)

View File

@ -0,0 +1,5 @@
[Paths]
QmlImports = "/path/to/myqml"
[Config]
MergeQtConf=true

View File

@ -16,6 +16,7 @@ private slots:
void path_data();
void path();
void paths();
void merge();
};
void tst_QLibraryInfo::initTestCase()
@ -80,6 +81,23 @@ void tst_QLibraryInfo::paths()
QCOMPARE(values[2], baseDir + "/relativePath");
}
void tst_QLibraryInfo::merge()
{
QString qtConfPath(u":/merge.qt.conf");
QLibraryInfoPrivate::setQtconfManualPath(&qtConfPath);
QLibraryInfoPrivate::reload();
QString baseDir = QCoreApplication::applicationDirPath();
QString docPath = QLibraryInfo::path(QLibraryInfo::DocumentationPath);
// we can't know where exactly the doc path points, but it should not point to ${baseDir}/doc,
// which would be the behavior without merge_qt_conf
QCOMPARE_NE(docPath, baseDir + "/doc");
QList<QString> values = QLibraryInfo::paths(QLibraryInfo::QmlImportsPath);
QCOMPARE(values.size(), 2); // custom entry + Qt default entry
QCOMPARE(values[0], "/path/to/myqml");
}
QTEST_GUILESS_MAIN(tst_QLibraryInfo)
#include "tst_qlibraryinfo.moc"