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.
The core module is named gnome. It provides the global table
gnome with following members intended for internal use:
- api
- 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 gnome.api when
loading.
- fundamental_map
- A table of fundamental data types. Keys are
a hash of the type name, values an index into an array of the core
module.
- typemap
- Similar to fundamental_map, this table's keys
are hashes of type names (like "GtkWindow"), values are an integer
representation of typespec_t, 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.
Following entries in the global table gnome are useful to users:
As mentioned above, each module provides a binding to one Gnome library, and
consists of the following parts:
- A list of functions consisting of the function's name, the type
of the return value and the types of all arguments
- A list of constants, i.e. enums and #defines. The values may
be numbers or strings, and have a data type like GtkWindowType.
- An array of data types; 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.
- A list of globals, i.e. global variables; each having a name and
a data type.
In the filesystem, a modules is a directory with the following files:
- The spec.lua file, explained in detail below.
- A Makefile listing source files to compile as well as dependencies.
In most cases this is quite simple; please refer to existing Makefiles
as model.
- An optional configure.lua script, if the setup is more complicated
than can be handled by settings in spec.lua. So far, this is
only the case for the core module.
- Some glue code, mostly in the file init.c, to load the
module. I plan to generate most of that automatically, too.
- Optionally overrides 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.
- Any number of extra source files as specified in the Makefile.
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 ffi library. 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.
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.
spec.lua files
Each module must have a spec.lua 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:
- name
- Name of the module, mostly used for the summary report
- pkg_config_name
- The package containing the library as known to
pkg-config; this is how compile and link flags are determined.
- required
- If set to true, the configure script will abort if this
module can't be built. It is set for glib, gdk and gtk.
- libraries
- Contains an entry for each supported architecture
(key, currently linux and win32) with the value being array of libraries to
link to, e.g. "/usr/lib/libgobject-2.0.so".
- headers
- An array of { full_path, with_numerical_defines } items,
each one advising parse-xml.lua to read the given header and extract
#defines, which are then available as constants.
- includes
- Similar to libraries, provides an array of
header files to #include 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.
- defs
- Similar to libraries, 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.
- include_types
- 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.
-
- function_flags
- 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:
- CONST_OBJECT
- NOT_NEW_OBJECT
- CHAR_PTR
- CONST_CHAR_PTR
- INCREF
- 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.
Available flags are listed in the file script/util.lua.
- ignore_functions
- 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".
- aliases
- Some functions don't have a consistent name that allows
them to be called as methods. For example,
gdk_draw_line
has a
first argument of the type GdkDrawable; it should, therefore, be named
gdk_drawable_draw_line
, so that obj:draw_line()
works.
This setting is a mapping with pairs in this form: new_name =
"old_name".
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".
- linklist
- 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.
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 >= '2.15'".
An easy method to get a list of external functions used is to compile
the module without the manual linking, and then do this:
nm module.so | grep " U " | grep -v "GLIBC\|lua_\|luaL_"
- moddep
- 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.
- module_info
- A map with settings for the automatic generation
of the struct module_info that each module exports. It defines
prefixes for functions, constants and types, prefix overrides, function
overrides, dependencies on other modules and more.
- 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:
- 1 byte: the total length of this entry including
the length byte and the last zero byte after the
function prefix
- class name (zero terminated)
- function prefix (also zero-terminated)
The end of this list is marked by a zero byte. For an example see
the modules "gnet" or "gconf".