suffix rules in zuo (as a make / shake replacment) ?

20 views
Skip to first unread message

Andreas Reuleaux

unread,
Oct 25, 2022, 12:37:51 AM10/25/22
to Racket Users
Hi,

I am trying to use zuo (as a make / shake ) replacement.


starting out from the example given
at https://docs.racket-lang.org/zuo/zuo-build.html


main.zuo
--------------------
#lang zuo

(provide-targets targets-at)

(define (targets-at at-dir vars)
(define demo (at-dir (.exe "demo")))

(define main.c (at-source "main.c"))
(define main.o (at-dir (.c->.o "main.c")))

(define helper.c (at-source "helper.c"))
(define helper.o (at-dir (.c->.o "helper.c")))

(make-targets
`([:target ,demo (,main.o ,helper.o)
,(lambda (dest token)
(c-link dest (list main.o helper.o) vars))]
[:target ,main.o (,main.c)
,(lambda (dest token)
(c-compile dest main.c vars))]
[:target ,helper.o (,helper.c)
,(lambda (dest token)
(c-compile dest helper.c vars))]
[:target clean ()
,(lambda (token)
(for-each rm* (list main.o helper.o demo)))])))
--------------------


I can add some definitions / targets to build a letter.pdf from a
letter.fo with fop in my case:


main.zuo
--------------------
...

(require zuo/shell)

...

(define (targets-at at-dir vars)
(define letter.pdf (at-source "letter.pdf"))
(define letter.fo (at-source "letter.fo"))

...

(make-targets
`(

...
[:target ,letter.pdf (,letter.fo)
,(lambda (dest token)
(shell/wait "fop -c cfg -fo" "letter.fo" "-pdf" dest)
)]
...
))
)
--------------------



So I can create letter.pdf with

zuo . letter.pdf



So far, so good. Now I am a little more ambitious: I want a make/shake
style suffix rule, how to create (in general) a .pdf from a .fo

And things start to get complicated - there should an easy
solution to this, I guess.

My attempt:


main.zuo
--------------------
...

(require zuo/shell)

...

(define (targets-at at-dir vars)


(define .pdf ????)

...

(make-targets
`(

...

[:target ,.pdf `(,(path-replace-extension ,.pdf #".fo"))
,(lambda (dest token)
`(shell/wait "fop -c cfg -fo" ,.fo "-pdf" dest)


...
))



)
--------------------

Somehow like this? How? Thanks in advance.

I have looked at some of the .zuo files in the racket source tree, but
haven't seen such suffix rules.


Btw in shake I would use


--------------------
; "*.pdf" %> \pdf -> do {
; let fo = pdf -<.> "fo"
; need [fo]
; need ["cfg"]
; cmd Shell "fop" ["-c", "cfg",
"-fo", fo,
"-pdf", pdf]
}
--------------------





-Andreas

Matthew Flatt

unread,
Oct 25, 2022, 1:44:39 AM10/25/22
to Andreas Reuleaux, Racket Users
At Tue, 25 Oct 2022 05:38:15 +0100, Andreas Reuleaux wrote:
> I want a make/shake
> style suffix rule, how to create (in general) a .pdf from a .fo
>
> And things start to get complicated - there should an easy
> solution to this, I guess.

There's no particular support for that right now.


In cases where I need a rule to map over files with the same suffix,
I've used `map` to generate a rule for each file. So, normally, I'd
have a list of ".pdf" files, and then I'd map a rule template over that
list to generate a list of rules:

...
,@(map
(lambda (.pdf)
(define .fo (path-replace-extension .pdf ".fo"))
`[:target ,.pdf (,.fo)
,(lambda (dest token)
(shell/wait "fop -c cfg -fo" .fo "-pdf" dest))])
pdf-files)
....

Using `map` is not the same as having a suffix rule, because it
requires the list `pdf-files` to be written down. Arguably, explicitly
defining a list like `pdf-files` is a good practice for the makefiles
that Zuo was designed to replace.


But there are cases where a suffix rule would be a good choice, and so
I'm not opposed to adding support. I'm tempted to work on this, but I
should do some other things right now, so here are a few thoughts in
case someone else is interested to try.

The `target` and `build` layer is flexible enough to support this
addition, but things like `build/command-line` and `find-target` are
not. I imagine that functions like `find-target` that expect with a
list of `target`s would need to handle something more general --- maybe
a `(list/c (or/c target? target-generator?))`. Most of the work is
probably in `make-targets` to set up target generation.


Matthew

Andreas Reuleaux

unread,
Oct 25, 2022, 7:12:49 AM10/25/22
to Racket Users
Thanks for the clarifications:

And well: it's arguably a very common use pattern in
make.

And maybe I should have been more precise:
really they are called pattern rules in make (or at least: that's what I want) -
and as I can read on: https://www.gnu.org/software/make/manual/html_node/Suffix-Rules.html

"Suffix rules are the old-fashioned way of defining implicit rules for
make. Suffix rules are obsolete because pattern rules are more general
and clearer. They are supported in GNU make for compatibility with old
makefiles.[...]"

(thus: with make pattern rules - for my use case:)

%.pdf: %.fo cfg
fop -c cfg -fo $< -pdf $@


shake (mentioned already),


redo has default targets (file default.pdf.do):

redo-ifchange $2.fo cfg
fop -c cfg -fo $2.fo -pdf $3


etc. - so for me this is a blocker for now (I use them a lot) - I was
just giving zuo a try, which otherwise looks promising.

Thanks again,
Andreas
Reply all
Reply to author
Forward
0 new messages