5ff1a1abe8
The term "POSIX" is an abbreviation referring to multiple IEEE standard versions, this is clarifying to use the latest one.
218 lines
6.6 KiB
Markdown
218 lines
6.6 KiB
Markdown
# POTATO MAKE
|
|
|
|
Potato Make is a scheme library that aims to simplify the task of
|
|
maintaining, updating, and regenerating programs. It is inspired by
|
|
the `make` utility in IEEE Std 1003.1-2017 (POSIX). With this library, you can write a
|
|
build script in Guile Scheme.
|
|
|
|
## 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
|
|
|
|
(execute)
|
|
|
|
The rules go in between `initialize` and `build`.
|
|
|
|
## A Simple Example
|
|
|
|
#!/usr/bin/env sh
|
|
exec guile -s "$0" "$@"
|
|
!#
|
|
|
|
(use-modules (potato make))
|
|
(initialize)
|
|
(:= CC "gcc")
|
|
(:= CFLAGS "-g -O2")
|
|
|
|
(: "all" '("foo"))
|
|
(: "foo" '("foo.o" "bar.o")
|
|
(~ ($ CC) "-o" $@ $^))
|
|
(-> ".c" ".o"
|
|
(~ ($ CC) "-c" $<))
|
|
(execute)
|
|
|
|
## Command-Line Arguments
|
|
|
|
This boilerplate loads the library functions and it parses the
|
|
command-line arguments. The command-line arguments are the following,
|
|
|
|
<your-script-name> [-hvqVeEbknB] [var=value...] [target_name...]
|
|
-h, --help
|
|
displays help
|
|
-v, --version
|
|
displays the version number of this script
|
|
-V [0,1,2,3], --verbosity=[0,1,2,3]
|
|
choose the verbosity of the output
|
|
-e, --environment
|
|
environment variables are converted to makevars
|
|
-E, --elevate-environment
|
|
environment variables are converted to makevars
|
|
and will override makevars set in the script
|
|
-b, --builtins
|
|
adds some default makevars and suffix rules
|
|
--ignore-errors [NOT IMPLEMENTED YET]
|
|
keep building even if a command fails
|
|
-k, --continue-on-error [NOT IMPLEMENTED YET]
|
|
keep building some targets even if a command fails
|
|
-n, --no-execute [NOT IMPLEMENTED YET]
|
|
print rules, but only execute rules marked as
|
|
'always execute'
|
|
-a, --ascii
|
|
use ASCII-only output and no colors
|
|
-W, --warn [NOT IMPLEMENTED YET]
|
|
enable warning messages
|
|
|
|
[var=value...]
|
|
set the value of makevars
|
|
[target_name...]
|
|
Set one or more targets to be executed. If no target
|
|
is specified, the first target found will be executed.
|
|
|
|
## 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.
|
|
You define makevars in the script, in the environment, or on the command line.
|
|
|
|
($ 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.
|
|
|
|
(?= 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" $<))
|
|
|
|
Recipe as a boolean to indicate pass or failure without doing any
|
|
processing. For example, the rule below tells Potato Make that
|
|
the file "foo.c" exists without actually testing for it.
|
|
|
|
(: "foo.c" '() #t)
|
|
|
|
If there is no recipe at all, it is shorthand for the recipe #t,
|
|
indicating a recipe that always passes. This is used
|
|
in prerequisite-only target rules, such as below, which passes
|
|
so long as the prerequisites
|
|
pass. These two rules are the same.
|
|
|
|
(: "all" '("foo.exe"))
|
|
(: "all" '("foo.exe") #t)
|
|
|
|
Lastly, if the recipe is #f, this target will always fail.
|
|
|
|
(: "fail" '() #f)
|
|
|
|
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
|
|
- automatic 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
|
|
|
|
## Automatic Variables
|
|
|
|
Recipes can contain the following automatic 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
|
|
|
|
## POSIX Makefile Parser
|
|
|
|
Recipes can contain the following parser function
|
|
|
|
(parse ...) reads a standard Makefile and creates
|
|
rules based on its contents.
|