La estructura de construcción

Generation of the source code for a gtkmm-style wrapper API requires use of tools such as gmmproc and generate_wrap_init.pl. In theory you could write your own build files to use these appropriately, but a much better option is to make use of the build infrastructure provided by the mm-common module. To get started, it helps a lot to pick an existing binding module as an example to look at.

For instance, let's pretend that we are wrapping a C library called libsomething. It provides a GObject-based API with types named, for instance, SomeWidget and SomeStuff.

G.1.1. Copiar el esqueleto del proyecto

Typically our wrapper library would be called libsomethingmm. We can start by copying the skeleton source tree from the mm-common module.

  $ git clone https://gitlab.gnome.org/GNOME/mm-common.git
  $ cp -a mm-common/skeletonmm libsomethingmm

This provides a directory structure for the source .hg and .ccg files and the generated .h and .cc files, with filelist.am Automake include files that can specify the various files in use, in terms of generic Automake variables. The directory structure usually looks like this, after we have renamed the directories appropriately:

  • libsomethingmm: The top-level directory.

    • libsomething: Contains the main include file and the pkg-config .pc file.

      • src: Contains .hg and .ccg source files.

      • libsomethingmm: Contains generated and hand-written .h and .cc files.

        • private: Contains generated *_p.h files.

As well as renaming the directories, we should rename some of the source files. For instance:

$ for f in $(find libsomethingmm -depth -name '*skeleton*'); do \
    d="${f%/*}"; b="${f##*/}"; mv "$f" "$d/${b//skeleton/libsomething}"; \
  done
A number of the skeleton files must still be filled in with project-specific content later.

Tenga en cuenta que los archivos que terminan en .in se utilizan para generar archivos con el mismo nombre pero sin el sufijo .in, mediante la sustitución de algunas variables con valores reales durante la fase de configuración.

G.1.2. Modificar archivos de construcción

Ahora se editan los archivos para adaptarlos a las necesidades. Tal vez prefiera usar una utilidad para buscar y reemplazar múltiples archivos, como regexxer. Tenga en cuenta que casi todos los archivos proporcionados con el esqueleto del árbol de fuentes contienen texto con marcadores de posición. Es por esto que las sustituciones se deben hacer globalmente, y no limitarse a los archivos de Automake y Autoconf.

Todas las menciones de skeleton deben reemplazarse por el nombre correcto de la biblioteca de C que está envolviendo, como «something» o «libsomething». De la misma manera, todas las instancias de SKELETON deben reemplazarse por «SOMETHING» o «LIBSOMETHING», y todas las apariciones de Skeleton deben cambiarse por «Something».

De la misma manera, reemplace todas las instancias de Joe Hacker por el nombre del titular de los derechos de autor, quien probablemente sea usted. Haga lo mismo para la dirección de correo-e joe@example.com.

G.1.2.1. configure.ac

In configure.ac,

  • The AC_CONFIG_SRCDIR() line must mention a file in our source tree. We can edit this later if we don't yet know the names of any of the files that we will create.
  • It is common for binding modules to track the version number of the library they are wrapping. So, for instance, if the C library is at version 1.23.4, then the initial version of the binding module would be 1.23.0. However, avoid starting with an even minor version number as that usually indicates a stable release.
  • The AC_CONFIG_HEADERS() line is used to generate two or more configuration header files. The first header file in the list contains all configuration macros which are set during the configure run. The remaining headers in the list contain only a subset of configuration macros and their corresponding config.h.in file will not be autogenerated. The reason for this separation is that the namespaced configuration headers are installed with your library and define publically visible macros.
  • The AC_SUBST([SOMETHINGMM_MODULES], ['...']) line may need to be modified to check for the correct dependencies.
  • The AC_CONFIG_FILES() block must mention the correct directory names, as described above.

G.1.2.2. Archivos Makefile.am

Next we must adapt the various Makefile.am files:

  • In skeleton/src/Makefile.am we must mention the correct values for the generic variables that are used elsewhere in the build system:

    binding_name

    The name of the library, such as libsomethingmm.

    wrap_init_flags

    Additional command-line flags passed to the generate_wrap_init.pl script, such as the C++ namespace and the parent directory prefix of include files.

  • In skeleton/skeletonmm/Makefile.am we must mention the correct values for the generic variables that are used elsewhere in the build system:

    lib_LTLIBRARIES

    This variable must mention the correct library name, and this library name must be used to form the _SOURCES, _LDFLAGS, and _LIBADD variable names. It is permissible to use variables substituted by configure like @SOMETHINGMM_API_VERSION@ as part of the variable names.

    AM_CPPFLAGS

    The command line options passed to the C preprocessor.

    AM_CXXFLAGS

    The command line options passed to the C++ compiler.

G.1.2.3. Crear archivos .hg y .ccg

Ahora se deben crear los primeros archivos .hg y .ccg, para envolver uno de los objetos en la biblioteca de C. Ya existen un par de archivos de fuentes de ejemplo: skeleton.ccg y skeleton.hg. Cree copias de estos archivos si es necesario.

Se deben mencionar todos los archivos .hg y .ccg en el archivo skeleton/src/filelist.am, típicamente en la variable files_hg.

Cualquier archivo de fuentes .h y .cc adicional no generado se puede poner en skeleton/skeletonmm/ y listar en skeleton/skeletonmm/filelist.am, típicamente en las variables files_extra_h y files_extra_cc.

En la sección archivos .hg y .ccg puede aprender acerca de la sintaxis usada en estos archivos.