From: ludo@gnu.org (Ludovic Courtès)
To: guile-user@gnu.org
Subject: Re: Using guile as an extension language for GNU make
Date: Sun, 18 Sep 2011 14:10:19 +0200 [thread overview]
Message-ID: <87pqiyaw5w.fsf@gnu.org> (raw)
In-Reply-To: 1316304616.28907.118.camel@homebase
Hi Paul,
Paul Smith <psmith@gnu.org> skribis:
> I've been experimenting with using Guile as an extension language to GNU
> make (optionally built-in of course).
Sounds like great news! :-)
> What I've done so far:
>
> * Modified GNU make's main to be invoked from scm_boot_guile(), if
> Guile is enabled.
Ideally, when Guile support is enabled, GNU make would be turned into a
Guile extension (a shared library and its companion Scheme module that
loads it with ‘load-extension’) that would expose make’s functionality.
The main advantage is that make could then be used by “normal” Guile
programs:
(use-modules (make))
(define c->o
(make-rule (make-target "foo.o")
(make-prerequisites '("foo.c" "foo.h"))
(list (make-expand "$(CC)") "-c -Wall"
(make-expand "$^") " -o "
(make-expand "$@"))))
(eval-make-rule c->o)
Or:
(use-modules (make))
(define mf (parse-makefile "/foo/GNUmakefile"))
(format #t "the targets are: ~a~%" (makefile-targets mf))
;; Imagine code that extracts the complete DAG, computes the critical
;; path length, and schedules tasks...
The ‘make’ executable would be a Guile script like:
(use-modules (make))
(apply run-make (command-line))
This is more intrusive than embedding libguile in make, but it’s also
more fruitful. On the general patterns of embedding vs. extending, see
the excellent <http://www.twistedmatrix.com/users/glyph/rant/extendit.html>.
> * Created a new GNU make function, $(guile ...), where the
> argument is passed to Guile for expansion and the result is
> turned into a string and used as the result; the code looks like
> this:
> func_guile (char *o, char **argv, const char *funcname UNUSED)
> {
> if (argv[0] && argv[0][0] != '\0')
> {
> char *str = scm_to_locale_string (scm_object_to_string (scm_c_eval_string (argv[0]),
> SCM_UNDEFINED));
> char *s = str;
> unsigned int l = strlen (s);
>
> if (s[0] == '"' && s[l-1] == '"')
There are two problems I can think of here:
- string unquoting is actually more complex than this (recall that
‘object->string’ merely calls ‘write’):
--8<---------------cut here---------------start------------->8---
(call-with-output-string
(lambda (p)
(set-port-encoding! p "ISO-8859-1")
(set-port-conversion-strategy! p 'substitute)
(write "\"λ\" is a Greek letter" p)))
=> "\"\\\"\\u03bb\\\" is a Greek letter\""
--8<---------------cut here---------------end--------------->8---
- ‘scm_c_eval_string’ can return any Scheme objects, some of which
have meaningless representations as strings:
--8<---------------cut here---------------start------------->8---
(object->string (current-module))
=> "#<directory (guile-user) 2405090>"
--8<---------------cut here---------------end--------------->8---
The latter is probably the most serious question. I think you would
really want to constrain expressions passed in $(guile ...) to return a
string, and not any other type of objects.
In that case, you could solve the first problem by using (display ...)
instead of (write ...).
> * Created two new functions and registered them with Guile:
> (make-expand <string>) which takes a string argument and expands
> it as a make expression, so it can be something like
> (make-expand "$(VAR)") for example to get the value of the make
> variable VAR. And (make-eval <string>) which takes a string
> argument and evaluates it as a makefile snippet; this is
> essentially the same as running (make-expand "$(eval <string>)")
> just shorter to type. This lets you define make constructs like
> rules and variables from within the Guile interpreter. The code
> looks like this:
Looks good to me.
Thanks!
Ludo’.
next prev parent reply other threads:[~2011-09-18 12:10 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-18 0:10 Using guile as an extension language for GNU make Paul Smith
2011-09-18 12:10 ` Ludovic Courtès [this message]
2011-09-18 17:21 ` Embedding vs. Extending (was: Re: Using guile as an extension language for GNU make) Paul Smith
2011-09-18 21:48 ` Embedding vs. Extending Ludovic Courtès
2011-09-18 17:42 ` Using guile as an extension language for GNU make Paul Smith
2011-09-18 21:28 ` Ludovic Courtès
2011-09-18 15:30 ` Thien-Thi Nguyen
2011-09-18 19:28 ` Paul Smith
2011-09-19 0:28 ` Thien-Thi Nguyen
2011-09-19 15:14 ` Paul Smith
2011-09-19 19:41 ` Hans Aberg
2011-09-19 21:56 ` Paul Smith
2011-09-19 22:35 ` Hans Aberg
2011-09-19 23:00 ` Hans Aberg
2011-09-21 2:42 ` Mark H Weaver
2011-09-21 8:24 ` Hans Aberg
2011-09-20 16:17 ` Thien-Thi Nguyen
2011-09-20 17:31 ` Paul Smith
2011-09-20 19:02 ` Paul Smith
2011-09-21 0:48 ` Thien-Thi Nguyen
2011-09-20 20:39 ` Thien-Thi Nguyen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87pqiyaw5w.fsf@gnu.org \
--to=ludo@gnu.org \
--cc=guile-user@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).