[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Using guile as an extension language for GNU make

From: Paul Smith
Subject: Re: Using guile as an extension language for GNU make
Date: Mon, 19 Sep 2011 17:56:26 -0400

On Mon, 2011-09-19 at 21:41 +0200, Hans Aberg wrote:
> On 19 Sep 2011, at 17:14, Paul Smith wrote:
> > In make, everything is just words: broken up on whitespace.  So for
> > example, maybe someone writes a Guile function that computes a complex
> > set of prerequisites for a target:
> > 
> >     target: $(guile (...some Guile program...))
> > 
> > The list of prerequisites is a whitespace-separated list of target
> > names.  If the Guile program returned a string like "dep1 dep2 dep3"
> > then that would be fine with what I have.  But it seems like it might be
> > nice to allow the Guile script to return it as a list instead.  Then I'd
> > like to convert a list like '(dep1 dep2 dep3) into a string "dep1 dep2
> > dep3" (not "(dep1 dep2 dep3)" as display would do).
> > 
> > But of course each element of the list could be something more complex,
> > as well.  So it gets tricky.
> How does 'make' store a list of words separated by strings internally?
> If Guile converts its lists to such strings, the behavior is likely to
> be fragile. It would better if 'make' converted those strings
> internally to lists, and the Guile extension interaction with those
> lists.

Hi Hans;

The first stage of make is reading in all the makefiles.  As part of
this, variables and functions are expanded (one line at a time) and the
result is a string.

The $(guile ...) make function, like all other make functions and
variables, is expanded in this way, so the return value of the guile
function must be converted to a string and appended to the string buffer
make is constructing.  Once all of the input is expanded and the
expansion is added to the buffer, then make will go back and parse it
(exactly how this is done is very context-dependent).

The short is, I agree that Guile would not want to try to convert a list
into some kind of internal make "list of words" data structure; in fact
that just wouldn't work because at the time it runs there is no such
thing.  All we have is a buffer with whitespace-separated words.

Rather, I need to define a translation from any Guile data type I want
to support into a make-appropriate string (char* buffer) so it can be
appended to make's read buffer, then parsed by make.  For any Guile data
type I can't or don't want to translate, I'll either throw a make error
or else just expand to the empty string.

So far, I have these translations (see the C code I posted earlier):

t               => "t" (for make conditionals, non-empty is true)
nil             => ""  (for make conditionals, empty is false)
"string"        => "string"
'symbol         => "symbol"
1234            => "1234"

I can see that it would be nice to be able to translate:

'(a b c)        => "a b c"

But what about more complex structures like lists of lists?  What about
simple pairs; should '(a . b) => "a b" as well?  Lists of words are just
about all make knows about so maybe the answer is yes.

And finally, currently I have all unknown types expanding to the empty
string but now I'm thinking it would be better to start out more
restrictive and throw errors.  This would ensure that people write their
Guile scripts correctly (giving valid return values) from the start, and
would let me, in the future, expand the supported types without breaking

reply via email to

[Prev in Thread] Current Thread [Next in Thread]