makefile-targets and some other meta info functions added
This commit is contained in:
@@ -5,27 +5,29 @@
|
||||
|
||||
## Functional makefiles
|
||||
|
||||
A makefile is ordinary Racket code inside a `makefile` form. The prefix and static symbolic target names are explicit values:
|
||||
|
||||
```racket
|
||||
#lang racket
|
||||
|
||||
(require racket-makefile)
|
||||
|
||||
(makefile wiki
|
||||
(default-target all)
|
||||
(phony all clean status)
|
||||
(makefile 'wiki
|
||||
(default-target 'all)
|
||||
(phony 'all 'clean 'status)
|
||||
|
||||
(target status
|
||||
(target 'status
|
||||
(displayln "status"))
|
||||
|
||||
(target clean
|
||||
(target 'clean
|
||||
(rm-rf "compiled"))
|
||||
|
||||
(target all
|
||||
(deps status)
|
||||
(target 'all
|
||||
(deps 'status)
|
||||
(displayln "all")))
|
||||
```
|
||||
|
||||
A `makefile` form defines real target procedures. The example above defines, among others:
|
||||
A statically quoted target name defines a real named procedure. The example above defines, among others:
|
||||
|
||||
```racket
|
||||
makefile-target-wiki-status
|
||||
@@ -40,7 +42,7 @@ They are ordinary procedures:
|
||||
(makefile-target-wiki-status)
|
||||
```
|
||||
|
||||
`make` is also an ordinary procedure. Target names are explicit Racket values:
|
||||
`make` is also an ordinary procedure:
|
||||
|
||||
```racket
|
||||
(make)
|
||||
@@ -48,18 +50,48 @@ They are ordinary procedures:
|
||||
(make 'clean 'all)
|
||||
```
|
||||
|
||||
`make` resolves target names for the active makefile in the global `makefile-targets` registry. It handles dependencies and timestamp checks and invokes the registered target procedure when the target needs to run.
|
||||
`make` resolves target names for the active makefile in an internal prefix-aware registry. It handles dependencies and timestamp checks and invokes the registered target procedure when the target needs to run.
|
||||
|
||||
## Ordinary Racket and generated targets
|
||||
|
||||
The body of `makefile` is not restricted to target clauses. Definitions, loops, conditionals, and other Racket forms can be used directly.
|
||||
|
||||
A target name is an expression. A quoted target name such as `'all` is known while the module is expanded and therefore gets a named Racket binding. A target name such as `obj` is evaluated while the makefile is registered and can therefore be generated by ordinary Racket code.
|
||||
|
||||
```racket
|
||||
(makefile 'stuff
|
||||
(define sources '("foo.c" "bar.c" "baz.c"))
|
||||
|
||||
(define objects
|
||||
(for/list ([src sources])
|
||||
(define obj (path-replace-extension src #".o"))
|
||||
(target obj
|
||||
(deps src)
|
||||
(run `(cc -c $< -o $target)))
|
||||
obj))
|
||||
|
||||
(default-target 'all)
|
||||
(phony 'all 'clean)
|
||||
|
||||
(target 'all
|
||||
(deps objects))
|
||||
|
||||
(target 'clean
|
||||
(apply rm-f objects)))
|
||||
```
|
||||
|
||||
The loop registers `foo.o`, `bar.o`, and `baz.o` as separate target procedures. Each generated procedure closes over the corresponding `src` and `obj` values. The static targets still define `makefile-target-stuff-all` and `makefile-target-stuff-clean` as normal Racket bindings.
|
||||
|
||||
## Makefile prefixes
|
||||
|
||||
Every makefile has a prefix:
|
||||
Every makefile has an explicit prefix:
|
||||
|
||||
```racket
|
||||
(makefile wiki
|
||||
(target status ...))
|
||||
(makefile 'wiki
|
||||
(target 'status ...))
|
||||
|
||||
(makefile audio
|
||||
(target status ...))
|
||||
(makefile 'audio
|
||||
(target 'status ...))
|
||||
```
|
||||
|
||||
Targets with the same name can therefore coexist. Evaluating a `makefile` form makes that prefix current. Consequently the last makefile definition evaluated is the one used by an unqualified `make` call:
|
||||
@@ -81,30 +113,47 @@ Targets with the same name can therefore coexist. Evaluating a `makefile` form m
|
||||
|
||||
Re-evaluating a makefile with the same prefix replaces the registrations for that prefix.
|
||||
|
||||
|
||||
## Inspecting makefiles and targets
|
||||
|
||||
The registered makefiles and targets can be inspected without exposing the mutable registry:
|
||||
|
||||
```racket
|
||||
(makefile-prefixes)
|
||||
;; '(wiki audio)
|
||||
|
||||
(makefile-targets)
|
||||
;; targets for the current prefix
|
||||
|
||||
(makefile-targets 'wiki)
|
||||
;; targets registered for 'wiki
|
||||
|
||||
(makefile-target-exists? 'status)
|
||||
(makefile-target-exists? 'wiki 'status)
|
||||
|
||||
(makefile-target-procedure 'status)
|
||||
(makefile-target-procedure 'wiki 'status)
|
||||
```
|
||||
|
||||
`makefile-targets` returns targets in registration order and preserves their original values. A quoted symbolic target is returned as a symbol, while a dynamically generated path target is returned as a path. The forms without an explicit prefix use `current-makefile-prefix`.
|
||||
|
||||
## Rash integration
|
||||
|
||||
Rash integration is intentionally kept out of this package. Install and require the separate `rash-makefile` package when `make target` line syntax is desired.
|
||||
|
||||
## Targets and dependencies
|
||||
|
||||
A target is declared only inside `makefile`:
|
||||
`target`, `phony`, and `default-target` are valid only in the lexical body of `makefile`. They may occur inside ordinary Racket forms nested in that body.
|
||||
|
||||
Dependencies are ordinary Racket expressions and may return nested lists; the build engine flattens them.
|
||||
|
||||
```racket
|
||||
(makefile example
|
||||
(target "program"
|
||||
(deps "program.c")
|
||||
(run '(cc -o program program.c))))
|
||||
```
|
||||
(makefile 'example
|
||||
(define prerequisites '("one.c" "two.c"))
|
||||
|
||||
Target and makefile names are literal identifiers, strings, paths, or quoted symbols. Dependencies may be expressions and may return nested lists; the build engine flattens them.
|
||||
|
||||
`phony` and `default-target` are also makefile clauses:
|
||||
|
||||
```racket
|
||||
(makefile example
|
||||
(default-target all)
|
||||
(phony all clean)
|
||||
...)
|
||||
(target 'program
|
||||
(deps prerequisites)
|
||||
(run '(cc -o program one.c two.c))))
|
||||
```
|
||||
|
||||
The automatic recipe values remain available inside target procedures:
|
||||
@@ -115,7 +164,7 @@ $deps
|
||||
$<
|
||||
```
|
||||
|
||||
Because a target is a real procedure, calling the generated procedure directly runs its recipe directly. Calling it through `make` adds dependency traversal and timestamp-based rebuilding.
|
||||
Because a target is a real procedure, calling a generated static procedure directly runs its recipe directly. Calling it through `make` adds dependency traversal and timestamp-based rebuilding.
|
||||
|
||||
## Refreshing
|
||||
|
||||
|
||||
Reference in New Issue
Block a user