8.13 The `guile' Function ========================= GNU make may be built with support for GNU Guile as an embedded extension language. You can check the `.FEATURES' variable for the word `guile' to determine if your version of GNU make provides this capability. GNU Guile implements the Scheme language. A review of GNU Guile and the Scheme language and its features is beyond the scope of this manual: see the documentation for GNU Guile and Scheme. If GNU Guile is available as an extension language, there will be one new `make' function available: `guile'. The `guile' function takes one argument which is first expanded by `make' in the normal fashion, then passed to the GNU Guile evaluator function. The result of the evaluator is converted into a string and used as the expansion of the `guile' function in the makefile. 8.13.1 Conversion of Guile Results ---------------------------------- When the `guile' function is evaluated, `make' will convert the result of the function into a string and use it as the result of the evaluation. The conversion of different Guile types into a string is as follows: `#f' The empty string: in `make' the empty string is considered false. `#t' The string `t': in `make' any non-empty string is considered true. `symbol' `number' A symbol or number is converted into the string representation of that symbol or number. `character' A printable character is converted to the same character. `string' A string containing only printable characters is converted to the same string. `list' A list is converted recursively according to the above rules. This implies that any structured list will be flattened (that is, a result of `'(a b (c d) e)' will be converted to the `make' string `a b c d e'). `other' Any other Guile type results in an error. In future versions of `make', other Guile types may be converted. As a consequence of these conversion rules you must be careful what results your Guile forms evaluate to. If there is no natural result for the script (that is the script exists solely for its side-effects, not for its result), you should have it return `#f' to avoid syntax errors in your makefile from result conversions. 8.13.2 Interfaces from Guile to `make' -------------------------------------- In addition to the `guile' function available in makefiles, there are three functions exported into GNU Guile by `make', for use in your Guile scripts. The `make' program creates a new module, `gnu make', and exports these functions as public interfaces from that module: `gmk-expand' This GNU Guile function takes a single string as an argument. The string is expanded by `make' using normal expansion rules. The result of the expansion is converted into a string and provided to GNU Guile as the result of the function. `gmk-eval' This function takes a single string as an argument. The string is evaluated by `make' as if it were a makefile. This is the same capability available via the `eval' function (*note Eval Function::). The result of the `gmk-eval' function is always the empty string. `gmk-var' This function takes a single string as an argument. The string is interpreted as the name of a `make' variable, which is then expanded. The result of the expansion is converted into a string and provided as the result of the function in GNU Guile. 8.13.3 Example Using Guile in `make' ------------------------------------ Here is a very simple example using GNU Guile to manage writing to a file. This set of Guile code simply opens a file, then allows writing strings to it (one string per line), then closes it again. 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. This code defines the Guile functions: 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) endef # Internalize the Guile IO functions $(guile $(GUILEIO)) 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