1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 2<html> 3<!-- 4 Copyright (C) 2004-2005, 2007-2008, 2010, 2012, 2014, 2019-2020 Free Software Foundation, Inc. 5 Written by Bruno Haible <bruno@clisp.org>, 2004. 6 7 This manual is free documentation. It is dually licensed under the 8 GNU FDL and the GNU GPL. This means that you can redistribute this 9 manual under either of these two licenses, at your choice. 10 11 This manual is covered by the GNU FDL. Permission is granted to copy, 12 distribute and/or modify this document under the terms of the 13 GNU Free Documentation License (FDL), either version 1.2 of the 14 License, or (at your option) any later version published by the 15 Free Software Foundation (FSF); with no Invariant Sections, with no 16 Front-Cover Text, and with no Back-Cover Texts. 17 A copy of the license is at 18 <https://www.gnu.org/licenses/old-licenses/fdl-1.2>. 19 20 This manual is covered by the GNU GPL. You can redistribute it and/or 21 modify it under the terms of the GNU General Public License (GPL), either 22 version 2 of the License, or (at your option) any later version published 23 by the Free Software Foundation (FSF). 24 A copy of the license is at 25 <https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html>. 26--> 27<head> 28 <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 29 <title>GNU gettext FAQ</title> 30</head> 31<body> 32<h1 style="text-align: center;">Frequently Asked Questions<br> 33for GNU gettext 34</h1> 35<h1 style="text-align: center;">Questions</h1> 36<h3>General</h3> 37<ul> 38 <li><a href="#general_mailinglist">Where is the mailing list?</a></li> 39 <li><a href="#general_source">Where is the newest gettext source?</a></li> 40 <li><a href="#general_announce">I want to be notified of new gettext 41releases.</a></li> 42</ul> 43<h3>Problems building GNU gettext</h3> 44<ul> 45 <li><a href="#building_solaris_libasprintf">On Solaris, I get a build 46error “text relocations remain” in the <span 47 style="font-family: monospace;">libasprintf</span> subdirectory</a></li> 48 <li><a href="#building_install">“make install” fails</a></li> 49</ul> 50<h3>Problems integrating GNU gettext</h3> 51<ul> 52 <li><a href="#integrating_howto">How do I make use of <span 53 style="font-family: monospace;">gettext()</span> in my package?</a></li> 54 <li><a href="#integrating_undefined">I get a linker error “undefined 55reference to libintl_gettext”</a></li> 56 <li><a href="#integrating_abuse_gettextize">gettextize adds multiple 57references to the same directories/files 58to <span style="font-family: monospace;">Makefile.am</span> and </a><span 59 style="font-family: monospace;"><a href="#integrating_abuse_gettextize">configure.ac</a><br> 60 </span></li> 61 <li><a href="#integrating_noop">My program compiles and links fine, 62but doesn't output translated 63strings.</a><br> 64 </li> 65</ul> 66<h3>GNU gettext on Windows</h3> 67<ul> 68 <li><a href="#windows_woe32">What does Woe32 mean?</a></li> 69 <li><a href="#windows_howto">How do I compile, link and run a program 70that uses the gettext() 71function?</a><br> 72 </li> 73 <li><a href="#windows_setenv">Setting the <span 74 style="font-family: monospace;">LANG</span> 75environment variable doesn't have any effect</a></li> 76</ul> 77<h3>Other</h3> 78<ul> 79 <li><a href="#newline">What does this mean: “'msgid' and 'msgstr' 80entries do not both 81end with '\n'”</a></li> 82 <li><a href="#translit">German umlauts are displayed like “ge"andert” 83instead of 84“geändert”</a></li> 85 <li><a href="#localename">The <span style="font-family: monospace;">LANGUAGE</span> 86environment variable is ignored after I set <span 87 style="font-family: monospace;">LANG=en</span></a></li> 88 <li><a href="#nonascii_strings">I use accented characters in my 89source code. How do I tell the 90C/C++ compiler in which encoding it is (like <span 91 style="font-family: monospace;">xgettext</span>'s <span 92 style="font-family: monospace;">--from-code</span> option)?</a></li> 93</ul> 94<h1 style="text-align: center;">Answers</h1> 95<h3>General</h3> 96<h4><a name="general_mailinglist"></a>Where is the mailing list?</h4> 97Three mailing lists are available: <br> 98<ul> 99 <li><span style="font-family: monospace;">bug-gettext@gnu.org</span><br> 100This mailing list is for discussion of features and bugs of the GNU 101gettext <span style="font-style: italic;">software</span>, including 102libintl, the gettext-tools, and its autoconf macros. The archive and subscription instructions can be found at <a href="https://lists.gnu.org/mailman/listinfo/bug-gettext">the information page</a>.</li> 103 <li><span style="font-family: monospace;">translation-i18n@lists.sourceforge.net</span><br> 104This mailing list is for methodology questions around 105internationalization, and for discussions of translator tools, 106including but not limited to GNU gettext.</li> 107 <li><span style="font-family: monospace;">coordinator@translationproject.org</span><br> 108This is the email address of the <a 109 href="https://translationproject.org/">Translation Project</a>, 110that is the project which manages the translated message 111catalogs for many free software packages. Note that KDE and GNOME 112packages are not part of this project; they have their own translation 113projects: <a href="https://l10n.kde.org/">l10n.kde.org</a> and <a 114 href="https://wiki.gnome.org/TranslationProject/">GNOME Translation Project</a>.<br> 115 </li> 116</ul> 117The <span style="font-family: monospace;">bug-gettext</span> list 118is archived <a href="https://lists.gnu.org/archive/html/bug-gettext/">here</a>. 119You may occasionally also see 120<span style="font-family: monospace;">bug-gnu-gettext</span>; this is an alias 121of <span style="font-family: monospace;">bug-gettext</span>.<br> 122<h4><a name="general_source"></a>Where is the newest gettext source?</h4> 123The newest gettext release is available on <span 124 style="font-family: monospace;">ftp.gnu.org</span> and its mirrors, in 125<a href="https://ftp.gnu.org/gnu/gettext/">https://ftp.gnu.org/gnu/gettext/</a>.<br> 126<br> 127Prereleases are announced on the <a 128 href="https://lists.gnu.org/mailman/listinfo/autotools-announce"><span 129 style="font-family: monospace;">autotools-announce</span> mailing list</a>. 130Note that prereleases are meant for testing and not meant for use in 131production environments. Please don't use the “gettextize” program of a 132prerelease on projects which you share with other programmers via CVS.<br> 133<br> 134If you want to live on the bleeding edge, you can also use the 135development sources. Instructions for retrieving the gettext CVS are 136found <a href="https://savannah.gnu.org/projects/gettext">here</a>. 137Note that building from CVS requires special tools (autoconf, automake, 138m4, groff, bison, etc.) and requires that you pay attention to the <span 139 style="font-family: monospace;">README-alpha</span> and <span 140 style="font-family: monospace;">autogen.sh</span> files in the CVS.<br> 141<h4><a name="general_announce"></a>I want to be notified of new gettext 142releases.</h4> 143If you are interested in stable gettext releases, you can follow the <a 144 href="https://lists.gnu.org/mailman/listinfo/info-gnu"><span 145 style="font-family: monospace;">info-gnu</span> mailing list</a>. It 146is also available as a newsgroup <a 147 href="nntp://news.gmane.org/gmane.org.fsf.announce"><span 148 style="font-family: monospace;">gmane.org.fsf.announce</span></a> 149through <a href="https://www.gmane.org/"><span 150 style="font-family: monospace;">gmane.org</span></a>.<br> 151<br> 152You can also periodically check the download location.<br> 153<br> 154If you are interested in testing prereleases as well, you can subscribe 155to the <a href="://lists.gnu.org/mailman/listinfo/autotools-announce"><span 156 style="font-family: monospace;">autotools-announce</span> mailing 157list</a>.<br> 158<h3>Problems building GNU gettext</h3> 159<h4><a name="building_solaris_libasprintf"></a>On Solaris, I get a 160build error “text relocations remain” in the <span 161 style="font-family: monospace;">libasprintf</span> subdirectory</h4> 162libtool (or more precisely, the version of libtool that was available 163at the time the gettext release waas made) doesn't support linking C++ 164libraries with some versions of GCC. As a workaround, you can configure 165gettext with the option <span style="font-family: monospace;">--disable-libasprintf</span>.<br> 166<h4><a name="building_install"></a>“make install” fails</h4> 167“<span style="font-family: monospace;">make install DESTDIR=<span 168 style="font-style: italic;">/some/tempdir</span></span>” can fail with 169an error message relating to <span style="font-family: monospace;">libgettextlib</span> 170or <span style="font-family: monospace;">libgettextsrc</span>, or can 171silently fail to install <span style="font-family: monospace;">libgettextsrc</span>. 172On some platforms, this is due to limitations of libtool regarding <span 173 style="font-family: monospace;">DESTDIR</span>. On other platforms, it 174is due to the way the system handles shared libraries, and libtool 175cannot work around it. Fortunately, on Linux and other glibc based 176systems, <span style="font-family: monospace;">DESTDIR</span> is 177supported if no different version of gettext is already installed (i.e. 178it works if you uninstall the older gettext before building and 179installing the newer one, or if you do a plain “<span 180 style="font-family: monospace;">make install</span>” before “<span 181 style="font-family: monospace;">make install DESTDIR=<span 182 style="font-style: italic;">/some/tempdir</span></span>”). On other 183systems, when <span style="font-family: monospace;">DESTDIR</span> 184does not work, you can still do “<span style="font-family: monospace;">make 185install</span>” and copy the installed files to <span 186 style="font-family: monospace;"><span style="font-style: italic;">/some/tempdir</span></span> 187afterwards.<br> 188<br> 189If “<span style="font-family: monospace;">make install</span>” without <span 190 style="font-family: monospace;">DESTDIR</span> fails, it's a bug which 191you are welcome to report to the usual bug report address. 192<h3>Problems integrating GNU gettext</h3> 193<h4><a name="integrating_howto"></a>How do I make use of <span 194 style="font-family: monospace;">gettext()</span> in my package?</h4> 195It's not as difficult as it sounds. Here's the recipe for C or C++ 196based packages.<br> 197<ul> 198 <li>Add an invocation of <span style="font-family: monospace;">AM_GNU_GETTEXT([external])</span> 199to the package's <span style="font-family: monospace;">configure.{ac,in}</span> 200file.</li> 201 <li>Invoke “<span style="font-family: monospace;">gettextize --copy</span>”. 202It will do most of the autoconf/automake related work for you.</li> 203 <li>Add the <span style="font-family: monospace;">gettext.h</span> 204file to the package's source directory, and include it in all source 205files that contain translatable strings or do output via <span 206 style="font-family: monospace;">printf</span> or <span 207 style="font-family: monospace;">fprintf</span>.</li> 208 <li>In the source file defining the main() function of the program, 209add these lines to the header<br> 210 <div style="margin-left: 40px;"><code><span 211 style="font-family: monospace;">#include <locale.h></span><br 212 style="font-family: monospace;"> 213 <span style="font-family: monospace;">#include "gettext.h"</span></code><br> 214 </div> 215and these lines near the beginning of the main() function:<br> 216 <div style="margin-left: 40px;"><code><span 217 style="font-family: monospace;">setlocale (LC_ALL, "");</span><br 218 style="font-family: monospace;"> 219 <span style="font-family: monospace;">bindtextdomain (PACKAGE, 220LOCALEDIR);</span><br style="font-family: monospace;"> 221 <span style="font-family: monospace;">textdomain (PACKAGE);</span></code><br> 222 </div> 223 </li> 224 <li>Mark all strings that should be translated with _(), like this: <span 225 style="font-family: monospace;">_("No errors found.")</span>. While 226doing this, try to turn the strings into good English, one entire 227sentence per string, not more than one paragraph per string, and use 228format strings instead of string concatenation. This is needed so that 229the translators can provide accurate translations.</li> 230 <li>In every source file containing translatable strings, add these lines 231to the header:<br> 232 <div style="margin-left: 40px;"><code><span 233 style="font-family: monospace;">#include "gettext.h"</span><br 234 style="font-family: monospace;"> 235 <span style="font-family: monospace;">#define _(string) gettext (string)</span></code><br> 236 </div> 237 </li> 238 <li>In the freshly created <span style="font-family: monospace;">po/</span> 239directory, set up the <span style="font-family: monospace;">POTFILES.in</span> 240file, and do a “<span style="font-family: monospace;">make update-po</span>”. 241Then distribute the generated <span style="font-family: monospace;">.pot</span> 242file to your nearest translation project.</li> 243 <li>Shortly before a release, integrate the translators' <span 244 style="font-family: monospace;">.po</span> files into the <span 245 style="font-family: monospace;">po/</span> directory and do “<span 246 style="font-family: monospace;">make update-po</span>” again.<br> 247 </li> 248</ul> 249You find detailed descriptions of how this all works in the GNU gettext 250manual, chapters “The Maintainer's View” and “Preparing Program 251Sources”. 252<h4><a name="integrating_undefined"></a>I get a linker error “undefined 253reference to libintl_gettext”</h4> 254This error means that the program uses the <span 255 style="font-family: monospace;">gettext()</span> function after having 256included the <span style="font-family: monospace;"><libintl.h></span> 257file from GNU gettext (which remaps it to <span 258 style="font-family: monospace;">libintl_gettext()</span>), however at 259link time a function of this name could not be linked in. (It is 260expected to come from the <span style="font-family: monospace;">libintl</span> 261library, installed by GNU gettext.)<br> 262<br> 263There are many possible reasons for this error, but in any case you 264should consider the <span style="font-family: monospace;">-I</span>, <span 265 style="font-family: monospace;">-L</span> and <span 266 style="font-family: monospace;">-l</span> options passed to the 267compiler. In packages using <span style="font-family: monospace;">autoconf</span> 268generated configure scripts, <span style="font-family: monospace;">-I</span> 269options come from the <span style="font-family: monospace;">CFLAGS</span> 270and <span style="font-family: monospace;">CPPFLAGS</span> variables 271(in Makefiles also <span style="font-family: monospace;">DEFS</span> 272and <span style="font-family: monospace;">INCLUDES</span>), <span 273 style="font-family: monospace;">-L</span> options come from the <span 274 style="font-family: monospace;">LDFLAGS</span> variable, and <span 275 style="font-family: monospace;">-l</span> options come from the <span 276 style="font-family: monospace;">LIBS</span> variable. The first thing 277you should check are the values of these variables in your environment 278and in the package's <span style="font-family: monospace;">config.status</span> 279autoconfiguration result.<br> 280<br> 281To find the cause of the error, a little analysis is needed. Does the 282program's final link command contains the option “-lintl”?<br> 283<ul> 284 <li>If yes:<br> 285Find out where the <span style="font-family: monospace;">libintl</span> 286comes from. To do this, you have to check for <span 287 style="font-family: monospace;">libintl.a</span> and <span 288 style="font-family: monospace;">libintl.so*</span> (<span 289 style="font-family: monospace;">libintl.dylib</span> on MacOS X) in 290each directory given as a -L option, as well as in the compiler's 291implicit search directories. (You get these implicit search directories 292for gcc by using “<span style="font-family: monospace;">gcc -v</span>” 293instead of “<span style="font-family: monospace;">gcc</span>” in the 294final link command line; compilers other than GCC usually look in <span 295 style="font-family: monospace;">/usr/lib</span> and <span 296 style="font-family: monospace;">/lib</span>.) A shell command like<br> 297 <div style="margin-left: 40px;"><code>$ for d in /usr/local/lib 298/usr/lib /lib; do ls -l $d/libintl.*; done</code><br> 299 </div> 300will show where the <span style="font-family: monospace;">libintl</span> 301comes from. By looking at the dates and whether each library defines <span 302 style="font-family: monospace;">libintl_gettext</span> (via “<span 303 style="font-family: monospace;">nm <span style="font-style: italic;">path</span>/libintl.so 304| grep libintl_gettext</span>”) you can now distinguish three possible 305causes of the error:<br> 306 <ul> 307 <li>Some older libintl is used instead of the newer one. The fix 308is to remove the old library or to reorganize your -L options.</li> 309 <li>The used libintl is the new one, and it doesn't contain 310libintl_gettext. This would be a bug in gettext. If this is the case, 311please report it to the usual bug report address.</li> 312 <li>The used libintl is a static library (libintl.a), there are 313no uses of gettext in .o files before the “-lintl” but there are some 314after the “-lintl”. In this case the fix is to move the “-lintl” to the 315end or near the end of the link command line. The only libintl 316dependency that needs to be mentioned after “-lintl” is “-liconv”.</li> 317 </ul> 318 </li> 319 <li>If no:<br> 320In this case it's likely a bug in the package you are building: The 321package's Makefiles should make sure that “-lintl” is used where needed.<br> 322Test whether libintl was found by configure. You can check this by doing<br> 323 <div style="margin-left: 40px;"><code>$ grep 324'\(INTLLIBS\|LIBINTL\)' config.status</code><br> 325 </div> 326and looking whether the value of this autoconf variable is non-empty.<br> 327 <ul> 328 <li>If yes: It should be the responsibility of the Makefile to 329use the value of this variable in the link command line. Does the 330Makefile.in rule for linking the program use <span 331 style="font-family: monospace;">@INTLLIBS@</span> or <span 332 style="font-family: monospace;">@LIBINTL@</span>?<br> 333 <ul> 334 <li>If no: It's a Makefile.am/in bug.</li> 335 <li>If yes: Something strange is going on. You need to dig 336deeper.</li> 337 </ul> 338Note that <span style="font-family: monospace;">@INTLLIBS@</span> is 339for <span style="font-family: monospace;">gettext.m4</span> versions 340<= 0.10.40 and <span style="font-family: monospace;">@LIBINTL@</span> 341is for <span style="font-family: monospace;">gettext.m4</span> 342versions >= 0.11, depending on which <span 343 style="font-family: monospace;">gettext.m4</span> was used to build 344the package's <span style="font-family: monospace;">configure</span> - 345regardless of which gettext you have now installed.</li> 346 <li>If no: So libintl was not found.<br> 347Take a look at the package's <span style="font-family: monospace;">configure.in/ac</span>. 348Does it invoke AM_GNU_GETTEXT?<br> 349 <ul> 350 <li>If no: The gettext maintainers take no responsibilities for 351lookalikes named CY_GNU_GETTEXT, AM_GLIB_GNU_GETTEXT, AM_GNOME_GETTEXT 352and similar, or for homebrewn autoconf checks. Complain to the package 353maintainer.</li> 354 <li>If yes: It looks like the <span 355 style="font-family: monospace;">-I</span> and <span 356 style="font-family: monospace;">-L</span> options were inconsistent. 357You should have a <span style="font-family: monospace;">-I<span 358 style="font-style: italic;">somedir</span>/include</span> in the <span 359 style="font-family: monospace;">CFLAGS</span> or <span 360 style="font-family: monospace;">CPPFLAGS</span> if and only if you 361also have a <span style="font-family: monospace;">-L<span 362 style="font-style: italic;">somedir</span>/lib</span> in the <span 363 style="font-family: monospace;">LDFLAGS</span>. And <span 364 style="font-family: monospace;"><span style="font-style: italic;">somedir</span>/include</span> 365should contain a <span style="font-family: monospace;">libintl.h</span> 366if and only if <span style="font-family: monospace;"><span 367 style="font-style: italic;">somedir</span>/lib</span> contains <span 368 style="font-family: monospace;">libintl.{a,so}</span>.<br> 369This case can also happen if you have configured a GCC < 3.2 with 370the same <span style="font-family: monospace;">--prefix</span> option 371as you used for GNU libiconv or GNU gettext. This is fatal, because 372these versions of GCC implicitly use <span 373 style="font-family: monospace;">-L<span style="font-style: italic;">prefix</span>/lib</span> 374but <span style="font-weight: bold; font-style: italic;">not</span><br 375 style="font-weight: bold; font-style: italic;"> 376 <span style="font-family: monospace;">-I<span 377 style="font-style: italic;">prefix</span>/include</span>. The 378workaround is to use a different <span style="font-family: monospace;">--prefix</span> 379for GCC.<br> 380 </li> 381 </ul> 382 </li> 383 </ul> 384 </li> 385</ul> 386<h4><a name="integrating_abuse_gettextize"></a>gettextize adds multiple 387references to the same directories/files 388to <span style="font-family: monospace;">Makefile.am</span> and <span 389 style="font-family: monospace;">configure.ac</span></h4> 390If <span style="font-family: monospace;">gettextize</span> is used on 391a package, then the <span style="font-family: monospace;">po/</span>, <span 392 style="font-family: monospace;">intl/</span>, <span 393 style="font-family: monospace;">m4/</span> directories of the package 394are removed, and then <span style="font-family: monospace;">gettextize</span> 395is invoked on the package again, it will re-add the <span 396 style="font-family: monospace;">po/</span>, <span 397 style="font-family: monospace;">intl/</span>, <span 398 style="font-family: monospace;">m4/</span> directories and change <span 399 style="font-family: monospace;">Makefile.am</span>, <span 400 style="font-family: monospace;">configure.ac</span> and <span 401 style="font-family: monospace;">ChangeLog</span> accordingly. This is 402normal. The second use of <span style="font-family: monospace;">gettextize</span> 403here is an abuse of the program. <span style="font-family: monospace;">gettextize</span> 404is a wizard intended to transform a <span style="font-style: italic;">working 405source package</span> into a <span style="font-style: italic;">working 406source package</span> that uses the newest version of gettext. If you 407start out from a nonfunctional source package (it is nonfunctional 408since you have omitted some directories), you cannot expect that <span 409 style="font-family: monospace;">gettextize</span> corrects it.<br> 410<br> 411Often this question arises in packages that use CVS. See the section 412“CVS Issues / Integrating with CVS” of the GNU gettext documentation. 413This section mentions a program <span style="font-family: monospace;">autopoint</span> 414which is designed to reconstruct those files and directories created by 415<span style="font-family: monospace;">gettextize</span> that can be 416omitted from a CVS repository.<br> 417<h4><a name="integrating_noop"></a>My program compiles and links fine, 418but doesn't output translated 419strings.</h4> 420There are several possible reasons. Here is a checklist that allows you 421to determine the cause.<br> 422<ol> 423 <li>Check that the environment variables LC_ALL, LC_MESSAGES, 424LC_CTYPE, LANG, LANGUAGE together specify a valid locale and language.<br> 425To check this, run the commands<br> 426 <div style="margin-left: 40px;"><code>$ gettext --version</code><br> 427 <code>$ gettext --help</code><br> 428 </div> 429You should see at least some output in your desired language. If not, 430either<br> 431 <ul> 432 <li>You have chosen a too exotic language. <span 433 style="font-family: monospace;">gettext</span> is localized to 33 434languages. Choose a less exotic language, such as Galician or 435Ukrainian. Or<br> 436 </li> 437 <li>There is a problem with your environment variables. Possibly 438LC_ALL points to a locale that is not installed, or LC_MESSAGES and 439LC_CTYPE are inconsistent.</li> 440 </ul> 441 </li> 442 <li>Check that your program contains a <span 443 style="font-family: monospace;">setlocale</span> call.<br> 444To check this, run your program under ltrace. For example,<br> 445 <div style="margin-left: 40px;"><code>$ ltrace ./myprog</code><br> 446 <code>...</code><br> 447 <code>setlocale(6, 448"") 449= "de_DE.UTF-8"</code><br> 450 </div> 451If you have no ltrace, you can also do this check by running your 452program under the debugger. For example,<br> 453 <div style="margin-left: 40px;"><code>$ gdb ./myprog</code><br> 454 <code>(gdb) break main</code><br> 455 <code>(gdb) run</code><br> 456 <code>Breakpoint 1, main ()</code><br> 457 <code>(gdb) break setlocale</code><br> 458 <code>(gdb) continue</code><br> 459 <code>Breakpoint 2, setlocale ()</code><br> 460 <code>;; OK, the breakpoint has been hit, setlocale() is being 461called.</code><br> 462 </div> 463Either way, check that the return value of <span 464 style="font-family: monospace;">setlocale()</span> is non-NULL. A NULL 465return value indicates a failure. </li> 466 <li>Check that your program contains a <span 467 style="font-family: monospace;">textdomain</span> call, a <span 468 style="font-family: monospace;">bindtextdomain</span> call referring 469to the same message domain, and then really calls the <span 470 style="font-family: monospace;">gettext</span>, <span 471 style="font-family: monospace;">dgettext</span> or <span 472 style="font-family: monospace;">dcgettext</span> function.<br> 473To check this, run the program under ltrace. For example,<br> 474 <div style="margin-left: 40px;"><code>$ ltrace ./myprog</code><br> 475 <code>...</code><br> 476 <code>textdomain("hello-c") 477= "hello-c"</code><br> 478 <code>bindtextdomain("hello-c", "/opt/share"...) = "/opt/share"...</code><br> 479 <code>dcgettext(0, 0x08048691, 5, 0x0804a200, 0x08048689) = 4800x4001721f</code><br> 481 </div> 482If you have no ltrace, you can also do this check by running your 483program under the debugger. For example,<br> 484 <div style="margin-left: 40px;"><code>$ gdb ./myprog</code><br> 485 <code>(gdb) break main</code><br> 486 <code>(gdb) run</code><br> 487 <code>Breakpoint 1, main ()</code><br> 488 <code>(gdb) break textdomain</code><br> 489 <code>(gdb) break bindtextdomain</code><br> 490 <code>(gdb) break gettext</code><br> 491 <code>(gdb) break dgettext</code><br> 492 <code>(gdb) break dcgettext</code><br> 493 <code>(gdb) continue</code><br> 494 <code>Breakpoint 2, textdomain ()</code><br> 495 <code>(gdb) continue</code><br> 496 <code>Breakpoint 3, bindtextdomain ()</code><br> 497 <code>(gdb) continue</code><br> 498 <code>Breakpoint 6, dcgettext ()</code><br> 499 </div> 500Note that here <span style="font-family: monospace;">dcgettext()</span> 501is called instead of the <span style="font-family: monospace;">gettext()</span> 502function mentioned in the source code; this is due to an optimization 503in <span style="font-family: monospace;"><libintl.h></span>.<br> 504When using libintl on a non-glibc system, you have to add a prefix “<span 505 style="font-family: monospace;">libintl_</span>” to all the function 506names mentioned here, because that's what the functions are really 507named, under the hood.<br> 508If <span style="font-family: monospace;">gettext</span>/<span 509 style="font-family: monospace;">dgettext</span>/<span 510 style="font-family: monospace;">dcgettext</span> is not called at all, 511the possible cause might be that some autoconf or Makefile macrology 512has turned off internationalization entirely (like the <span 513 style="font-family: monospace;">--disable-nls</span> configuration 514option usually does).<br> 515 </li> 516 <li>Check that the <span style="font-family: monospace;">.mo</span> 517file that contains the translation is really there where the program 518expects it.<br> 519To check this, run the program under strace and look at the <span 520 style="font-family: monospace;">open()</span> calls. For example,<br> 521 <div style="margin-left: 40px;"><code>$ strace ./myprog 2>&1 522| grep '^open('</code><br> 523 <code>open("/etc/ld.so.preload", O_RDONLY) = -1 524ENOENT (No such file or directory)</code><br> 525 <code>open("/etc/ld.so.cache", 526O_RDONLY) = 5</code><br> 527 <code>open("/lib/libc.so.6", 528O_RDONLY) = 5</code><br> 529 <code>open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) 530= 5</code><br> 531 <code>open("/usr/share/locale/locale.alias", O_RDONLY) = 5</code><br> 532 <code>open("/opt/share/locale/de/LC_MESSAGES/hello-c.mo", O_RDONLY) 533= 5</code><br> 534 <code>...</code><br> 535 </div> 536A nonnegative <span style="font-family: monospace;">open()</span> 537return value means that the file has been found.<br> 538If you have no strace, you can also guess the <span 539 style="font-family: monospace;">.mo</span> file's location: it is<br> 540 <div style="margin-left: 40px;"><span 541 style="font-family: monospace;"><span style="font-style: italic;">localedir</span>/<span 542 style="font-style: italic;">lang</span>/LC_MESSAGES/<span 543 style="font-style: italic;">domain</span>.mo</span><br> 544 </div> 545where <span style="font-style: italic;">domain</span> is the argument 546passed to <span style="font-family: monospace;">textdomain()</span>, <span 547 style="font-style: italic;">localedir</span> is the second argument 548passed to <span style="font-family: monospace;">bindtextdomain()</span>, 549and <span style="font-style: italic;">lang</span> is the language (<span 550 style="font-style: italic;">LL</span>) or language and territory (<span 551 style="font-style: italic;">LL</span>_<span style="font-style: italic;">CC</span>), 552depending on the environment variables checked in step 1.</li> 553 <li>Check that the .mo file contains a translation for the string 554that is being asked for.<br> 555To do this, you need to convert the .mo file back to PO file format, 556through the command<br> 557 <div style="margin-left: 40px;"><code>$ msgunfmt </code><span 558 style="font-family: monospace;"><span style="font-style: italic;">localedir</span>/<span 559 style="font-style: italic;">lang</span>/LC_MESSAGES/<span 560 style="font-style: italic;">domain</span>.mo</span><br> 561 <code></code></div> 562and look for an <span style="font-family: monospace;">msgid</span> 563that matches the given string.<br> 564 </li> 565</ol> 566<h3>GNU gettext on Windows</h3> 567<h4><a name="windows_woe32"></a>What does Woe32 mean?</h4> 568“Woe32” denotes the Windows 32-bit operating systems for x86: Windows 569NT/2000/XP/Vista and Windows 95/98/ME. Microsoft uses the term “Win32” to 570denote these; this is a psychological trick in order to make everyone 571believe that these OSes are a “win” for the user. However, for most 572users and developers, they are a source of woes, which is why I call 573them “Woe32”.<br> 574<h4><a name="windows_howto"></a>How do I compile, link and run a 575program that uses the gettext() 576function?</h4> 577When you use RedHat's cygwin environment, it's as on Unix:<br> 578<ul> 579 <li>You need to add an <span style="font-family: monospace;">-I</span> 580option to the compilation command line, so that the compiler finds the <span 581 style="font-family: monospace;">libintl.h</span> include file, and</li> 582 <li>You need to add an <span style="font-family: monospace;">-L</span> 583option to the link command line, so that the linker finds the <span 584 style="font-family: monospace;">libintl</span> library.</li> 585</ul> 586When you use the Mingw environment (either from within cygwin, with <span 587 style="font-family: monospace;">CC="gcc -mno-cygwin"</span>, or from 588MSYS, with <span style="font-family: monospace;">CC="gcc"</span>), I 589don't know the details.<br> 590<br> 591When you use the Microsoft Visual C/C++ (MSVC) compiler, you will 592likely use the precompiled Woe32 binaries. For running a program that 593uses gettext(), one needs the <span style="font-family: monospace;">.bin.woe32.zip</span> 594packages of <span style="font-family: monospace;">gettext-runtime</span> 595and <span style="font-family: monospace;">libiconv</span>. As a 596developer, you'll also need the <span style="font-family: monospace;">xgettext</span> 597and <span style="font-family: monospace;">msgfmt</span> programs that 598are contained in the <span style="font-family: monospace;">.bin.woe32.zip</span> 599package of <span style="font-family: monospace;">gettext-tools</span>. 600Then<br> 601<ul> 602 <li>You need to add an <span style="font-family: monospace;">-MD</span> 603option to all compilation and link command lines. MSVC has six 604different, mutually incompatible, compilation models (<span 605 style="font-family: monospace;">-ML</span>, <span 606 style="font-family: monospace;">-MT</span>, <span 607 style="font-family: monospace;">-MD</span>, <span 608 style="font-family: monospace;">-MLd</span>, <span 609 style="font-family: monospace;">-MTd</span>, <span 610 style="font-family: monospace;">-MDd</span>); the default is <span 611 style="font-family: monospace;">-ML</span>. <span 612 style="font-family: monospace;">intl.dll</span> uses the <span 613 style="font-family: monospace;">-MD</span> model, therefore the rest 614of the program must use <span style="font-family: monospace;">-MD</span> 615as well.<br> 616 </li> 617 <li>You need to add an <span style="font-family: monospace;">-I</span> 618option to the compilation command line, so that the compiler finds the <span 619 style="font-family: monospace;">libintl.h</span> include file.<br> 620 </li> 621 <li>You need to add an <span style="font-family: monospace;">-L</span> 622option to the link command line, so that the linker finds the <span 623 style="font-family: monospace;">intl.lib</span> library.</li> 624 <li>You need to copy the <span style="font-family: monospace;">intl.dll</span> 625and <span style="font-family: monospace;">iconv.dll</span> to the 626directory where your <span style="font-family: monospace;">.exe</span> 627files are created, so that they will be found at runtime.<br> 628 </li> 629</ul> 630<h4><a name="windows_setenv"></a>Setting the <span 631 style="font-family: monospace;">LANG</span> 632environment variable doesn't have any effect</h4> 633If neither LC_ALL, LC_MESSAGES nor LANGUAGES is set, it's the LANG 634environment variable which determines the language into which gettext() 635translates the messages.<br> 636<br> 637You can test your program by setting the LANG environment variable from 638outside the program. In a Windows command interpreter:<br> 639<div style="margin-left: 40px;"><code>set LANG=de_DE</code><br> 640<code>.\myprog.exe</code><br> 641</div> 642Or in a Cygwin shell:<br> 643<div style="margin-left: 40px;"><code>$ env LANG=de_DE ./myprog.exe</code><br> 644</div> 645<br> 646If this test fails, look at the question “My program compiles and links 647fine, but doesn't output translated 648strings.” above.<br> 649<br> 650If this test succeeds, the problem is related in the way you set the 651environment variable. Here is a checklist:<br> 652<ul> 653 <li>Check that you are using the <span 654 style="font-family: monospace;">-MD</span> option in all compilation 655and link command lines. Otherwise you might end up calling the <span 656 style="font-family: monospace;">putenv()</span> function from 657Microsoft's <span style="font-family: monospace;">libc.lib</span>, 658whereas <span style="font-family: monospace;">intl.dll</span> is using 659the <span style="font-family: monospace;">getenv()</span> function 660from Mictosoft's <span style="font-family: monospace;">msvcrt.lib</span>.</li> 661 <li>Check that you set the environment variable using <span 662 style="font-style: italic;">both</span> <span 663 style="font-family: monospace;">SetEnvironmentVariable()</span> and <span 664 style="font-family: monospace;">putenv()</span>. A convenient way to 665do so, and to deal with the fact that some Unix systems have <span 666 style="font-family: monospace;">setenv()</span> and some don't, is the 667following function.<br> 668 <br> 669 <div style="margin-left: 40px;"><code>#include <string.h></code><br> 670 <code>#include <stdlib.h></code><br> 671 <code>#if defined _WIN32</code><br> 672 <code># include <windows.h></code><br> 673 <code>#endif</code><br> 674 <code></code><br> 675 <code>int my_setenv (const char * name, const char * value) {</code><br> 676 <code> size_t namelen = strlen(name);</code><br> 677 <code> size_t valuelen = (value==NULL ? 0 : strlen(value));</code><br> 678 <code>#if defined _WIN32</code><br> 679 <code> /* On Woe32, each process has two copies of the 680environment variables,</code><br> 681 <code> one managed by the OS and one 682managed by the C library. We set</code><br> 683 <code> the value in both locations, so that 684other software that looks in</code><br> 685 <code> one place or the other is guaranteed 686to see the value. Even if it's</code><br> 687 <code> a bit slow. See also</code><br> 688 <code> <<a 689 href="https://article.gmane.org/gmane.comp.gnu.mingw.user/8272">https://article.gmane.org/gmane.comp.gnu.mingw.user/8272</a>></code><br> 690 <code> <<a 691 href="https://article.gmane.org/gmane.comp.gnu.mingw.user/8273">https://article.gmane.org/gmane.comp.gnu.mingw.user/8273</a>></code><br> 692 <code> <<a 693 href="https://www.cygwin.com/ml/cygwin/1999-04/msg00478.html">https://www.cygwin.com/ml/cygwin/1999-04/msg00478.html</a>> 694*/</code><br> 695 <code> if (!SetEnvironmentVariableA(name,value))</code><br> 696 <code> return -1; </code><br> 697 <code>#endif</code><br> 698 <code>#if defined(HAVE_PUTENV)</code><br> 699 <code> char* buffer = (char*)malloc(namelen+1+valuelen+1);</code><br> 700 <code> if (!buffer)</code><br> 701 <code> return -1; /* no need to set errno = 702ENOMEM */</code><br> 703 <code> memcpy(buffer,name,namelen);</code><br> 704 <code> if (value != NULL) {</code><br> 705 <code> buffer[namelen] = '=';</code><br> 706 <code> memcpy(buffer+namelen+1,value,valuelen);</code><br> 707 <code> buffer[namelen+1+valuelen] = 0;</code><br> 708 <code> } else</code><br> 709 <code> buffer[namelen] = 0;</code><br> 710 <code> return putenv(buffer);</code><br> 711 <code>#elif defined(HAVE_SETENV)</code><br> 712 <code> return setenv(name,value,1);</code><br> 713 <code>#else</code><br> 714 <code> /* Uh oh, neither putenv() nor setenv() ... */</code><br> 715 <code> return -1;</code><br> 716 <code>#endif</code><br> 717 <code>}</code><br> 718 <code></code></div> 719 <br> 720 </li> 721</ul> 722<h3>Other</h3> 723<h4><a name="newline"></a>What does this mean: “'msgid' and 'msgstr' 724entries do not both end 725with '\n'”</h4> 726It means that when the original string ends in a newline, your 727translation must also end in a newline. And if the original string does 728not end in a newline, then your translation should likewise not have a 729newline at the end.<br> 730<h4><a name="translit"></a>German umlauts are displayed like 731“ge"andert” instead of “geändert”</h4> 732This symptom occurs when the <span style="font-family: monospace;">LC_CTYPE</span> 733facet of the locale is not set; then gettext() doesn't know which 734character set to use, and converts all messages to ASCII, as far as 735possible.<br> 736<br> 737If the program is doing<br> 738<code><br> 739setlocale (LC_MESSAGES, "");<br> 740<br> 741</code>then change it to<br> 742<code><br> 743setlocale (LC_CTYPE, "");<br> 744setlocale (LC_MESSAGES, "");<br> 745</code><br> 746or do both of these in a single call:<br> 747<code><br> 748setlocale (LC_ALL, "");<br> 749</code><br> 750If the program is already doing<br> 751<code><br> 752setlocale (LC_ALL, "");<br> 753</code><br> 754then the symptom can still occur if the user has not set <span 755 style="font-family: monospace;">LANG</span>, but instead has set <span 756 style="font-family: monospace;">LC_MESSAGES</span> to a valid locale 757and has set <span style="font-family: monospace;">LC_CTYPE</span> to 758nothing or an invalid locale. The fix for the user is then to set <span 759 style="font-family: monospace;">LANG</span> instead of <span 760 style="font-family: monospace;">LC_MESSAGES</span>.<br> 761<h4><a name="localename"></a>The <span style="font-family: monospace;">LANGUAGE</span> 762environment variable is ignored after I set <span 763 style="font-family: monospace;">LANG=en</span></h4> 764This is because “en” is a language name, but not a valid locale name. 765The <a href="https://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html">documentation</a> says:<br> 766<blockquote> 767In the <span style="font-family: monospace;">LANGUAGE</span> 768environment variable, but not in the <span 769 style="font-family: monospace;">LANG</span> environment variable, <span 770 style="font-style: italic;">LL</span>_<span style="font-style: italic;">CC</span><span 771 style="font-family: monospace;"> </span>combinations can be 772abbreviated as <span style="font-style: italic;">LL</span> to 773denote the language's main dialect.</blockquote> 774Why is <span style="font-family: monospace;">LANG=en</span> not 775allowed? Because <span style="font-family: monospace;">LANG</span> is 776a setting for the entire locale, including monetary information, and 777this depends on the country: en_GB, en_AU, en_ZA all have different 778currencies.<br> 779<h4><a name="nonascii_strings"></a>I use accented characters in my 780source code. How do I tell the 781C/C++ compiler in which encoding it is (like <span 782 style="font-family: monospace;">xgettext</span>'s <span 783 style="font-family: monospace;">--from-code</span> option)?</h4> 784Short answer: If you want your program to be useful to other people, 785then <span style="font-style: italic;">don't use accented characters</span> 786(or other non-ASCII characters) in string literals <span 787 style="font-style: italic;">in the source code</span>. Instead, use 788only ASCII for string literals, and use <span 789 style="font-family: monospace;">gettext()</span> to retrieve their 790display-ready form.<br> 791<br> 792Long explanation:<br> 793The reason is that the ISO C standard specifies that the character set 794at compilation time can be different from the character set at 795execution time.<br> 796The character encoding at compilation time is the one which determines 797how the source files are interpreted and also how string literals are 798stored in the compiled code. This character encoding is generally 799unspecified; for recent versions of GCC, it depends on the LC_CTYPE 800locale in effect during the compilation process.<br> 801The character encoding at execution time is the one which determines 802how standard functions like <span style="font-family: monospace;">isprint()</span>, 803<span style="font-family: monospace;">wcwidth()</span> etc. work and 804how strings written to standard output should be encoded. This 805character encoding is specified by POSIX to depend on the LC_CTYPE 806locale in effect when the program is executed; see also the description 807in the <a href="https://www.gnu.org/software/gettext/manual/html_node/Locale-Names.html">documentation</a>.<br> 808Strings in the compiled code are not magically converted between the 809time the program is compiled and the time it is run.<br> 810<br> 811Therefore what could you do to get accented characters to work?<br> 812<br> 813Can you ensure that the execution character set is the same as the 814compilation character set? Even if your program is to be used only in a 815single country, this is not realistically possible. For example, in 816Germany there are currently three character encodings in use: UTF-8, 817ISO-8859-15 and ISO-8859-1. Therefore you would have to explicitly 818convert the accented strings from the compilation character set to the 819execution character set at runtime, for example through iconv().<br> 820<br> 821Can you ensure that the compilation character set is the one in which 822your source files are stored? This is not realistically possible 823either: For compilers other than GCC, there is no way to specify the 824compilation character set. So let's assume for a moment that everyone 825uses GCC; then you will specify the LC_CTYPE or LC_ALL environment 826variable in the Makefile. But for this you have to assume that everyone 827has a locale in a given encoding. Be it UTF-8 or ISO-8859-1 - this is 828not realistic. People often have no locale installed besides the one 829they use.<br> 830<br> 831Use of wide strings <span style="font-family: monospace;">L"..."</span> 832doesn't help solving the problem, because on systems like FreeBSD or 833Solaris, the way how wide string literals are stored in compiled code 834depends on the compilation character set, just as it does for 835narrow strings <span style="font-family: monospace;">"..."</span>. 836Moreover, wide strings have problems of their own.<br> 837<br> 838Use of ISO C 99 Unicode escapes "\u<span style="font-style: italic;">xxxx</span>" 839doesn't help either because these characters are converted to the 840compilation character set at compile time; so again, since you can't 841guarantee that the compilation character set is not ASCII, you're 842risking compilation errors just as if the real character had been used 843in the source instead of the Unicode escape.<br> 844<br> 845So, in summary, there is no way to make accented characters in string 846literals work in C/C++.<br> 847<br> 848You might then wonder what <span style="font-family: monospace;">xgettext</span>'s 849<span style="font-family: monospace;">--from-code</span> option is good 850for. The answer is<br> 851<ol> 852 <li>For the comments in C/C++ source code. The compiler ignores them.<br> 853 </li> 854 <li>For other programming languages like Java, for which the compiler 855converts all string literals to UTF-8.</li> 856</ol> 857<br> 858<hr style="width: 100%; height: 2px;"> 859<address>GNU gettext FAQ<br> 860Bruno Haible <<a href="mailto:bruno@clisp.org">bruno@clisp.org</a>></address> 861<p>Last modified: 6 June 2020 862</p> 863</body> 864</html> 865