I have a small application that I develop and I am distributing; now I would like to add i18n support to it with gettext. I see that gettext requires running several commands and generating various files (and updating them when new strings are included in the source code).
What is the usual way to have gettext interact with a typical git workflow? Should I generate my .pot
file myself and include it in the repository, or should it be generated automatically at build time by my Makefile? What about .mo
files? Similarly, do I need to include msgmerge
in my build script, or do I just add its result to the version-controlled files?
I am using C++, a hand-written Makefile (no automake) and github, in case it matters.
Three types of files are involved here, and all of them are generated, at least kind of.
The
.pot
PO Template file that contains the master message catalog. This is under version control in every project I know although it is strictly spoken generated and redundant.The
.po
files with the individual translations. They are sometimes generated, sometimes not. When you merge in new strings withmsgmerge
, they are generated. But when your translators send back a new translation, they are not. You have to put them under version control because they contain the translations.The
.mo
files that the.po
files compile to. Do not put them under version control but ship them with releases (source and binary).More important is the logic in your Makefile. None of the above mentioned files should be generated automatically but only on demand. Otherwise your
po/
directory will be dirty, whenever you edit a source file.IMHO it is best practice to ensure that a git clone can be built without having the gettext tools (xgettext, msgmerge, msgfmt) installed. Make sure that they are only invoked on demand.
The Perl binding for gettext libint-perl (disclaimer: I am the author) contains a sample po directory with a complete Makefile: https://github.com/gflohr/libintl-perl/tree/master/sample/simplecal/po. You can probably use that Makefile directly in your project. You only have to modify the
xgettext
invocation for the programming language of your choice.I'm not sure this is quite the right sort of question for SO.
However, the answer is "it's up to you". Projects do it both ways and there are pros and cons to each. A lot of it depends on (a) how many contributors you have and (b) how easy you want to make it on other people to be able to build directly from your Git repository.
If you check in your derived files then other people don't need to have any of these extra tools installed on their systems to build the software (but, see a caveat below). However, if you have multiple contributors and they don't all have identical versions of the tools, you can get warring spurious file changes as these derived files are regenerated with slight differences then committed.
If you don't check in your derived files then your repository much cleaner and, abstractly, more "correct" (just like you wouldn't expect people to check in the object files that are generated during compilation). However anyone who wants to build the code will need to have a suite of tools installed themselves. On GNU/Linux systems this is pretty trivial but not so on some others. Generally people who make this choice provide a shell script that will "prep" the source directory.
One caveat with the first method: even if you do check in all derived files you probably will need to write and run some sort of "prep" script, assuming you are using make and writing makefiles to keep your gettext files up to date: Git doesn't preserve timestamps so if you want to avoid rebuilding of derived files after they've been cloned or checked out, you need to run a little script that will
touch
files in the proper order to ensuremake
knows they're up to date.FWIW, I personally never check in any derived files into my repositories. I acknowledge this makes life difficult for some users but IMO it's the right way to do things.