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