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

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

(Различия между версиями)
Перейти к: навигация, поиск
(Запуск приложения)
 
(38 промежуточных версий не показаны.)
Строка 1: Строка 1:
= Введение =
= Введение =
-
В данном руководстве будет разобран простой пример локализации приложения в ОС Windows с помощью пакета программ Gettext.
+
В данном руководстве будет разобран простой пример локализации приложения в [http://ru.wikipedia.org/wiki/Microsoft_Windows ОС Microsoft Windows] с помощью пакета программ [http://ru.wikipedia.org/wiki/Gettext Gettext].
-
При этом подразумеваем, что приложение будем собирать с использованием компилятора MinGW при помощи системы кросс-платформенной сборки CMake.
+
-
После своего запуска, приложение просто будет выполнять печать в консоль строки ''"Привет, мир!"'' и завершаться.
+
При этом подразумеваем, что приложение будем собирать с использованием компилятора [http://ru.wikipedia.org/wiki/MinGW MinGW] при помощи системы кросс-платформенной сборки [http://ru.wikipedia.org/wiki/CMake CMake].
 +
 
 +
После запуска приложение просто будет выполнять печать в консоль строки ''"Привет, мир!"'' и завершаться.
Данное руководство не является панацеей или каким-то определенным рецептом при решении данной задачи,  
Данное руководство не является панацеей или каким-то определенным рецептом при решении данной задачи,  
Строка 15: Строка 16:
Для решения нашей задачи нам понадобятся следующее программное обеспечение (ПО):
Для решения нашей задачи нам понадобятся следующее программное обеспечение (ПО):
-
# ОС Microsoft Windows - операционная система семейств XP/Vista/7 и т.п.
+
# [http://ru.wikipedia.org/wiki/Microsoft_Windows ОС Microsoft Windows] - операционная система семейств XP/Vista/7 и т.п.
-
# MinGW - порт пакета утилит и компиляторов GCC для Microsoft Windows.  
+
# [http://ru.wikipedia.org/wiki/MinGW MinGW] - порт пакета утилит и компиляторов GCC для Microsoft Windows.  
-
# CMake - кроссплатформенная система автоматизации сборки программного обеспечения из исходного кода.
+
# [http://ru.wikipedia.org/wiki/CMake CMake] - кросс-платформенная система автоматизации сборки программного обеспечения из исходного кода.
-
# Gettext - библиотека проекта GNU для интернационализации.
+
# [http://ru.wikipedia.org/wiki/Gettext Gettext] - библиотека проекта GNU для интернационализации.
= Получение и установка инструментов =
= Получение и установка инструментов =
-
== Получение и установка опереционной системы MS Windows ==
+
== Получение и установка операционной системы MS Windows ==
Описывать этот процесс не имеет смысла, т.к. всем и так все ясно. :)
Описывать этот процесс не имеет смысла, т.к. всем и так все ясно. :)
Строка 28: Строка 29:
'''Получение:'''
'''Получение:'''
-
Этот пакет программ распространяется бесплатно и скачать инсталляцию можно '''тут'''.
+
Этот пакет программ распространяется бесплатно и скачать инсталляцию можно [http://www.mingw.org/ тут].
'''Установка:'''
'''Установка:'''
Строка 39: Строка 40:
'''Получение:'''
'''Получение:'''
-
Этот пакет программ распространяется бесплатно и скачать инсталляцию можно '''тут'''.
+
Этот пакет программ распространяется бесплатно и скачать инсталляцию можно [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.
Строка 51: Строка 53:
'''Получение:'''
'''Получение:'''
-
Этот пакет программ распространяется бесплатно и скачать инсталляцию можно '''тут'''.
+
Этот пакет программ распространяется бесплатно и скачать инсталляцию можно [http://gnuwin32.sourceforge.net/packages/gettext.htm тут], а именно, качать нужно [http://gnuwin32.sourceforge.net/downlinks/gettext.php это].
 +
 
Скачиваемый пакет является полным набором всех необходимых файлов для локализации приложения,
Скачиваемый пакет является полным набором всех необходимых файлов для локализации приложения,
-
т.е. содержит как RunTime компоненты, так и компоненты для разработки программ.  
+
т.е. содержит как ''runtime'' компоненты, так и компоненты для разработки программ.  
'''Установка:'''
'''Установка:'''
Строка 62: Строка 65:
При этом, интересующими нас директориями будут являться:
При этом, интересующими нас директориями будут являться:
-
* '''D:\GnuWin32\bin'''    - директория runtime компонентов
+
* ''D:\GnuWin32\bin''    - директория ''runtime'' компонентов
-
* '''D:\GnuWin32\include''' - директория заголовочных файлов gettext для разрабтчика
+
* ''D:\GnuWin32\include'' - директория заголовочных файлов [http://ru.wikipedia.org/wiki/Gettext Gettext] для разработчика
-
* '''D:\GnuWin32\bin'''    - директория линкуемых библиотек gettext для разрабтчика
+
* ''D:\GnuWin32\lib''    - директория линкуемых библиотек [http://ru.wikipedia.org/wiki/Gettext Gettext] для разработчика
= Подготовка к сборке =
= Подготовка к сборке =
== Создание дерева директории исходных кодов проекта ==
== Создание дерева директории исходных кодов проекта ==
-
Итак, локализовать мы будем простое консольное приложение (которое сами же и напишем и соберем) на два языва: русский и немецкий.
+
Итак, локализовать мы будем простое консольное приложение (которое сами же и напишем и соберем) на два языка: ''русский'' и ''немецкий''.
-
 
+
-
При этом, наш проект будет иметь такую структуру директорий:
+
 +
При этом, наш проект будет иметь следующую структуру директорий:
  /SourceTestProject
  /SourceTestProject
  |->main.cpp
  |->main.cpp
Строка 81: Строка 83:
  |
  |
  |->CMakeLists.txt
  |->CMakeLists.txt
-
 
+
где:
-
где
+
* ''/SourceTestProject'' - директория исходных кодов нашего проекта
-
* '''/SourceTestProject''' - директория исходных кодов нашего проекта
+
* ''main.cpp''          - собственно код нашего приложения
-
* '''main.cpp'''          - собственно код нашего приложения
+
* ''/po''                - директория с каталогами, содержащими файлы исходных переводов на различные языки
-
* '''/po'''                - директория с каталогами, содержащими файлы исходных переводов на различные языки
+
* ''/de, /ru''          - директории, которые содержат файлы переводов на русский и немецкий языки соответственно
-
* '''/de, /ru'''          - директории, которые содержат файлы переводов на русский и немецкий языки соответственно
+
* ''CMakeLists.txt''    - файлы конфигурации сборки приложения для [http://ru.wikipedia.org/wiki/CMake CMake]
-
* '''CMakeLists.txt'''    - файлы конфигурации сборки приложения для CMake
+
== Создание директории сборки проекта ==
== Создание директории сборки проекта ==
-
Сборку проекта с использованием CMake лучше всего производить вне директории нашего проекта,
+
Сборку проекта с использованием [http://ru.wikipedia.org/wiki/CMake CMake] лучше всего производить вне директории нашего проекта чтобы не засорять её продуктами компиляции, а также для исключения случайной модификации исходных файлов директории проекта.  
-
чтобы не замусоривать её, а также для исключения случайной модификации исходных файлов директории проекта.
+
-
Да и вообще, сборка вне директории с исходным кодом является "правилом хорошего тона".
+
-
Поэтому для сборки, параллельно директории проекта, создадим директорию сборки:
+
{{Замечание | Да и вообще, сборка вне директории с исходным кодом является "правилом хорошего тона".}}
 +
Поэтому для сборки, параллельно директории проекта создадим директорию сборки:
  /..
  /..
  |->/SourceTestProject
  |->/SourceTestProject
  |->/build-project
  |->/build-project
-
 
+
где:
-
где
+
* ''/..''                - какая-то родительская директория
-
* '''/..'''                - какая-то родительская директория
+
* ''/SourceTestProject''  - директория исходных кодов нашего проекта
-
* '''/SourceTestProject'''  - директория исходных кодов нашего проекта
+
* ''/build-project''      - директория для сборки нашего проекта (в которой бумем его собирать)
-
* '''/build-project'''      - директория для сборки нашего проекта (в которой бумем его собирать)
+
== Создание окружения сборки проекта ==
== Создание окружения сборки проекта ==
Для задания переменных окружения и путей к исполняемым файлам и библиотекам пакетов программ  
Для задания переменных окружения и путей к исполняемым файлам и библиотекам пакетов программ  
-
типа CMake, MinGW, Gettext и системным утилитам из System32, а также
+
типа [http://ru.wikipedia.org/wiki/CMake CMake], [http://ru.wikipedia.org/wiki/MinGW MinGW], [http://ru.wikipedia.org/wiki/Gettext Gettext] и системным утилитам из System32, а также
для исключения влияния этих переменных на другие, создадим для себя
для исключения влияния этих переменных на другие, создадим для себя
консоль сборки с необходимыми нам параметрами.
консоль сборки с необходимыми нам параметрами.
-
Для этого создадим файл '''MyBuildEnv.bat''' с таким содержимым:
+
Для этого создадим файл ''MyBuildEnv.bat'' с таким содержимым:
<source lang="dos">
<source lang="dos">
@echo off
@echo off
Строка 123: Строка 122:
</source >
</source >
где:
где:
-
* '''D:\MinGW\bin'''          - путь к runtime компонентам компилятора MinGW
+
* ''D:\MinGW\bin''          - путь к runtime компонентам компилятора [http://ru.wikipedia.org/wiki/MinGW MinGW]
-
* '''D:\CMake\bin'''          - путь runtime компонентам сборщика CMake
+
* ''D:\CMake\bin''          - путь runtime компонентам сборщика [http://ru.wikipedia.org/wiki/CMake CMake]
-
* '''D:\GnuWin32\bin'''      - путь runtime компонентам транслятора Gettext
+
* ''D:\GnuWin32\bin''      - путь runtime компонентам транслятора [http://ru.wikipedia.org/wiki/Gettext Gettext]
-
* '''%SystemRoot%\System32''' - путь системным runtime компонентам Windows
+
* ''%SystemRoot%\System32'' - путь системным runtime компонентам Windows
-
* '''GETTEXT_INCLUDE_DIR=d:\GnuWin32\include''' - путь к заголовочным файлам Gettext (понадобится далее для сборки приложения)
+
* ''GETTEXT_INCLUDE_DIR=d:\GnuWin32\include'' - путь к заголовочным файлам [http://ru.wikipedia.org/wiki/Gettext Gettext] (понадобится далее для сборки приложения)
-
* '''GETTEXT_LIB_DIR=d:\GnuWin32\lib'''        - путь к линкуемым библиотекам Gettext (понадобится далее для сборки приложения)
+
* ''GETTEXT_LIB_DIR=d:\GnuWin32\lib''        - путь к линкуемым библиотекам [http://ru.wikipedia.org/wiki/Gettext Gettext] (понадобится далее для сборки приложения)
-
 
+
-
Скопируем/переместим этот файл куда нибудь, например, пусть он будет находится в корне диска '''D:'''
+
 +
Скопируем/переместим этот файл куда нибудь, например, пусть он будет находится в корне диска ''D:''
  D:\MyBuildEnv.bat
  D:\MyBuildEnv.bat
Теперь создадим на рабочем столе ярлык, указывающий на нашу консоль сборки
Теперь создадим на рабочем столе ярлык, указывающий на нашу консоль сборки
-
в которой будут использованы переменные окружения из '''MyBuildEnv.bat'''
+
в которой будут использованы переменные окружения из ''MyBuildEnv.bat''
На вкладке "Общие" задаем имя нашей консоли, например:
На вкладке "Общие" задаем имя нашей консоли, например:
Строка 148: Строка 146:
== Создание кода приложения ==
== Создание кода приложения ==
-
Весь код нашего приложения будет находится в одном единственном файле '''main.cpp'''.
+
Весь код нашего приложения будет находится в одном единственном файле ''main.cpp''.
-
Код '''main.cpp''':
+
Код ''main.cpp'':
<source lang="cpp">
<source lang="cpp">
#include <iostream>
#include <iostream>
Строка 164: Строка 162:
     bindtextdomain(domain.c_str(), localedir.c_str());
     bindtextdomain(domain.c_str(), localedir.c_str());
     textdomain(domain.c_str());
     textdomain(domain.c_str());
 +
    bind_textdomain_codeset(domain.c_str(), "CP866");
     std::cout << gettext("Hello, world!") << std::endl;
     std::cout << gettext("Hello, world!") << std::endl;
     return 0;
     return 0;
Строка 169: Строка 168:
</source>
</source>
где:
где:
-
* '''#include <libintl.h>'''        - подключаемые заголовки Gettext
+
* ''#include <libintl.h>''        - подключаемые заголовки [http://ru.wikipedia.org/wiki/Gettext Gettext]
-
* '''#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''!}}
== Определение структуры и содержимого каталогов собранного приложения ==
== Определение структуры и содержимого каталогов собранного приложения ==
Задаем имя и расположение директории локализаций по нашему усмотрению,
Задаем имя и расположение директории локализаций по нашему усмотрению,
-
но обычно (в Windows) лучше и проще чтобы она имела имя '''locale'''
+
но обычно (в Windows) лучше и проще чтобы она имела имя ''locale''
и находилась в корне каталога с исполняемым файлом приложения.
и находилась в корне каталога с исполняемым файлом приложения.
-
(Да и у нас далее, в исходном коде приложения будет задано именно такое расположение каталога локализации).
 
 +
{{Замечание | Да и у нас, в исходном коде приложения (см. ''main.cpp'') задано именно такое расположение каталога локализации.}}
{{Замечание | В данном случае речь идет о структуре каталогов уже готового (т.е. собранного приложения)
{{Замечание | В данном случае речь идет о структуре каталогов уже готового (т.е. собранного приложения)
-
и никоим образом это не относится к описанному в (<Создание дерева директории исходных кодов проекта>). }}
+
и никоим образом это не относится к описанному в '''Создание дерева директории исходных кодов проекта'''. }}
Поддиректории в этой директории должны иметь определенную структуру, например:
Поддиректории в этой директории должны иметь определенную структуру, например:
-
 
  /InstallTestProject
  /InstallTestProject
  |-> test.exe
  |-> test.exe
Строка 203: Строка 203:
где:
где:
-
* '''/InstallTestProject''' - имя директории с готовым проектом (например, установленным в "Program Files" и т.п.)
+
* ''/InstallTestProject'' - имя директории с готовым проектом (например, установленным в "Program Files" и т.п.)
-
* '''test.exe'''            - исполняемый файл нашего приложения
+
* ''test.exe''            - исполняемый файл нашего приложения
-
* '''test1.dll/testN.dll''' - разделяемые библиотеки нашего приложения (но в текущей задаче их у нас нет)
+
* ''test1.dll/testN.dll'' - разделяемые библиотеки нашего приложения (но в текущей задаче их у нас нет)
-
* '''/ru, /de'''            - директории в которых находятся откомпилированные gettext-ом переводы *.mo
+
* ''/ru, /de''            - директории в которых находятся откомпилированные [http://ru.wikipedia.org/wiki/Gettext Gettext]-ом переводы ''*.mo''
-
* '''/LC_MESSAGES'''        - обязательная директория, имя которой должно быть таким как есть
+
* ''/LC_MESSAGES''        - обязательная директория, имя которой должно быть таким как есть
== Создание конфигурации сборки для CMake ==
== Создание конфигурации сборки для CMake ==
-
Конфигурация для сборки проекта при помощи CMake будет содержаться всего в двух файлах CMakeLists.txt:
+
Конфигурация для сборки проекта при помощи [http://ru.wikipedia.org/wiki/CMake CMake] будет содержаться всего в двух файлах ''CMakeLists.txt'':
* один находится в корне проекта с исходными кодами
* один находится в корне проекта с исходными кодами
-
 
  /SourceTestProject/CMakeLists.txt
  /SourceTestProject/CMakeLists.txt
-
 
* другой находится в корне директории /po c переводами
* другой находится в корне директории /po c переводами
  /po/CMakeLists.txt
  /po/CMakeLists.txt
Строка 221: Строка 219:
===Содержимое файла /SourceTestProject/CMakeLists.txt===
===Содержимое файла /SourceTestProject/CMakeLists.txt===
-
 
Ниже приведено содержимое файла с подробными комментариями:
Ниже приведено содержимое файла с подробными комментариями:
<source lang="cmake">
<source lang="cmake">
# Задаем имя нашему проекту.
# Задаем имя нашему проекту.
# При этом результирующий исполняемый файл приложения пусть тоже имеет такое имя, где:
# При этом результирующий исполняемый файл приложения пусть тоже имеет такое имя, где:
-
# '''test''' - имя проекта
+
# test - имя проекта
set( APP_TARGET test )
set( APP_TARGET test )
project( ${APP_TARGET} )
project( ${APP_TARGET} )
Строка 234: Строка 231:
# которые нам потребуются для сборки приложения.
# которые нам потребуются для сборки приложения.
# В данном случае нам нужны только заголовки от gettext, где:
# В данном случае нам нужны только заголовки от gettext, где:
-
# '''GETTEXT_INCLUDE_DIR''' - переменная окружения пути к заголовкам gettext,  
+
# GETTEXT_INCLUDE_DIR - переменная окружения пути к заголовкам gettext,  
# которую мы установили, запустив *.bat файл.
# которую мы установили, запустив *.bat файл.
include_directories( $ENV{GETTEXT_INCLUDE_DIR} )
include_directories( $ENV{GETTEXT_INCLUDE_DIR} )
Строка 241: Строка 238:
# которые нам потребуются для линковки приложения.
# которые нам потребуются для линковки приложения.
# В данном случае нам нужны только библиотеки от gettext, где:
# В данном случае нам нужны только библиотеки от gettext, где:
-
# '''GETTEXT_LIB_DIR''' - переменная окружения пути к библиотекам gettext,  
+
# GETTEXT_LIB_DIR - переменная окружения пути к библиотекам gettext,  
# которую мы установили, запустив *.bat файл.
# которую мы установили, запустив *.bat файл.
link_directories( $ENV{GETTEXT_LIB_DIR} )
link_directories( $ENV{GETTEXT_LIB_DIR} )
Строка 250: Строка 247:
# Указываем какие именно нам нужны библиотеки для линковки с приложением.
# Указываем какие именно нам нужны библиотеки для линковки с приложением.
-
# В нашем случае это библиотека от gettext: '''intl'''.
+
# В нашем случае это библиотека от gettext: intl.
target_link_libraries( ${APP_TARGET}  intl )
target_link_libraries( ${APP_TARGET}  intl )
# Указываем имя директории (bin) куда установится исполняемый файл приложения
# Указываем имя директории (bin) куда установится исполняемый файл приложения
-
# после выполнения команды: '''$mingw32-make install'''.
+
# после выполнения команды: $mingw32-make install.
install( TARGETS ${APP_TARGET} RUNTIME DESTINATION bin )
install( TARGETS ${APP_TARGET} RUNTIME DESTINATION bin )
Строка 262: Строка 259:
===Содержимое файла /po/CMakeLists.txt===
===Содержимое файла /po/CMakeLists.txt===
-
 
Ниже приведено содержимое файла с подробными комментариями:
Ниже приведено содержимое файла с подробными комментариями:
<source lang="cmake">
<source lang="cmake">
 +
#
set( DOMAIN  ${APP_TARGET} )
set( DOMAIN  ${APP_TARGET} )
Строка 271: Строка 268:
# языком приложения по умолчанию, поэтому переводить его не нужно).
# языком приложения по умолчанию, поэтому переводить его не нужно).
# При этом, кодам имен локализаций у нас соответствуют имена  
# При этом, кодам имен локализаций у нас соответствуют имена  
-
# поддиректорий '''de, ru'''. Это сделано просто для упрощения и наглядности,
+
# поддиректорий de, ru. Это сделано просто для упрощения и наглядности,
# а в принципе структуру поддиректорий и их названий можно делать какой угодно,
# а в принципе структуру поддиректорий и их названий можно делать какой угодно,
# главное в дальнейшем правильно написать скрипты для CMake. :)
# главное в дальнейшем правильно написать скрипты для CMake. :)
Строка 278: Строка 275:
# Устанавливаем имя директории в которую будут устанавливаться уже готовые,
# Устанавливаем имя директории в которую будут устанавливаться уже готовые,
# откомпилированные с помощью gettext файлы переводов *.mo., где:
# откомпилированные с помощью gettext файлы переводов *.mo., где:
-
# '''locale''' - имя этой директории.
+
# locale - имя этой директории.
set( LOCALE_INSTALL_DIR locale )
set( LOCALE_INSTALL_DIR locale )
Строка 286: Строка 283:
# Генерируем шаблон перевода, сканируя исходники приложения и
# Генерируем шаблон перевода, сканируя исходники приложения и
# извлекая всё что подлежит переводу.
# извлекая всё что подлежит переводу.
 +
# Еще помимо *.cpp файлов сюда можно подставлять и *.h файлы.
file( GLOB _srcFiles ../*.cpp )
file( GLOB _srcFiles ../*.cpp )
-
message( STATUS "src files: ${_srcFiles} ")
 
add_custom_target( translation ALL DEPENDS )
add_custom_target( translation ALL DEPENDS )
Строка 298: Строка 295:
     file( GLOB _poFile ${LANG}/*.po )
     file( GLOB _poFile ${LANG}/*.po )
     if( EXISTS ${_poFile} )
     if( EXISTS ${_poFile} )
-
        #message( STATUS " Po file: ${_poFile}" )
 
         set( PO_FILE_NEW ${CMAKE_CURRENT_BINARY_DIR}/${LANG}.po )
         set( PO_FILE_NEW ${CMAKE_CURRENT_BINARY_DIR}/${LANG}.po )
         set( GMO_FILE_NEW ${CMAKE_CURRENT_BINARY_DIR}/${LANG}.gmo )
         set( GMO_FILE_NEW ${CMAKE_CURRENT_BINARY_DIR}/${LANG}.gmo )
Строка 311: Строка 307:
</source>
</source>
-
 
+
Генерация бинарных файлов переводов происходит у нас в несколько этапов:
-
{{Замечание | Генерация бинарных файлов переводов происходит у нас в несколько этапов:
+
# Сначала из всех ''*.cpp'' файлов проекта извлекаются всё то, что подлежит переводу, и создается файл-шаблон ''*.pot'' (команда ''$xgettext'').
-
 
+
# Далее, по очереди проверяется наличие готовых исходных файлов переводов ''*.po'' разных языков и на их основе и основе шаблона ''*.pot'' создаются обновленные файлы переводов ''*.po'' (команда ''$msgmerge''). При этом, исходные файлы переводов остаются нетронутыми. {{Замечание | Это сделано для исключения модификации файлов в директории исходных кодов.}}
-
# Сначала из всех *.cpp файлов проекта извлекаются всё то, что подлежит переводу, и создается файл-шаблон *.pot (команда '''$xgettext''').
+
# Далее, на основе каждого вновь созданного (обновленного) файла ''*.po'' создается результирующий бинарный файл перевода ''*.gmo'' ( команда ''$msgfmt'').
-
# Далее, по очереди проверяется наличие готовых исходных файлов переводов *.po разных языков и, на их основе, и основе шаблона *.pot создаются обновленные файлы переводов *.po. При этом, исходные файлы переводов остаются нетронутыми. Это сделано для исключения модификации файлов в директории исходных кодов (команда '''$msgmerge''').  
+
-
# Далее, на основе каждого вновь созданного (обновленного) файла *.po создается результирующий бинарный файл перевода *.gmo ( команда '''$msgfmt'''). }}
+
= Сборка приложения =
= Сборка приложения =
-
Итак, после того как все готово, можно приступить к сборке приложения,  
+
Итак, после того, как все готово, можно приступить к сборке приложения,  
но перед этим необходимо сгенерировать и перевести файлы исходных переводов.
но перед этим необходимо сгенерировать и перевести файлы исходных переводов.
-
Все ниже описанные операции выполняются в "нашей" консоли, которую мы предварительно настроили и запустили (см. тут).
+
Все ниже описанные операции выполняются в "нашей" консоли, которую мы предварительно настроили и запустили (см. '''Создание окружения сборки проекта''').
== Первоначальная генерация исходных переводов ==
== Первоначальная генерация исходных переводов ==
Строка 330: Строка 324:
$ xgettext -C -a -o messages.pot *.cpp
$ xgettext -C -a -o messages.pot *.cpp
</source>  
</source>  
-
После выполнения этой команды, в той директории где мы находимся появится файл шаблона '''messages.pot'''.
+
После выполнения этой команды, в той директории где мы находимся появится файл шаблона ''messages.pot''.
Теперь, нам необходимо из шаблона сгенерировать исходные файлы переводов для разных языков:
Теперь, нам необходимо из шаблона сгенерировать исходные файлы переводов для разных языков:
Строка 337: Строка 331:
$ msginit -i messages.pot -o po\ru\messages.po -l ru
$ msginit -i messages.pot -o po\ru\messages.po -l ru
</source>  
</source>  
-
После выполнения данных команд, в директориях '''po\de''' и '''po\de''' появятся необходимые нам файлы.
+
После выполнения данных команд, в директориях ''po\de'' и ''po\ru'' появятся необходимые нам файлы.
-
Теперь файл шаблона нам не нужен и мы можем его удалить.  
+
Теперь файл шаблона ''messages.pot'' нам не нужен и мы можем его удалить.  
-
Т.е. для распространения исходных кодов нашего проекта достаточно иметь только файлы переводов *.po
+
{{Замечание | Для распространения исходных кодов нашего проекта достаточно иметь только файлы переводов ''*.po'', естественно, иметь и ''*.cpp'' и ''CMakeLists.txt'', что само собой разумеется.}}
-
(естественно и иметь *.cpp и CMakeLists.txt, это само собой разумеется).
+
-
Далее, произведем "перевод" сообщений в *.po файлах на требуемые нам языки.
+
Далее, произведем "перевод" сообщений в ''*.po'' файлах на требуемые нам языки.
Для этого, редактируем их любым доступным образом и добавляем нужные сообщения:
Для этого, редактируем их любым доступным образом и добавляем нужные сообщения:
-
 
+
* для ''po\de\messages.po''
-
* для '''po\de\messages.po'''
+
  ...
  ...
  msgid "Hello, world!"
  msgid "Hello, world!"
  msgstr "Hallo Welt!"
  msgstr "Hallo Welt!"
  ...
  ...
-
 
+
* для ''po\ru\messages.po''
-
* для '''po\ru\messages.po'''
+
  ...
  ...
  msgid "Hello, world!"
  msgid "Hello, world!"
Строка 375: Строка 366:
При успехе в консоль отобразится примерно следующее:
При успехе в консоль отобразится примерно следующее:
-
 
  D:\SVN\lang_test>cd ..\build
  D:\SVN\lang_test>cd ..\build
   
   
Строка 412: Строка 402:
При этом, автоматически сгенерируются:  
При этом, автоматически сгенерируются:  
-
* исполняемый файл приложения '''test.exe'''
+
* исполняемый файл приложения ''test.exe''
-
* бинарные файлы переводов '''*.gmo'''
+
* бинарные файлы переводов ''*.gmo''
= Установка проекта =
= Установка проекта =
Теперь, после того как мы собрали проект, мы можем установить его в какую нибудь директорию.
Теперь, после того как мы собрали проект, мы можем установить его в какую нибудь директорию.
-
Допустим, хотим установить в '''D:\install''', для этого выполняем в консоли следующую команду:
+
 
 +
Допустим, хотим установить в  
 +
D:\install
 +
для этого выполняем в консоли следующую команду:
<source lang="bash">  
<source lang="bash">  
$ mingw32-make DESTDIR=d:\install install
$ mingw32-make DESTDIR=d:\install install
</source>  
</source>  
-
В итоге, в директории '''d:\install''' получим следующую структуру каталогов:
+
В итоге, в директории ''d:\install'' получим следующую структуру каталогов:
-
 
+
  /install
  /install
     |->/Program Files
     |->/Program Files
Строка 434: Строка 426:
                         |            |->test.mo
                         |            |->test.mo
                         |->/ru
                         |->/ru
-
                            |->/LC_MESSAGES
+
                              |->/LC_MESSAGES
-
                                    |->test.mo
+
                                      |->test.mo
{{Замечание | Как видно, файлы переводов теперь вместо расширений ''*.gmo'' имеют расширение ''*.mo'', процесс переименования файлов произошел в процессе установки приложения. }}
{{Замечание | Как видно, файлы переводов теперь вместо расширений ''*.gmo'' имеют расширение ''*.mo'', процесс переименования файлов произошел в процессе установки приложения. }}
= Запуск приложения =
= Запуск приложения =
-
Для запуска приложения необходимо, находять в нашей консоли сборки перейти в директорию с установленным проектом и выполнить файл '''test.exe'''
+
Для запуска приложения необходимо, находять в нашей консоли сборки, перейти в директорию с установленным проектом и выполнить файл ''test.exe''
<source lang="bash">  
<source lang="bash">  
$ cd d:\install\Program Files\test
$ cd d:\install\Program Files\test
-
$ cd bin\test.exe
+
$ bin\test.exe
</source>  
</source>  
После выполнения в консоли увидим:
После выполнения в консоли увидим:
-
 
  D:\SVN\inst\Program Files\test>bin\test.exe
  D:\SVN\inst\Program Files\test>bin\test.exe
-
  ¦ЁштхЄ, ьшЁ!
+
  Привет, мир!
-
 
+
-
Крякозяблы ''¦ЁштхЄ, ьшЁ!''  есть текст перевода ''"Привет, мир!"'', не пугайтесь! :)
+
-
 
+
-
{{Замечание | Дело в том, что текст в консоли Windows выводится в кодировке ''CP866'', но у нас файлы перевода сгенерированы для кодировки ''CP1251''. Если бы мы делали GUI приложение, то текст в нем выводился бы корректно (в теории), но в данном случае нам необходимо выполнить ряд мер
+
-
для устранения данного несоответствия, о чем, может быть, будет написано позже. }}
+
-
= Важные замечания =
+
{{Замечание | Так как мы линковали наше приложение с библиотеками от [http://ru.wikipedia.org/wiki/Gettext Gettext], то для правильной его работы необходимо, чтобы наше приложение имело к ним доступ, для чего можно поступить двумя путями:
-
{{Замечание | Так как мы линковали наше приложение с библиотеками от Gettext, то для правильной его работы необходимо, чтобы наше приложение имело к ним доступ, для чего можно поступить двумя путями:
+
* Или, в каталог с исполнеяемым файлом ''test.exe'' скопировать как минимум такие библиотеки [http://ru.wikipedia.org/wiki/Gettext Gettext] как: ''libintl3.dll'' и ''libiconv2.dll''. И в этом случае, наше приложение будет работать на любой машине где не установлен [http://ru.wikipedia.org/wiki/Gettext Gettext].
-
* Или, в каталог с исполнеяемым файлом '''test.exe''' скопировать как минимум такие библиотеки Gettext как: '''libintl3.dll''' и '''libiconv2.dll'''. И в этом случае, наше приложение будет работать на любой машине где не установлен Gettext.
+
* Или, если на машине установлен Gettext, необходимо в переменных окружения прописать путь к runtime компонентам Gettext (т.е. путь к директории где находятся разделяемые библиотеки ''*.dll'' [http://ru.wikipedia.org/wiki/Gettext Gettext]-а , например, ''/bin''). }}
-
* Или, если на машине установлен Gettext, необходимо в переменных окружения прописать путь к runtime компонентам Gettext (т.е. путь к директории где находятся разделяемые библиотеки *.dll Gettext-а , например, /bin). }}
+

Текущая версия на 18:19, 8 октября 2010

Содержание

[править] Введение

В данном руководстве будет разобран простой пример локализации приложения в ОС Microsoft Windows с помощью пакета программ Gettext.

При этом подразумеваем, что приложение будем собирать с использованием компилятора MinGW при помощи системы кросс-платформенной сборки CMake.

После запуска приложение просто будет выполнять печать в консоль строки "Привет, мир!" и завершаться.

Данное руководство не является панацеей или каким-то определенным рецептом при решении данной задачи, оно представляет собой альтернативный вариант и предназначено для краткого ознакомления читателя со стадиями процесса локализации и сборки программы.

Предполагается, что читатель имеет некоторые знания и навыки программирования.

[править] Инструменты

Для решения нашей задачи нам понадобятся следующее программное обеспечение (ПО):

  1. ОС Microsoft Windows - операционная система семейств XP/Vista/7 и т.п.
  2. MinGW - порт пакета утилит и компиляторов GCC для Microsoft Windows.
  3. CMake - кросс-платформенная система автоматизации сборки программного обеспечения из исходного кода.
  4. Gettext - библиотека проекта GNU для интернационализации.

[править] Получение и установка инструментов

[править] Получение и установка операционной системы MS Windows

Описывать этот процесс не имеет смысла, т.к. всем и так все ясно. :)

[править] Получение и установка MinGW

Получение: Этот пакет программ распространяется бесплатно и скачать инсталляцию можно тут.

Установка: Для установки пакета программ запускаем исполняемый файл установщика и следуем его советам.

Допустим, он установился в каталог:

D:\MinGW

[править] Получение и установка CMake

Получение: Этот пакет программ распространяется бесплатно и скачать инсталляцию можно тут.

Скачивать и использовать можно как версии 2.6.x так и версии 2.8.x, но лучше все-же использовать более свежую версию 2.8.x.

Установка: Для установки пакета программ запускаем исполняемый файл установщика и следуем его советам.

Допустим, он установился в каталог:

D:\CMake

[править] Получение и установка Gettext

Получение: Этот пакет программ распространяется бесплатно и скачать инсталляцию можно тут, а именно, качать нужно это.

Скачиваемый пакет является полным набором всех необходимых файлов для локализации приложения, т.е. содержит как runtime компоненты, так и компоненты для разработки программ.

Установка: Для установки пакета программ запускаем исполняемый файл установщика и следуем его советам.

Допустим, он установился в каталог:

D:\GnuWin32

При этом, интересующими нас директориями будут являться:

  • D:\GnuWin32\bin - директория runtime компонентов
  • D:\GnuWin32\include - директория заголовочных файлов Gettext для разработчика
  • D:\GnuWin32\lib - директория линкуемых библиотек Gettext для разработчика

[править] Подготовка к сборке

[править] Создание дерева директории исходных кодов проекта

Итак, локализовать мы будем простое консольное приложение (которое сами же и напишем и соберем) на два языка: русский и немецкий.

При этом, наш проект будет иметь следующую структуру директорий:

/SourceTestProject
|->main.cpp
|->/po
|    |->/de
|    |->/ru
|    |->CMakeLists.txt
|
|->CMakeLists.txt

где:

  • /SourceTestProject - директория исходных кодов нашего проекта
  • main.cpp - собственно код нашего приложения
  • /po - директория с каталогами, содержащими файлы исходных переводов на различные языки
  • /de, /ru - директории, которые содержат файлы переводов на русский и немецкий языки соответственно
  • CMakeLists.txt - файлы конфигурации сборки приложения для CMake

[править] Создание директории сборки проекта

Сборку проекта с использованием CMake лучше всего производить вне директории нашего проекта чтобы не засорять её продуктами компиляции, а также для исключения случайной модификации исходных файлов директории проекта.

Замечание Замечание: Да и вообще, сборка вне директории с исходным кодом является "правилом хорошего тона".

Поэтому для сборки, параллельно директории проекта создадим директорию сборки:

/..
|->/SourceTestProject
|->/build-project

где:

  • /.. - какая-то родительская директория
  • /SourceTestProject - директория исходных кодов нашего проекта
  • /build-project - директория для сборки нашего проекта (в которой бумем его собирать)

[править] Создание окружения сборки проекта

Для задания переменных окружения и путей к исполняемым файлам и библиотекам пакетов программ типа CMake, MinGW, Gettext и системным утилитам из System32, а также для исключения влияния этих переменных на другие, создадим для себя консоль сборки с необходимыми нам параметрами.

Для этого создадим файл MyBuildEnv.bat с таким содержимым:

@echo off
echo Setting up a MinGW/CMake/Gettext/Libiconv only environment...
set PATH=D:\Qt\2009.04\mingw\bin
set PATH=%PATH%;D:\CMake 2.6\bin
set PATH=%PATH%;D:\GnuWin32\bin
set PATH=%PATH%;%SystemRoot%\System32
set GETTEXT_INCLUDE_DIR=d:\GnuWin32\include
set GETTEXT_LIB_DIR=d:\GnuWin32\lib

где:

  • D:\MinGW\bin - путь к runtime компонентам компилятора MinGW
  • D:\CMake\bin - путь runtime компонентам сборщика CMake
  • D:\GnuWin32\bin - путь runtime компонентам транслятора Gettext
  • %SystemRoot%\System32 - путь системным runtime компонентам Windows
  • GETTEXT_INCLUDE_DIR=d:\GnuWin32\include - путь к заголовочным файлам Gettext (понадобится далее для сборки приложения)
  • GETTEXT_LIB_DIR=d:\GnuWin32\lib - путь к линкуемым библиотекам Gettext (понадобится далее для сборки приложения)

Скопируем/переместим этот файл куда нибудь, например, пусть он будет находится в корне диска D:

D:\MyBuildEnv.bat

Теперь создадим на рабочем столе ярлык, указывающий на нашу консоль сборки в которой будут использованы переменные окружения из MyBuildEnv.bat

На вкладке "Общие" задаем имя нашей консоли, например:

  • My Env Build Command Prompt

На вкладке "Ярлык" пишем к примеру это:

  • Объект: C:\WINDOWS\system32\cmd.exe /K d:\MyBuildEnv.bat
  • Рабочая папка: D:\

И теперь, при клике по ярлыку "My Env Build Command Prompt" запустится настроеная под наши нужды консоль (командная строка) в которой мы будем производить компиляцию проекта.

[править] Создание кода приложения

Весь код нашего приложения будет находится в одном единственном файле main.cpp.

Код main.cpp:

#include <iostream>
#include <libintl.h> 
#include <locale.h>
 
int main(int argc, char* argv[])
{
    std::string domain("test"); 
    std::string localedir("./locale"); 
 
    setlocale(LC_ALL, "");
    bindtextdomain(domain.c_str(), localedir.c_str());
    textdomain(domain.c_str());
    bind_textdomain_codeset(domain.c_str(), "CP866");
    std::cout << gettext("Hello, world!") << std::endl;
    return 0;
}

где:

  • #include <libintl.h> - подключаемые заголовки Gettext
  • #include <locale.h> - подключаемые системные заголовки компилятора
  • #include <iostream> - подключаемые системные заголовки компилятора
  • domain("test") - домен которому мы присвоили имя test(этим именем у нас также будет назван и исполняемый файл test.exe нашего приложения)
  • string localedir("./locale") - это имя каталога в котором будут находится бинарные файлы переводов.
  • gettext("Hello, world!") - собственно строка, которую будем локализовать на разные языки.
Замечание Замечание: Функция bind_textdomain_codeset(domain.c_str(), "CP866") нам необходима для корректного отображения кириллических символов в консоли и использовать ее нужно только в том случае, если мы имеем консольное приложение. Если же у нас приложение имеет GUI, то использовать данную функцию нельзя (или можно, но нужно вместо кодировки CP866 указать кодировку CP1251). Дело в том, что в Windows в консоль выводятся символы в кодировке CP866, но в GUI приложения в кодировке CP1251!

[править] Определение структуры и содержимого каталогов собранного приложения

Задаем имя и расположение директории локализаций по нашему усмотрению, но обычно (в Windows) лучше и проще чтобы она имела имя locale и находилась в корне каталога с исполняемым файлом приложения.

Замечание Замечание: Да и у нас, в исходном коде приложения (см. main.cpp) задано именно такое расположение каталога локализации.
Замечание Замечание: В данном случае речь идет о структуре каталогов уже готового (т.е. собранного приложения) и никоим образом это не относится к описанному в Создание дерева директории исходных кодов проекта.

Поддиректории в этой директории должны иметь определенную структуру, например:

/InstallTestProject
|-> test.exe
|-> test1.dll (если необходима)
|-> ...
|-> testN.dll
|->/locale
       |->/ru
       |   |->/LC_MESSAGES
       |            |->test.mo
       |->/de
       |   |->/LC_MESSAGES
       |            |->test.mo
       |
      и т.п.

где:

  • /InstallTestProject - имя директории с готовым проектом (например, установленным в "Program Files" и т.п.)
  • test.exe - исполняемый файл нашего приложения
  • test1.dll/testN.dll - разделяемые библиотеки нашего приложения (но в текущей задаче их у нас нет)
  • /ru, /de - директории в которых находятся откомпилированные Gettext-ом переводы *.mo
  • /LC_MESSAGES - обязательная директория, имя которой должно быть таким как есть

[править] Создание конфигурации сборки для CMake

Конфигурация для сборки проекта при помощи CMake будет содержаться всего в двух файлах CMakeLists.txt:

  • один находится в корне проекта с исходными кодами
/SourceTestProject/CMakeLists.txt
  • другой находится в корне директории /po c переводами
/po/CMakeLists.txt

Итак, рассмотрим содержимое этих файлов по очереди.

[править] Содержимое файла /SourceTestProject/CMakeLists.txt

Ниже приведено содержимое файла с подробными комментариями:

# Задаем имя нашему проекту.
# При этом результирующий исполняемый файл приложения пусть тоже имеет такое имя, где:
# test - имя проекта
set( APP_TARGET test )
project( ${APP_TARGET} )
cmake_minimum_required( VERSION 2.6.0 )
 
# Здесь подключаем директории с заголовочными файлами,
# которые нам потребуются для сборки приложения.
# В данном случае нам нужны только заголовки от gettext, где:
# GETTEXT_INCLUDE_DIR - переменная окружения пути к заголовкам gettext, 
# которую мы установили, запустив *.bat файл.
include_directories( $ENV{GETTEXT_INCLUDE_DIR} )
 
# Здесь подключаем директории с дополнительными библиотеками,
# которые нам потребуются для линковки приложения.
# В данном случае нам нужны только библиотеки от gettext, где:
# GETTEXT_LIB_DIR - переменная окружения пути к библиотекам gettext, 
# которую мы установили, запустив *.bat файл.
link_directories( $ENV{GETTEXT_LIB_DIR} )
 
set( APP_SRCS main.cpp )
 
add_executable( ${APP_TARGET} ${APP_SRCS} )
 
# Указываем какие именно нам нужны библиотеки для линковки с приложением.
# В нашем случае это библиотека от gettext: intl.
target_link_libraries( ${APP_TARGET}  intl )
 
# Указываем имя директории (bin) куда установится исполняемый файл приложения
# после выполнения команды: $mingw32-make install.
install( TARGETS ${APP_TARGET} RUNTIME DESTINATION bin )
 
# Подключаем поддиректорию с файлами переводов.
add_subdirectory( po )

[править] Содержимое файла /po/CMakeLists.txt

Ниже приведено содержимое файла с подробными комментариями:

#
set( DOMAIN  ${APP_TARGET} )
 
# Устанавливаем набор языков, на которые переведено наше приложение.
# В нашем случае это русский и немецкий (английский язык является
# языком приложения по умолчанию, поэтому переводить его не нужно).
# При этом, кодам имен локализаций у нас соответствуют имена 
# поддиректорий de, ru. Это сделано просто для упрощения и наглядности,
# а в принципе структуру поддиректорий и их названий можно делать какой угодно,
# главное в дальнейшем правильно написать скрипты для CMake. :)
set( LINGUAS de ru )
 
# Устанавливаем имя директории в которую будут устанавливаться уже готовые,
# откомпилированные с помощью gettext файлы переводов *.mo., где:
# locale - имя этой директории.
set( LOCALE_INSTALL_DIR locale )
 
# Задаем имя шаблона файла перевода *.pot.
set( POT_FILE ${CMAKE_CURRENT_BINARY_DIR}/messages.pot )
 
# Генерируем шаблон перевода, сканируя исходники приложения и
# извлекая всё что подлежит переводу.
# Еще помимо *.cpp файлов сюда можно подставлять и *.h файлы.
file( GLOB _srcFiles ../*.cpp )
 
add_custom_target( translation ALL DEPENDS )
add_custom_command( TARGET translation
                    COMMAND xgettext --from-code CP1251 -C -a -o ${POT_FILE} ${_srcFiles}
)
 
# Пробегаем по всем именам директорий (локализациям) и обрабатываем их gettext-ом.
foreach( LANG ${LINGUAS})
    file( GLOB _poFile ${LANG}/*.po )
    if( EXISTS ${_poFile} )
        set( PO_FILE_NEW ${CMAKE_CURRENT_BINARY_DIR}/${LANG}.po )
        set( GMO_FILE_NEW ${CMAKE_CURRENT_BINARY_DIR}/${LANG}.gmo )
        add_custom_command( TARGET translation
                            COMMAND msgmerge ${_poFile} ${POT_FILE} -o ${PO_FILE_NEW}
                            COMMAND msgfmt -c -o ${GMO_FILE_NEW} ${PO_FILE_NEW}
        )
        install(FILES ${GMO_FILE_NEW} DESTINATION ${LOCALE_INSTALL_DIR}/${LANG}/LC_MESSAGES RENAME ${DOMAIN}.mo )
 
    endif( EXISTS ${_poFile} )
endforeach( LANG )

Генерация бинарных файлов переводов происходит у нас в несколько этапов:

  1. Сначала из всех *.cpp файлов проекта извлекаются всё то, что подлежит переводу, и создается файл-шаблон *.pot (команда $xgettext).
  2. Далее, по очереди проверяется наличие готовых исходных файлов переводов *.po разных языков и на их основе и основе шаблона *.pot создаются обновленные файлы переводов *.po (команда $msgmerge). При этом, исходные файлы переводов остаются нетронутыми.
    Замечание Замечание: Это сделано для исключения модификации файлов в директории исходных кодов.
  3. Далее, на основе каждого вновь созданного (обновленного) файла *.po создается результирующий бинарный файл перевода *.gmo ( команда $msgfmt).

[править] Сборка приложения

Итак, после того, как все готово, можно приступить к сборке приложения, но перед этим необходимо сгенерировать и перевести файлы исходных переводов.

Все ниже описанные операции выполняются в "нашей" консоли, которую мы предварительно настроили и запустили (см. Создание окружения сборки проекта).

[править] Первоначальная генерация исходных переводов

Генерируем шаблон исходного файла локализации, предварительно перейдя в корневой каталог исходных кодов проекта:

 
$ cd <Путь к каталогу исходников проекта>\SourceTestProject
$ xgettext -C -a -o messages.pot *.cpp

После выполнения этой команды, в той директории где мы находимся появится файл шаблона messages.pot.

Теперь, нам необходимо из шаблона сгенерировать исходные файлы переводов для разных языков:

 
$ msginit -i messages.pot -o po\de\messages.po -l de
$ msginit -i messages.pot -o po\ru\messages.po -l ru

После выполнения данных команд, в директориях po\de и po\ru появятся необходимые нам файлы.

Теперь файл шаблона messages.pot нам не нужен и мы можем его удалить.

Замечание Замечание: Для распространения исходных кодов нашего проекта достаточно иметь только файлы переводов *.po, естественно, иметь и *.cpp и CMakeLists.txt, что само собой разумеется.

Далее, произведем "перевод" сообщений в *.po файлах на требуемые нам языки.

Для этого, редактируем их любым доступным образом и добавляем нужные сообщения:

  • для po\de\messages.po
...
msgid "Hello, world!"
msgstr "Hallo Welt!"
...
  • для po\ru\messages.po
...
msgid "Hello, world!"
msgstr "Привет, мир!"
...

Всё, теперь сохраняем все изменения. На этом перевод закончен, и можно приступить к сборке проекта.

[править] Собираем проект

Сначала перейдем в пустую директорию сборки (которую мы заранее создали):

 
$ cd <Путь к директории сборки>/build-project

Теперь сама сборка:

 
$ cmake ..\SourceTestProject -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
$ mingw32-make

При успехе в консоль отобразится примерно следующее:

D:\SVN\lang_test>cd ..\build

D:\SVN\build>cmake ..\lang_test -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Check for working C compiler: D:/Qt/2009.04/mingw/bin/gcc.exe
-- Check for working C compiler: D:/Qt/2009.04/mingw/bin/gcc.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: D:/Qt/2009.04/mingw/bin/g++.exe
-- Check for working CXX compiler: D:/Qt/2009.04/mingw/bin/g++.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- src files: D:/SVN/lang_test/po/../main.cpp
-- Configuring done
-- Generating done
-- Build files have been written to: D:/SVN/build

D:\SVN\build>mingw32-make
Scanning dependencies of target test
[100%] Building CXX object CMakeFiles/test.dir/main.cpp.obj
Linking CXX executable test.exe
[100%] Built target test
Scanning dependencies of target translation
D:/SVN/lang_test/po/../main.cpp:32: warning: Empty msgid.  It is reserved by GNU gettext:
                                             gettext("") returns the header entry with
                                             meta information, not the empty string.
. done.
msgfmt: D:/SVN/build/po/de.po: field `Project-Id-Version' still has initial default value
. done.
msgfmt: D:/SVN/build/po/ru.po: field `Project-Id-Version' still has initial default value
[100%] Built target translation

D:\SVN\build>

При этом, автоматически сгенерируются:

  • исполняемый файл приложения test.exe
  • бинарные файлы переводов *.gmo

[править] Установка проекта

Теперь, после того как мы собрали проект, мы можем установить его в какую нибудь директорию.

Допустим, хотим установить в

D:\install

для этого выполняем в консоли следующую команду:

 
$ mingw32-make DESTDIR=d:\install install

В итоге, в директории d:\install получим следующую структуру каталогов:

/install
    |->/Program Files
            |->/test
                  |->/bin
                  |    |->test.exe
                  |->/locale
                        |->/de
                        |    |->/LC_MESSAGES
                        |            |->test.mo
                        |->/ru
                             |->/LC_MESSAGES
                                     |->test.mo
Замечание Замечание: Как видно, файлы переводов теперь вместо расширений *.gmo имеют расширение *.mo, процесс переименования файлов произошел в процессе установки приложения.

[править] Запуск приложения

Для запуска приложения необходимо, находять в нашей консоли сборки, перейти в директорию с установленным проектом и выполнить файл test.exe

 
$ cd d:\install\Program Files\test
$ bin\test.exe

После выполнения в консоли увидим:

D:\SVN\inst\Program Files\test>bin\test.exe
Привет, мир!
Замечание Замечание: Так как мы линковали наше приложение с библиотеками от Gettext, то для правильной его работы необходимо, чтобы наше приложение имело к ним доступ, для чего можно поступить двумя путями:
  • Или, в каталог с исполнеяемым файлом test.exe скопировать как минимум такие библиотеки Gettext как: libintl3.dll и libiconv2.dll. И в этом случае, наше приложение будет работать на любой машине где не установлен Gettext.
  • Или, если на машине установлен Gettext, необходимо в переменных окружения прописать путь к runtime компонентам Gettext (т.е. путь к директории где находятся разделяемые библиотеки *.dll Gettext-а , например, /bin).