Help to understand locale dir in flatpak/Flathub

I’m trying to improve the installation of .mo files (gettext) in the Frescobaldi application.

Here’s what it’s currently installed:

[📦 org.frescobaldi.Frescobaldi org.frescobaldi.Frescobaldi]$ find /app -name *.mo
/app/dev/share/locale/ca/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/cs/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/da/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/de/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/el/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/eo/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/es/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/fi/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/fr/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/it/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/ja/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/nl/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/ru/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/sv/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/tr/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/uk/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/vi/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/zh_CN/LC_MESSAGES/lilypond.mo
/app/dev/share/locale/zh_TW/LC_MESSAGES/lilypond.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/cs/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/cs/LC_MESSAGES/userguide.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/de/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/de/LC_MESSAGES/userguide.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/es/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/es/LC_MESSAGES/userguide.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/fr/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/fr/LC_MESSAGES/userguide.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/gl/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/gl/LC_MESSAGES/userguide.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/it/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/it/LC_MESSAGES/userguide.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/ja/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/ja/LC_MESSAGES/userguide.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/ko/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/ko/LC_MESSAGES/userguide.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/nl/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/nl/LC_MESSAGES/userguide.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/pl/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/pl/LC_MESSAGES/userguide.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/pt_BR/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/pt_BR/LC_MESSAGES/userguide.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/ru/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/ru/LC_MESSAGES/userguide.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/sv/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/sv/LC_MESSAGES/userguide.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/tr/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/tr/LC_MESSAGES/userguide.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/uk/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/uk/LC_MESSAGES/userguide.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/zh_CN/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/zh_CN/LC_MESSAGES/userguide.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/zh_HK/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/zh_HK/LC_MESSAGES/userguide.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/zh_TW/LC_MESSAGES/frescobaldi.mo
/app/lib/python3.12/site-packages/frescobaldi/i18n/zh_TW/LC_MESSAGES/userguide.mo
/app/share/locale/en_US/LC_MESSAGES/mit-krb5.mo
/app/share/runtime/locale/ca/share/ca/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/cs/share/cs/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/da/share/da/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/de/share/de/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/el/share/el/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/eo/share/eo/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/es/share/es/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/fi/share/fi/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/fr/share/fr/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/it/share/it/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/ja/share/ja/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/nl/share/nl/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/ru/share/ru/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/sv/share/sv/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/tr/share/tr/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/uk/share/uk/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/vi/share/vi/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/zh/share/zh_CN/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/zh/share/zh_TW/LC_MESSAGES/lilypond.mo

I have some questions:

  1. I’m building two different LilyPond versions. The development version installed in the /app/dev prefixes gets normal paths for the .mo files, that is for example: /app/dev/share/locale/fr/LC_MESSAGES/lilypond.mo. For the stable version installed in the /app prefix instead the .mo files paths are: /app/share/runtime/locale/fr/share/fr/LC_MESSAGES/lilypond.mo. Why is this happening?

  2. The main app Frescobaldi is a simple python project which does not use Meson or any other similar tool to handle the installation. So the .mo files are copied only in the python install dir /app/lib/python3.12/site-packages/frescobaldi. I know I should add a command to copy these files to /app/share/locale, in order for appstream to build the translation metadata used by software centers to inform the users if the app is available in their language or not. However it seems that I cannot touch /app/share/locale; it seems a reserved directory. See my attempts in this PR.
    I should search other Python projects in Flathub which do not use Meson and see how they deal with this, but I haven’t found any yet. EDIT: I’ve found this one: it seems to have .mo files in /app/share/locale but I cannot understand how this is achieved.

  3. /app/share/locale/en_US/LC_MESSAGES/mit-krb5.mo seems something not cleaned up by the PyQt.BaseApp? Is it really useful?

Why is this happening?

I think that’s how the Locale extension works, it’s mounted in /app/share/runtime/locale/ rather than /app/share/locale. Because you put your development version into a subfolder it can’t be automatically separated (it only works for the default folder, i.e. /app/share/locale), see flatpak-manifest:

       separate-locales (boolean)
           Separate out locale files and translations to an extension runtime. Defaults to true.

However it seems that I cannot touch /app/share/locale; it seems a reserved directory.

What exactly is the issue you’re seeing.

I was about to reply: “Then why some apps do have .mo files in /app/share/locale?”

Then I better checked org.gnome.Evolution and found out that:

  1. Even if /app/share/locale contains the language directories it doesn’t mean they have the .mo files inside.
  2. The .mo files for my system language are mounted on /app/share/runtime/locale, as you said.
[📦 org.gnome.Evolution ~]$ ls /app/share/locale/
ab   ar   be@latin  bs		 cs  el       eo     es_CR  es_HN  es_PR  eu   ga  hi  ie  kab	ku   mg   mr   nl  pl	  ru  sq	te  uk	zh_CN
af   as   bg	    ca		 cy  en_AU    es     es_DO  es_MX  es_SV  fa   gd  hr  is  kk	ky   mjw  ms   nn  ps	  rw  sr	tg  uz	zh_HK
am   ast  bn	    ca@valencia  da  en_CA    es_AR  es_EC  es_NI  es_UY  fi   gl  hu  it  km	lt   mk   nb   oc  pt	  si  sr@latin	th  vi	zh_TW
an   az   bn_IN     ckb		 de  en_GB    es_CL  es_ES  es_PA  es_VE  fr   gu  hy  ja  kn	lv   ml   nds  or  pt_BR  sk  sv	tr  wa
ang  be   br	    crh		 dz  en@shaw  es_CO  es_GT  es_PE  et	  fur  he  id  ka  ko	mai  mn   ne   pa  ro	  sl  ta	ug  xh
[📦 org.gnome.Evolution ~]$ find /app/share/locale/ -name *.mo
/app/share/locale/en@shaw/LC_MESSAGES/evolution-data-server.mo
/app/share/locale/en@shaw/LC_MESSAGES/evolution.mo
/app/share/locale/en@shaw/LC_MESSAGES/libgweather-4.0-locations.mo
/app/share/locale/en@shaw/LC_MESSAGES/libgweather-4.0.mo
/app/share/locale/en_AU/LC_MESSAGES/evolution-data-server.mo
/app/share/locale/en_AU/LC_MESSAGES/evolution.mo
/app/share/locale/en_CA/LC_MESSAGES/evolution-data-server.mo
/app/share/locale/en_CA/LC_MESSAGES/evolution.mo
/app/share/locale/en_CA/LC_MESSAGES/libgweather-4.0-locations.mo
/app/share/locale/en_CA/LC_MESSAGES/libgweather-4.0.mo
/app/share/locale/en_GB/LC_MESSAGES/evolution-data-server.mo
/app/share/locale/en_GB/LC_MESSAGES/evolution-ews.mo
/app/share/locale/en_GB/LC_MESSAGES/evolution.mo
/app/share/locale/en_GB/LC_MESSAGES/gnome-online-accounts.mo
/app/share/locale/en_GB/LC_MESSAGES/gspell-1.mo
/app/share/locale/en_GB/LC_MESSAGES/libgweather-4.0-locations.mo
/app/share/locale/en_GB/LC_MESSAGES/libgweather-4.0.mo
/app/share/locale/en_GB/LC_MESSAGES/libsecret.mo
[📦 org.gnome.Evolution ~]$ find /app/share/runtime/ -name *.mo
/app/share/runtime/locale/it/share/it/LC_MESSAGES/evolution-data-server.mo
/app/share/runtime/locale/it/share/it/LC_MESSAGES/evolution-ews.mo
/app/share/runtime/locale/it/share/it/LC_MESSAGES/evolution.mo
/app/share/runtime/locale/it/share/it/LC_MESSAGES/gnome-online-accounts.mo
/app/share/runtime/locale/it/share/it/LC_MESSAGES/gspell-1.mo
/app/share/runtime/locale/it/share/it/LC_MESSAGES/libgweather-4.0-locations.mo
/app/share/runtime/locale/it/share/it/LC_MESSAGES/libgweather-4.0.mo
/app/share/runtime/locale/it/share/it/LC_MESSAGES/libsecret.mo

So I should rephrase the question to:

  • How can I check which languages are included in the .Locale extension?
  • How can I manually add .mo files (in the manifest) to the .Locale extension?

Trying to answer…

I can simply add a command in the manifest to copy the .mo files in /app/share/locale. I already knew this. What I was missing is how to double-check that this is working.

Here’s my workaround. First, set all languages for your flatpak configuration:

flatpak config --set languages "*"

Then build the flatpak from the manifest you are testing.
Now you can check if all .mo files from .Locale are mounted:

[📦 org.frescobaldi.Frescobaldi ~]$ find /app/share/runtime/locale/ -name *.mo
/app/share/runtime/locale/ca/share/ca/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/cs/share/cs/LC_MESSAGES/frescobaldi.mo
/app/share/runtime/locale/cs/share/cs/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/cs/share/cs/LC_MESSAGES/userguide.mo
/app/share/runtime/locale/da/share/da/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/de/share/de/LC_MESSAGES/frescobaldi.mo
/app/share/runtime/locale/de/share/de/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/de/share/de/LC_MESSAGES/userguide.mo
/app/share/runtime/locale/el/share/el/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/eo/share/eo/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/es/share/es/LC_MESSAGES/frescobaldi.mo
/app/share/runtime/locale/es/share/es/LC_MESSAGES/lilypond.mo
/app/share/runtime/locale/es/share/es/LC_MESSAGES/userguide.mo

[cut]

I’ve verified that the copy command in the manifest worked fine.

Change again the language settings:

flatpak config --unset languages

If you know better methods I’m all ears.

This topic was automatically closed after 2 days. New replies are no longer allowed.