Previous: Guile Interface, Up: Guile Integration


12.1.3 Example Using Guile in make

Here is a very simple example using GNU Guile to manage writing to a file. These Guile procedures simply open a file, allow writing to the file (one string per line), and close the file. Note that because we cannot store complex values such as Guile ports in make variables, we'll keep the port as a global variable in the Guile interpreter.

You can create Guile functions easily using define/endef to create a Guile script, then use the guile function to internalize it:

     define GUILEIO
     ;; A simple Guile IO library for GNU make
     
     (define MKPORT #f)
     
     (define (mkopen name mode)
       (set! MKPORT (open-file name mode))
       #f)
     
     (define (mkwrite s)
       (display s MKPORT)
       (newline MKPORT)
       #f)
     
     (define (mkclose)
       (close-port MKPORT)
       #f)
     
     #f
     endef
     
     # Internalize the Guile IO functions
     $(guile $(GUILEIO))

If you have a significant amount of Guile support code, you might consider keeping it in a different file (e.g., guileio.scm) and then loading it in your makefile using the guile function:

     $(guile (load "guileio.scm"))

An advantage to this method is that when editing guileio.scm, your editor will understand that this file contains Scheme syntax rather than makefile syntax.

Now you can use these Guile functions to create files. Suppose you need to operate on a very large list, which cannot fit on the command line, but the utility you're using accepts the list as input as well:

     prog: $(PREREQS)
             @$(guile (mkopen "tmp.out" "w")) \
              $(foreach X,$^,$(guile (mkwrite "$(X)"))) \
              $(guile (mkclose))
             $(LINK) < tmp.out

A more comprehensive suite of file manipulation procedures is possible of course. You could, for example, maintain multiple output files at the same time by choosing a symbol for each one and using it as the key to a hash table, where the value is a port, then returning the symbol to be stored in a make variable.