qt5, qt6: use versioned QML import paths in wrappers

Qt is smart enough to figure out the target Qt version for native plugins.
However, Qt is _not_ smart enough to figure out the target Qt version for
QML imports, which causes all kinds of funny breakage when you start running
Qt 5 applications from Qt 6 ones and vice versa.

So, do some minimally invasive surgery to make different Qt versions pick up
different QML import path variables, so they don't mess with each other.

This is kind of very cursed, but what can you do.
This commit is contained in:
K900 2024-01-17 11:26:21 +03:00
parent e73431e32f
commit ee70129510
6 changed files with 51 additions and 2 deletions

View File

@ -51,6 +51,8 @@ let
./qtdeclarative.patch
# prevent headaches from stale qmlcache data
./qtdeclarative-default-disable-qmlcache.patch
# add version specific QML import path
./qtdeclarative-qml-paths.patch
];
qtlocation = lib.optionals stdenv.cc.isClang [
# Fix build with Clang 16

View File

@ -0,0 +1,33 @@
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 289f11d006..80c422403c 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -1897,17 +1897,22 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e)
addImportPath(installImportsPath);
// env import paths
- if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QML2_IMPORT_PATH"))) {
- const QString envImportPath = qEnvironmentVariable("QML2_IMPORT_PATH");
+ auto addEnvImportPath = [this](const char *var) {
#if defined(Q_OS_WIN)
QLatin1Char pathSep(';');
#else
QLatin1Char pathSep(':');
#endif
- QStringList paths = envImportPath.split(pathSep, Qt::SkipEmptyParts);
- for (int ii = paths.count() - 1; ii >= 0; --ii)
- addImportPath(paths.at(ii));
- }
+ if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty(var))) {
+ const QString envImportPath = qEnvironmentVariable(var);
+ QStringList paths = envImportPath.split(pathSep, Qt::SkipEmptyParts);
+ for (int ii = paths.count() - 1; ii >= 0; --ii)
+ addImportPath(paths.at(ii));
+ }
+ };
+
+ addEnvImportPath("NIXPKGS_QT5_QML_IMPORT_PATH");
+ addEnvImportPath("QML2_IMPORT_PATH");
addImportPath(QStringLiteral("qrc:/qt-project.org/imports"));
addImportPath(QCoreApplication::applicationDirPath());

View File

@ -31,7 +31,7 @@ qtHostPathHook() {
local qmlDir="$1/${qtQmlPrefix:?}"
if [ -d "$qmlDir" ]
then
qtWrapperArgs+=(--prefix QML2_IMPORT_PATH : "$qmlDir")
qtWrapperArgs+=(--prefix NIXPKGS_QT5_QML_IMPORT_PATH : "$qmlDir")
fi
}
addEnvHooks "$targetOffset" qtHostPathHook

View File

@ -31,7 +31,7 @@ if [[ -z "${__nix_wrapQtAppsHook-}" ]]; then
local qmlDir="$1/${qtQmlPrefix:?}"
if [ -d "$qmlDir" ]; then
qtWrapperArgs+=(--prefix QML2_IMPORT_PATH : "$qmlDir")
qtWrapperArgs+=(--prefix NIXPKGS_QT6_QML_IMPORT_PATH : "$qmlDir")
fi
}
addEnvHooks "$targetOffset" qtHostPathHook

View File

@ -12,5 +12,7 @@ qtModule {
patches = [
# prevent headaches from stale qmlcache data
../patches/qtdeclarative-default-disable-qmlcache.patch
# add version specific QML import path
../patches/qtdeclarative-qml-paths.patch
];
}

View File

@ -0,0 +1,12 @@
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index a7d1a3f77f..aac7392d4f 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -1515,6 +1515,7 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e)
};
// env import paths
+ addEnvImportPath("NIXPKGS_QT6_QML_IMPORT_PATH");
addEnvImportPath("QML_IMPORT_PATH");
addEnvImportPath("QML2_IMPORT_PATH");