make remade
Mk is a reboot of the Plan 9 mk command, which itself is a successor to make. This tool is for anyone who loves make, but hates all its stupid bullshit.
go get github.com/dcjones/mk
$GOPATH/binis in your
PATH.
Way back in the 90s, some smart guys at Bell Labs got together and decided to write new operating system to replace Unix. The idea was to keep everything that was great about Unix, but totally disregard backwards compatibility in a quest for something better. The operating system they designed, Plan 9, had a lot of terrific ideas, and though some were cherry picked, the OS as a whole never really caught on.
Among the gems in Plan 9 was a rewrite of the venerable Unix make command, in the form of mk. Simply put, mk is make, but with a large collection of relatively minor improvements, adding up to something more consistent, elegant, and powerful. To name a few specifics:
.SECONDARY:.
$target,
$prereq, and
$stemin place of make's pointlessly cryptic
[email protected],
$^, and
$*.
%.o: %.c), mk has more powerful regular expression rules.
.
$.
And much more! Read Maintaining Files on Plan 9 with Mk for good overview.
This mk stays mostly faithful to Plan 9, but makes a few (in my opinion) improvements.
-p=1if this is the case.
$stem1,
$stem2, etc, rather than
\1,
\2, etc.
mk [options] [target] ...
-f filenameUse the given file as the mkfile.
-nDry run, print commands without actually executing.
-rForce building of the immediate targets.
-aForce building the targets and of all their dependencies.
-pMaximum number of jobs to execute in parallel (default: 8)
-iShow rules that will execute and prompt before executing.
Non-shell recipes are a major addition over Plan 9 mk. They can be used with the
S[command]attribute, where
commandis an arbitrary command that the recipe will be piped into. For example, here's a recipe to add the read numbers from a file and write their mean to another file. Unlike a typical recipe, it's written in Julia.
mean.txt:Sjulia: input.txt println(open("$target", "w"), mean(map(parseint, eachline(open("$prereq")))))
Functional, but with some bugs and some unimplemented minor features. Give it a try and see what you think!