LinuxCommandLibrary

mk

Create makefile(s) for various programming languages

TLDR

Call the first target specified in the Mkfile (usually named "all")

$ mk
copy

Call a specific target
$ mk [target]
copy

Call a specific target, executing 4 jobs at a time in parallel
$ NPROC=4 mk [target]
copy

Force mking of a target, even if source files are unchanged
$ mk -w[target] [target]
copy

Assume all targets to be out of date. Thus, update target and all of its dependencies
$ mk -a [target]
copy

Keep going as far as possible on error
$ mk -k
copy

SYNOPSIS

mk [ -ackndprst ] [ -f file ] [ target ... ]

PARAMETERS

-a
    Build all targets explicitly listed in the mkfile, even if they appear to be up-to-date.

-c
    Clean targets by removing files generated by the build process, typically defined in an "install" or "clean" rule.

-d
    Enable debug mode, printing detailed information about rule evaluation, dependency resolution, and command execution.

-f file
    Specify an alternate mkfile to use instead of the default "mkfile" or "Mkfile".

-k
    Keep going; continue building other targets even if errors occur during the compilation of some targets.

-n
    No-execute; perform a dry run, printing the commands that would be executed without actually running them.

-p
    Print the parsed rules and dependencies as mk understands them, useful for debugging mkfiles.

-r
    Remove dependencies; delete the dependency files generated by mk (often hidden files used for quick rebuilding).

-s
    Silent mode; suppress the printing of commands as they are executed. Only output from the commands themselves will be shown.

-t
    Touch; update the modification time of target files without executing their recipes. Useful for marking targets as up-to-date.

DESCRIPTION

The mk command is a sophisticated build tool originating from the Plan 9 from Bell Labs operating system. While not a standard utility bundled with most mainstream Linux distributions, it is widely available through the Plan 9 from User Space (plan9port) project, allowing it to run seamlessly on Linux. mk serves a similar purpose to the traditional Unix make utility: to automate the compilation and linking of software projects and manage arbitrary dependencies. However, mk is designed with a focus on simplicity, readability, and inherent concurrency. It resolves dependencies and executes commands in parallel by default, making efficient use of multi-core processors. Its rule syntax is often considered more straightforward than make's, using semicolons to separate dependencies from recipes and lacking complex directives, thus leading to more concise and maintainable build scripts.

CAVEATS

The mk command is not a standard, pre-installed utility on most Linux distributions. Its primary origin is the Plan 9 operating system. To use mk on Linux, you typically need to install the plan9port package or compile it from source. Consequently, its presence cannot be assumed on every Linux system. Its rule syntax and feature set differ significantly from the ubiquitous GNU make, meaning mkfiles are generally incompatible with make and vice-versa. Users accustomed to make's extensive features, such as pattern rules or sophisticated variable expansion, may find mk more restrictive but often clearer in its design.

MKFILES AND BASIC RULES

An mk build script, known as an mkfile (typically named "mkfile" or "Mkfile"), defines the relationships between files and the commands needed to build them. A basic rule in an mkfile consists of a target, its dependencies, and a recipe (the commands to execute), all separated by a semicolon. For example:
prog: main.o sub.o
${LD} -o $@ main.o sub.o

main.o: main.c
${CC} -c -o $@ $

Here, `prog` depends on `main.o` and `sub.o`. The recipe for `prog` is executed if `prog` is older than its dependencies. The variables `$` (target name), `$<` (first dependency), and `$*` (all dependencies) are commonly used within recipes. mk automatically handles parallel execution of independent rules.

HISTORY

The mk utility was developed at Bell Labs as part of the Plan 9 operating system project, which began in the late 1980s as a successor to Unix. Designed by Stuart Feldman, who also created the original Unix make, mk represents a re-thinking of build system design. It aimed to simplify the complexity often associated with make and to provide inherent support for parallel execution without requiring explicit job control. Its development reflects Plan 9's overall philosophy of simplicity, clarity, and distributed computing. While Plan 9 never achieved mainstream adoption like Unix, mk remains a respected and influential build tool, particularly within the Plan 9 community and those appreciating its elegant design, accessible through ports to other operating systems like Linux.

SEE ALSO

make(1), ninja(1)

Copied to clipboard