SWIG and Guile

# 14 SWIG and Guile

- Meaning of "Module"
- Linkage
  - Simple Linkage
  - Passive Linkage
  - Native Guile Module Linkage
  - Old Auto-Loading Guile Module Linkage
  - Hobbit4D Linkage
  - General Remarks on Multiple SWIG Modules
- Underscore Folding
- Typemaps
- Smobs
- Exception Handling
- Procedure documentation
- Procedures with setters

This section details guile-specific support in SWIG.

## 14.1 Meaning of "Module"

There are three different concepts of "module" involved, defined separately for SWIG, Guile, and Libtool. To avoid horrible confusion, we explicitly prefix the context, e.g., "guile-module".

## 14.2 Linkage

Guile support is complicated by a lack of user community cohesiveness, which manifests in multiple shared-library usage conventions. A set of policies implementing a usage convention is called a linkage.

### 14.2.1 Simple Linkage

The default linkage is the simplest; nothing special is done. In this case the function `SWIG_init()` is exported. Simple linkage can be used in several ways:

- Embedded Guile, no modules. You want to embed a Guile interpreter into your program; all bindings made by SWIG shall show up in the root module. Then call `SWIG_init()` in the `inner_main()` function. See the "simple" and "matrix" examples under `Examples/guile`.
- Dynamic module mix-in. You want to create a Guile module using `define-module`, containing both Scheme code and bindings made by SWIG; you want to load the SWIG modules as shared libraries into Guile.

  >     (define-module (my module))
  >     (define my-so (dynamic-link "./example.so"))
  >     (dynamic-call "SWIG_init" my-so) ; make SWIG bindings
  >     ;; Scheme definitions can go here

  Newer Guile versions provide a shorthand for `dynamic-link` and `dynamic-call`:

  >     (load-extension "./example.so" "SWIG_init")

  You need to explicitly export those bindings made by SWIG that you want to import into other modules:

  >     (export foo bar)

  In this example, the procedures `foo` and `bar` would be exported. Alternatively, you can export all bindings with the following module-system hack:

  >     (module-map (lambda (sym var)
  >     	      (module-export! (current-module) (list sym)))
  >     	    (current-module))

  SWIG can also generate this Scheme stub (from `define-module` up to `export`) semi-automagically if you pass it the command-line argument `-scmstub foo.scm`. Since SWIG doesn't know how to load your extension module (with `dynamic-link` or `load-extension`), you need to supply this information by including a directive like this in the interface file:

  >     %scheme %{ (load-extension "./example.so" "SWIG_init") %}

  (The `%scheme` directive allows to insert arbitrary Scheme code into the generated file `foo.scm`; it is placed between the `define-module` form and the `export` form.)

If you want to include several SWIG modules, you would need to rename `SWIG_init` via a preprocessor define to avoid symbol clashes. For this case, however, passive linkage is available.

### 14.2.2 Passive Linkage

Passive linkage is just like simple linkage, but it generates an initialization function whose name is derived from the module and package name (see below).

You should use passive linkage rather than simple linkage when you are using multiple modules.

### 14.2.3 Native Guile Module Linkage

SWIG can also generate wrapper code that does all the Guile module declarations on its own if you pass it the `-Linkage module` command-line option. This requires Guile 1.5.0 or later.

The module name is set with the `-package` and `-module` command-line options. Suppose you want to define a module with name `(my lib foo)`; then you would have to pass the options `-package my/lib -module foo`. Note that the last part of the name can also be set via the SWIG directive `%module`.

You can use this linkage in several ways:

- Embedded Guile with SWIG modules. You want to embed a Guile interpreter into your program; the SWIG bindings shall be put into different modules. Simply call the function `scm_init_my_modules_foo_module` in the `inner_main()` function.
- Dynamic Guile modules. You want to load the SWIG modules as shared libraries into Guile; all bindings are automatically put in newly created Guile modules.

  >     (define my-so (dynamic-link "./foo.so"))
  >     ;; create new module and put bindings there:
  >     (dynamic-call "scm_init_my_modules_foo_module" my-so)

  Newer Guile versions have a shorthand procedure for this:

  >     (load-extension "./foo.so" "scm_init_my_modules_foo_module")

### 14.2.4 Old Auto-Loading Guile Module Linkage

Guile used to support an autoloading facility for object-code modules. This support has been marked deprecated in version 1.4.1 and is going to disappear sooner or later. SWIG still supports building auto-loading modules if you pass it the `-Linkage ltdlmod` command-line option.

Auto-loading worked like this: Suppose a module with name `(my lib foo)` is required and not loaded yet. Guile will then search all directories in its search path for a Scheme file `my/modules/foo.scm` or a shared library `my/modules/libfoo.so` (or `my/modules/libfoo.la`; see the GNU libtool documentation). If a shared library is found that contains the symbol `scm_init_my_modules_foo_module`, the library is loaded, and the function at that symbol is called with no arguments in order to initialize the module.

When invoked with the `-Linkage ltdlmod` command-line option, SWIG generates an exported module initialization function with an apropriate name.

### 14.2.5 Hobbit4D Linkage

The only other linkage supported at this time creates shared object libraries suitable for use by hobbit's `(hobbit4d link)` guile module. This is called the "hobbit" linkage, and requires also using the "-package" command line option to set the part of the module name before the last symbol. For example, both command lines:

>     swig -guile -package my/lib foo.i
>     swig -guile -package my/lib -module foo foo.i

would create module `(my lib foo)` (assuming in the first case foo.i declares the module to be "foo"). The installed files are my/lib/libfoo.so.X.Y.Z and friends. This scheme is still very experimental; the (hobbit4d link) conventions are not well understood.

### 14.2.6 General Remarks on Multiple SWIG Modules

If you want to use multiple SWIG modules, they have to share some run-time data for the typing system. You have two options:

- Either generate all but one wrapper module with the `-c` command-line argument. Compile all wrapper files with the C compiler switch `-DSWIG_GLOBAL`.
- Or generate all wrapper modules with the `-c` command-line argument and compile all wrapper files with the C compiler switch `-DSWIG_GLOBAL`. Then link against the runtime library `libswigguile`, which is built by `make runtime`. The needed linker flags are reported by SWIG if you invoke it with the `-guile -ldflags` command-line arguments.

## 14.3 Underscore Folding

Underscores are converted to dashes in identifiers. Guile support may grow an option to inhibit this folding in the future, but no one has complained so far.

You can use the SWIG directives `%name` and `%rename` to specify the Guile name of the wrapped functions and variables (see CHANGES).

## 14.4 Typemaps

The Guile module handles all types via typemaps. This information is read from `Lib/guile/typemaps.i`. Some non-standard typemap substitutions are supported:

- `$descriptor` expands to a type descriptor for use with the `SWIG_Guile_MakePtr()` and `SWIG_Guile_GetPtr` functions.
- For pointer types, `$*descriptor` expands to a descriptor for the direct base type (i.e., one pointer is stripped), whereas `$basedescriptor` expands to a descriptor for the base type (i.e., all pointers are stripped).

A function returning `void` (more precisely, a function whose `out` typemap returns `GH_UNSPECIFIED`) is treated as returning no values. In `argout` typemaps, one can use the macro `GUILE_APPEND_RESULT` in order to append a value to the list of function return values.

Multiple values can be passed up to Scheme in one of three ways:

- Multiple values as lists. By default, if more than one value is to be returned, a list of the values is created and returned; to switch back to this behavior, use

  >     %values_as_list;

- Multiple values as vectors. By issueing

  >     %values_as_vector;

  vectors instead of lists will be used.
- Multiple values for multiple-value continuations. This is the most elegant way. By issueing

  >     %multiple_values;

  multiple values are passed to the multiple-value continuation, as created by `call-with-values` or the convenience macro `receive`. The latter is available if you issue `(use-modules (srfi srfi-8))`. Assuming that your `divide` function wants to return two values, a quotient and a remainder, you can write:

  >     (receive (quotient remainder)
  >         (divide 35 17)
  >       body...)

  In `body`, the first result of `divide` will be bound to the variable `quotient`, and the second result to `remainder`.

See also the "multivalue" example.

## 14.5 Smobs

For pointer types, SWIG uses Guile smobs.

In earlier versions of SWIG, C pointers were represented as Scheme strings containing a hexadecimal rendering of the pointer value and a mangled type name. As Guile allows registering user types, so-called "smobs" (small objects), a much cleaner representation has been implemented now. The details will be discussed in the following.

A smob is a cons cell where the lower half of the CAR contains the smob type tag, while the upper half of the CAR and the whole CDR are available. `SWIG_Guile_Init()` registers a smob type named "swig" with Guile; its type tag is stored in the variable `swig_tag`. The upper half of the CAR store an index into a table of all C pointer types seen so far, to which new types seen are appended. The CDR stores the pointer value. SWIG smobs print like this: `#<swig struct xyzzy * 0x1234affe>` Two of them are `equal?` if and only if they have the same type and value.

To construct a Scheme object from a C pointer, the wrapper code calls the function `SWIG_Guile_MakePtr()`, passing a pointer to a struct representing the pointer type. The type index to store in the upper half of the CAR is read from this struct.

To get the pointer represented by a smob, the wrapper code calls the function `SWIG_Guile_GetPtr`, passing a pointer to a struct representing the expected pointer type. If the Scheme object passed was not a SWIG smob representing a compatible pointer, a `wrong-type-arg` exception is raised.

## 14.6 Exception Handling

SWIG code calls `scm_error` on exception, using the following mapping:

          MAP(SWIG_MemoryError,	"swig-memory-error");
          MAP(SWIG_IOError,		"swig-io-error");
          MAP(SWIG_RuntimeError,	"swig-runtime-error");
          MAP(SWIG_IndexError,	"swig-index-error");
          MAP(SWIG_TypeError,	"swig-type-error");
          MAP(SWIG_DivisionByZero,	"swig-division-by-zero");
          MAP(SWIG_OverflowError,	"swig-overflow-error");
          MAP(SWIG_SyntaxError,	"swig-syntax-error");
          MAP(SWIG_ValueError,	"swig-value-error");
          MAP(SWIG_SystemError,	"swig-system-error");

The default when not specified here is to use "swig-error". See Lib/exception.i for details.

## 14.7 Procedure documentation

If invoked with the command-line option `-procdoc file`, SWIG creates documentation strings for the generated wrapper functions, describing the procedure signature and return value, and writes them to file. You need Guile 1.4 or later to make use of the documentation files.

SWIG can generate documentation strings in three formats, which are selected via the command-line option `-procdocformat format`:

- `guile-1.4` (default): Generates a format suitable for Guile 1.4.
- `plain`: Generates a format suitable for Guile 1.4.1 and later.
- `texinfo`: Generates texinfo source, which must be run through texinfo in order to get a format suitable for Guile 1.4.1 and later.

You need to register the generated documentation file with Guile like this:

    (use-modules (ice-9 documentation))
    (set! documentation-files
          (cons "file" documentation-files))

Documentation strings can be configured using the Guile-specific typemaps `indoc`, `outdoc`, `argoutdoc`, `varindoc`, and `varoutdoc`. See `Lib/guile/typemaps.i` for details.

## 14.8 Procedures with setters

For global variables, SWIG creates a single wrapper procedure `(variable :optional value)`, which is used for both getting and setting the value. For struct members, SWIG creates two wrapper procedures `(struct-member-get pointer)` and `(struct-member-set pointer value)`.

If invoked with the command-line option `-emit-setters`, SWIG will additionally create procedures with setters. For global variables, the procedure-with-setter `variable` is created, so you can use `(variable)` to get the value and `(set! (variable) value)` to set it. For struct members, the procedure-with-setter `struct-member` is created, so you can use `(struct-member pointer)` to get the value and `(set! (struct-member pointer) value)` to set it.