Наши партнеры

UnixForum





Библиотека сайта 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.