You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Please combine all the translations for each locale's modules into a single qt_??.qm file #194
In addition to the application's QM files, you need to deploy the QM files for the Qt modules that you use in the application, unless they are installed on the system.
The QM files are split up by module and there is a so-called meta catalog file which includes the QM files of all modules. However, you only need to deploy the QM files for the modules that you use in the application.
You can use the lconvert tool in the deploy step to concatenate the required QM files into one file that matches the meta catalog file. For example, to create a German translation file for an application that uses the Qt Core, Qt GUI, and Qt Quick modules, run:
I'm in the process of migrating my project from linuxdeployqt to linuxdeploy with the linuxdeploy-plugin-qt plugin and have just spotted that the latter is including (in my particular case) qtbase_xx.qm and qtmultimedia_xx.qm for each locale whereas the former does produce the combined qt_xx.qm that the above suggests. I would point you to the shared.cpp file in that project but since it is GPL licenced whereas this one is MIT I don't want to lead anyone to precisely copy what is there as it can't be used here. I'm guessing that (inline bool) deployTranslations(appdir::AppDir&, const fs::path&, const std::vector<QtModule>&) is the place to fix this...
If they are not merged together then in an application it has to find and load the Qt translations for each module individually - whereas if they are combined it only has to instantiate one QTranslator instance to hold all the Qt modules' translations. In my application I'd have to rewrite https://github.com/Mudlet/Mudlet/blob/development/src/mudlet.cpp#L1376 to find each module's corresponding locale translation and then load them all making for more complexity.
I've worked around things temporarily by running linuxdeploy twice - the first time with this plug in - to assembly all the translation files, then used a bit of bashery to combine them in the manner that Qt themselves suggest (with lconvert) and then delete the individual files leaving behind the combined ones before running linuxdeployagain (without this plugin) to merge the changes back into the AppDir. Running linuxdeploy is not a particularly fast process - even in the GitHub CI/CB process (it takes a couple of minutes on my Desktop) so having to run it twice is not nice...
The first run with this qt and the gstreamer plugins:
Fri, 11 Apr 2025 20:53:25 GMT to Fri, 11 Apr 2025 20:54:19 GMT = 55 seconds
The second run without either plugin just to update the translation files in the AppImage after combining them:
Fri, 11 Apr 2025 20:54:19 GMT to Fri, 11 Apr 2025 20:54:56 GMT = 35 seconds
Note that windeployqt, the Qt deployment tool for Windows only includes qt_??.qm files, no qtbase, qtmultimedia or anything else.
My Qt program is written to read qt Qt translation files compatible with windows deployment. This also works with packaged installation, because distros1 package qt qm files alongside the more specific ones.
The only outlier in my deployment process is linuxdeploy-plugin-qt now. Like SlySven, I am unwilling to rewrite my code just for this outlier, so I'll have to hack this together myself somehow.
Footnotes
I checked only a few distros, I do not know whether this is common for most. ↩
I'm willing to contribute a fix, but I need to discuss with maintainers how to do this in a sensible and backwards compatible way.
I think the most sensible option is to deploy both library specific and qt qm files for backwards compatibility, add a flag to let the user choose betwen one or the other (or both).
I'd also add a flag that would let the user pick languages which are bundled. Current behavior seems to be to bundle everything there is to bundle. For example the aforementioned windeployqt has a --translations flag which can limit the bundled translations.
I'd like to deprecate library specific translation files as default (but perhaps keep it if overriden by the flag proposed above). I don't know how linuxdeploy-plugin-qt would handle such deprecations.
Thanks for the additional research. I am still not 100% sure when to perform such a step, but I am not opposed to it at all. It looks like since translations are scattered across, we'd have to register all .qm files and run lconvert as a post-processing step or so in the plugin. Is that assumption right?
The aggregated qt qm files are usually1 available alongside the library specific ones. No need to lconvert if it's already there.
I guess making linuxdeploy-plugin-qt capable of lconverting its own qt file could prove useful in some scenarios, but the qt qm file should just be copied over if it's there.
UPDATE: It appears to be more complicated than that. The fact that a /usr/share/qt6/translations/qt_??.qm file exists doesn't have to mean that it has any usable content. On ubuntu:22.04, the qt6-translations-l10n package does provide qt files, but they don't contain anything useful. Here's for example qt_cs.qm:
Perhaps qm files can transparently link to other qm files? That would explain such small qm files. The paste above perhaps links to qtbase and qtmultimedia. I don't know.
Ubuntu 22.04 is a bit old, it is possible that Qt changed how qt is bundled in newer versions. But with this discovery in mind, I believe that using lconvert is the best solution.
Footnotes
Again, I am speaking about the few distros I tested this on. ↩
I've updated my previous comment, please read that.
I haven't talked about app .qm files yet. Their handling is simpler. There are two ways to bundle translations: to bundle them into the executable with qrc or to provide separate .qm files.
Bundled translations do not require special attention from linuxdeploy-plugin-qt.
With that in mind, app translations shouldn't require special attention from linuxdeploy-plugin-qt.
I'd certainly add a section on translations into the project's README alongside my implementation PR.
Qt's translation loading mechanism is quite manual, the file names and directory locations are hardcoded to a certain extent. Renaming the translations or merging them with lconvert would most likely break things.
TBH I had abandoned migrating my project from linuxdeployqt to linuxdeploy as eventually probonod updated things in the former so it would work with the (then later libc I think) in the GH Actions ubuntu 22.04 runner - this was during/shortly after the depreciation/removal of the older ubuntu 20.04 runner.
However the same situation is going to occur again by April 2027 as now the 22.04 runner is on death-row - so I may have to look again.
Activity
TheAssassin commentedon Apr 11, 2025
Why would linuxdeploy have to do this, though? Wouldn't it be just as easy to run it manually if needed? I don't see the advantage (yet).
SlySven commentedon Apr 11, 2025
If they are not merged together then in an application it has to find and load the Qt translations for each module individually - whereas if they are combined it only has to instantiate one
QTranslatorinstance to hold all the Qt modules' translations. In my application I'd have to rewrite https://github.com/Mudlet/Mudlet/blob/development/src/mudlet.cpp#L1376 to find each module's corresponding locale translation and then load them all making for more complexity.I've worked around things temporarily by running
linuxdeploytwice - the first time with this plug in - to assembly all the translation files, then used a bit of bashery to combine them in the manner that Qt themselves suggest (withlconvert) and then delete the individual files leaving behind the combined ones before runninglinuxdeployagain (without this plugin) to merge the changes back into the AppDir. Running linuxdeploy is not a particularly fast process - even in the GitHub CI/CB process (it takes a couple of minutes on my Desktop) so having to run it twice is not nice...Ah, some timing details from the most recent run I've done like this: https://github.com/Mudlet/Mudlet/actions/runs/14411660189/job/40420749088?pr=7806
The first run with this qt and the
gstreamerplugins:Fri, 11 Apr 2025 20:53:25 GMT to Fri, 11 Apr 2025 20:54:19 GMT = 55 seconds
The second run without either plugin just to update the translation files in the AppImage after combining them:
Fri, 11 Apr 2025 20:54:19 GMT to Fri, 11 Apr 2025 20:54:56 GMT = 35 seconds
meator commentedon Aug 18, 2026
I also vote for this.
Note that
windeployqt, the Qt deployment tool for Windows only includesqt_??.qmfiles, noqtbase,qtmultimediaor anything else.My Qt program is written to read
qtQt translation files compatible with windows deployment. This also works with packaged installation, because distros1 packageqtqm files alongside the more specific ones.The only outlier in my deployment process is linuxdeploy-plugin-qt now. Like SlySven, I am unwilling to rewrite my code just for this outlier, so I'll have to hack this together myself somehow.
Footnotes
I checked only a few distros, I do not know whether this is common for most. ↩
meator commentedon Aug 18, 2026
I'm willing to contribute a fix, but I need to discuss with maintainers how to do this in a sensible and backwards compatible way.
I think the most sensible option is to deploy both library specific and
qtqm files for backwards compatibility, add a flag to let the user choose betwen one or the other (or both).I'd also add a flag that would let the user pick languages which are bundled. Current behavior seems to be to bundle everything there is to bundle. For example the aforementioned
windeployqthas a--translationsflag which can limit the bundled translations.I'd like to deprecate library specific translation files as default (but perhaps keep it if overriden by the flag proposed above). I don't know how linuxdeploy-plugin-qt would handle such deprecations.
TheAssassin commentedon Aug 18, 2026
Thanks for the additional research. I am still not 100% sure when to perform such a step, but I am not opposed to it at all. It looks like since translations are scattered across, we'd have to register all
.qmfiles and runlconvertas a post-processing step or so in the plugin. Is that assumption right?meator commentedon Aug 18, 2026
The aggregated
qtqm files are usually1 available alongside the library specific ones. No need tolconvertif it's already there.I guess making linuxdeploy-plugin-qt capable of
lconverting its ownqtfile could prove useful in some scenarios, but theqtqm file should just be copied over if it's there.UPDATE: It appears to be more complicated than that. The fact that a
/usr/share/qt6/translations/qt_??.qmfile exists doesn't have to mean that it has any usable content. Onubuntu:22.04, theqt6-translations-l10npackage does provideqtfiles, but they don't contain anything useful. Here's for exampleqt_cs.qm:Here are all translations: qt6-translations-l10n-6.2.4-1.tar.gz
Perhaps qm files can transparently link to other qm files? That would explain such small qm files. The paste above perhaps links to
qtbaseandqtmultimedia. I don't know.Ubuntu 22.04 is a bit old, it is possible that Qt changed how
qtis bundled in newer versions. But with this discovery in mind, I believe that using lconvert is the best solution.Footnotes
Again, I am speaking about the few distros I tested this on. ↩
TheAssassin commentedon Aug 18, 2026
So the idea is: detect app
.qmfiles and combine them toqt_*.qmwithlconvertinto a known position, retaining the original ones?meator commentedon Aug 18, 2026
I've updated my previous comment, please read that.
I haven't talked about app
.qmfiles yet. Their handling is simpler. There are two ways to bundle translations: to bundle them into the executable with qrc or to provide separate.qmfiles.Bundled translations do not require special attention from linuxdeploy-plugin-qt.
If the build system is instructed to install things into the
AppDiras described in https://docs.appimage.org/packaging-guide/from-source/native-binaries.html#using-the-build-system-to-build-the-basic-appdir, it should install qm translations into a sensible direcory.With that in mind, app translations shouldn't require special attention from linuxdeploy-plugin-qt.
I'd certainly add a section on translations into the project's README alongside my implementation PR.
Qt's translation loading mechanism is quite manual, the file names and directory locations are hardcoded to a certain extent. Renaming the translations or merging them with
lconvertwould most likely break things.TheAssassin commentedon Aug 18, 2026
Kind of confused now. A draft PR would be very welcome to showcase the concept.
SlySven commentedon Aug 20, 2026
TBH I had abandoned migrating my project from
linuxdeployqttolinuxdeployas eventually probonod updated things in the former so it would work with the (then laterlibcI think) in the GH Actionsubuntu 22.04runner - this was during/shortly after the depreciation/removal of the olderubuntu 20.04runner.However the same situation is going to occur again by April 2027 as now the 22.04 runner is on death-row - so I may have to look again.