z-applocal: Add Qt 6 plugin deployment support - #2092
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends the internal z-applocal command to deploy Qt 6 plugins in addition to the existing Qt 5 behavior, using Qt 6 module metadata (share/Qt6/modules/*.json) to determine plugin directories to copy. It also adds a Windows E2E test project and pipeline coverage to validate correct deployment for both Qt 5/6 in release/debug layouts.
Changes:
- Add Qt 6 plugin deployment logic to
z-applocal, keyed offQt6*.dllimports andshare/Qt6/modules/<Module>.jsonplugin_types. - Split existing Qt logic into Qt 5 vs Qt 6 detection paths.
- Add Windows E2E coverage and a synthetic “installed” tree to validate deployment behavior for Qt 5/6 (release/debug) and ensure the correct plugin root is used.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/vcpkg/commands.z-applocal.cpp | Adds Qt 6 plugin deployment based on Qt module JSON metadata; refactors Qt 5 handling into deployQt5() and adds deployQt6(). |
| azure-pipelines/end-to-end-tests-dir/z-applocalcpp.ps1 | Adds E2E coverage for Qt 5/Qt 6 applocal deployment (release/debug) and verifies copied-files logging. |
| azure-pipelines/e2e-projects/applocal/qt/build.bat | Builds a synthetic set of Qt-like DLLs and plugins (Qt5/Qt6, release/debug) for E2E validation. |
| azure-pipelines/e2e-projects/applocal/qt/main.cpp | Test executable importing Qt-like DLLs to trigger applocal dependency copying. |
| azure-pipelines/e2e-projects/applocal/qt/qtcore.cpp | Produces a minimal QtCore-like DLL for the E2E scenario. |
| azure-pipelines/e2e-projects/applocal/qt/qtgui.cpp | Produces a minimal QtGui-like DLL for the E2E scenario. |
| azure-pipelines/e2e-projects/applocal/qt/qtnetwork.cpp | Produces a minimal QtNetwork-like DLL for the E2E scenario. |
| azure-pipelines/e2e-projects/applocal/qt/qtprintsupport.cpp | Produces a minimal QtPrintSupport-like DLL for the E2E scenario. |
| azure-pipelines/e2e-projects/applocal/qt/qtsql.cpp | Produces a minimal QtSql-like DLL for the E2E scenario. |
| azure-pipelines/e2e-projects/applocal/qt/qtwidgets.cpp | Produces a minimal QtWidgets-like DLL for the E2E scenario. |
| azure-pipelines/e2e-projects/applocal/qt/qtplugin.cpp | Produces a minimal plugin DLL used as the source for copied plugin variants. |
| azure-pipelines/e2e-projects/applocal/qt/installed/plugins/qtdeploy.ps1 | Marker file to trigger Qt 5 deployment path in z-applocal during tests. |
| azure-pipelines/e2e-projects/applocal/qt/installed/debug/plugins/qtdeploy.ps1 | Debug marker file to trigger Qt 5 deployment path in z-applocal during tests. |
| azure-pipelines/e2e-projects/applocal/qt/installed/share/Qt6/modules/Core.json | Test Qt 6 module metadata (Core) providing plugin_types for Qt6 deployment. |
| azure-pipelines/e2e-projects/applocal/qt/installed/share/Qt6/modules/Gui.json | Test Qt 6 module metadata (Gui) providing plugin_types for Qt6 deployment. |
| azure-pipelines/e2e-projects/applocal/qt/installed/share/Qt6/modules/Network.json | Test Qt 6 module metadata (Network) providing plugin_types for Qt6 deployment. |
| azure-pipelines/e2e-projects/applocal/qt/installed/share/Qt6/modules/PrintSupport.json | Test Qt 6 module metadata (PrintSupport) providing plugin_types for Qt6 deployment. |
| azure-pipelines/e2e-projects/applocal/qt/installed/share/Qt6/modules/Sql.json | Test Qt 6 module metadata (Sql) providing plugin_types for Qt6 deployment. |
| azure-pipelines/e2e-projects/applocal/qt/installed/share/Qt6/modules/Widgets.json | Test Qt 6 module metadata (Widgets) providing plugin_types for Qt6 deployment. |
| $expectedPluginSource = Join-Path (Join-Path $qtDir $qtCase.PluginsDir) "platforms/$platformPlugin" | ||
| $unexpectedPluginSource = Join-Path (Join-Path $qtDir $qtCase.OtherPluginsDir) "platforms/$platformPlugin" |
| if (Strings::case_insensitive_ascii_starts_with(c_filename, "qwindows") && | ||
| Strings::case_insensitive_ascii_ends_with(c_filename, ".dll")) | ||
| { | ||
| deploy_binary(new_dir, qt_plugins_dir / "platforms", c_filename); | ||
| } |
|
I think not handling this was somewhat intentional because we didn't want to expand the scope of the hardcoded stuff without bound but we never got to designing the feature that was supposed to fix it for good where a port could declare with a JSON document or similar "a dependency on a.dll implies a dependency on plugins/b.dll" or something like that. We also wanted to have similar handling for the "tools" problem today where qt can get order dependent because different qt packages try to copy dependent DLLs around; also affects Python and friends. It implies needing to not have single ownership for those anymore. (To be clear, I am not saying that we should not take this, just recording the thought here while I noticed) |
I noticed this pr #2048, but currently z-applocal doesn't handle qt6 plugins, so I let gpt 5.6 sol add this
deployQt6function, and the azure-pipelines e2e tests are also generated by gpt 5.6 sol.Qt 5 / Qt 6 vcpkg Layout Comparison
qt6 metadata in
vcpkg_installed/x64-windows/share/Qt6/modules/<Module>.jsonthe key
plugin_typesindicates related plugins{ "schema_version": 3, "name": "Gui", "repository": "qtbase", "version": "6.11.1", "plugin_types": ["accessiblebridge", "platforms", "platforms/darwin", "xcbglintegrations", "platformthemes", "platforminputcontexts", "generic", "iconengines", "imageformats", "egldeviceintegrations", "wayland-graphics-integration-client", "wayland-decoration-client", "wayland-shell-integration"], "qpa": { "platforms": ["windows"], "default_platform": "windows" }, "platforms": [ { "name": "Windows", "version": "10.0.26200", "compiler_id": "MSVC", "compiler_version": "19.44.35228.0", "targets": [ { "architecture": "x86_64", "abi": "x86_64-little_endian-lp64" } ] } ] }ref: qt6 windeployqt source https://github.com/qt/qtbase/blob/163e23edd42d47a5bf0c1b9b63928e66da9b374e/src/tools/windeployqt/qtmoduleinfo.cpp#L102