Hi Alexandre et al., In November/December 2003, we started thinking about how to extend automake so that po/Makefile.in.in can be replaced with a po/Makefile.am or entirely integrated into the main Makefile.am.
On 2003-11-11 I explained the details of existing PO file support. http://lists.gnu.org/archive/html/automake/2003-11/msg00046.html On 2003-12-14 you replied: http://lists.gnu.org/archive/html/automake/2003-12/msg00097.html > It might be nice to devise a `dir_PRIMARY' syntax, for > uniformity with the other installable kinds of files. This way > maybe we can even get rid of "the PO directory" assumption (can > we?). > > I'm thinking of something along the lines of > > locale_POTS = foo.pot > foo_pot_SOURCES = a.c a.h b.c b.h ... > foo_pot_LANGFILE = LINGUAS > foo_pot_XGETTEXTFLAGS = --keyword=_ --keyword=N_ > etc. > > (For a moment I though about using `locale_DOMAINS = foo', but I > realized that foo_SOURCES also lists the source of the foo binary.) I completely agree. You know the principles of automake better than me. > One way to further decouple the Gettext tools from the Makefile > rules is to supply tools that achieve the most complex > operations. This would also help people who write their own > Makefile.in. (Think about install-info or libtool > --mode=install.) Yes. This is an excellent way to minimize the interdependencies between automake and gettext releases. I'll add a 'potool' program to gettext. Furthermore this will allow to treat the generation of "synthetic" .gmo files like [EMAIL PROTECTED] and [EMAIL PROTECTED] completely transparently, without effort from the developer. Let me bring concrete proposals. I need your cooperation because I won't learn Perl nor the automake internals. ------------------------------------------------------------------------- 1) Choice of the PRIMARY. The two entities that are to be managed are - POT files (PO templates, containing untranslated messages), - collections of PO files, one per language. Should we have two primaries for this, or a single one? Since the relation between the two is 1 POT file -- 0 or 1 collections of PO files, it appears to be useful to have a single primary, for the POT file. The presence of a LINGUAS setting for the POT file could then determine whether there is an associated collection of PO files. So, for example: noinst_POTS = hello.pot denotes a POT file only, locale_POTS = hello.pot hello_pot_LINGUAS = de fr nl denotes a POT file with associated PO files (German, French, Dutch in this case). In the second case automake generates rules for installing the compiled PO files (in .gmo or similar format). I believe that choosing two different kinds of primaries would needlessly make things more complex. It would be possible to simplify the generated Makefile by collecting all the PO files and/or all compiled message catalogs in a tar file or ar file, but it decreases transparency for the maintainer and for the translator. A directory populated with individual files (and with individual timestamps) is easier to handle than a tar file or ar file. Keeping transparency is more important than saving 50 or 100 lines of automake code. ------------------------------------------------------------------------- 2) Kinds of message catalogs. The rules for installing message catalogs depends on the type of message catalog. The simplest would be if the user can simply declare it like this: hello_pot_CATALOGTYPE = {gmo,qm,properties,class,msg} The default CATALOGTYPE should of course been 'gmo'. The CATALOGTYPE influences the naming and rules for the compiled message catalogs. The CATALOGTYPE has no effect if no associated _LINGUAS variable is specified. In the following, let's concentrate on the common 'gmo' case. ------------------------------------------------------------------------- 3) Installation. xxxxxx_POTS denotes the POT file and message catalogs that are to be installed under xxxxxxdir. That directory depends on the CATALOGTYPE setting: - .gmo files are installed under $(localedir), - Qt programs: .qm files are installed under $(pkgdatadir)/locale, - Java programs: .properties or .class files are not directly installed. - Tcl programs: .msg files are installed under $(pkgdatadir)/msgs. I propose to let the developer take care of this. I.e. in the .gmo case he writes locale_POTS = hello.pot In the Qt case he writes: pkglocaledir = $(pkgdatadir)/locale pkglocale_POTS = hello.pot In the Java case he writes: noinst_POTS = hello.pot In the Tcl case he writes: pkglocaledir = $(pkgdatadir)/msgs pkglocale_POTS = hello.pot Rationale: It helps keeping automake consistent. This choice of the installation directory is not much burden on the programmer. Already now the programmers must be aware to not use bin_LTLIBRARIES or lib_PROGRAMS. ------------------------------------------------------------------------- 4) Naming of PO files in the source directory. I propose to incorporate the name of the POT file as a prefix. Currently, the German PO file is called de.po. I propose to call it for locale_POTS = hello.pot hello.de.po, and for locale_POTS = po/hello.pot po/hello.de.po. The TP distributes files under the name $(DOMAIN)-$(VERSION).$(LOCALE).pot. I think removing the version number is appropriate, since it is not desirable that old PO files accumulate in the directory. The 'msginit' program will need a change for this naming convention. Automake should check that for any POT primary that has a _LINGUAS specification, the name ends in ".pot"; otherwise the gettext "domain" and the prefix of PO files cannot be determined from it in an unambiguous way. ------------------------------------------------------------------------- 5) Naming of compiled message catalogs in the source directory. Remember that these are distributed with the source package so that the installer doesn't need the gettext tools installed. I propose to put the .gmo files next to the .po files, with the same prefix. This is simple and easy to understand. It doesn't allow to use these .gmo files between "make" and "make install". Support for trying an uninstalled program with i18n enabled requires a "make install localedir=." command and a different argument to bindtextdomain in the code. ------------------------------------------------------------------------- 6) How do the rules for a hello-world program look like? Like this: ============================== po/Makefile.am =============================== locale_POTS = hello.pot hello_pot_LINGUAS = af ca de el es fr ga hu it ja nl pl pt ro ru sk sl \ sr sv tr uk vi zh_CN zh_TW hello_pot_SOURCES = hello.c hello_pot_SOURCEDIR = $(top_srcdir) hello_pot_XGETTEXT_OPTIONS = \ --keyword=_ --flag=_:1:pass-c-format \ --keyword=N_ --flag=N_:1:pass-c-format hello_pot_XGETTEXT_MINVERSION = 0.13 hello_pot_COPYRIGHT_HOLDER = Free Software Foundation, Inc. ============================================================================= ------------------------------------------------------------------------- 7) How to write rules that combine just the POT file, not the translations? According to the choices made in 1), these look like this: locale_POTS = hello.pot hello_pot_LINGUAS = de fr nl noinst_POTS = hello-c.pot hello-php.pot hello-java.pot hello_pot_POTADD = hello-c.pot hello-php.pot hello-java.pot The hello.pot combines the hello-c.pot, hello-php.pot, hello-java.pot by use of xgettext. ------------------------------------------------------------------------- 8) How to write rules that combine the POT file and the corresponding translations? This will be useful for gnulib, where the POT file of a package should contain several "modular" POT files. The developer simply declares the languages like this: locale_POTS = hello.pot hello_pot_LINGUAS = de fr nl noinst_POTS = error.pot getopt.pot hello_pot_SOURCES = hello.c hello_pot_SOURCEDIR = $(top_srcdir) hello_pot_POTADD = error.pot getopt.pot error_pot_LINGUAS = de fr nl getopt_pot_LINGUAS = fr Here you see why _POTADD is not the same as _SOURCES: The _SOURCES are relative to the _SOURCEDIR (so that the filenames occurring in the context lines of the POT file don't contain unncessary "../"), whereas the _POTADD are relative to the current directory. ------------------------------------------------------------------------- 9) How are the Makevars parameters integrated? They are set as additional variables for the primary. Examples: hello_pot_XGETTEXT_OPTIONS = ... hello_pot_XGETTEXT_MINVERSION = ... hello_pot_COPYRIGHT_HOLDER = ... hello_pot_MSGID_BUGS_ADDRESS = ... hello_pot_EXTRA_LOCALE_CATEGORIES = ... hello_pot_USE_MSGCTXT = ... (USE_MSGCTXT exists in gettext-0.15, and XGETTEXT_MINVERSION does not yet exist in gettext.) Future developments: To allow the installer download translations from the internet, that were produced after the package release, the following could be supported: hello_pot_DOWNLOAD_URLS = \ http://www.iro.umontreal.ca/translation/trans/%L/hello-%V.%L.po \ ftp://ftp.unex.es/pub/gnu-i18n/po/trans/%L/hello-%V.%L.po hello_pot_VERSION = $(VERSION) ------------------------------------------------------------------------- Now, what do you think of this? The next step after defining the syntax in the Makefile.am will be to describe what it expands to in the Makefile.in, and to define the command-line options of 'potool'. Bruno