Giter VIP home page Giter VIP logo

mk's Introduction

Logo

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.

Installation

  1. Install Go.
  2. Run go get github.com/dcjones/mk
  3. Make sure $GOPATH/bin is in your PATH.

Why Plan 9 mk is better than make

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:

  1. Recipes are delimited by any indentation, not tab characters in particular.
  2. Phony targets are handled separately from file targets. Your mkfile won't be broken by having a file named 'clean'.
  3. Attributes instead of weird special targets like .SECONDARY:.
  4. Special variables like $target, $prereq, and $stem in place of make's pointlessly cryptic $@, $^, and $*.
  5. In addition to suffix rules (e.g. %.o: %.c), mk has more powerful regular expression rules.
  6. Sane handling of rules with multiple targets.
  7. An optional attribute to delete targets when a recipe fails, so you aren't left with corrupt output.
  8. 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.
  9. A generalized mechanism to determine if a target is out of date, for when timestamps won't cut it.
  10. Variables are expanded in recipes only if they are defined. They way you usually don't have to escape $.

And much more! Read Maintaining Files on Plan 9 with Mk for good overview.

Improvements over Plan 9 mk

This mk stays mostly faithful to Plan 9, but makes a few (in my opinion) improvements.

  1. A clean, modern implementation in Go, that doesn't depend on the whole Plan 9 stack.
  2. Parallel by default. Modern computers can build more than one C file at a time. Cases that should not be run in parallel are the exception. Use -p=1 if this is the case.
  3. Use Go regular expressions, which are perl-like. The original mk used plan9 regex, which few people know or care to learn.
  4. Regex matches are substituted into rule prerequisites with $stem1, $stem2, etc, rather than \1, \2, etc.
  5. Allow blank lines in recipes. A recipe is any indented block of text, and continues until a non-indented character or the end of the file. (Similar to blocks in Python.)
  6. Add an 'S' attribute to execute recipes with programs other than sh. This way, you don't have to separate your six line python script into its own file. Just stick it directly in the mkfile.
  7. Pretty colors.

Usage

mk [options] [target] ...

Options

  • -f filename Use the given file as the mkfile.
  • -n Dry run, print commands without actually executing.
  • -r Force building of the immediate targets.
  • -a Force building the targets and of all their dependencies.
  • -p Maximum number of jobs to execute in parallel (default: 8)
  • -i Show rules that will execute and prompt before executing.

Non-shell recipes

Non-shell recipes are a major addition over Plan 9 mk. They can be used with the S[command] attribute, where command is 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")))))

Current State

Functional, but with some bugs and some unimplemented minor features. Give it a try and see what you think!

mk's People

Contributors

dcjones avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

mk's Issues

<| tokenization doesn't support binary commands

Perhaps a non-bug but P9P mk can do this:

<|cmd

where cmd is a binary.

mk can't because the sh in

[output, success := subprocess("sh", args, "", true)](https://github.com/dcjones/mk/blob/73d1b31466c16d0a13a220e5fad7cd8ef6d984d1/parse.go#L121)

should be cmd.

Convert <|cmd to <|-c cmd to work around this.

Doesn't know how to mk files with recipes

Hey @dcjones ,

Very cool program here!

Tried running a working plan9 mk file through your version of mk, but came across some trouble. Here is the plan9 mk file:

ALL=`{ls *.md | sort | sed s/.md$/.pdf/g}

all:V: thesis.pdf

thesis.pdf: $ALL
    pdfjoin $ALL  --outfile thesis.pdf
    page thesis.pdf

%.pdf: %.md
    pandoc -S --normalize --toc $stem.md -o $stem.pdf

view:V: thesis.pdf
    page thesis.pdf

I found that I needed to change the shell escape from `{} to``, but then I receive the following error:

don't know how to make 00titlePage.pdf
01abstract.pdf
02intro.pdf
03methods.pdf
04results.pdf
05discussion.pdf
 in /home/rje/my_docs/publications/dissertation

It also doesn't like a missing empty line for EOF, whereas plan9 mk doesn't care. Do you have a short-and-dirty table of subtle syntax changes? Or, is this a valid bug?

Thanks,
rob

call isatty on stdout before colouring output

Sometimes it might be useful to get output from the build command. Colour makes it difficult to parse. Most well-behaved tools (like grep on certain systems) will only colour by default if the output stream is a terminal (see isatty(3) on your favourite Unix).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.