pman/CHEATSHEET.md
2021-02-10 11:18:43 -08:00

4.2 KiB

CHEATSHEET FOR POTATO MAKE

Boilerplate

Add this at the top of your build script.

#!/usr/bin/env sh
exec guile -s "$0" "$@"
!#

(use-modules (potato make))
(initialize)

Add this at the bottom of your build script

(build)

The rules go in between initialize and build

MAKEVARS

A hash table called %makevars has string keys. These procedures are syntax that add quotation marks around key, so you call them without the quotes on key. The returned value of $ is a string, or an empty string on failure.

($ KEY) -> "VAL"
(Q KEY) -> "\"VAL\""

($ key [transformer])
    Look up `key` in the `%makevars` hash table and return the result
    as a string.  If `key` is not found, return an empty string.
    If a string-to-string transformer procedure is provided, apply it to each
    space-separated token in the result.
(Q key [transformer])
    Like `$` above, except the returned value string has double quotation marks around
    each space-separated token.  If transformer is supplied, the quotation
    marks are added after the transformer is applied to each space-separated
    token.
(?= key val)
    Assign `val` to `key` in the `%makevars` hash table. If `val` is a procedure,
    assign its output to `key` the first time that `key` is referenced.
(:= key val)
    Assign `val` to `key` in the `%makevars` hash table. If `val` is a procedure,
    evaluate it and assign its output to `key` immediately.

Rules

The target rule is for when the target, and the prerequisites, if any, have filenames or phony names.

(: target-name '(prereq-name-1 prereq-name-2 ...)
   recipe-1
   recipe-2
   ...)
   
 `target-name` is a string which is either a filename to be created
 or an phony name like "all" or "clean".
 
 Recipe as a string to be evaluated by the system
 
 (: "foo.o" '("foo.c")
   "cc -c foo.o")
 
 Recipe as a procedure
 
 (: "clean-foo" '()
   (lambda ()
     (delete-file "foo.o")))
   
 Recipe as a procedure that returns #f to indicate failure
 
 (: "recent" '()
   (lambda ()
     (if condition
       #t
       #f))))
   
 Recipe as a procedure returning a string to be evaluated by the system
 
 (: "foo.o" '("foo.c")
   (lambda ()
     (format #f "cc ~A -c foo.c" some-flags))
     
 Recipe using recipe helper procedures, which create a string to be
 evaluated by the system
 
 (: "foo.c" '("foo.c")
   (~ ($ CC) ($ CFLAGS) "-c" $<))

The suffix rule is a generic rule to convert one source file to a target file, based on the filename extensions.

 (-> ".c" ".o"
   (~ ($ CC) ($ CFLAGS) "-c" $< "-o" $@))

Recipe Helpers

 Concatenate elements with `~`. `~` inserts spaces between the elements.
 Elements can be
 - strings
 - procedures that return strings
 - `%makevar` hash-table references
 - special variables
 - anything whose string representation as created by
   (format #f "~A" ...) make sense
 
 Any procedures are applied lazily, when the rule is executed.
 
 (~ "string" (lambda () "string") ($ KEY) $@ 100 )
 
 Three versions of `~` with special effects
 (~- ...)   ignores any errors
 (~@ ...)   doesn't print recipe to console
 (~+ ...)   runs even when `--no-execute` was chosen

Special Variables

 Recipes can contain the following special variables
 
 $@    the target
 $*    the target w/o a filename suffix
 $<    the first prerequisite
 $^    the prerequisites, as a single space-separated string
 $$^   the prerequisites, as a scheme list of strings
 $?    the prerequisites that are files newer than the target file
       as a single space-separated string
 $$?   the prerequisites that are files newer than the target file
       as a scheme list of strings
       
 There are quoted variants to all the above, where each target
 or prerequisite string is placed within double quotation marks, as might
 be required for filenames or paths that contain spaces.
 
 Q@ Q* Q< Q^ QQ^ Q? QQ?