juxt/mach

Ideas to consider: Mk

ohpauleez opened this issue · 2 comments

Plan 9's Mk has a lot going for it and you might find a lot inspiration from studying the design decisions.

Consider looking at this recent port and the original overview doc

Paul - thanks for the tip, I've spent some time investigating Mk - I know about Plan 9 of course but didn't know about Mk. Really learned a lot reading about it.

Recipes are delimited by any indentation, not tab characters in particular.

As a Lisp guy, I'm not a fan of indentation, commas, semi-colons and other syntactic devices for grouping, hence I've gone with a Lisp style for Mach. As always with these things, the point isn't to encourage widespread adoption but more to create a tool with a syntax that fit well with Clojure and ClojureScript.

Phony targets are handled separately from file targets. Your mkfile won't be broken by having a file named 'clean'.

Totally agree - I've separated the concept of a target from the idea of a target file or files. That seems like a good simplification.

Attributes instead of weird special targets like .SECONDARY:.

Attributes look interesting - definitely worth considering.

Special variables like $target, $prereq, and $stem in place of make's pointlessly cryptic $@, $^, and $*.

See the last point below.

In addition to suffix rules (e.g. %.o: %.c), mk has more powerful regular expression rules.

In Mach, every rule is a ClojureScript expression. Those could get unwieldy eventually but I'm holding off sprinkling any syntactic sugar for now, it might be premature at this stage. Targets and dependencies can be computed (or at least that's the idea).

Sane handling of rules with multiple targets.

I've separated rules and targets with Mach, so there can be a one-to-many correspondence.

An optional attribute to delete targets when a recipe fails, so you aren't left with corrupt output.

That's a good idea.

Plan 9 mkfiles can not only include other mkfiles, but pipe in the output of recipes. Your mkfile can configure itself by doing something like <|sh config.sh.

Lisp can do it (with eval).

A generalized mechanism to determine if a target is out of date, for when timestamps won't cut it.

That's the idea of the novelty expression.

Variables are expanded in recipes only if they are defined. That way you usually don't have to escape $.

That's currently the behaviour in Mach, but the scoping is primitive and currently based on a simple clojure.walk postwalk, replacing symbols with those in scope - that would play havoc with complex recipes so I'll replace this with something less brutal.

All sounds lovely to me! Thanks for taking the time.