LINUX.ORG.RU

Локализация ПО с помощью утилиты gettext

 ,


1

1

Пробовал русифицировать простую программу, написанную на C++, но так и не смог до конца осилить полную последовательность действий, необходимую для успешной локализации.

Вот код программы:

#include <iostream>
#include <stdlib.h>
#include <libintl.h>
#include <locale.h>

#define _(String) gettext (String)
using namespace std;
int main()
{
    setlocale(LC_ALL,"");
    bindtextdomain("test","/usr/share/locale");
    textdomain("test");
    system("clear");
    cout << (_("TEST"));
    return 0;
}

Выполняю следующие действия:

1). в каталоге с файлом test.cpp создаётся каталог po;

2). с помощью команды

xgettext -d test -o po/test.pot -k_ -s test.cpp
создаётся файл test.pot в каталоге po;

3). в каталоге po создаётся каталог ru;

4). с помощью команды

cp test.pot ru/test.po
создаётся файл test.po в каталоге ru.

Что нужно делать далее?

★★★★★

ru/test.po

 msgid "TEST"
-msgstr ""
+msgstr "ТЕСТ"

Остальное (компиляция .po) и выкладывание в каталог локали — за системой сборки пакета/установки пакета.

bormant ★★★★★
()

можно с помощью boost.locale, там есть инструкция еще :)

zerhud
()

Из .po нужно сгененировать .mo. Еще его нужно закнуть по пути, указанному в исходниках, чтобы перевод подхватился.

Panika
()
Ответ на: комментарий от Mischutka

Что-то вроде :

msgfmt test.po -o /usr/share/locale/ru/LS_MESSAGES/test.mo.

Если сделано верно, но прога не переводится, то можно попробовать указать Content-Type: text/plain; charset=UTF-8 в test.po вместо дефолтной и перегенерировать .mo. Также стоит проверить права на .mo и установить соответствующие, если потребуется.

Panika
()
Ответ на: комментарий от Panika

Работать в /usr/share/locale – плохая идея. Во первых для этого нужны права рута, а во вторых так появляется мусор в системных папках.

DrBrown
()
Ответ на: комментарий от DrBrown

Ну начинается… Во-первых, протестировать перевод без root никак не получится. Во-вторых в системных каталогах/директориях уже по умолчанию замусорено, достаточно посмотреть в /usr/share/locale.

Panika
()
Ответ на: комментарий от Panika

Чтобы протестировать переводы без рута, не надо хардкорить пути к каталогам переводов. Берём директорию, в которой лежит программа, поднимаемся на один уровень, добавляем /share/locale и результат отдаем в bindtextdomain.

DrBrown
()
Ответ на: комментарий от Panika

Для начала включи мозги, потом перемотай страницу на начало, там у ТС есть немного кода со строкой

bindtextdomain("test","/usr/share/locale");

Вот про это я и говорил.

DrBrown
()
Последнее исправление: DrBrown (всего исправлений: 1)
Ответ на: комментарий от DrBrown

Для начала включил мозги

Давай-ка повежливее.

Panika
()
Ответ на: комментарий от bormant

Отредактировал ru/test.po:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-06 18:09+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#: test.cpp:14
msgid "TEST"
msgstr "Проверка"
Затем создал mo-файл командой:
msgfmt test.po -o test.mo
Скопировал его в /usr/share/locale/ru/LC_MESSAGES/

Выполнил запуск программы:

LANG=ru_IN
./test

Результат работы программы: TEST.

Mischutka ★★★★★
() автор топика
Ответ на: комментарий от DrBrown

Выполнил

sudo chmod 644 /usr/share/locale/ru/LC_MESSAGES/test.mo
, затем снова
LANG=ru_IN
./test
И снова результат работы программы: TEST.

Mischutka ★★★★★
() автор топика
Ответ на: комментарий от Mischutka

Там нет LANG=ru_IN, там LANG=hi_IN! Я же говорил заменить:

"Content-Type: text/plain; charset=CHARSET\n"

На:

"Content-Type: text/plain; charset=UTF-8\n"

Пересоздай .mo, копируй перевод и ставь права. Потом запускай.

PS. Я проверил, прога из примера по ссылке работает.

Panika
()
Ответ на: комментарий от Mischutka

Несомненно, человек, выделивший несколько часов своего времени, в своей единственный выходной, заслуживает хамский ответ в виде тролинга.

Panika
()
Ответ на: комментарий от Panika

Какой троллинг? Я несколько раз приступал к локализации программы с помощью gettext и до сегодняшнего дня терпел неудачу в этом деле. И только сегодня, во многом, благодаря Вам это дело наконец-то завершилось успехом.

Mischutka ★★★★★
() автор топика
Ответ на: комментарий от Mischutka

это дело наконец-то завершилось успехом

И замечательно.

// А я как счастливый пользователь Qt Linguist читаю эту тему, как советский зритель смотрел телепередачу «их нравы»…

hobbit ★★★★★
()
Последнее исправление: hobbit (всего исправлений: 1)

Итак, как видно из данной темы, человек вроде меня может долго маяться, пытаясь русифицировать программу с помощью утилиты gettext, не имея перед глазами небольшого примера на родном языке, поэтому я решил сделать итоговую выжимку успешно проведённой локализации (вдруг кому пригодится):

Код программы, выводящий на экран слово «ТЕСТ»:

#include <iostream>
#include <stdlib.h>
#include <libintl.h>
#include <locale.h>

#define _(String) gettext (String)
using namespace std;
int main()
{
    setlocale(LC_ALL,"");
    bindtextdomain("test","/usr/share/locale");
    textdomain("test");
    system("clear");
    cout << (_("TEST"));
    return 0;
}

Задача: русифицировать данную программу таким образом, чтобы на экран выводилось слово «Проверка».

Решение:

1). в каталоге с файлом test.cpp создаётся каталог po;

2). с помощью команды

xgettext -d test -o po/test.pot -k_ -s test.cpp
создаётся файл test.pot в каталоге po;

3). в каталоге po создаётся каталог ru;

4). с помощью команды

cp test.pot ru/test.po
создаётся файл test.po в каталоге ru;

5). редактирование файла ru/test.po:

строка

"Content-Type: text/plain; charset=CHARSET\n"
меняется на
"Content-Type: text/plain; charset=UTF-8\n"

строка

msgstr ""
меняется на
msgstr "Проверка"
6). с помощью команды
msgfmt test.po -o test.mo
создаётся файл test.mo в каталоге ru;

7). с использованием прав root файл test.mo копируется в /usr/share/locale/ru/LC_MESSAGES, затем на данный файл устанавливается соответствующее право доступа:

sudo chmod 644 /usr/share/locale/ru/LC_MESSAGES/test.mo

8). выполняется запуск программы из каталога, в котором находится бинарник test:

LANGUAGE=ru
./test

Хочу ещё раз выразить особую признательность пользователю Panika, без терпения и помощи которого, составление данной методики не стало бы возможным.

Mischutka ★★★★★
() автор топика
Ответ на: комментарий от Panika

Неудачно сформулировал ответ. Думаю, лучше сформулировать таким образом: пользуясь различными источниками (в основном англоязычными), так и не смог определиться с методикой локализации ПО с помощью gettext и, соответственно, русифицировать программу.

Mischutka ★★★★★
() автор топика
11 апреля 2023 г.
Ответ на: комментарий от Panika

Для записи в /usr/share/locale требуются права root, но вы можете указать locale или $(pwd)/locale, расположенный в каталоге проекта, чтобы получилось так:

├── locale
│   └── ru
│       └── LC_MESSAGES
│           └── script.mo
├── script.po
└── script.sh

Для проверки этого достаточно.

Pyka
()
Ответ на: комментарий от hobbit

// А я как счастливый пользователь Qt Linguist

А тебя не смущает, что расположение переводов приходится или «хардкодить» в программе, или задавать в совершенно левых переменных окружения?

ABW ★★★★★
()
Ответ на: комментарий от ABW

Для случая, когда программа позволяет переключать язык прямо в своих настройках, хардкод — вполне нормальное решение, а что?

hobbit ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.