Change behavior. (require racket-makefile) and use (make <target>) instead of racket Makefile.rkt <target>
This commit is contained in:
@@ -20,3 +20,4 @@ compiled/
|
|||||||
|
|
||||||
/*.bak
|
/*.bak
|
||||||
/gui/*.bak
|
/gui/*.bak
|
||||||
|
/doc
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
|
0.1.2
|
||||||
|
|
||||||
|
Makefile loading no longer starts a build automatically.
|
||||||
|
Added explicit make form: (make), (make target), and (make target ...).
|
||||||
|
Command-line use is now: racket -t Makefile.rkt -e "(make target)".
|
||||||
|
DrRacket can load the makefile with Run and execute make forms interactively.
|
||||||
|
Bare identifiers in make are always interpreted as literal target names.
|
||||||
|
Expanded documentation and examples for command-line and DrRacket use.
|
||||||
|
|
||||||
0.1.1
|
0.1.1
|
||||||
|
|
||||||
Initial racket-makefile language implementation.
|
Initial racket-makefile language implementation.
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
Racket available and only adds targets, dependencies, timestamp based rebuilds,
|
Racket available and only adds targets, dependencies, timestamp based rebuilds,
|
||||||
phony targets, external command execution and a few cleanup helpers.
|
phony targets, external command execution and a few cleanup helpers.
|
||||||
|
|
||||||
|
A makefile only defines its targets. Loading or running the file does not build
|
||||||
|
anything by itself. Builds are started explicitly with `make`.
|
||||||
|
|
||||||
```racket
|
```racket
|
||||||
#lang racket-makefile
|
#lang racket-makefile
|
||||||
|
|
||||||
@@ -26,6 +29,8 @@ phony targets, external command execution and a few cleanup helpers.
|
|||||||
(cleanup "scrbl" '("**.html" "**.js" "**.css")))
|
(cleanup "scrbl" '("**.html" "**.js" "**.css")))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
Install a local checkout with:
|
Install a local checkout with:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
@@ -35,20 +40,68 @@ raco pkg install
|
|||||||
For a versioned archive, give the package name explicitly:
|
For a versioned archive, give the package name explicitly:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
raco pkg install --name racket-makefile racket-makefile-0.1.1.zip
|
raco pkg install --name racket-makefile racket-makefile-0.1.2.zip
|
||||||
```
|
```
|
||||||
|
|
||||||
Run the default target or select one or more targets explicitly:
|
## Running targets
|
||||||
|
|
||||||
|
Load the makefile with `-t` and evaluate a `make` expression with `-e`:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
racket Makefile.rkt
|
racket -t Makefile.rkt -e "(make)"
|
||||||
racket Makefile.rkt clean
|
racket -t Makefile.rkt -e "(make all)"
|
||||||
racket Makefile.rkt clean all
|
racket -t Makefile.rkt -e "(make clean)"
|
||||||
|
racket -t Makefile.rkt -e "(make clean all)"
|
||||||
```
|
```
|
||||||
|
|
||||||
The language adds `target`, `deps`, `phony`, `default-target`, `run`, `rm-f`,
|
`(make)` uses the target selected with `default-target`. If no default target is
|
||||||
`rm-rf`, `cleanup`, `$target`, `$deps` and `$<`. Dependency expressions may
|
specified, the first declared target is used.
|
||||||
also produce lists, which are automatically flattened. Everything else is
|
|
||||||
|
Loading the file alone only registers the targets:
|
||||||
|
|
||||||
|
```text
|
||||||
|
racket -t Makefile.rkt
|
||||||
|
```
|
||||||
|
|
||||||
|
No recipe is executed in that case.
|
||||||
|
|
||||||
|
In DrRacket, open the makefile and press **Run**. This also only loads and
|
||||||
|
registers the targets. Then use the Interactions window:
|
||||||
|
|
||||||
|
```racket
|
||||||
|
> (make)
|
||||||
|
> (make clean)
|
||||||
|
> (make all)
|
||||||
|
> (make clean all)
|
||||||
|
```
|
||||||
|
|
||||||
|
Bare identifiers in `make` are target names, so no quote is needed. For
|
||||||
|
example, `(make clean)` selects the target named `clean`.
|
||||||
|
|
||||||
|
## Generated targets
|
||||||
|
|
||||||
|
Because the rest of the language is ordinary Racket, targets can be generated
|
||||||
|
with normal definitions and loops:
|
||||||
|
|
||||||
|
```racket
|
||||||
|
(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))
|
||||||
|
|
||||||
|
(target all
|
||||||
|
(deps objects))
|
||||||
|
```
|
||||||
|
|
||||||
|
Dependency expressions may produce lists; they are recursively flattened.
|
||||||
|
|
||||||
|
The language adds `target`, `deps`, `phony`, `default-target`, `make`, `run`,
|
||||||
|
`rm-f`, `rm-rf`, `cleanup`, `$target`, `$deps` and `$<`. Everything else is
|
||||||
ordinary Racket.
|
ordinary Racket.
|
||||||
|
|
||||||
See the installed `racket-makefile` Scribble documentation for the full API.
|
See the installed `racket-makefile` Scribble documentation for the full API.
|
||||||
|
|||||||
@@ -1,5 +1,16 @@
|
|||||||
#lang racket-makefile
|
#lang racket-makefile
|
||||||
|
|
||||||
|
;; Load only:
|
||||||
|
;; racket -t Makefile.rkt
|
||||||
|
;;
|
||||||
|
;; Build the default target:
|
||||||
|
;; racket -t Makefile.rkt -e "(make)"
|
||||||
|
;;
|
||||||
|
;; Clean and rebuild:
|
||||||
|
;; racket -t Makefile.rkt -e "(make clean all)"
|
||||||
|
;;
|
||||||
|
;; In DrRacket, press Run and then enter (make), (make clean), etc.
|
||||||
|
|
||||||
(define CC 'cc)
|
(define CC 'cc)
|
||||||
(define CFLAGS '(-Wall -O2))
|
(define CFLAGS '(-Wall -O2))
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#lang racket-makefile
|
||||||
|
|
||||||
|
;; Ordinary Racket can generate targets and dependency lists.
|
||||||
|
|
||||||
|
(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))
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#lang info
|
#lang info
|
||||||
|
|
||||||
(define pkg-authors '(hnmdijkema))
|
(define pkg-authors '(hnmdijkema))
|
||||||
(define version "0.1.1")
|
(define version "0.1.2")
|
||||||
(define license 'MIT)
|
(define license 'MIT)
|
||||||
(define collection "racket-makefile")
|
(define collection "racket-makefile")
|
||||||
(define pkg-desc
|
(define pkg-desc
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
deps
|
deps
|
||||||
phony
|
phony
|
||||||
default-target
|
default-target
|
||||||
|
make
|
||||||
run
|
run
|
||||||
rm-f
|
rm-f
|
||||||
rm-rf
|
rm-rf
|
||||||
@@ -20,20 +21,32 @@
|
|||||||
$deps
|
$deps
|
||||||
$<)
|
$<)
|
||||||
|
|
||||||
|
;; For target declarations we want a bound identifier to remain an ordinary
|
||||||
|
;; Racket expression. This makes generated targets such as (target obj ...)
|
||||||
|
;; possible inside a for loop. An unbound identifier is a literal target name.
|
||||||
(define-for-syntax (literal-name-or-expression stx)
|
(define-for-syntax (literal-name-or-expression stx)
|
||||||
(if (and (identifier? stx)
|
(if (and (identifier? stx)
|
||||||
(not (identifier-binding stx)))
|
(not (identifier-binding stx)))
|
||||||
(datum->syntax stx `(quote ,(syntax-e stx)) stx stx)
|
(datum->syntax stx `(quote ,(syntax-e stx)) stx stx)
|
||||||
stx))
|
stx))
|
||||||
|
|
||||||
|
;; For interactive make invocations a bare identifier is always a literal
|
||||||
|
;; target name. Thus (make compile) means the target named "compile" even if
|
||||||
|
;; Racket happens to provide a binding named compile.
|
||||||
|
(define-for-syntax (literal-make-name stx)
|
||||||
|
(if (identifier? stx)
|
||||||
|
(datum->syntax stx `(quote ,(syntax-e stx)) stx stx)
|
||||||
|
stx))
|
||||||
|
|
||||||
(define-syntax (makefile-module-begin stx)
|
(define-syntax (makefile-module-begin stx)
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(_ form ...)
|
[(_ form ...)
|
||||||
#'(racket-module-begin
|
#'(racket-module-begin
|
||||||
(reset-makefile!)
|
(reset-makefile!)
|
||||||
form ...
|
form ...
|
||||||
(module+ main
|
;; Re-export make so that `racket -t Makefile.rkt -e "(make all)"`
|
||||||
(run-selected-target!)))]))
|
;; imports the make form into the command-line evaluation namespace.
|
||||||
|
(provide make quote #%top-interaction #%app #%datum #%top))]))
|
||||||
|
|
||||||
(define-syntax (deps stx)
|
(define-syntax (deps stx)
|
||||||
(raise-syntax-error 'deps "only valid as the dependency clause of target" stx))
|
(raise-syntax-error 'deps "only valid as the dependency clause of target" stx))
|
||||||
@@ -70,6 +83,14 @@
|
|||||||
(with-syntax ([target-name (literal-name-or-expression #'name)])
|
(with-syntax ([target-name (literal-name-or-expression #'name)])
|
||||||
#'(set-default-target! target-name))]))
|
#'(set-default-target! target-name))]))
|
||||||
|
|
||||||
|
(define-syntax (make stx)
|
||||||
|
(syntax-case stx ()
|
||||||
|
[(_ name ...)
|
||||||
|
(with-syntax ([(target-name ...)
|
||||||
|
(map literal-make-name
|
||||||
|
(syntax->list #'(name ...)))])
|
||||||
|
#'(make-targets! target-name ...))]))
|
||||||
|
|
||||||
(define-syntax $target
|
(define-syntax $target
|
||||||
(syntax-id-rules ()
|
(syntax-id-rules ()
|
||||||
[$target
|
[$target
|
||||||
|
|||||||
+9
-8
@@ -6,7 +6,7 @@
|
|||||||
mark-phony!
|
mark-phony!
|
||||||
set-default-target!
|
set-default-target!
|
||||||
reset-makefile!
|
reset-makefile!
|
||||||
run-selected-target!
|
make-targets!
|
||||||
current-target
|
current-target
|
||||||
current-dependencies
|
current-dependencies
|
||||||
current-first-dependency)
|
current-first-dependency)
|
||||||
@@ -128,20 +128,21 @@
|
|||||||
(hash-set! built-results key rebuilt?)
|
(hash-set! built-results key rebuilt?)
|
||||||
rebuilt?]))
|
rebuilt?]))
|
||||||
|
|
||||||
(define (selected-targets)
|
(define (default-targets)
|
||||||
(define args (vector->list (current-command-line-arguments)))
|
|
||||||
(cond
|
(cond
|
||||||
[(pair? args) args]
|
|
||||||
[default-target-name (list default-target-name)]
|
[default-target-name (list default-target-name)]
|
||||||
[(pair? target-order) (list (car target-order))]
|
[(pair? target-order) (list (car target-order))]
|
||||||
[else '()]))
|
[else '()]))
|
||||||
|
|
||||||
(define (run-selected-target!)
|
(define (make-targets! . names)
|
||||||
(define names (selected-targets))
|
(define selected
|
||||||
(when (null? names)
|
(if (null? names)
|
||||||
|
(default-targets)
|
||||||
|
(append-map target-keys names)))
|
||||||
|
(when (null? selected)
|
||||||
(error 'racket-makefile "no target defined"))
|
(error 'racket-makefile "no target defined"))
|
||||||
(define built-results (make-hash))
|
(define built-results (make-hash))
|
||||||
(define visiting (make-hash))
|
(define visiting (make-hash))
|
||||||
(for ([name (in-list names)])
|
(for ([name (in-list selected)])
|
||||||
(build-target! name built-results visiting))
|
(build-target! name built-results visiting))
|
||||||
(void))
|
(void))
|
||||||
|
|||||||
+81
-10
@@ -3,7 +3,7 @@
|
|||||||
@(require (for-label racket/base
|
@(require (for-label racket/base
|
||||||
racket/file
|
racket/file
|
||||||
(only-in racket-makefile
|
(only-in racket-makefile
|
||||||
target deps phony default-target
|
target deps phony default-target make
|
||||||
run rm-f rm-rf cleanup
|
run rm-f rm-rf cleanup
|
||||||
$target $deps $<)))
|
$target $deps $<)))
|
||||||
|
|
||||||
@@ -17,6 +17,9 @@ targets, dependencies, timestamp based rebuilding, phony targets, command
|
|||||||
execution, and a few cleanup helpers. The rest of the language is ordinary
|
execution, and a few cleanup helpers. The rest of the language is ordinary
|
||||||
Racket.
|
Racket.
|
||||||
|
|
||||||
|
A makefile only defines targets. Loading or running the module does not execute
|
||||||
|
any recipe automatically. Builds are started explicitly with @racket[make].
|
||||||
|
|
||||||
@section{Installation}
|
@section{Installation}
|
||||||
|
|
||||||
Install the package from a local checkout with:
|
Install the package from a local checkout with:
|
||||||
@@ -28,7 +31,7 @@ raco pkg install
|
|||||||
For a versioned archive, specify the package name explicitly:
|
For a versioned archive, specify the package name explicitly:
|
||||||
|
|
||||||
@verbatim{
|
@verbatim{
|
||||||
raco pkg install --name racket-makefile racket-makefile-0.1.1.zip
|
raco pkg install --name racket-makefile racket-makefile-0.1.2.zip
|
||||||
}
|
}
|
||||||
|
|
||||||
After installation a makefile can start with:
|
After installation a makefile can start with:
|
||||||
@@ -37,16 +40,74 @@ After installation a makefile can start with:
|
|||||||
#lang racket-makefile
|
#lang racket-makefile
|
||||||
}
|
}
|
||||||
|
|
||||||
Run a makefile with Racket:
|
@section{A first makefile}
|
||||||
|
|
||||||
@verbatim{
|
For example:
|
||||||
racket Makefile.rkt
|
|
||||||
racket Makefile.rkt clean
|
@racketblock[
|
||||||
racket Makefile.rkt clean package
|
(define CC 'cc)
|
||||||
|
(define CFLAGS '(-Wall -O2))
|
||||||
|
|
||||||
|
(default-target all)
|
||||||
|
(phony all clean)
|
||||||
|
|
||||||
|
(target all
|
||||||
|
(deps "hello"))
|
||||||
|
|
||||||
|
(target "hello"
|
||||||
|
(deps "hello.c")
|
||||||
|
(run `(,CC ,@CFLAGS -o $target $<)))
|
||||||
|
|
||||||
|
(target clean
|
||||||
|
(rm-f "hello")
|
||||||
|
(rm-rf "compiled")
|
||||||
|
(cleanup "scrbl" '("**.html" "**.js" "**.css")))
|
||||||
|
]
|
||||||
|
|
||||||
|
Loading the file only registers these targets; it does not build @tt{all} or
|
||||||
|
any other target.
|
||||||
|
|
||||||
|
@section{Executing targets}
|
||||||
|
|
||||||
|
@defform[(make name ...)]{
|
||||||
|
Builds the supplied targets. A bare identifier is always interpreted as a
|
||||||
|
literal target name, so @racket[(make clean)] selects the target named
|
||||||
|
@racket['clean] and does not require quoting.
|
||||||
|
|
||||||
|
With no arguments, @racket[(make)] builds the target selected by
|
||||||
|
@racket[default-target]. If no default target has been specified, the first
|
||||||
|
declared target is used.
|
||||||
|
|
||||||
|
Multiple targets are allowed and are processed in the supplied order, for
|
||||||
|
example @racket[(make clean all)]. Dependencies that are shared by multiple
|
||||||
|
selected targets are built only once during that @racket[make] invocation.
|
||||||
}
|
}
|
||||||
|
|
||||||
With no command-line target, @racket[default-target] is used. If no default is
|
From the command line, load the makefile with @tt{-t} and evaluate a
|
||||||
specified, the first declared target is used.
|
@racket[make] form with @tt{-e}:
|
||||||
|
|
||||||
|
@verbatim{
|
||||||
|
racket -t Makefile.rkt -e "(make)"
|
||||||
|
racket -t Makefile.rkt -e "(make all)"
|
||||||
|
racket -t Makefile.rkt -e "(make clean)"
|
||||||
|
racket -t Makefile.rkt -e "(make clean all)"
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading a makefile without @tt{-e} executes no target:
|
||||||
|
|
||||||
|
@verbatim{
|
||||||
|
racket -t Makefile.rkt
|
||||||
|
}
|
||||||
|
|
||||||
|
In DrRacket, open the makefile and press @bold{Run}. This loads and registers
|
||||||
|
the targets. Then execute targets in the Interactions window:
|
||||||
|
|
||||||
|
@verbatim{
|
||||||
|
> (make)
|
||||||
|
> (make clean)
|
||||||
|
> (make all)
|
||||||
|
> (make clean all)
|
||||||
|
}
|
||||||
|
|
||||||
@section{Targets and dependencies}
|
@section{Targets and dependencies}
|
||||||
|
|
||||||
@@ -77,7 +138,8 @@ when reached as a dependency.
|
|||||||
}
|
}
|
||||||
|
|
||||||
@defform[(default-target name)]{
|
@defform[(default-target name)]{
|
||||||
Selects the target used when no target is supplied on the command line.
|
Selects the target used by @racket[(make)] when no target is supplied. If no
|
||||||
|
default target is specified, the first declared target is used.
|
||||||
}
|
}
|
||||||
|
|
||||||
A non-phony target is rebuilt when its output does not exist or when a
|
A non-phony target is rebuilt when its output does not exist or when a
|
||||||
@@ -183,6 +245,9 @@ example, targets can be generated in a loop:
|
|||||||
(deps objects))
|
(deps objects))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
The expression @racket[objects] evaluates to a list of dependencies. Dependency
|
||||||
|
lists are recursively flattened by @tt{racket-makefile}.
|
||||||
|
|
||||||
@section{Package example}
|
@section{Package example}
|
||||||
|
|
||||||
The optional @hyperlink["https://docs.racket-lang.org/package-zipper/index.html"]{@tt{package-zipper}}
|
The optional @hyperlink["https://docs.racket-lang.org/package-zipper/index.html"]{@tt{package-zipper}}
|
||||||
@@ -201,3 +266,9 @@ package combines naturally with @tt{racket-makefile}:
|
|||||||
(target package
|
(target package
|
||||||
(zip-package))
|
(zip-package))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
The package target can then be executed explicitly, for example:
|
||||||
|
|
||||||
|
@verbatim{
|
||||||
|
racket -t Makefile.rkt -e "(make package)"
|
||||||
|
}
|
||||||
|
|||||||
+3
-3
@@ -32,18 +32,18 @@
|
|||||||
(list (list "result.txt"))
|
(list (list "result.txt"))
|
||||||
void)
|
void)
|
||||||
|
|
||||||
(run-selected-target!)
|
(make-targets!)
|
||||||
(check-equal? build-count 1)
|
(check-equal? build-count 1)
|
||||||
(check-true (file-exists? "result.txt"))
|
(check-true (file-exists? "result.txt"))
|
||||||
|
|
||||||
;; Nothing changed, so the file target remains up to date.
|
;; Nothing changed, so the file target remains up to date.
|
||||||
(run-selected-target!)
|
(make-targets!)
|
||||||
(check-equal? build-count 1)
|
(check-equal? build-count 1)
|
||||||
|
|
||||||
;; Make the input newer than the output and verify that it rebuilds.
|
;; Make the input newer than the output and verify that it rebuilds.
|
||||||
(define result-time (file-or-directory-modify-seconds "result.txt"))
|
(define result-time (file-or-directory-modify-seconds "result.txt"))
|
||||||
(file-or-directory-modify-seconds "input.txt" (+ result-time 2))
|
(file-or-directory-modify-seconds "input.txt" (+ result-time 2))
|
||||||
(run-selected-target!)
|
(make-targets!)
|
||||||
(check-equal? build-count 2)))
|
(check-equal? build-count 2)))
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(delete-directory/files tmp #:must-exist? #f)))
|
(delete-directory/files tmp #:must-exist? #f)))
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#lang racket
|
||||||
|
|
||||||
|
(require rackunit
|
||||||
|
racket/file
|
||||||
|
racket/runtime-path
|
||||||
|
racket/system)
|
||||||
|
|
||||||
|
(define-runtime-path package-root "..")
|
||||||
|
|
||||||
|
(define racket-executable
|
||||||
|
(find-system-path 'exec-file))
|
||||||
|
|
||||||
|
(define tmp (make-temporary-file "racket-makefile-make~a" 'directory))
|
||||||
|
|
||||||
|
(define (run-racket . args)
|
||||||
|
(parameterize ([current-directory tmp])
|
||||||
|
(apply system* racket-executable args)))
|
||||||
|
|
||||||
|
(dynamic-wind
|
||||||
|
void
|
||||||
|
(lambda ()
|
||||||
|
(call-with-output-file (build-path tmp "Makefile.rkt")
|
||||||
|
(lambda (out)
|
||||||
|
(displayln "#lang racket-makefile" out)
|
||||||
|
(displayln "(default-target all)" out)
|
||||||
|
(displayln "(phony all clean 'compile)" out)
|
||||||
|
(displayln "(target all (call-with-output-file \"all.out\" (lambda (o) (display \"all\" o)) #:exists 'replace))" out)
|
||||||
|
(displayln "(target clean (rm-f \"all.out\" \"compile.out\"))" out)
|
||||||
|
;; `compile` is deliberately chosen because Racket already binds that
|
||||||
|
;; identifier. `(make compile)` must still mean the target named compile.
|
||||||
|
(displayln "(target 'compile (call-with-output-file \"compile.out\" (lambda (o) (display \"compile\" o)) #:exists 'replace))" out)))
|
||||||
|
|
||||||
|
;; Loading the makefile alone must not run any target.
|
||||||
|
(check-true (run-racket "-t" "Makefile.rkt"))
|
||||||
|
(check-false (file-exists? (build-path tmp "all.out")))
|
||||||
|
|
||||||
|
;; Explicit make invocation from the command line.
|
||||||
|
(check-true (run-racket "-t" "Makefile.rkt" "-e" "(make all)"))
|
||||||
|
(check-true (file-exists? (build-path tmp "all.out")))
|
||||||
|
|
||||||
|
;; A bare target identifier is literal, even when Racket binds the same name.
|
||||||
|
(check-true (run-racket "-t" "Makefile.rkt" "-e" "(make compile)"))
|
||||||
|
(check-true (file-exists? (build-path tmp "compile.out")))
|
||||||
|
|
||||||
|
;; Multiple targets are executed in the requested order.
|
||||||
|
(check-true (run-racket "-t" "Makefile.rkt" "-e" "(make clean all)"))
|
||||||
|
(check-true (file-exists? (build-path tmp "all.out")))
|
||||||
|
(check-false (file-exists? (build-path tmp "compile.out")))
|
||||||
|
|
||||||
|
;; (make) uses the configured default target.
|
||||||
|
(delete-file (build-path tmp "all.out"))
|
||||||
|
(check-true (run-racket "-t" "Makefile.rkt" "-e" "(make)"))
|
||||||
|
(check-true (file-exists? (build-path tmp "all.out"))))
|
||||||
|
(lambda ()
|
||||||
|
(delete-directory/files tmp #:must-exist? #f)))
|
||||||
Reference in New Issue
Block a user