diff options
author | ptomulik <ptomulik@meil.pw.edu.pl> | 2012-06-06 20:14:26 (GMT) |
---|---|---|
committer | ptomulik <ptomulik@meil.pw.edu.pl> | 2012-06-06 20:14:26 (GMT) |
commit | 045bb7d4cfc3e1a4c0c41619248211c7c3b9ca5a (patch) | |
tree | ce81b8f9455c354c8a85e77134b0ece9b5903c66 /doc/user/gettext.xml | |
parent | 69ec58de81fae315449b1f6f425526977a7a2699 (diff) | |
download | SCons-045bb7d4cfc3e1a4c0c41619248211c7c3b9ca5a.zip SCons-045bb7d4cfc3e1a4c0c41619248211c7c3b9ca5a.tar.gz SCons-045bb7d4cfc3e1a4c0c41619248211c7c3b9ca5a.tar.bz2 |
Added gettext tools
Diffstat (limited to 'doc/user/gettext.xml')
-rw-r--r-- | doc/user/gettext.xml | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/doc/user/gettext.xml b/doc/user/gettext.xml new file mode 100644 index 0000000..9b1b631 --- /dev/null +++ b/doc/user/gettext.xml @@ -0,0 +1,335 @@ +<!-- + + __TOOL_COPYRIGHT__ + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--> + + <para> + The &t-link-gettext; toolset supports internationalization and localization + of SCons-based projects. The tools provided within &t-link-gettext; by + automatize generation and updates of translation files. You can manage + translations and translation templates simillary as it was done with + autotools. + </para> + + <section> + <title>Prerequisites</title> + <para> + Setup your operating system, so you can use several languages. In following + examples we use locales <literal>en_US</literal>, <literal>de_DE</literal>, + and <literal>pl_PL</literal>. + </para> + + <para> + Ensure, that you have <ulink url="http://www.gnu.org/software/gettext/manual/gettext.html">GNU gettext + utilities</ulink> installed on your system. + </para> + + <para> + To edit translation files, you may install <ulink url="http://www.poedit.net/">poedit</ulink> editor. + </para> + </section> + + <section> + <title>Simple project</title> + <para> + Let's start with some simple project, the "Hello world" program + for example + <programlisting> + /* hello.c */ + #include <stdio.h> + int main(int argc, char* argv[]) + { + printf("Hello world\n"); + return 0; + } + </programlisting> + + Prepare simple <filename>SConstruct</filename> script to compile the + program. + <programlisting> + # SConstruct + env = Environment() + hello = Program(["hello.c"]) + </programlisting> + </para> + + <para> + Now we'll convert the project to multi-lingual one. I assume, that you + already have <ulink url="http://www.gnu.org/software/gettext/manual/gettext.html">GNU gettext + utilities</ulink> installed. If not, install it from repository, or + download from <ulink url="http://ftp.gnu.org/gnu/gettext/"> + http://ftp.gnu.org/gnu/gettext/</ulink>. For the purpose of this example, + you should have following three locales installed on your system + <literal>en_US</literal>, <literal>de_DE</literal> and + <literal>pl_PL</literal>. On debian, for example, you may enable certain + locales through <command>dpkg-reconfigure locales</command>. + </para> + + <para> + We first prepare the <filename>hello.c</filename> program, for + internationalization. Change the previous code so it reads as follows: + <programlisting> + /* hello.c */ + #include <stdio.h> + #include <libintl.h> + #include <locale.h> + int main(int argc, char* argv[]) + { + bindtextdomain("hello", "locale"); + setlocale(LC_ALL, ""); + textdomain("hello"); + printf(gettext("Hello world\n")); + return 0; + } + </programlisting> + This way we prepared source code. Detailed recipes for such preparation can + be found at <ulink url="http://www.gnu.org/software/gettext/manual/gettext.html#Sources"> + http://www.gnu.org/software/gettext/manual/gettext.html#Sources</ulink>. + The <function>gettext("...")</function> in above source has two purposes. + First is is recognized by the <command>xgettext(1)</command> program, which + we will use to extract from the sources the messages for localization. + Second, it calls the <literal>gettext</literal> library internals to + translate the message at runtime. + </para> + + <para> + Now we shall instruct SCons how to generate and maintain translation files. + For that, we use &b-link-Translate; builder and &b-link-MOFiles; builder. + First one takes a couple of source files, extracts internationalized + messages from them, creates so-called <literal>POT</literal> file + (translation template), and then creates <literal>PO</literal> translation + files, one for each requested language. Later, during the development + lifecycle, the builder keeps all these files up-to date. The + &b-link-MOFiles; builder compiles the <literal>PO</literal> files to binary + form. After all, we install the <literal>MO</literal> files under directory + called <filename>locale</filename>. + </para> + + <para> The complete code of + <filename>SConstruct</filename> script for multi-lingual "Hello world" will + be following: + <programlisting> + # SConstruct + env = Environment( tools = ['default', 'gettext'] ) + hello = env.Program(["hello.c"]) + env['XGETTEXTFLAGS'] = [ + '--package-name=%s' % 'hello', + '--package-version=%s' % '1.0', + ] + po = env.Translate(["pl","en", "de"], ["hello.c"], POAUTOINIT = 1) + mo = env.MOFiles(po) + InstallAs(["locale/en/LC_MESSAGES/hello.mo"], ["en.mo"]) + InstallAs(["locale/pl/LC_MESSAGES/hello.mo"], ["pl.mo"]) + InstallAs(["locale/de/LC_MESSAGES/hello.mo"], ["de.mo"]) + </programlisting> + </para> + <para> + Generate translation files with <command>scons po-update</command>. + You should see the output from SCons simillar to this: + <screen> + ptomulik@:$ scons po-update + scons: Reading SConscript files ... + scons: done reading SConscript files. + scons: Building targets ... + Entering '/home/ptomulik/projects/tmp' + xgettext --package-name=hello --package-version=1.0 -o - hello.c + Leaving '/home/ptomulik/projects/tmp' + Writting 'messages.pot' (new file) + msginit --no-translator -l pl -i messages.pot -o pl.po + Created pl.po. + msginit --no-translator -l en -i messages.pot -o en.po + Created en.po. + msginit --no-translator -l de -i messages.pot -o de.po + Created de.po. + scons: done building targets. + </screen> + </para> + + <para> + If everything is right, you shall see following new files. + <screen> + ptomulik@:$ ls *.po* + de.po en.po messages.pot pl.po + </screen> + </para> + + <para> + Open <filename>en.po</filename> in <command>poedit</command> and provide + english "translation" to message <literal>"Hello world\n"</literal>. Do the + same for <filename>de.po</filename> (deutsch) and + <filename>pl.po</filename> (polish). Let the translations be, for example: + <itemizedlist> + <listitem><para> + <literal>en: "Welcome to beautiful world!\n"</literal> + </para></listitem> + <listitem><para> + <literal>de: "Hallo Welt!\n"</literal> + </para></listitem> + <listitem><para> + <literal>pl: "Witaj swiecie!\n"</literal> + </para></listitem> + </itemizedlist> + </para> + <para> + Now compile the project by executing <command>scons</command> command. The + output should be similar to this: + <screen> + ptomulik@:$ scons + scons: Reading SConscript files ... + scons: done reading SConscript files. + scons: Building targets ... + msgfmt -c -o de.mo de.po + msgfmt -c -o en.mo en.po + gcc -o hello.o -c hello.c + gcc -o hello hello.o + Install file: "de.mo" as "locale/de/LC_MESSAGES/hello.mo" + Install file: "en.mo" as "locale/en/LC_MESSAGES/hello.mo" + msgfmt -c -o pl.mo pl.po + Install file: "pl.mo" as "locale/pl/LC_MESSAGES/hello.mo" + scons: done building targets. + </screen> + SCons automatically compiled <literal>PO</literal> files to binary format + <literal>MO</literal>, and the <literal>InstallAs</literal> lines installed + these files under <filename>locale</filename> folder. + </para> + <para> + Your program should be now ready. You may try it as follows (linux): + <screen> + ptomulik@:$ LANG=en_US.UTF-8 ./hello + Welcome to beautiful world + </screen> + <screen> + ptomulik@:$ LANG=de_DE.UTF-8 ./hello + Hallo Welt + </screen> + <screen> + ptomulik@:$ LANG=pl_PL.UTF-8 ./hello + Witaj swiecie + </screen> + </para> + <para> + To demonstrate further life of translation files, let's change polish + translation (<command>poedit pl.po</command>) to <literal>"Witaj drogi + swiecie\n"</literal>. Run <command>scons</command> to see how scons + reacts to this + <screen> + ptomulik@:$scons + scons: Reading SConscript files ... + scons: done reading SConscript files. + scons: Building targets ... + msgfmt -c -o pl.mo pl.po + Install file: "pl.mo" as "locale/pl/LC_MESSAGES/hello.mo" + scons: done building targets. + </screen> + </para> + <para> + Now, open <filename>hello.c</filename> and add another one + <literal>printf</literal> line with new message. + <programlisting> + /* hello.c */ + #include <stdio.h> + #include <libintl.h> + #include <locale.h> + int main(int argc, char* argv[]) + { + bindtextdomain("hello", "locale"); + setlocale(LC_ALL, ""); + textdomain("hello"); + printf(gettext("Hello world\n")); + printf(gettext("and good bye\n")); + return 0; + } + </programlisting> + </para> + <para> + Compile project with <command>scons</command>. This time, the + <command>msgmerge(1)</command> program is used by SCons to update + <literal>PO</literal> file. The output from compilation is like: + <screen> + ptomulik@:$scons + scons: Reading SConscript files ... + scons: done reading SConscript files. + scons: Building targets ... + Entering '/home/ptomulik/projects/tmp' + xgettext --package-name=hello --package-version=1.0 -o - hello.c + Leaving '/home/ptomulik/projects/tmp' + Writting 'messages.pot' (messages in file were outdated) + msgmerge --update de.po messages.pot + ... done. + msgfmt -c -o de.mo de.po + msgmerge --update en.po messages.pot + ... done. + msgfmt -c -o en.mo en.po + gcc -o hello.o -c hello.c + gcc -o hello hello.o + Install file: "de.mo" as "locale/de/LC_MESSAGES/hello.mo" + Install file: "en.mo" as "locale/en/LC_MESSAGES/hello.mo" + msgmerge --update pl.po messages.pot + ... done. + msgfmt -c -o pl.mo pl.po + Install file: "pl.mo" as "locale/pl/LC_MESSAGES/hello.mo" + scons: done building targets. + </screen> + </para> + <para> + The last example demonstrates what happens, if we change the source code + in such way, that the internationalized messages do not change. The answer + is, that none of translation files (<literal>POT</literal>, + <literal>PO</literal>) is touched (i.e. no content changes, no + creation/modification time changed and so on). Let's append another one + instruction to the program (after the last printf), so its code becomes: + <programlisting> + /* hello.c */ + #include <stdio.h> + #include <libintl.h> + #include <locale.h> + int main(int argc, char* argv[]) + { + bindtextdomain("hello", "locale"); + setlocale(LC_ALL, ""); + textdomain("hello"); + printf(gettext("Hello world\n")); + printf(gettext("and good bye\n")); + printf("----------------\n"); + return a; + } + </programlisting> + Compile project. You'll see on your screen + <screen> + ptomulik@:$scons + scons: Reading SConscript files ... + scons: done reading SConscript files. + scons: Building targets ... + Entering '/home/ptomulik/projects/tmp' + xgettext --package-name=hello --package-version=1.0 -o - hello.c + Leaving '/home/ptomulik/projects/tmp' + Not writting 'messages.pot' (messages in file found to be up-to-date) + gcc -o hello.o -c hello.c + gcc -o hello hello.o + scons: done building targets. + </screen> + As you see, the internationalized messages ditn't change, so the + <literal>POT</literal> and the rest of translation files have not + even been touched. + </para> + </section> |