Files
racket-makefile/main.rkt
T
2026-08-08 14:32:18 +02:00

90 lines
2.6 KiB
Racket

#lang racket/base
(require (except-in racket #%module-begin)
(only-in racket/base [#%module-begin racket-module-begin])
(for-syntax racket/base)
"private/commands.rkt"
"private/engine.rkt")
(provide (all-from-out racket)
(rename-out [makefile-module-begin #%module-begin])
target
deps
phony
default-target
run
rm-f
rm-rf
cleanup
$target
$deps
$<)
(define-for-syntax (literal-name-or-expression stx)
(if (and (identifier? stx)
(not (identifier-binding stx)))
(datum->syntax stx `(quote ,(syntax-e stx)) stx stx)
stx))
(define-syntax (makefile-module-begin stx)
(syntax-case stx ()
[(_ form ...)
#'(racket-module-begin
(reset-makefile!)
form ...
(module+ main
(run-selected-target!)))]))
(define-syntax (deps stx)
(raise-syntax-error 'deps "only valid as the dependency clause of target" stx))
(define-syntax (target stx)
(syntax-case stx (deps)
[(_ name (deps dependency ...) body ...)
(with-syntax ([target-name (literal-name-or-expression #'name)]
[(target-dependency ...)
(map literal-name-or-expression
(syntax->list #'(dependency ...)))])
#'(register-target!
target-name
(list target-dependency ...)
(lambda () body ... (void))))]
[(_ name body ...)
(with-syntax ([target-name (literal-name-or-expression #'name)])
#'(register-target!
target-name
'()
(lambda () body ... (void))))]))
(define-syntax (phony stx)
(syntax-case stx ()
[(_ name ...)
(with-syntax ([(target-name ...)
(map literal-name-or-expression
(syntax->list #'(name ...)))])
#'(mark-phony! target-name ...))]))
(define-syntax (default-target stx)
(syntax-case stx ()
[(_ name)
(with-syntax ([target-name (literal-name-or-expression #'name)])
#'(set-default-target! target-name))]))
(define-syntax $target
(syntax-id-rules ()
[$target
(or (current-target)
(error '$target "$target is only available while a target recipe is running"))]))
(define-syntax $deps
(syntax-id-rules ()
[$deps
(or (current-dependencies)
(error '$deps "$deps is only available while a target recipe is running"))]))
(define-syntax $<
(syntax-id-rules ()
[$<
(or (current-first-dependency)
(error '$< "$< is only available while a target recipe with dependencies is running"))]))