makefile-targets and some other meta info functions added
This commit is contained in:
+66
-22
@@ -13,27 +13,27 @@
|
||||
|
||||
@section{A functional makefile}
|
||||
|
||||
A makefile is declared with one prefix and a set of target clauses:
|
||||
A makefile is ordinary Racket code inside @racket[makefile]. The prefix and static symbolic target names are explicit values:
|
||||
|
||||
@racketblock[
|
||||
(require racket-makefile)
|
||||
|
||||
(makefile wiki
|
||||
(default-target all)
|
||||
(phony status clean all)
|
||||
(makefile 'wiki
|
||||
(default-target 'all)
|
||||
(phony 'status 'clean 'all)
|
||||
|
||||
(target status
|
||||
(target 'status
|
||||
(displayln "status"))
|
||||
|
||||
(target clean
|
||||
(target 'clean
|
||||
(rm-rf "compiled"))
|
||||
|
||||
(target all
|
||||
(deps status)
|
||||
(target 'all
|
||||
(deps 'status)
|
||||
(displayln "all")))
|
||||
]
|
||||
|
||||
The @racket[makefile] form defines real Racket procedures. The example defines @racket[makefile-target-wiki-status], @racket[makefile-target-wiki-clean], and @racket[makefile-target-wiki-all]. They can be inspected or called like any other procedure.
|
||||
A statically quoted target name defines a real Racket procedure binding. The example defines @racket[makefile-target-wiki-status], @racket[makefile-target-wiki-clean], and @racket[makefile-target-wiki-all]. They can be inspected or called like any other procedure.
|
||||
|
||||
@racketblock[
|
||||
(procedure? makefile-target-wiki-status)
|
||||
@@ -44,35 +44,65 @@ Calling a generated target procedure directly executes the recipe directly. Call
|
||||
|
||||
@section{Makefile definitions}
|
||||
|
||||
@defform[(makefile prefix clause ...)]{
|
||||
Defines one prefixed makefile. The @racket[prefix] is a literal identifier, string, path, or quoted symbol. Each @racket[clause] is a @racket[target], @racket[phony], or @racket[default-target] clause.
|
||||
@defform[(makefile prefix form ...)]{
|
||||
Defines one prefixed makefile and evaluates @racket[form ...] as ordinary Racket code in the lexical context of that makefile. The @racket[prefix] is explicit, normally a quoted symbol such as @racket['wiki].
|
||||
|
||||
Before registering the new clauses, registrations for the same prefix are removed. After all clauses are registered, @racket[current-makefile-prefix] is set to the prefix. Consequently the last evaluated @racket[makefile] form becomes the active makefile.
|
||||
Before the body is evaluated, registrations for the same prefix are removed. After the complete body has been evaluated, @racket[current-makefile-prefix] is set to the prefix. Consequently the last evaluated @racket[makefile] form becomes the active makefile.
|
||||
|
||||
A target named @racket[status] in a makefile with prefix @racket[wiki] defines the procedure @racket[makefile-target-wiki-status].
|
||||
Ordinary definitions, loops, conditionals, and other Racket forms may occur in the body. The declaration forms @racket[target], @racket[phony], and @racket[default-target] obtain the surrounding prefix lexically and can therefore also occur inside nested Racket forms.
|
||||
}
|
||||
|
||||
@defform[(target name (deps dependency ...) body ...)]{
|
||||
Defines a named target procedure inside @racket[makefile]. The @racket[name] is a literal identifier, string, path, or quoted symbol. The target procedure executes @racket[body ...].
|
||||
Registers one target procedure for the surrounding makefile. The @racket[name] is an ordinary Racket expression.
|
||||
|
||||
Dependency expressions are evaluated when the makefile is registered. A dependency expression may produce nested lists; the build engine flattens them.
|
||||
When @racket[name] is a quoted static value, for example @racket['status], the macro also defines a normal Racket procedure binding. In a makefile with prefix @racket['wiki], @racket[(target 'status ...)] defines @racket[makefile-target-wiki-status].
|
||||
|
||||
When @racket[name] is an expression such as a variable, the expression is evaluated while the surrounding makefile body runs. The resulting procedure is registered dynamically and closes over the lexical values used by its recipe. This allows ordinary loops to generate targets.
|
||||
|
||||
Dependency expressions are evaluated when the target is registered. A dependency expression may produce nested lists; the build engine flattens them.
|
||||
}
|
||||
|
||||
A target without a @racket[deps] clause has no dependencies.
|
||||
|
||||
@defform[(deps dependency ...)]{
|
||||
Specifies target dependencies. The form is valid only as the dependency clause of @racket[target].
|
||||
Specifies target dependencies. Each dependency is an ordinary Racket expression. The form is valid only as the dependency clause of @racket[target].
|
||||
}
|
||||
|
||||
@defform[(phony name ...)]{
|
||||
Marks the named targets as phony for the surrounding makefile prefix. A phony target is always executed when requested or reached as a dependency.
|
||||
Marks the values produced by @racket[name ...] as phony for the surrounding makefile prefix. A value may also be a list of target names. A phony target is always executed when requested or reached as a dependency.
|
||||
}
|
||||
|
||||
@defform[(default-target name)]{
|
||||
Selects the target used by @racket[(make)] for the surrounding makefile prefix. If no default is specified, the first declared target is used.
|
||||
Selects the target value produced by @racket[name] for @racket[(make)] in the surrounding makefile prefix. If no default is specified, the first registered target is used.
|
||||
}
|
||||
|
||||
The declaration forms @racket[target], @racket[deps], @racket[phony], and @racket[default-target] are not standalone declarations in version 0.3.0. They are clauses of @racket[makefile].
|
||||
@section{Generated targets}
|
||||
|
||||
Because @racket[makefile] is a lexical context instead of a fixed list of clauses, targets can be generated by ordinary Racket code:
|
||||
|
||||
@racketblock[
|
||||
(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 a separate target procedure for each object file. Each procedure closes over the corresponding @racket[src] and @racket[obj] values. The quoted static targets still define the normal bindings @racket[makefile-target-stuff-all] and @racket[makefile-target-stuff-clean].
|
||||
|
||||
@section{Executing targets}
|
||||
|
||||
@@ -81,7 +111,7 @@ Builds the supplied targets in the makefile selected by @racket[current-makefile
|
||||
|
||||
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 @racket[make] call.
|
||||
|
||||
For a target that needs rebuilding, the engine looks up the target procedure in @racket[makefile-targets] and calls it.
|
||||
For a target that needs rebuilding, the engine looks up the registered target procedure for the active prefix and calls it.
|
||||
}
|
||||
|
||||
@defthing[current-makefile-prefix parameter?]{
|
||||
@@ -95,8 +125,22 @@ Another registered makefile can be selected explicitly:
|
||||
]
|
||||
}
|
||||
|
||||
@defthing[makefile-targets hash?]{
|
||||
The global prefix-aware target registry. Registry values are the generated target procedures themselves. This binding is exposed mainly for inspection and tooling; normal target execution should use @racket[make].
|
||||
@section{Inspecting registered makefiles}
|
||||
|
||||
@defproc[(makefile-prefixes) list?]{
|
||||
Returns the registered makefile prefixes in evaluation order. The original prefix values are preserved.
|
||||
}
|
||||
|
||||
@defproc[(makefile-targets [prefix (or/c symbol? path-string?) (current-makefile-prefix)]) list?]{
|
||||
Returns the targets registered for @racket[prefix] in registration order. The original target values are preserved, so symbolic targets are returned as symbols and dynamically generated path targets are returned as paths.
|
||||
}
|
||||
|
||||
@defproc[(makefile-target-exists? [name (or/c symbol? path-string?)]) boolean?]{
|
||||
Returns whether @racket[name] exists in the active makefile. To inspect another prefix, use @racket[(makefile-target-exists? prefix name)].
|
||||
}
|
||||
|
||||
@defproc[(makefile-target-procedure [name (or/c symbol? path-string?)]) procedure?]{
|
||||
Returns the registered target procedure for @racket[name] in the active makefile. To inspect another prefix, use @racket[(makefile-target-procedure prefix name)]. An unknown target raises an exception.
|
||||
}
|
||||
|
||||
@section{Rash integration}
|
||||
|
||||
Reference in New Issue
Block a user