make: Guile Example

 
 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.