File: modularization.html

package info (click to toggle)
lua-gtk 0.9%2B20100528-2
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 2,176 kB
  • ctags: 1,934
  • sloc: ansic: 9,571; sh: 373; makefile: 241
file content (222 lines) | stat: -rwxr-xr-x 9,667 bytes parent folder | download
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

<p>
Since Version 1.0, LuaGnome is split into modules, each one being a shared
object providing binding to one Gnome library, e.g. glib, gdk or gtk.  Care
has been taken not to create build time dependencies, so that additional
modules can be used from a different build or even from an independent source
tree.
</p>

<p>The core module is named <b>gnome</b>.  It provides the global table
<tt>gnome</tt> with following members intended for internal use:
</p>

<dl>
 <dt>api</dt><dd>A userdata that basically is a jump table to functions
  provided by the core module, along with version information to detect
  incompatibilities.  Each module accesses <tt>gnome.api</tt> when
  loading.</dd>
 <dt>fundamental_map</dt><dd>A table of fundamental data types.  Keys are
  a hash of the type name, values an index into an array of the core
  module.</dd>
 <dt>typemap</dt><dd>Similar to <tt>fundamental_map</tt>, this table's keys
  are hashes of type names (like "GtkWindow"), values are an integer
  representation of <tt>typespec_t</tt>, i.e. a module index and a type index.
  The module index specifies which module handles the type, while the type
  index gives the offset in the module's type array.</dd>
</dl>

<p>
Following entries in the global table <tt>gnome</tt> are useful to users:
</p>

<p>
As mentioned above, each module provides a binding to one Gnome library, and
consists of the following parts:
</p>

<ul>
 <li>A list of <b>functions</b> consisting of the function's name, the type
  of the return value and the types of all arguments</li>

 <li>A list of <b>constants</b>, i.e. enums and #defines.  The values may
  be numbers or strings, and have a data type like GtkWindowType.</li>

 <li>An array of <b>data types</b>; functions and constants refer to entries
  in that array by indices.  This array is built at compile time and is sorted
  by frequency, so that often used types have low indices.  This allows using
  just one byte for the index in many cases.</li>

 <li>A list of <b>globals</b>, i.e. global variables; each having a name and
  a data type.</li>
</ul>

<p>
In the filesystem, a modules is a directory with the following files:
</p>

<ul>
  <li>The <b>spec.lua</b> file, explained in detail below.</li>

  <li>A <b>Makefile</b> listing source files to compile as well as dependencies.
    In most cases this is quite simple; please refer to existing Makefiles
    as model.</li>

  <li>An optional <b>configure.lua</b> script, if the setup is more complicated
    than can be handled by settings in <tt>spec.lua</tt>.  So far, this is
    only the case for the core module.</li>

 <li>Some <b>glue code</b>, mostly in the file <tt>init.c</tt>, to load the
   module.  I plan to generate most of that automatically, too.</li>
 
 <li>Optionally <b>overrides</b> to provide an "impedance matching" between
  Lua and C conventions.  Overrides should only be used when calling wouldn't
  otherwise be possible, not to provide new functions or to change the API.
  This might seem nice in some cases, but to make the binding as transparent
  and small as possible, such improvements shouldn't be made.</li>

 <li>Any number of extra source files as specified in the <tt>Makefile</tt>.
 </li>

</ul>

<p>
Note that there are no "wrapper functions", as often seen in library bindings,
but a specification of return and argument types.  The call is then performed
using the <a href="http://en.wikipedia.org/wiki/Libffi">ffi library</a>.  The
arguments provided by the user are Lua values, which are converted to ffi types
before the call.  The return value and possibly "output arguments" (pointers to
memory which is changed by the called function) are converted back to Lua
values after the call.
</p>

<p>
This design greatly reduces the binding size, and also makes it easy to
support most functions by automatically generating the data.
Furthermore the API of the binding is almost identical to the underlying
library, so that no separate API has to be invented, documented and learned by
the user.
</p>

<h3>spec.lua files</h3>

<p>
Each module must have a <i>spec.lua</i> file in its directory.  It contains
build information, like what dynamic libraries to link with, which header
files to extract constants from, compiler flags and more.  Following
settings are currently known:
</p>

<dl>
 <dt>name</dt><dd>Name of the module, mostly used for the summary report</dd>

 <dt>pkg_config_name</dt><dd>The package containing the library as known to
  <i>pkg-config</i>; this is how compile and link flags are determined.</dd>

 <dt>required</dt><dd>If set to true, the configure script will abort if this
  module can't be built.  It is set for glib, gdk and gtk.</dd>

 <dt>libraries</dt><dd>Contains an entry for each supported architecture
  (key, currently linux and win32) with the value being array of libraries to
  link to, e.g. <tt>"/usr/lib/libgobject-2.0.so"</tt>.</dd>

 <dt>headers</dt><dd>An array of { full_path, with_numerical_defines } items,
  each one advising <tt>parse-xml.lua</tt> to read the given header and extract
  <tt>#define</tt>s, which are then available as constants.</dd>

 <dt>includes</dt><dd>Similar to <i>libraries</i>, provides an array of
  header files to <tt>#include</tt> for generation of the type list.  As a
  special case, the architecture "all" is always used, in addition to an
  optional architecture-specific list of includes. </dd>

 <dt>defs</dt><dd>Similar to <i>libraries</i>, has a list of statements to
  put into the generated .c file that, when compiled with gccxml, results in
  the file types.xml.  It can have the entries "all" or architecture-specific
  entries. </dd>

 <dt>include_types</dt><dd>A list of additional types to be supported by the
  module.  The list is generated at build time starting with types used by
  functions and globals, and completed with all types reachable from there,
  i.e. by types of structure elements, which may be function prototypes again
  using a list of types.  Any non-reachable types are omitted, but some useful
  types might be missing.  In this case, specify them in this setting.</dd>
 <dt>

 <dt>function_flags</dt><dd>It is possible to specify flags for a function's
  return value or any of its arguments.  In many cases this can replace an
  override.  Supported flags are: <dl>
   <dt>CONST_OBJECT</dt>
   <dt>NOT_NEW_OBJECT</dt>
   <dt>CHAR_PTR</dt>
   <dt>CONST_CHAR_PTR</dt>
   <dt>INCREF</dt><dd>This flag for function arguments causes the refcount
    of an object used as argument to be increased after the call.  Use this
    to handle the case of a function that "uses" an existing reference.</dd>
  </dl>
  Available flags are listed in the file <tt>script/util.lua</tt>.
  </dd>
 
 <dt>ignore_functions</dt><dd>Add any functions that should not be supported
  by the module to this hash table, the key being the function name, and
  the value "true".</dd>

 <dt>aliases</dt><dd>Some functions don't have a consistent name that allows
 them to be called as methods.  For example, <code>gdk_draw_line</code> has a
 first argument of the type GdkDrawable; it should, therefore, be named
 <code>gdk_drawable_draw_line</code>, so that <code>obj:draw_line()</code>
 works.  <br/> This setting is a mapping with pairs in this form: new_name =
 "old_name".
 </dd>
 
 Add any functions that should not be supported
  by the module to this hash table, the key being the function name, and
  the value "true".</dd>
 
 <dt>linklist</dt><dd>If the bound libraries are not loaded automatically,
  but through a manual linking process, functions are called through a
  function table that is automatically generated using this list.  The
  advantage is that an older version of the library can be loaded by the
  module, not causing an error until a missing function is called.
  <br/>
  Each entry in this list is either a simple string, i.e. the function's
  name, or a two-item table: { "functionname", "condition" }.  The condition
  is a string that is evaluated as Lua expression and can evaluate the
  versions of the library, e.g. "glib &gt;= '2.15'".
  <br/>
  An easy method to get a list of external functions used is to compile
  the module without the manual linking, and then do this:
  <code>nm module.so | grep " U " | grep -v "GLIBC\|lua_\|luaL_"</code>

  </dd>

  <dt>moddep</dt><dd>An array listing names of other modules.  Their spec
    files will be read and CFLAGS defined by them are used.  The only case
    where this is currently required is for cairo and libxml2, which both
    do not depend on glib, but common include files do, e.g. GType is
    used.</dd>

  <dt>module_info</dt><dd>A map with settings for the automatic generation
    of the <tt>struct module_info</tt> that each module exports.  It defines
    prefixes for functions, constants and types, prefix overrides, function
    overrides, dependencies on other modules and more.
    <ul>
	    <li>prefix_func_remap: give the name of a constant string that
	    specifies the function prefix to use for one or more types
	    (classes).  This prefix is normally computed automatically, like
	    gtk_vbox_ for GtkVBox, but somtimes the function (method) names are
	    not so regular.  Each entry in this string has this components:
	    	<ul>
			<li> 1 byte: the total length of this entry including
			the length byte and the last zero byte after the
			function prefix </li>
			<li> class name (zero terminated) </li>
			<li> function prefix (also zero-terminated) </li>
		</ul>
	    The end of this list is marked by a zero byte.  For an example see
	    the modules "gnet" or "gconf".
	    </li>
    </ul>
    </dd>

</dl>