racket-makefile
| (require racket-makefile) | package: racket-makefile |
racket-makefile provides make-style dependency builds as ordinary Racket functionality. The package has no Rash dependency. Rash integration is provided by the separate rash-makefile package.
1 A functional makefile
A makefile is declared with one prefix and a set of target clauses:
(require racket-makefile) (makefile wiki (default-target all) (phony status clean all) (target status (displayln "status")) (target clean (rm-rf "compiled")) (target all (deps status) (displayln "all")))
The makefile form defines real Racket procedures. The example defines makefile-target-wiki-status, makefile-target-wiki-clean, and makefile-target-wiki-all. They can be inspected or called like any other procedure.
(procedure? makefile-target-wiki-status) (makefile-target-wiki-status)
Calling a generated target procedure directly executes the recipe directly. Calling the target through make adds dependency traversal and timestamp based rebuilding.
2 Makefile definitions
syntax
(makefile prefix clause ...)
Before registering the new clauses, registrations for the same prefix are removed. After all clauses are registered, current-makefile-prefix is set to the prefix. Consequently the last evaluated makefile form becomes the active makefile.
A target named status in a makefile with prefix wiki defines the procedure makefile-target-wiki-status.
syntax
(target name (deps dependency ...) body ...)
Dependency expressions are evaluated when the makefile is registered. A dependency expression may produce nested lists; the build engine flattens them.
A target without a deps clause has no dependencies.
syntax
(deps dependency ...)
syntax
(phony name ...)
syntax
(default-target name)
The declaration forms target, deps, phony, and default-target are not standalone declarations in version 0.3.0. They are clauses of makefile.
3 Executing targets
procedure
name : (or/c symbol? path-string?)
With no arguments, the configured default target is used. If no explicit default exists, the first target of the active makefile is used. Multiple supplied targets are processed in order, and shared dependencies are built once during one make call.
For a target that needs rebuilding, the engine looks up the target procedure in makefile-targets and calls it.
Another registered makefile can be selected explicitly:
(current-makefile-prefix 'wiki) (make 'status)
value
4 Rash integration
Rash integration is intentionally provided by the separate rash-makefile package so that racket-makefile remains a pure Racket dependency.
5 Recipe context
syntax
syntax
syntax
The generated procedure establishes this context even when called directly.
6 Dependency processing
A non-phony target is rebuilt when its output does not exist or when a dependency is newer than the target. Registered target dependencies are built first. A dependency that is neither a registered target in the same prefix nor an existing file is an error. Dependency cycles are reported as errors.
Multiple makefile prefixes can remain registered simultaneously. Dependency lookup stays within the prefix of the target being built.
7 Refreshing definitions
procedure
In DrRacket, pressing Run is usually the simpler way to reevaluate a Racket or Rash makefile.
8 Running commands
The symbols '$target, '$deps, and '$< are expanded from the current target context when they occur in the command list.
9 Cleanup helpers
procedure
path : path-string?
procedure
path : path-string?
procedure
directory : path-string? patterns : list?
procedure
(list-dir/files directory regexp [ #:recursive recursive]) → list? directory : path-string? regexp : regexp? recursive : any/c = #f
procedure
(list-files directory regexp [ #:recursive recursive]) → list? directory : path-string? regexp : regexp? recursive : any/c = #f
procedure
(list-dirs directory regexp [ #:recursive recursive]) → list? directory : path-string? regexp : regexp? recursive : any/c = #f