Package Qt6 macOS App Bundle With Translation Files In CMake

Recently, I wrote about how you can create a macOS app bundle with CMake for a Qt6 application. I omitted the inclusion of translation files, which also required code changes. Well, I figured it out and will briefly explain what I had to do.

In my WorkTracker application, I store the language files in a folder called “l10n” at the project’s root. The first thing to do is instruct CMake to copy the *.qm files to the app bundle’s “Resource” folder. I have done that before for the app icon, and the process is similar for this kind of file.


set_source_files_properties(${l10n_files} PROPERTIES 
    MACOSX_PACKAGE_LOCATION "Resources/l10n")

qt_add_executable(WorkTracker MACOSX_BUNDLE 
  1. Define a variable l10n_files that contains all the files.
  2. Tell CMake that these files shall end up in the app bundle, in the “Resources/l10n” folder, to be precise.
  3. Include the files in the call to the qt_add_executable function.
A macOS Finder window showing the contents of the "Resources/l10n" folder in an app bundle.

Now that the translations are part of the bundle, a minor modification to the code tells the application where to find them. The Qt documentation contains a section about using macOS APIs to determine the bundle location. That is not necessary, though. Qt also has a helpful method to achieve the same goal, QApplication::applicationDirPath().

#if defined(Q_OS_LINUX)
    // On Linux the translations can be found in /usr/share/worktracker/l10n.
    auto l10nPath = "/../share/worktracker/l10n/";
#elif defined (Q_OS_WIN)
    // On Windows the translations are in the l10n folder in the exe dir.
    auto l10nPath = "/l10n/";
#elif defined (Q_OS_MAC)
    // On OS X the data is somewhere in the bundle.
    auto l10nPath = "/../Resources/l10n/";

auto appDir = QApplication::applicationDirPath() + l10nPath;

This method returns the absolute path to the “MacOS” folder inside of the bundle, the folder where the application’s binary is located. Appending /../Resources/l10n/ first navigates up to the “Content” folder (via /..), which is more or less the bundle’s “root” directory, and from there, goes to “Resources/l10n”. Finally, the language files are loaded like on Windows, and the translation works as expected.

I hope this was helpful because I could not find much information on this specific topic.

Thank you for reading.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.