LINUX.ORG.RU

Не грузится mo-файл

 , ,


0

1

Не знаю уже, куда копать. Есть несколько еще библиотек на вала (по сути на Си), где все настроено похоже и все работает.

Есть одна не рабочая библиотека, назовем ее libanon.
Библиотека зависит от GLib, собираю с помощью CMake. Опции сборки получены через (gettext явно как-то не подключаю):

pkg_check_modules( GLIB2 REQUIRED gio-2.0 glib-2.0 gobject-2.0 gmodule-2.0 gthread-2.0 )

Компилятору Си также передаю флаги:

-DGETTEXT_PACKAGE=\«libanon\» -DG_LOG_DOMAIN=\«libanon\»

Если флаги не передать, то сборка фейлится, так как не объявлен GETTEXT_PACKAGE. Все логично тут.

Внутри библиотеки есть весь (?) необходимый код:

#include <glib/gi18n-lib.h>
...
bindtextdomain («libanon», «po»);
_tmp2_ = _ («Some text»);

Перевод «Some text» прописан в po-файле, собран mo-файл и лежит он в

./po/ru/LC_MESSAGES/libanon.mo

Собираю тестовую программу, смотрю вывод:

strace ./bin/anon_test 2>&1 | grep --color '\.mo'

И вижу, как грузятся mo-файлы glib, libc, других моих аналогичных libanon библиотек, но mo-файл libanon не упоминается в выводе, даже нет попыток его открыть.

★★

Может там рабочий каталог меняется. Можно попробовать вместо «po» использовать полный путь.

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

Беда в том, что тестовая программа вообще не пытается открыть libanon.mo, ни в каком каталоге (это по strace видно). Дело точно не в неправильно указанном каталоге.

Я к сожалению даже не знаю логики gettext, например когда он должен открыть mo-файл, при вызове bindtextdomain или при первом вызове _() с новым доменом?

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

Что мешает проверить тем же strace-ом на примере из пары строк или (лучше!) посмотреть в исходники gettext?

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

Я к сожалению даже не знаю логики gettext, например когда он должен открыть mo-файл, при вызове bindtextdomain или при первом вызове _() с новым доменом?

Отложено, т.е. когда текущий domain первый раз запрашивается. Текущий, кстати, устанавливается функцией textdomain(), может её не хватает.

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

перечитай man bindtextdomain. должно лежать в ./po/locale/ru/LC_MESSAGES/libanon.mo

Повторюсь, ошибка не в каталоге с mo, по strace видно, что libanon.mo не ищется вообще

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

Что мешает проверить тем же strace-ом на примере из пары строк или (лучше!) посмотреть в исходники gettext?

На паре строк работает, на других моих либах работает. Пробовал сократить эту - не заработало. Возможно, попробую еще раз копнуть в эту сторону или даже в исходники gettext.

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

Отложено, т.е. когда текущий domain первый раз запрашивается. Текущий, кстати, устанавливается функцией textdomain(), может её не хватает.

Ясно, спасибо.
Текущий, я так понимаю, вполне берется из переменной GETTEXT_DOMAIN. В других либах вообще не вызываю ничего кроме _() и все работает. Хотя попробую вызвать textdomain(), как доберусь до компа.

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

из переменной GETTEXT_DOMAIN

То есть _PACKAGE

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

попробую вызвать textdomain(), как доберусь до компа.

Завтра попробую такой код:

warning("0>>> %s", Intl.textdomain(null));
var some_text = _("Some text");
warning("1>>> %s", Intl.textdomain(null));
Intl.textdomain("libanon");
warning("2>>> %s", Intl.textdomain(null));
var another_text = _("Another text");
warning("3>>> %s", Intl.textdomain(null));
Вместе с:
strace ./bin/anon_test 2>&1 | egrep --color '\.mo|>>>'

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

Завтра попробую такой код:

Попробовал, переводы заработали, увидел вот что:

(anon_test:5735): libanon-WARNING **: anon.vala:106: 0>>> messages
(anon_test:5735): libanon-WARNING **: anon.vala:108: 1>>> messages
(anon_test:5735): libanon-WARNING **: anon.vala:110: 2>>> libanon
open("/home/user/libanon/po//ru_RU.UTF-8/LC_MESSAGES/libanon.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/user/libanon/po//ru_RU.utf8/LC_MESSAGES/libanon.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/user/libanon/po//ru_RU/LC_MESSAGES/libanon.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/user/libanon/po//ru.UTF-8/LC_MESSAGES/libanon.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/user/libanon/po//ru.utf8/LC_MESSAGES/libanon.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/user/libanon/po//ru/LC_MESSAGES/libanon.mo", O_RDONLY) = 12
(anon_test:5735): libanon-WARNING **: anon.vala:112: 3>>> libanon

Т.е. после textdomain(«libanon») при вызове _() открылся mo-файл.
Блин, но в доках GLib не написано, что нужно выставлять textdomain в библиотеке. PACKAGE_GETTEXT 100% прописан корректно (пробовал его распечатать там же). В других моих, может где-то более простых, либах хватает одних _() с прописанным GETTEXT_PACKAGE.

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

в доках GLib не написано, что нужно выставлять textdomain

Да и выставлять его — костыль. textdomain() выставляет дефотный домен для приложения (см. ниже).

Вот здесь https://developer.gnome.org/glib/stable/glib-I18N.html#g-dgettext еще описано, что если не удалось загрузить переводы для дефолтного домена, то GLib не грузит и другие переводы, чтобы приложение не стало наполовину переведенным. Но это не мой случай:

  • У меня переводы библиотек грузятся, т.к. не выполняется условие «textdomain() has been called to set a default text domain)»;
  • Пробовал вызывать textdomain() в начале main() anon_test и ставить домен другой либы, для которой есть рабочие переводы (и они подгрузились в момент вызова textdomain() судя по strace), но libanon все равно не заработал.
Tayler ★★
() автор топика

Ох, мой был косяк.
В одном из хэдеров, подключаемых в libanon, был позорно подключен

#include <glib/gi18n.h>
В итоге _() редефайнилось на g_dcgettext((void*)0, ..., ...).
Раскурил анализом Си-кода после препроцессора (gcc -E).
Всем отозвавшимся спасибо за помощь!

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