Search code examples
c++makefilegettextwsl-2

How to setup gettext in C++ with Make in WSL


When I run my console application, all the text that should be translated (and is included in the .mo files) shows up in the original language, instead of the locale that I have provided.

I'm trying to enable an English locale for a Russian console application that I have translated. I have setup gettext using Poedit to create the required .mo files in a local directory myapp/locale/en/initial-domain.mo.

Most of the existing issues related to this on StackOverflow correspond to the global locale overriding the local project locale. This is not my issue as the app is in Russian, and the only provided locale is the English translation I have created, which is also the global locale for my WSL instance.

Gettext is included as follows in the stat.hpp header, with some macros I've assigned for clarity:

    #include <libintl.h>
    #include <locale.h>

    #define _(STRING) gettext(STRING)

    #define GETTEXT_DOMAIN "initial-domain"
    #define GETTEXT_OUTPUT_DIR "locale"
    #define GETTEXT_LANGUAGE "en"

These are called in my main function in main.cpp, as follows:

    //i18n: initializes the entire current locale of the program as per environment variables set by the user
    setlocale(LC_MESSAGES, GETTEXT_LANGUAGE);
    
    //i18n: Indicate the path of the i18n catalog file
    bindtextdomain(GETTEXT_DOMAIN, GETTEXT_OUTPUT_DIR);
    
    //i18n: sets the message domain
    textdomain(GETTEXT_DOMAIN);

Here is a tree of my project:

.
├── locale
│   ├── en
│   │   └── LC_MESSAGES
│   │       └── initial-domain.mo
│   └── initial-domain.pot
├── main
├── main.cpp
├── Makefile
└── stat.hpp

The Makefile configuration:

CPPFLAGS=-Wall -Wextra -std=c++17
main: main.cpp stat.hpp

After I make there is no change in the displayed characters whatsoever. I have tried forcing the domain assignment using LANG=en before running but this has not effect.

Do I need to link the <libintl.h> library differently in the Makefile? Is this due to running on WSL? I am aware that the way that Windows handles locales (per thread) means that there's some additional configuration required (as described in this blog post), but I cannot find docs showing that this is true of WSL2, which I believe has its own 'local' locale.

Thanks in advance for any pointers in the right direction, banging my head against the wall over here. Please let me know if there is clarifying info I can provide.

Cheers, HAL.


Solution

  • After a bit more time to stew on this I fixed it -- this was a pathing error, where the name of the final generated .mo file did not match the value expected by the bindtextdomain function. Name your sources carefully...

    Debugging here was most effective with strace, specifically looking for calls of the setlocale() and bindtextdomain() functions.

    Please be aware no additional linking was required for libintl.so (part of the gettext library) as I additionally suspected.