automake
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

moving po/Makefile.in.in to automake


From: Bruno Haible
Subject: moving po/Makefile.in.in to automake
Date: Mon, 26 Jun 2006 15:59:14 +0200
User-agent: KMail/1.9.1

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 address@hidden and address@hidden 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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]