Tools to automate adding libraries
**********************************

You want to ...

The chapters Libguile -- high level interface and Libguile -- SCM interface showed how to make C libraries available from Scheme. Here I will describe some automated tools that the Guile team has made available.  Some have been written especially for Guile (the Guile Magic Snarfer), and some are also in use with other languages (Python, Perl, ...)

By hand with gh_
================

By hand with Guile Magic Snarfer
================================

When writing C code for use with Guile, you typically define a set of C functions, and then make some of them visible to the Scheme world by calling the scm_make_gsubr function; a C functions published in this way is called a subr.  If you have many subrs to publish, it can sometimes be annoying to keep the list of calls to scm_make_gsubr in sync with the list of function definitions. Frequently, a programmer will define a new subr in C, recompile his application, and then discover that the Scheme interpreter cannot see the subr, because he forgot to call scm_make_gsubr.

Guile provides the guile-snarf command to manage this problem. Using this tool, you can keep all the information needed to define the subr alongside the function definition itself; guile-snarf will extract this information from your source code, and automatically generate a file of calls to scm_make_gsubr which you can #include into an initialization function.  (The command name comes from the verb ``to snarf'', here meaning ``to unceremoniously extract information from a somewhat unwilling source.'')

How guile-snarf works
---------------------

For example, here is how you might define a new subr called clear-image, implemented by the C function clear_image:

     #include <libguile.h>

     ...

     SCM_PROC (s_clear_image, "clear-image", 1, 0, 0, clear_image);

     SCM
     clear_image (SCM image_smob)
     {
       ...
     }

     ...

     void
     init_image_type ()
     {
     #include "image-type.x"
     }

The SCM_PROC declaration says that the C function clear_image implements a Scheme subr called clear-image, which takes one required argument, no optional arguments, and no tail argument.  SCM_PROC also declares a static array of characters named s_clear_image, initialized to the string "clear-image".  The body of clear_image may use the array in error messages, instead of writing out the literal string; this may save string space on some systems.

Assuming the text above lives in a file named image-type.c, you will need to execute the following command to compile this file:

     guile-snarf image-type.c > image-type.x

This scans image-type.c for SCM_PROC declarations, and sends the following output to the file image-type.x:

     scm_make_gsubr (s_clear_image, 1, 0, 0, clear_image);

When compiled normally, SCM_PROC is a macro which expands to a declaration of the s_clear_image string.

In other words, guile-snarf scans source code looking for uses of the SCM_PROC macro, and generates C code to define the appropriate subrs.  You need to provide all the same information you would if you were using scm_make_gsubr yourself, but you can place the information near the function definition itself, so it is less likely to become incorrect or out-of-date.

If you have many files that guile-snarf must process, you should consider using a rule like the following in your Makefile:

     .SUFFIXES: .x
     .c.x:
     	./guile-snarf $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $< > $

This tells make to run guile-snarf to produce each needed .x file from the corresponding .c file.

guile-snarf passes all its command-line arguments directly to the C preprocessor, which it uses to extract the information it needs from the source code. this means you can pass normal compilation flags to guile-snarf to define preprocessor symbols, add header file directories, and so on.

Macros guile-snarf recognizes
-----------------------------

Here are the macros you can use in your source code from which guile-snarf can construct initialization code:

 -- Macro: SCM_PROC (NAMESTR, NAME, REQ, OPT, TAIL, C_FUNC)
     Declare a new Scheme primitive function, or subr.  The new subr will be named NAME in Scheme code, and be implemented by the C function C_FUNC.  The subr will take REQ required arguments and OPT optional arguments.  If TAIL is non-zero, the function will accept any remaining arguments as a list.

     Use this macro outside all function bodies, preferably above the definition of C_FUNC itself.  When compiled, the SCM_PROC declaration will expand to a definition for the NAMESTR array, initialized to NAME.  The guile-snarf command uses this declaration to automatically generate initialization code to create the subr and bind it in the top-level environment.  See How guile-snarf works, for more info.

     See Subrs, for details on argument passing and how to write C_FUNC.

 -- Macro: SCM_GLOBAL (VAR, SCHEME_NAME)
     Declare a global Scheme variable named SCHEME_NAME, and a static C variable named VAR to point to it.  The value of the Scheme variable lives in the CDR of the cell VAR points to. Initialize the variable to #f.

     Use this macro outside all function bodies.  When compiled, the SCM_GLOBAL macro will expand to a definition for the variable VAR, initialized to an innocuous value.  The guile-snarf command will use this declaration to automatically generate code to create a global variable named SCHEME_NAME, and store a pointer to its cell in VAR.

 -- Macro: SCM_CONST_LONG (VAR, SCHEME_NAME, VALUE)
     Like SCM_GLOBAL, but initialize the variable to VALUE, which must be an integer.

 -- Macro: SCM_SYMBOL (VAR, NAME)
     Declare a C variable of type SCM named VAR, and initialize it to the Scheme symbol object whose name is NAME.

     Use this macro outside all function bodies.  When compiled, the SCM_SYMBOL macro will expand to a definition for the variable VAR, initialized to an innocuous value.  The guile-snarf command will use this declaration to automatically generate code to create a symbol named NAME, and store it in VAR.

Automatically using libtool
===========================

Automatically using SWIG
========================