em_installtdeb(1) generate Emdebian TDeb translation packages and source.



em_installtdeb [LANG_CODE]

em_installtdeb [--no-act]

em_installtdeb [--no-sign]

Copyright and Licence

 Copyright (C) 2007-2008  Neil Williams <[email protected]>
 This package is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 3 of the License, or
 (at your option) any later version.
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.


em_installtdeb is a debhelper add-on created by Emdebian to create translation packages (tdebs). em_installtdeb is intended to separate out the individual translation files from the current Debian packages into packages without any translation files and a series of tdeb locale packages, one per translation. Generated packages use the syntax: $package-locale-$language_code_$version_all.deb

(From v3.0.0 onwards, TDebs are architecture-independent.)

Once a package uses em_installtdeb, translation files should be removed from all packages in the normal build. em_installtdeb runs as a second build (very small, very fast) that simply converts and packages the *.po files into tdebs. A tdeb source package is created (.dsc, .tar.gz and .changes) alongside the existing build data. The source package is used by translators to build updated or new tdeb packages. Tdeb .changes files need to be uploaded only to secondary locale repositories instead of the main Debian mirrors and these repositories can have much more relaxed upload policies. Tdeb packages have no dependencies and no packages may depend upon them.

em_installtdeb currently only supports gettext translation.

Certain language codes need to be modified to make acceptable components of a debian package name. Underscores are converted to hyphens, '@' is converted to '+' and all codes are made lowercase. These changes only apply to the package name, the installation location is unchanged.

The locale package must use GETTEXT_PACKAGE for the eventual filename of the binary translation file - although this may be the same as the $dh{MAINPACKAGE}. GETTEXT_PACKAGE is determined by upstream, not Debian. When building the whole package, the binary translation file may be in debian/tmp/usr/share/locale/$lang/LC_MESSAGES but when in translator mode, this location is not available. Instead retrieve GETTEXT_PACKAGE from the POT filename, the Makefile GETTEXT_PACKAGE macro or if that is not set, use the upstream source package name. This may need extending.

The ``source'' for translators therefore includes:

 debian/rules  /* dummy file */
 po*/$lang.po  /* if any */
 po*/$GETTEXT_PACKAGE.pot /* may be more than one */

Some packages use multiple po directories and em_installtdeb checks for a POT file in all usable po directories, including them in the tdeb source along with all po files: e.g.


When packaged, the tdeb built from this source would contain:


An equivalent tdeb for the 'de' locale would contain:


This compares with the Debian ``space-is-cheap'' model of separating the application.mo and library.mo files but combining all the translations in one package, so that the equivalent Debian package would contain:


(Repeated again for the other package.)

Many packages contain dozens of translations - some contain over 70 .mo files and .mo files can vary between 2kb and 30kb each. Without tdebs, all users get all 70 translations even if only one or two are used. With tdebs, all users get both the library and the application translations but only for the one or two locales supported by that installation. The extra granularity achieved by splitting application.mo and library.mo into separate packages for the same locale is not likely to be worth the workload. (In effect, this means that packages with multiple translations are not actually supported - at least not in the original manner.) It is possible that developments like dpkg filtering will be able to implement this final level of division, where necessary.

em_installtdeb will try to generate the necessary POT file(s) and then create a $package_$version_tdeb.tar.gz containing the source files.

Any package can have a source tdeb, as long as the POT file is either packaged or can be built. The package does not have to have been translated already.

For more detail on Tdebs, see: <http://www.emdebian.org/emdebian/langupdate.html> <http://wiki.debian.org/i18n/TranslationDebs>

Note that the Emdebian implementation of tdebs differs from the proposed tdebs for Debian because Emdebian does not care about manpages in general, let alone translated manpages. Once the 'nodocs' DEB_BUILD_OPTION is supported in debhelper, this will not be an issue as the tdebs can be built for Emdebian without any manpages. Other translated documentation would be omitted under 'nodocs' too. Images containing translated text are relatively few.

To manage the increase in package numbers (average ten fold), the secondary locale repository organises the tdeb packages by locale root, e.g. 'en_GB' is beneath 'en' and '[email protected]' beneath 'sr'. Each locale root becomes a single apt source in the locale repository to support fallback from a specific locale to a the more general locale root. In this manner, each device only has to cope with cache data for a fraction of the total number of tdeb packages (roughly 1 part in 30).

A new C/C++ application then handles the installation and update of tdeb packages according to the list of supported locales and the list of installed packages. Data cached by langupdate is temporary and is not intended to be stored between runs of langupdate.


The default action is to process all available po files.

This mode is used by package maintainers to generate tdeb source and binaries at the end of the Debian build (with translation files omitted). Note that this means a second .dsc, second .changes, a second (much smaller) .tar.gz using the tdeb.tar.gz suffix and a separate upload to the secondary locale repositories. emdebian-tools will include handlers for these operations and Debian can create similar wrappers as needed.

This single-language update mode of em_installtdeb is unlikely to be retained once dpkg-gentdeb is available because translations are less likely to be updated within Emdebian than within Debian.

LANG_CODE can either be the name of the locale as specified in the PO filename (fr, en_GB, [email protected] etc.) or the name of the locale as specified in the eventual package name (fr, en-gb, sr+ltn etc.).

If a po file already exists for this locale, em_installtdeb processes just that one translation and builds a single tdeb package.

If the po file does not exist, em_installtdeb exits with an error. (Copy the POT file from the original source to create a new po file for the new locale and edit it to include the new translation, then run em_installtdeb again.)

LANG_CODE is intended as a 'translator mode' where individual tdeb packages can be built by the translator and uploaded to a suitable repository. em_installtdeb creates the tdeb source tarball, a usable .dsc file to describe the tdeb source and a tdeb.changes file.

em_installtdeb will just print the control data that would be used for the tdeb if the debhelper --no-act option is used.
em_installtdeb normally calls 'debsign' when the .changes is written. This option suppresses this behaviour.

Use in Debian

Note that the use of debian/xcontrol in the current script means that XS-TDeb-Build-Directory and XS-TDeb-POT-Names will need to be supported in debian/control before adoption by Debian. At the same time, XC-Package-Type: tdeb needs support too.

reprepro needs a patch to accept .tdeb and allow .tdeb in the repository files:
 $ reprepro --ignore=extension -b /path/ includedeb \
 unstable ../qof-locale-sv_0.7.5-1em1_arm.tdeb
 $ ls /opt/reprepro/locale/pool/main/q/qof/

 Filename: pool/main/q/qof/qof-locale-sv_0.7.5-1em1_all.deb
 Description: sv translation for qof (tdeb)

reprepro also needs a way to handle a .tdeb .changes file.
 reprepro -b /opt/reprepro/locale/ include unstable ../qof_0.7.5-1em1_arm.changes
 'qof-locale-id_0.7.5-1em1_arm.tdeb' is not .deb or .udeb!
 There have been errors!

For the debian/rules file in the generated source package to be useful, em_installtdeb needs to be split up so that dpkg-buildpackage gets the right data to create a usable .changes file because em_installtdeb is too good at cleaning up after itself.


Until version 3.0.0, Emdebian packages used architecture-dependent TDebs but this proved to be unnecessary, TDebs are now architecture-independent, using the internal gettext wrapper.

Other translations

Packages may also contain translated manpages and translations for debconf templates. These translations are not packaged or processed by em_installtdeb because Emdebian does not need to handle such files and because each variant will need customised handling (most of the debconf support is already available). If Tdebs are to be supported in Debian, these issues will need to be resolved such that Emdebian can continue to only package the gettext program translations, omitting translated manpages and leaving debconf translation support to existing tools.

Use of debhelper::init

The problem with init is that $dh{DOPACKAGES} works from debian/control and the locale packages are not *in* debian/control. So em_installtdeb gets the ``Source: '' package name to use as the prefix for the locale package names.

Translator mode

This is a special mode, not usually something that debhelper would do. In translator mode, debian/rules is not used. em_installtdeb does everything needed to configure, build, install and package the requested tdeb and the appropriate tdeb source package using a temporary directory to ensure that the correct control and changelog data is available.

There are a few issues with this method - the build needs a debian/changelog but also needs to create the translation as a native package (to prevent the need for an empty .diff.gz) even if the upstream package is non-native. The current solution is to create a new version (with tdeb appended) to create a clean changelog entry that does not try to re-close bugs from the original upload and then use that version to force dpkg-source to treat the tdeb source as a native package. This may need changing in future but such changes are likely to need support in dpkg. This method, whilst not ideal, does work with the existing support. Using a modified version also ensures that the generated files do not interfere with other builds in the same location. Although not used, a basic debian/rules file is added.

if DEBSIGN_KEYID is defined, em_installtdeb tries to use debsign to sign the .tdeb.changes and .dsc files. This could be made optional if it is later decided that translation uploads will need full changelog entries to close bugs in the Debian BTS. Part of the appeal of tdebs is that i18n bugs would not normally need to be filed in the BTS.