Совместное использование

Совместное использование [Вперед] [Вверх] [Назад] [Содержание]
Дальше: Об этом документе ... Вверх: Интернационализация сообщений Назад: Простой пример

Совместное использование

И наконец, проиллюстрируем совместное использование утилит Autoconf/Automake и Gettext. Обратимся к примеру из предыдущих глав.

Сначала изменим программу. В ней имеются две строковые константы (в файлах foo.c и bar.c), переводы которые необходимо предоставить. Следовательно, там будет находиться вызов функции gettext(), которую для этого следует обьявить. Лучще всего это сделать в общем заголовочном файле main.h, который изменится следующим образом:

#ifndef __MAIN_H__
#define __MAIN_H__

#include <stdio.h>
#include <libintl.h>

extern void foo (void);
extern void bar (void);

#define _(str) gettext(str)

#endif /* __MAIN_H__ */

Макрос _(str) не несет никакой смысловой нагрузки -- это просто соглашение. Соответственно файлы foo.c и bar.c изменятся так:

foo.c:

#include "main.h"

void foo (void) {
  printf (_("I am foo !\n"));
}

bar.c:

#include "main.h"

void bar (void) {
  printf (_("I am bar !\n"));
}

И наконец, инициируем операции локализации в фунцкии main():

#include "main.h"

int main (void) {

  setlocale (LC_MESSAGES, "");
  bindtextdomain ("prog", LOCALEDIR);
  textdomain ("prog");

  foo ();
  bar ();
  return 0;
}

Здесь мы для простоты предполагаем, что имя нащей программы ``prog'' вряд ли будет меняться, и внесем его непосредственно в код. Но, в отличие от предыдущего примера, LOCALEDIR будет устанавливаться при конфигурации программы. Для этого в файл Makefile.am придется внести некоторые изменения. Но сначала придется сделать следующее:

[user@host:~] cd prog-1.0
[user@host:prog-1.0] gettextize -f -c .

Очевидно, необходимы пояснения. Дело в том, что согласно фактическим стандартам GNU исходные тексты должны выглядеть некоторым определенным образом. В частности, исходные тексты должны быть размещены одним из трех описанных выше способов (deep/shallow/flat), в корневой директории проекта должны находиться файлы COPYING, INSTALL, NEWS и т.п., а при использовании интернационализации -- еще и файл ABOUT-NLS. Кроме того, при использовании интернационализации учитывается возможность компиляциии программы на платформе, где либо отсутствует фунцкиональность, необходимая для этого, либо просто устроена по-другому. Для решения этой проблемы весь код, реализующий функцию gettext(), включается в проект, а при конфигурации определяется, имеется ли правильно фунцкионирующий gettext() на данной платформе. Если да, то используется он, а ``принесенный с собой'' код игнорируется. Иначе же программа вынуждена использовать только ``принесенный с собой'' код. Соответствующий выбор обеспечивается правильной генерацией Makefile-файлов.

Для того, чтобы включить в проект исходный код, реализующий интернационализацию, и используется программа gettextize. По соглашению она создает в корневой директории проекта поддиректорию intl и копирует туда все необходимые файлы. Дополнительно в корневую директорию проекта копируется файл ABOUT-NLS.

Учитывая все вышесказанное, посмотрим на измененный Makefile.am:

SUBDIRS = po intl
localedir= $(prefix)/share/locale
DEFS = -DLOCALEDIR=\"$(localedir)\"

bin_PROGRAMS = prog
prog_SOURCES = main.c main.h foo.c bar.c

Снова пояснения. Ранее все четыре файла нащего проекта находились в корневой директории, т.е. проект имел организацию ``flat''. Теперь появилась две поддиректории:

  • intl, содержащая код, реализующий операции gettext();
  • po, по соглашению содержащая данные локализации;

и, следовательно, проект имеет организацию ``shallow'' (см. выше). Следовательно, необходимо указать поддиректории. Это достигается определением макроса SUBDIRS, который приведет к генерации корректного Makefile.in.

Следующие две строки необходимы для того, чтобы при конфигурации можно было определить имя директории, куда будут установлены файлы локализации, и придать соответствующее значение макросу LOCALEDIR в исходном коде. Переменная prefix является одной из стандартных замещаемых переменных configure, а так как данные локализации по соглашению находятся в $(prefix)/share/locale, то в Makefile.in после запуска automake появится определение localedir. И наконец, макрос DEFS=... используется, чтобы к стандартным опциям компилятора добавить пару -Dмакрос=значение для установки значения LOCALEDIR. Так как остальные исходные тексты остались без изменений, две оставшиеся строки файла Makefile.am остались без изменений.

Также необходимо изменить содержимое файла configure.in. Теперь он будет выглядеть так:

dnl Process this file with autoconf to produce a configure script.
AC_INIT(bar.c)
AM_INIT_AUTOMAKE(prog,1.0)

dnl Checks for programs.
AC_PROG_INSTALL
AC_PROG_CC
AC_PROG_MAKE_SET

dnl Check for internationalization support.
ALL_LINGUAS="en ru"
AC_SUBST(ALL_LINGUAS)
AM_GNU_GETTEXT

dnl Checks for libraries.

dnl Checks for header files.
AC_CHECK_HEADER(stdio.h)

dnl Checks for typedefs, structures, and compiler characteristics.

dnl Checks for library functions.
AC_CHECK_FUNC(printf)

AC_OUTPUT(Makefile intl/Makefile po/Makefile.in)

Добавлены следующие макросы:

  • ALL_LINGUALS, информирующий о том, какие локализации предоставляются;
  • AM_GNU_GETTEXT, информирущий о том, что используется GNU gettxet

Как и в примере из предыдушей главы, макрос AM_GNU_GETTEXT является нестандартным, и его нужно поместить в файл aclocal.m4, запустив программу aclocal.



Dmitry A. Antipov
1999-05-26