# racket-makefile `racket-makefile` provides make-style dependency builds as ordinary Racket functionality. `racket-makefile` is a Racket library and has no dependency on Rash. Rash integration is provided separately by the `rash-makefile` package. ## Functional makefiles ```racket #lang racket (require racket-makefile) (makefile wiki (default-target all) (phony all clean status) (target status (displayln "status")) (target clean (rm-rf "compiled")) (target all (deps status) (displayln "all"))) ``` A `makefile` form defines real target procedures. The example above defines, among others: ```racket makefile-target-wiki-status makefile-target-wiki-clean makefile-target-wiki-all ``` They are ordinary procedures: ```racket (procedure? makefile-target-wiki-status) (makefile-target-wiki-status) ``` `make` is also an ordinary procedure. Target names are explicit Racket values: ```racket (make) (make 'status) (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. ## Makefile prefixes Every makefile has a prefix: ```racket (makefile wiki (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: ```racket (current-makefile-prefix) ;; 'audio (make 'status) ;; invokes makefile-target-audio-status through the make engine ``` `current-makefile-prefix` is a parameter, so another registered makefile can be selected explicitly: ```racket (current-makefile-prefix 'wiki) (make 'status) ``` Re-evaluating a makefile with the same prefix replaces the registrations for that 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`: ```racket (makefile example (target "program" (deps "program.c") (run '(cc -o program program.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) ...) ``` The automatic recipe values remain available inside target procedures: ```racket $target $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. ## Refreshing A `makefile` form remembers the source module in which it occurs. `refresh-makefile` reloads that source without restarting the Racket process: ```racket (refresh-makefile) (make 'all) ``` In DrRacket, pressing **Run** is normally the simpler way to reevaluate a Rash or Racket makefile. ## Helpers The functional helpers provided by `racket-makefile` are `run`, `raco`, `rm-f`, `rm-rf`, `cleanup`, `list-dir/files`, `list-files`, and `list-dirs`. `raco` locates the executable belonging to the active Racket installation before falling back to `PATH`. `racket-makefile` also continues to re-export the package APIs it uses for build scripts, including `git-cli`, `package-zipper`, `net/sendurl`, and `racket/string`.