Hi, I'm one of the Qt+KDE package maintainers for openSUSE. For making sure that all shipped .qml files have their imports available, during package build we generate a list of provided and required capabilities for packages including .qml and qmldir files. Those are used by RPM and package management tools for dependency resolution. In practice it looks like this:
qtgraphicaleffects 5.15 provides qt5qmlimport(QtGraphicalEffects.1) = 15 qtquickcontrols2 5.15 requires qt5qmlimport(QtGraphicalEffects.1) >= 12 So simply because a .qml file in the qtquickcontrols2 package contains "import QtGraphicalEffects 1.12", it automatically pulls in qtgraphicaleffects in the right version. [1] has a more in-depth explanation on how the capabilities are designed and implemented. Generating the list of required QML imports is easy: For each .qml file just run qmlimportscanner and put it into a format which RPM understands. The biggest hurdle here is to decide which Qt version a .qml file will be used with during runtime, as this decides for instance whether qtquickcontrols2 from Qt 5 or Qt 6 is needed. Finding out what a QML module provides is much harder. The task is basically: Given a qmldir file, find out which import statements it can satisfy (including version). This is pretty much the QML engine's import resolution in reverse. For simple qmldir files which just reference components written in QML, the information is directly available: For each major version, get the highest minor version. Once plugins are involved, it gets more complex. The version information is now contained in code with arbitrary logic, so the only way to get to it is by loading the plugin and executing the registration code. qmlplugindump works like that, but it's unfortunately not suitable for this. It needs both the URI and major.minor versions, but the task is to find out the available versions in the first place. Additionally, the information it dumps lacks some important aspects of registration, like for instance the versions passed to qmlRegisterModule, which can bump the maximum available minor version without registering a type for it. This is for instance how qtquickcontrols2 5.14 achieves that it can be imported as 5.14, even if no new features were added for that minor version bump. Without being aware of such calls, the generated capability would only express "qt5qmlimport(QtQuick.Controls.2) >= 13". To get around the restrictions of qmlplugindump, I wrote a custom program [2] which uses the private API (yuck) to load a plugin and get all available URIs and versions. It also catches qmlRegisterModule manually. Is there already a better way to do this? If not, could it maybe be added to qmlplugindump? This mechanism is used for package builds in openSUSE Tumbleweed for a few months now and thus pretty much left the PoC phase. So I'd like to get at least some parts of this upstream, if possible. [1] Documentation of how the capabilities work: https://build.opensuse.org/package/view_file/openSUSE:Factory/qml-autoreqprov/README?expand=1 [2] Current program used to dump available exports: https://build.opensuse.org/package/view_file/openSUSE:Factory/qmlpluginexports/qmlpluginexports.cpp?expand=1 Cheers, Fabian _______________________________________________ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest