#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)))