1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
|
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="highlight.min.css">
<script src="highlight.min.js"></script><script>
hljs.configure({languages: ['cpp']});
hljs.highlightAll();
</script><title>Appendix G. Wrapping C Libraries with gmmproc</title>
<link rel="stylesheet" type="text/css" href="style.css">
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
<link rel="home" href="index.html" title="Programming with gtkmm 4">
<link rel="up" href="index.html" title="Programming with gtkmm 4">
<link rel="prev" href="sec-installing-jhbuild.html" title="Installing and Using the git version of gtkmm">
<link rel="next" href="sec-wrapping-defs-files.html" title="Generating the .defs files.">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr><th colspan="3" align="center">Appendix G. Wrapping C Libraries with gmmproc</th></tr>
<tr>
<td width="20%" align="left">
<a accesskey="p" href="sec-installing-jhbuild.html"><img src="icons/prev.png" alt="Prev"></a> </td>
<th width="60%" align="center"> </th>
<td width="20%" align="right"> <a accesskey="n" href="sec-wrapping-defs-files.html"><img src="icons/next.png" alt="Next"></a>
</td>
</tr>
</table>
<hr>
</div>
<div class="appendix">
<div class="titlepage"><div><div><h1 class="title">
<a name="chapter-wrapping-c-libraries"></a>Appendix G. Wrapping C Libraries with gmmproc</h1></div></div></div>
<div class="toc">
<p><b>Table of Contents</b></p>
<ul class="toc">
<li><span class="section"><a href="chapter-wrapping-c-libraries.html#sec-wrapping-build-structure">The build structure</a></span></li>
<li><span class="section"><a href="sec-wrapping-defs-files.html">Generating the .defs files.</a></span></li>
<li><span class="section"><a href="sec-wrapping-hg-files.html">The .hg and .ccg files</a></span></li>
<li><span class="section"><a href="sec-wrapping-hand-coded-files.html">Hand-coded source files</a></span></li>
<li><span class="section"><a href="sec-wrapping-initialization.html">Initialization</a></span></li>
<li><span class="section"><a href="sec-wrapping-problems.html">Problems in the C API.</a></span></li>
<li><span class="section"><a href="sec-wrapping-documentation.html">Documentation</a></span></li>
</ul>
</div>
<p><span class="application">gtkmm</span> uses the <span class="command"><strong>gmmproc</strong></span> tool to generate most of its
source code, using .defs files that define the APIs of
<code class="classname">GObject</code>-based libraries. So it's quite easy to create
additional gtkmm-style wrappers of other glib/GObject-based
libraries.</p>
<p>This involves a variety of tools, some of them crufty, but at least
they work, and has been used successfully by several
projects.</p>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="sec-wrapping-build-structure"></a>The build structure</h2></div></div></div>
<p>Generation of the source code for a gtkmm-style wrapper API requires use
of tools such as <span class="command"><strong>gmmproc</strong></span> and
<code class="filename">generate_wrap_init.pl</code>, which are included in
<span class="application">glibmm</span>. 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 <span class="application">mm-common</span>
module. To get started, it helps a lot to pick an existing binding module as an example
to look at.</p>
<p>For instance, let's pretend that we are wrapping a C library called
libsomething. It provides a <code class="classname">GObject</code>-based API with
types named, for instance, <code class="classname">SomeWidget</code> and
<code class="classname">SomeStuff</code>.</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="copying-skeleton-project"></a>Copying the skeleton project</h3></div></div></div>
<p>Typically our wrapper library would be called libsomethingmm. We can start by
copying the <a class="ulink" href="https://gitlab.gnome.org/GNOME/mm-common/tree/master/skeletonmm" target="_top">
skeleton source tree</a> from the <span class="application">mm-common</span> module.
Starting with <span class="application">mm-common</span> 1.0.0 this skeleton application
is built with the <a class="ulink" href="https://mesonbuild.com/" target="_top">Meson build system</a>.
</p>
<pre class="programlisting"><code class="code"> $ git clone https://gitlab.gnome.org/GNOME/mm-common.git
$ cp -a mm-common/skeletonmm libsomethingmm
</code></pre>
<p>This provides a directory structure for the source .hg and .ccg files and the hand-written
.h and .cc files, with <code class="filename">meson.build</code> files that can specify the
various files in use, in terms of Meson variables. The directory structure usually
looks like this, after we have renamed the directories appropriately:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
<p><code class="filename">libsomethingmm</code>: The top-level directory.</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem">
<p><code class="filename">libsomething</code>: Contains the main include file and the pkg-config .pc file.</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: square; ">
<li class="listitem"><p><code class="filename">src</code>: Contains .hg and .ccg source files.</p></li>
<li class="listitem">
<p><code class="filename">libsomethingmm</code>: Contains hand-written .h and .cc files.</p>
</li>
</ul></div>
</li></ul></div>
</li></ul></div>
<p>
</p>
<p>As well as renaming the directories, we should rename some of the source
files. For instance:</p>
<pre class="programlisting"><code class="code">$ for f in $(find libsomethingmm -depth -name '*skeleton*'); do \
d="${f%/*}"; b="${f##*/}"; mv "$f" "$d/${b//skeleton/libsomething}"; \
done
</code></pre>
<p>A number of the skeleton files must still be filled in with project-specific content later.
</p>
<p>Note that files ending in <code class="filename">.in</code> will be used to generate
files with the same name but without the <code class="filename">.in</code> suffix, by
replacing some variables with actual values during the configure stage.</p>
<p>Generated files are saved in the build tree, which is separated from the
source tree when <span class="command"><strong>meson</strong></span> and <span class="command"><strong>ninja</strong></span> are used.</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="modifying-build-files"></a>Modifying build files</h3></div></div></div>
<p>Now we edit the files to adapt them to our needs. You might prefer to use a multiple-file
search-replace utility for this, such as <span class="command"><strong>regexxer</strong></span>. Note that nearly all of the
files provided with the skeleton source tree contain placeholder text. Thus, the substitutions
should be performed globally, and not be limited to the Meson files.</p>
<p>All mentions of <code class="varname">skeleton</code> should be replaced by the correct name of the C
library you are wrapping, such as "something" or "libsomething". In the same manner, all
instances of <code class="varname">SKELETON</code> should be replaced by "SOMETHING" or "LIBSOMETHING", and
all occurrences of <code class="varname">Skeleton</code> changed to "Something".</p>
<p>Likewise, replace all instances of <code class="varname">Joe Hacker</code> by the name of the intended
copyright holder, which is probably you. Do the same for the <code class="varname">joe@example.com</code>
email address.</p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="modifying-top-meson.build"></a>meson.build in the top-level directory</h4></div></div></div>
<p>
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem"><p>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.</p></li>
<li class="listitem"><p>In the <code class="function">project()</code> function, change the
license and the C++ version, if necessary.</p></li>
<li class="listitem"><p>You probably need to add more required modules than
<span class="application">glibmm</span> and <span class="application">skeleton</span>
(<span class="application">libsomething</span>).</p></li>
</ul></div>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="modifying-other-meson.build"></a>Other meson.build files</h4></div></div></div>
<p>Next we must adapt the other <code class="filename">meson.build</code> files:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p><code class="filename">skeleton/meson.build</code>: Perhaps not much
to change here more than the global name substitutions.</p>
</li>
<li class="listitem">
<p><code class="filename">skeleton/skeletonmm/meson.build</code></p>
<div class="variablelist"><dl class="variablelist">
<dt><span class="term"><code class="varname">defs_basefiles</code></span></dt>
<dd><p>If we have more .defs and docs.xml files,
we add them here.</p></dd>
<dt><span class="term"><code class="varname">hg_ccg_basenames</code></span></dt>
<dd><p>We must mention all of our <code class="filename">.hg</code> and
<code class="filename">.ccg</code> files here.</p></dd>
<dt><span class="term"><code class="varname">extra_cc_files, extra_h_files</code></span></dt>
<dd><p>Any additional hand-written <code class="filename">.h</code> and
<code class="filename">.cc</code> source files go here.</p></dd>
</dl></div>
</li>
</ul></div>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="creating-hg-ccg"></a>Creating .hg and .ccg files</h4></div></div></div>
<p>We should now create our first <code class="filename">.hg</code> and <code class="filename">.ccg</code> files,
to wrap one of the objects in the C library. One pair of example source files already exists:
<code class="filename">skeleton.ccg</code> and <code class="filename">skeleton.hg</code>. Create copies of these
files as necessary.</p>
<p>In the <a class="link" href="sec-wrapping-hg-files.html" title="The .hg and .ccg files">.hg and .ccg files</a>
section you can learn about the syntax used in these files.</p>
</div>
</div>
</div>
</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left">
<a accesskey="p" href="sec-installing-jhbuild.html"><img src="icons/prev.png" alt="Prev"></a> </td>
<td width="20%" align="center"> </td>
<td width="40%" align="right"> <a accesskey="n" href="sec-wrapping-defs-files.html"><img src="icons/next.png" alt="Next"></a>
</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Installing and Using the git version of <span class="application">gtkmm</span> </td>
<td width="20%" align="center"><a accesskey="h" href="index.html"><img src="icons/home.png" alt="Home"></a></td>
<td width="40%" align="right" valign="top"> Generating the .defs files.</td>
</tr>
</table>
</div>
</body>
</html>
|