From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: ludo@gnu.org (Ludovic =?iso-8859-1?Q?Court=E8s?=) Newsgroups: gmane.lisp.guile.user Subject: Re: Using guile as an extension language for GNU make Date: Sun, 18 Sep 2011 14:10:19 +0200 Message-ID: <87pqiyaw5w.fsf@gnu.org> References: <1316304616.28907.118.camel@homebase> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Trace: dough.gmane.org 1316359595 15451 80.91.229.12 (18 Sep 2011 15:26:35 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sun, 18 Sep 2011 15:26:35 +0000 (UTC) To: guile-user@gnu.org Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Sun Sep 18 17:26:31 2011 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1R5JGI-0002sp-Rp for guile-user@m.gmane.org; Sun, 18 Sep 2011 17:26:31 +0200 Original-Received: from localhost ([::1]:45443 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R5JGI-0005yE-Az for guile-user@m.gmane.org; Sun, 18 Sep 2011 11:26:30 -0400 Original-Received: from eggs.gnu.org ([140.186.70.92]:39882) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R5JGF-0005xK-PT for guile-user@gnu.org; Sun, 18 Sep 2011 11:26:29 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1R5JGE-0005c4-2o for guile-user@gnu.org; Sun, 18 Sep 2011 11:26:27 -0400 Original-Received: from lo.gmane.org ([80.91.229.12]:51991) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R5JGD-0005c0-LA for guile-user@gnu.org; Sun, 18 Sep 2011 11:26:26 -0400 Original-Received: from list by lo.gmane.org with local (Exim 4.69) (envelope-from ) id 1R5JGC-0002rm-35 for guile-user@gnu.org; Sun, 18 Sep 2011 17:26:24 +0200 Original-Received: from reverse-83.fdn.fr ([80.67.176.83]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sun, 18 Sep 2011 17:26:24 +0200 Original-Received: from ludo by reverse-83.fdn.fr with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sun, 18 Sep 2011 17:26:24 +0200 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 113 Original-X-Complaints-To: usenet@dough.gmane.org X-Gmane-NNTP-Posting-Host: reverse-83.fdn.fr User-Agent: Gnus/5.110018 (No Gnus v0.18) Emacs/24.0.50 (gnu/linux) X-URL: http://www.fdn.fr/~lcourtes/ X-Revolutionary-Date: Jour du =?iso-8859-1?Q?G=E9nie?= de =?iso-8859-1?Q?l?= =?iso-8859-1?Q?'Ann=E9e?= 219 de la =?iso-8859-1?Q?R=E9volution?= X-PGP-Key-ID: 0xEA52ECF4 X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc X-PGP-Fingerprint: 83C4 F8E5 10A3 3B4C 5BEA D15D 77DD 95E2 EA52 ECF4 X-OS: x86_64-unknown-linux-gnu Cancel-Lock: sha1:Y2YH1yHX9zdRy5/RfEv7unE9pys= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 80.91.229.12 X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Original-Sender: guile-user-bounces+guile-user=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.user:8798 Archived-At: Hi Paul, Paul Smith 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 . > * 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)) => "#" --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 ) 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 ) which takes a string > argument and evaluates it as a makefile snippet; this is > essentially the same as running (make-expand "$(eval )") > 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’.