Библиотека сайта rus-linux.net
Программирование с использованием gtkmm 3. Создание с помощью утилиты gmmproc оберток для разработанных с использованием языка программирования C библиотек
Оригинал: Programming with gtkmm 3Авторы: Murray Cumming, Bernhard Rieder, Jonathon Jongsma, Ole Laursen, Marko Anastasov, Daniel Elstner, Chris Vine, David King, Pedro Ferreira, Kjell Ahlstedt
Дата публикации: 15 Октября 2013 г.
Перевод: А.Панин
Дата перевода: 25 Апреля 2014 г.
Приложение G. Создание с помощью утилиты gmmproc оберток для разработанных с использованием языка программирования C библиотек
Для генерации большей части кода gtkmm используется утилита gmmproc, которая обрабатывает файлы с расширением .defs, описывающие API библиотек на основе системы типов GObject. Таким образом, создание аналогичных gtkmm оберток для других библиотек на основе glib/GObject является достаточно простой задачей.
Процесс создания оберток для библиотек связан с использованием множества инструментов, некоторые из которых являются достаточно сложными, но, по крайней мере, они работают и успешно используются несколькими проектами.
G.1. Структура директорий для сборки
Генерация исходного кода для API в стиле gtkmm связана с использованием таких инструментов, как gmmproc и generate_wrap_init.pl. Теоретически вы могли бы разработать свои собственные файлы сборки для последующего использования, но гораздо более удачным вариантом является использование инфраструктуры сборки, предоставляемой модулем mm-common. В начале работы очень полезно выбрать существующий модуль, который сможет использоваться в будущем в качестве наглядного примера.
Например, представим, что мы создаем обертку для разработанной с использованием языка программирования C библиотеки под названием libsomething. Она предоставляет API на основе системы типов GObject с такими названиями типов, как, к примеру, SomeWidget и SomeStuff.
G.1.1. Копирование прототипа проекта
libsomethingmm. Мы можем начать свою работу с копирования дерева исходного кода прототипа проекта из модуля mm-common.
$ git clone git://git.gnome.org/mm-common $ cp -a mm-common/skeletonmm libsomethingmm
.hg и .ccg, сгенерированных файлов с расширениями .h и .cc, а также для подключаемых файлов Automake с именами filelist.am, которые позволяют указывать различные используемые файлы с помощью стандартных переменных Automake. После соответствующего переименования директорий их структура обычно выглядит аналогично приведенной ниже:
libsomethingmm: Директория верхнего уровня.libsomething: Содержит основной подключаемый файл и файл с расширением.pcдляpkg-config.src: Содержит фалы исходного кода с расширениями.hgи.ccg.libsomethingmm: Содержит сгенерированные и созданные вручную файлы исходного кода с расширениями.hи.cc.private: Содержит сгенерированные файлы с именами*_p.h.
$ for f in $(find libsomethingmm -depth -name '*skeleton*'); do \
d="${f%/*}"; b="${f##*/}"; mv "$f" "$d/${b//skeleton/libsomething}"; \
done
Файлы прототипа проекта в будущем должны быть заполнены специфичными для проекта данными.
Учтите, что файлы с заканчивающимися на .in именами будут использоваться для генерации файлов с такими же именами, но без суффиксов .in путем замены некоторых переменных на реальные значения в процессе конфигурации.
G.1.2. Модификация файлов сборки
Теперь мы должны модифицировать файлы сборки для их адаптации к нашим потребностям. Для выполнения этой задачи вы можете предпочесть использовать утилиту, выполняющую поиск и замену данных во множестве файлов, такую, как regexxer. Учтите, что практически все эти файлы из дерева исходного кода прототипа проекта содержат текст для заполнения. Следовательно, должны осуществляться глобальные подстановки, не ограничивающиеся файлами Automake и Autoconf.
Все упоминания о названии прототипа проекта должны заменяться на корректное название созданной с использованием языка программирования C библиотеки, для которой создается обертка, такое, как "something" или "libsomething" и, таким же образом, все слова "SKELETON" должны быть заменены на "SOMETHING" или "LIBSOMETHING", а все слова "Skeleton - на "Something".
Аналогичным образом следует заменить все сочетания "Joe Hacker" на имя владельца авторских прав, которым, скорее всего, являетесь вы. То же самое нужно сделать и с адресом электронной почты "joe@example.com".
G.1.2.1. Файл configure.ac
configure.ac,
- В строке
AC_CONFIG_SRCDIR()должны быть приведены имена файлов из нашего дерева исходного кода. Мы можем отредактировать ее позднее в том случае, если нам пока не известны имена каких-либо файлов, которые мы будем создавать. - Для модулей биндингов стандартной практикой является отслеживание версии библиотеки, для которой создается обертка. Таким образом, к примеру, в том случае, если созданная с использованием языка программирования C библиотека имеет версию 1.23.4, начальной версией модуля биндингов будет 1.23.0. При этом следует избегать четкого указания номера подверсии, так как обычно указывается стабильный релиз.
- Строка
AC_CONFIG_HEADERS()используется для генерации двух и более заголовочных конфигурационных файлов. Первый конфигурационный файл в списке содержит все макросы конфигурации, которые устанавливаются в процессе конфигурации. Остальные заголовочные файлы списка содержат только подмножества макросов конфигурации и соответствующий им файл с именемconfig.h.inне будет генерироваться автоматически. Причина этого разделения состоит в том, что заголовочные файлы конфигурации с пространствами имен будут устанавливаться вместе с вашей библиотекой и описывать доступные всем макросы. - Редактирование строки
AC_SUBST([SOMETHINGMM_MODULES], ['...'])также может потребоваться в том случае, если необходима проверка корректности установки необходимых программных компонентов. - В блоке
AC_CONFIG_FILES()должны приводится корректные имена директорий таким образом, как было описано выше.
G.1.2.2. Файлы Makefile.am
Makefile.am:
-
В файле
skeleton/Makefile.amнам следует указать корректные значения стандартных переменных, которые будут использоваться на других этапах сборки:- binding_name
- Имя библиотеки, такое, как
libsomethingmm - wrap_init_flags
- Дополнительные флаги командной строки, передающиеся сценарию
generate_wrap_init.pl, такие, как пространство имен для языка программирования C++ и префикс, устанавливающий родительскую директорию для подключаемых файлов.
-
В файле
skeleton/skeletonmm/Makefile.amнам также следует указать корректные значения стандартных переменных, которые будут использоваться на других этапах сборки:- lib_LTLIBRARIES
- Значением данной переменной должно быть корректное название библиотеки, причем это название библиотеки должно использоваться для формирования имен переменных
_SOURCES,_LDFLAGSи_LIBADD. Разрешается использовать такие заменяемые сценариемconfigureшаблоны, как@SOMETHINGMM_API_VERSION@в качестве частей имен переменных. - AM_CPPFLAGS
- Параметры командной строки, передаваемые препроцессору языка программирования C.
- AM_CXXFLAGS
- Параметры командной строки, передаваемые препроцессору языка программирования C++.
G.1.2.3. Создание файлов .hg и .cgg
Теперь мы должны создать первые файлы с расширениями .hg и .ccg с целью формирования обертки для одного из объектов созданной с использованием языка программирования C библиотеки. Одна пара примеров файлов исходного кода уже существует: skeleton.ccg и skeleton.hg. Создавайте копии этих файлов по мере необходимости.
Мы должны указать имена всех наших файлов с расширениями .hg и .cgg в файле skeleton/src/filelist.am обычно в качестве значения переменной files_hg.
Любые дополнительные не сгенерированные файлы исходного кода с расширениями .h и .cc могут быть размещены в директории skeleton/skeletonmm/ и описаны в файле skeleton/skeletonmm/filelist.am обычно с помощью значений переменных files_extra_h и files_extra_cc.
В разделе "Файлы с расширениями .hg и .ccg" вы можете узнать о синтаксисе, используемом в этих файлах.
G.2. Генерация файлов с расширением .defs
.defs являются текстовыми файлами в формате lisp, описывающими API созданной с использованием языка программирования C библиотеки, в частности:
- объекты (типа GObject, виджеты, интерфейсы, обертки для структур (boxed-type) и обычные структуры)
- функции
- перечисления
- сигналы
- свойства
- виртуальные функции
.deps и именно поэтому производится распределение различной информации по отдельным файлам. Например, в директории gtk/src исходных кодов gtkmm вы сможете обнаружить следующие файлы:
- gtk.defs
- Используется для подключения других файлов.
- gtk_methods.defs
- Хранит описания объектов и функций.
- gtk_enums.defs
- Хранит описания перечислений.
- gtk_signals.defs
- Хранит описания сигналов и свойств.
- gtk_vfuncs.defs
- Хранит описания виртуальных функций (полей структур, представленных указателями на функции), создаваемые вручную.
Сценарий skeleton/codegen/generate_defs_and_docs.sh генерирует все файлы с расширением .defs и файл *_docs.xml, описанный в разделе "Документация".
G.2.1. Генерация файла с расширением .defs для хранения описаний методов
.defs данного типа хранит описания объектов и их функций. Он генерируется с помощью сценария h2def.py, который вы можете найти в директории tools/defs_gen. Пример команды для генерации файла:
$ ./h2def.py /usr/include/gtk-3.0/gtk/*.h > gtk_methods.defs
G.2.2. Генерация файла с расширением .defs для хранения описаний перечислений
.defs данного типа хранит описания типов перечислений и их возможных значений. Он генерируется с помощью сценария enum.pl, который вы можете найти в директории tools исходного кода glibmm. Пример команды для генерации файла:
$ ./enum.pl /usr/include/gtk-3.0/gtk/*.h > gtk_enums.defs
G.2.3. Генерация файла с расширением .defs для хранения описаний сигналов и свойств
.defs данного типа хранит описания сигналов и свойств. Он генерируется с помощью специальной утилиты generate_extra_defs, которая поставляется вместе с исходными кодами любого проекта по созданию обертки для библиотеки, например, в нашем случае она расположена в директории gtkmm/tools/extra_defs_gen/. Пример команды для генерации файла:
$ cd tools/extra_defs_gen $ ./generate_extra_defs > gtk_signals.defs
Вы должны отредактировать исходный код вашей утилиты generate_extra_defs с целью генерации файлов с расширением .defs для объявленных на уровне языка программирования C типов GObject, для которых вы желаете создать обертки. В дереве исходного кода прототипа проекта имя файла исходного кода утилиты codegen/extradefs/generate_extra_defs_skeleton.cc. Если вы еще не переименовали этот файл, сделайте это, заменив "skeleton" на основное название вашей новой обертки. В файле codegen/Makefile.am также должно использоваться новое имя файла исходного кода.
.cc, указав корректные типы. Например, ваша функция main() может выглядеть следующим образом:
#include <libsomething.h>
int main(int, char**)
{
something_init();
std::cout << get_defs(SOME_TYPE_WIDGET)
<< get_defs(SOME_TYPE_STUFF);
return 0;
}
G.2.4. Создание файла с расширением .defs для хранения описаний виртуальных функций
Файл с расширением .defs данного типа описывает виртуальные функции (vfuncs). Он должен создаваться вручную. Существует прототип данного файла с именем skeleton/src/skeleton_vfunc.defs, с редактирования которого можно начать работу. Также вы можете рассмотреть файл gtk/src/gtk_vfuncs.defs из дерева исходного кода gtkmm.
Следующий раздел : Приложение G.3. Файлы с расширениями .hg и .ccg.
