Wikipedia entry for GNU gettext shows an example where the locale is just the lanuage, "fr". Whereas the 'i18n gettext() “hello world” example' in SO has the locale value with both the language and country, "es_MX".
I have modified the "es_MX" example to use just the lanuage, "es". This covers making an "es" rather than "'es_MX'" message catalog and invoking the program with environment variable LANG set to "es".But this produces the English text rather the expected Spanish.
cat >hellogt.cxx <<EOF // hellogt.cxx #include <libintl.h> #include <locale.h> #include <iostream> int main (){ setlocale(LC_ALL, ""); bindtextdomain("hellogt", "."); textdomain( "hellogt"); std::cout << gettext("hello, world!") << std::endl; } EOF g++ -ohellogt hellogt.cxx xgettext -d hellogt -o hellogt.pot hellogt.cxx msginit --no-translator -l es -o hellogt_spanish.po -i hellogt.pot sed --in-place hellogt_spanish.po --expression='/#: /,$ s/""/"hola mundo"/' sed --in-place hellogt_spanish.po --expression='s/PACKAGE VERSION/hellogt 1.0/' mkdir -p ./es.utf8/LC_MESSAGES msgfmt -c -v -o ./es.utf8/LC_MESSAGES/hellogt.mo hellogt_spanish.po LANG=es.utf8 ./hellogt According to Controlling your locale with environment variables:
environment variable, LANGUAGE, which is used only by GNU gettext ... If defined, LANGUAGE takes precedence over LC_ALL, LC_MESSAGES, and LANG.
LANGUAGE=es.utf8 ./hellogt produces the expected Spanish text rather than English.
But this does not explain why "LANG=es" does not work.
xx_YYwherexxis a language subtag andYYis a region subtag, sometimes followed by a character set indication.