Редактирование: Gettext в приложениях Windows собранных CMake с использованием MinGW

Материал из Wiki.crossplatform.ru

Перейти к: навигация, поиск
Внимание: Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.

ПРЕДУПРЕЖДЕНИЕ: Длина этой страницы составляет 30 килобайт. Страницы, размер которых приближается к 32 КБ или превышает это значение, могут неверно отображаться в некоторых браузерах. Пожалуйста, рассмотрите вариант разбиения страницы на меньшие части.

Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия Ваш текст
Строка 2: Строка 2:
В данном руководстве будет разобран простой пример локализации приложения в [http://ru.wikipedia.org/wiki/Microsoft_Windows ОС Microsoft Windows] с помощью пакета программ [http://ru.wikipedia.org/wiki/Gettext Gettext].
В данном руководстве будет разобран простой пример локализации приложения в [http://ru.wikipedia.org/wiki/Microsoft_Windows ОС Microsoft Windows] с помощью пакета программ [http://ru.wikipedia.org/wiki/Gettext Gettext].
-
 
При этом подразумеваем, что приложение будем собирать с использованием компилятора [http://ru.wikipedia.org/wiki/MinGW MinGW] при помощи системы кросс-платформенной сборки [http://ru.wikipedia.org/wiki/CMake CMake].
При этом подразумеваем, что приложение будем собирать с использованием компилятора [http://ru.wikipedia.org/wiki/MinGW MinGW] при помощи системы кросс-платформенной сборки [http://ru.wikipedia.org/wiki/CMake CMake].
-
После запуска приложение просто будет выполнять печать в консоль строки ''"Привет, мир!"'' и завершаться.
+
После своего запуска, приложение просто будет выполнять печать в консоль строки ''"Привет, мир!"'' и завершаться.
Данное руководство не является панацеей или каким-то определенным рецептом при решении данной задачи,  
Данное руководство не является панацеей или каким-то определенным рецептом при решении данной задачи,  
Строка 18: Строка 17:
# [http://ru.wikipedia.org/wiki/Microsoft_Windows ОС Microsoft Windows] - операционная система семейств XP/Vista/7 и т.п.
# [http://ru.wikipedia.org/wiki/Microsoft_Windows ОС Microsoft Windows] - операционная система семейств XP/Vista/7 и т.п.
# [http://ru.wikipedia.org/wiki/MinGW MinGW] - порт пакета утилит и компиляторов GCC для Microsoft Windows.  
# [http://ru.wikipedia.org/wiki/MinGW MinGW] - порт пакета утилит и компиляторов GCC для Microsoft Windows.  
-
# [http://ru.wikipedia.org/wiki/CMake CMake] - кросс-платформенная система автоматизации сборки программного обеспечения из исходного кода.
+
# [http://ru.wikipedia.org/wiki/CMake CMake] - кроссплатформенная система автоматизации сборки программного обеспечения из исходного кода.
# [http://ru.wikipedia.org/wiki/Gettext Gettext] - библиотека проекта GNU для интернационализации.
# [http://ru.wikipedia.org/wiki/Gettext Gettext] - библиотека проекта GNU для интернационализации.
= Получение и установка инструментов =
= Получение и установка инструментов =
-
== Получение и установка операционной системы MS Windows ==
+
== Получение и установка опереционной системы MS Windows ==
Описывать этот процесс не имеет смысла, т.к. всем и так все ясно. :)
Описывать этот процесс не имеет смысла, т.к. всем и так все ясно. :)
Строка 29: Строка 28:
'''Получение:'''
'''Получение:'''
-
Этот пакет программ распространяется бесплатно и скачать инсталляцию можно [http://www.mingw.org/ тут].
+
Этот пакет программ распространяется бесплатно и скачать инсталляцию можно '''тут'''.
'''Установка:'''
'''Установка:'''
Строка 40: Строка 39:
'''Получение:'''
'''Получение:'''
-
Этот пакет программ распространяется бесплатно и скачать инсталляцию можно [http://www.cmake.org/cmake/resources/software.html тут].
+
Этот пакет программ распространяется бесплатно и скачать инсталляцию можно '''тут'''.
-
 
+
Скачивать и использовать можно как версии 2.6.x так и версии 2.8.x, но лучше все-же использовать более свежую версию 2.8.x.
Скачивать и использовать можно как версии 2.6.x так и версии 2.8.x, но лучше все-же использовать более свежую версию 2.8.x.
Строка 56: Строка 54:
Скачиваемый пакет является полным набором всех необходимых файлов для локализации приложения,
Скачиваемый пакет является полным набором всех необходимых файлов для локализации приложения,
-
т.е. содержит как ''runtime'' компоненты, так и компоненты для разработки программ.  
+
т.е. содержит как RunTime компоненты, так и компоненты для разработки программ.  
'''Установка:'''
'''Установка:'''
Строка 65: Строка 63:
При этом, интересующими нас директориями будут являться:
При этом, интересующими нас директориями будут являться:
-
* ''D:\GnuWin32\bin''    - директория ''runtime'' компонентов
+
* ''D:\GnuWin32\bin''    - директория runtime компонентов
-
* ''D:\GnuWin32\include'' - директория заголовочных файлов [http://ru.wikipedia.org/wiki/Gettext Gettext] для разработчика
+
* ''D:\GnuWin32\include'' - директория заголовочных файлов [http://ru.wikipedia.org/wiki/Gettext Gettext] для разрабтчика
-
* ''D:\GnuWin32\lib''    - директория линкуемых библиотек [http://ru.wikipedia.org/wiki/Gettext Gettext] для разработчика
+
* ''D:\GnuWin32\lib''    - директория линкуемых библиотек [http://ru.wikipedia.org/wiki/Gettext Gettext] для разрабтчика
= Подготовка к сборке =
= Подготовка к сборке =
== Создание дерева директории исходных кодов проекта ==
== Создание дерева директории исходных кодов проекта ==
-
Итак, локализовать мы будем простое консольное приложение (которое сами же и напишем и соберем) на два языка: ''русский'' и ''немецкий''.
+
Итак, локализовать мы будем простое консольное приложение (которое сами же и напишем и соберем) на два языва: ''русский'' и ''немецкий''.
 +
 
 +
При этом, наш проект будет иметь такую структуру директорий:
-
При этом, наш проект будет иметь следующую структуру директорий:
 
  /SourceTestProject
  /SourceTestProject
  |->main.cpp
  |->main.cpp
Строка 83: Строка 82:
  |
  |
  |->CMakeLists.txt
  |->CMakeLists.txt
 +
где:
где:
* ''/SourceTestProject'' - директория исходных кодов нашего проекта
* ''/SourceTestProject'' - директория исходных кодов нашего проекта
Строка 91: Строка 91:
== Создание директории сборки проекта ==
== Создание директории сборки проекта ==
-
Сборку проекта с использованием [http://ru.wikipedia.org/wiki/CMake CMake] лучше всего производить вне директории нашего проекта чтобы не засорять её продуктами компиляции, а также для исключения случайной модификации исходных файлов директории проекта.  
+
Сборку проекта с использованием [http://ru.wikipedia.org/wiki/CMake CMake] лучше всего производить вне директории нашего проекта,
 +
чтобы не замусоривать её, а также для исключения случайной модификации исходных файлов директории проекта.
 +
Да и вообще, сборка вне директории с исходным кодом является "правилом хорошего тона".
-
{{Замечание | Да и вообще, сборка вне директории с исходным кодом является "правилом хорошего тона".}}
+
Поэтому для сборки, параллельно директории проекта, создадим директорию сборки:
-
Поэтому для сборки, параллельно директории проекта создадим директорию сборки:
 
  /..
  /..
  |->/SourceTestProject
  |->/SourceTestProject
  |->/build-project
  |->/build-project
 +
где:
где:
* ''/..''                - какая-то родительская директория
* ''/..''                - какая-то родительская директория
Строка 130: Строка 132:
Скопируем/переместим этот файл куда нибудь, например, пусть он будет находится в корне диска ''D:''
Скопируем/переместим этот файл куда нибудь, например, пусть он будет находится в корне диска ''D:''
 +
  D:\MyBuildEnv.bat
  D:\MyBuildEnv.bat
Строка 171: Строка 174:
* ''#include <locale.h>''          - подключаемые системные заголовки компилятора
* ''#include <locale.h>''          - подключаемые системные заголовки компилятора
* ''#include <iostream>''          - подключаемые системные заголовки компилятора
* ''#include <iostream>''          - подключаемые системные заголовки компилятора
-
* ''domain("test")''              - домен которому мы присвоили имя ''test''(этим именем у нас также будет назван и исполняемый файл ''test.exe'' нашего приложения)
+
* ''domain("test")''              - домен которому мы присвоили имя "test" (этим именем у нас также будет назван и исполняемый файл ''test.exe'' нашего приложения)
* ''string localedir("./locale")'' - это имя каталога в котором будут находится бинарные файлы переводов.
* ''string localedir("./locale")'' - это имя каталога в котором будут находится бинарные файлы переводов.
* ''gettext("Hello, world!")''    - собственно строка, которую будем локализовать на разные языки.
* ''gettext("Hello, world!")''    - собственно строка, которую будем локализовать на разные языки.
-
{{Замечание | Функция ''bind_textdomain_codeset(domain.c_str(), "CP866")'' нам необходима для корректного отображения кириллических символов в консоли и использовать ее нужно только в том случае, если мы имеем консольное приложение. Если же у нас приложение имеет GUI, то использовать данную функцию нельзя (или можно, но нужно вместо кодировки ''CP866'' указать кодировку ''CP1251''). Дело в том, что в Windows в консоль выводятся символы в кодировке ''CP866'', но в GUI приложения в кодировке ''CP1251''!}}
+
 
 +
{{Замечание | Функция ''bind_textdomain_codeset(domain.c_str(), "CP866")'' нам необходима для корректного отображения киррилических символов в консоли и использовать ее нужно только в том случае, если мы имеем консольное приложение. Если же у нас приложение имеет GUI, то использовать данную функцию нельзя (или можно, но нужно вместо кодировки ''CP866'' указать кодировку ''CP1251''). Дело в том, что в Windows в консоль выводятся символы в кодировке ''CP866'', но в GUI приложения в кодировке ''CP1251''!}}
== Определение структуры и содержимого каталогов собранного приложения ==
== Определение структуры и содержимого каталогов собранного приложения ==
Строка 183: Строка 187:
{{Замечание | Да и у нас, в исходном коде приложения (см. ''main.cpp'') задано именно такое расположение каталога локализации.}}
{{Замечание | Да и у нас, в исходном коде приложения (см. ''main.cpp'') задано именно такое расположение каталога локализации.}}
 +
{{Замечание | В данном случае речь идет о структуре каталогов уже готового (т.е. собранного приложения)
{{Замечание | В данном случае речь идет о структуре каталогов уже готового (т.е. собранного приложения)
-
и никоим образом это не относится к описанному в '''Создание дерева директории исходных кодов проекта'''. }}
+
и никоим образом это не относится к описанному в (<Создание дерева директории исходных кодов проекта>). }}
Поддиректории в этой директории должны иметь определенную структуру, например:
Поддиректории в этой директории должны иметь определенную структуру, например:
 +
  /InstallTestProject
  /InstallTestProject
  |-> test.exe
  |-> test.exe
Строка 213: Строка 219:
* один находится в корне проекта с исходными кодами
* один находится в корне проекта с исходными кодами
  /SourceTestProject/CMakeLists.txt
  /SourceTestProject/CMakeLists.txt
 +
* другой находится в корне директории /po c переводами
* другой находится в корне директории /po c переводами
  /po/CMakeLists.txt
  /po/CMakeLists.txt
Строка 219: Строка 226:
===Содержимое файла /SourceTestProject/CMakeLists.txt===
===Содержимое файла /SourceTestProject/CMakeLists.txt===
 +
Ниже приведено содержимое файла с подробными комментариями:
Ниже приведено содержимое файла с подробными комментариями:
<source lang="cmake">
<source lang="cmake">
Строка 259: Строка 267:
===Содержимое файла /po/CMakeLists.txt===
===Содержимое файла /po/CMakeLists.txt===
 +
Ниже приведено содержимое файла с подробными комментариями:
Ниже приведено содержимое файла с подробными комментариями:
<source lang="cmake">
<source lang="cmake">
Строка 283: Строка 292:
# Генерируем шаблон перевода, сканируя исходники приложения и
# Генерируем шаблон перевода, сканируя исходники приложения и
# извлекая всё что подлежит переводу.
# извлекая всё что подлежит переводу.
-
# Еще помимо *.cpp файлов сюда можно подставлять и *.h файлы.
 
file( GLOB _srcFiles ../*.cpp )
file( GLOB _srcFiles ../*.cpp )
Строка 308: Строка 316:
Генерация бинарных файлов переводов происходит у нас в несколько этапов:
Генерация бинарных файлов переводов происходит у нас в несколько этапов:
 +
# Сначала из всех ''*.cpp'' файлов проекта извлекаются всё то, что подлежит переводу, и создается файл-шаблон ''*.pot'' (команда ''$xgettext'').
# Сначала из всех ''*.cpp'' файлов проекта извлекаются всё то, что подлежит переводу, и создается файл-шаблон ''*.pot'' (команда ''$xgettext'').
-
# Далее, по очереди проверяется наличие готовых исходных файлов переводов ''*.po'' разных языков и на их основе и основе шаблона ''*.pot'' создаются обновленные файлы переводов ''*.po'' (команда ''$msgmerge''). При этом, исходные файлы переводов остаются нетронутыми. {{Замечание | Это сделано для исключения модификации файлов в директории исходных кодов.}}  
+
# Далее, по очереди проверяется наличие готовых исходных файлов переводов ''*.po'' разных языков и, на их основе, и основе шаблона ''*.pot'' создаются обновленные файлы переводов ''*.po'' (команда ''$msgmerge''). При этом, исходные файлы переводов остаются нетронутыми. {{Замечание | Это сделано для исключения модификации файлов в директории исходных кодов.}}  
# Далее, на основе каждого вновь созданного (обновленного) файла ''*.po'' создается результирующий бинарный файл перевода ''*.gmo'' ( команда ''$msgfmt'').
# Далее, на основе каждого вновь созданного (обновленного) файла ''*.po'' создается результирующий бинарный файл перевода ''*.gmo'' ( команда ''$msgfmt'').
= Сборка приложения =
= Сборка приложения =
-
Итак, после того, как все готово, можно приступить к сборке приложения,  
+
Итак, после того как все готово, можно приступить к сборке приложения,  
но перед этим необходимо сгенерировать и перевести файлы исходных переводов.
но перед этим необходимо сгенерировать и перевести файлы исходных переводов.
Строка 335: Строка 344:
Теперь файл шаблона ''messages.pot'' нам не нужен и мы можем его удалить.  
Теперь файл шаблона ''messages.pot'' нам не нужен и мы можем его удалить.  
-
{{Замечание | Для распространения исходных кодов нашего проекта достаточно иметь только файлы переводов ''*.po'', естественно, иметь и ''*.cpp'' и ''CMakeLists.txt'', что само собой разумеется.}}
+
Т.е. для распространения исходных кодов нашего проекта достаточно иметь только файлы переводов ''*.po''
 +
(естественно и иметь ''*.cpp'' и ''CMakeLists.txt'', это само собой разумеется).
Далее, произведем "перевод" сообщений в ''*.po'' файлах на требуемые нам языки.
Далее, произведем "перевод" сообщений в ''*.po'' файлах на требуемые нам языки.
Для этого, редактируем их любым доступным образом и добавляем нужные сообщения:
Для этого, редактируем их любым доступным образом и добавляем нужные сообщения:
 +
* для ''po\de\messages.po''
* для ''po\de\messages.po''
  ...
  ...
Строка 345: Строка 356:
  msgstr "Hallo Welt!"
  msgstr "Hallo Welt!"
  ...
  ...
 +
* для ''po\ru\messages.po''
* для ''po\ru\messages.po''
  ...
  ...
Строка 366: Строка 378:
При успехе в консоль отобразится примерно следующее:
При успехе в консоль отобразится примерно следующее:
 +
  D:\SVN\lang_test>cd ..\build
  D:\SVN\lang_test>cd ..\build
   
   
Строка 416: Строка 429:
В итоге, в директории ''d:\install'' получим следующую структуру каталогов:
В итоге, в директории ''d:\install'' получим следующую структуру каталогов:
 +
  /install
  /install
     |->/Program Files
     |->/Program Files
Строка 426: Строка 440:
                         |            |->test.mo
                         |            |->test.mo
                         |->/ru
                         |->/ru
-
                              |->/LC_MESSAGES
+
                            |->/LC_MESSAGES
-
                                      |->test.mo
+
                                    |->test.mo
{{Замечание | Как видно, файлы переводов теперь вместо расширений ''*.gmo'' имеют расширение ''*.mo'', процесс переименования файлов произошел в процессе установки приложения. }}
{{Замечание | Как видно, файлы переводов теперь вместо расширений ''*.gmo'' имеют расширение ''*.mo'', процесс переименования файлов произошел в процессе установки приложения. }}
Строка 439: Строка 453:
После выполнения в консоли увидим:
После выполнения в консоли увидим:
 +
  D:\SVN\inst\Program Files\test>bin\test.exe
  D:\SVN\inst\Program Files\test>bin\test.exe
  Привет, мир!
  Привет, мир!
 +
= Важные замечания =
{{Замечание | Так как мы линковали наше приложение с библиотеками от [http://ru.wikipedia.org/wiki/Gettext Gettext], то для правильной его работы необходимо, чтобы наше приложение имело к ним доступ, для чего можно поступить двумя путями:
{{Замечание | Так как мы линковали наше приложение с библиотеками от [http://ru.wikipedia.org/wiki/Gettext Gettext], то для правильной его работы необходимо, чтобы наше приложение имело к ним доступ, для чего можно поступить двумя путями:
* Или, в каталог с исполнеяемым файлом ''test.exe'' скопировать как минимум такие библиотеки [http://ru.wikipedia.org/wiki/Gettext Gettext] как: ''libintl3.dll'' и ''libiconv2.dll''. И в этом случае, наше приложение будет работать на любой машине где не установлен [http://ru.wikipedia.org/wiki/Gettext Gettext].
* Или, в каталог с исполнеяемым файлом ''test.exe'' скопировать как минимум такие библиотеки [http://ru.wikipedia.org/wiki/Gettext Gettext] как: ''libintl3.dll'' и ''libiconv2.dll''. И в этом случае, наше приложение будет работать на любой машине где не установлен [http://ru.wikipedia.org/wiki/Gettext Gettext].
* Или, если на машине установлен Gettext, необходимо в переменных окружения прописать путь к runtime компонентам Gettext (т.е. путь к директории где находятся разделяемые библиотеки ''*.dll'' [http://ru.wikipedia.org/wiki/Gettext Gettext]-а , например, ''/bin''). }}
* Или, если на машине установлен Gettext, необходимо в переменных окружения прописать путь к runtime компонентам Gettext (т.е. путь к директории где находятся разделяемые библиотеки ''*.dll'' [http://ru.wikipedia.org/wiki/Gettext Gettext]-а , например, ''/bin''). }}

Пожалуйста, обратите внимание, что все ваши добавления могут быть отредактированы или удалены другими участниками. Если вы не хотите, чтобы кто-либо изменял ваши тексты, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений, или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого (см. Wiki.crossplatform.ru:Авторское право). НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ МАТЕРИАЛЫ!


Шаблоны, использованные на текущей версии страницы: