a simple and unix-idiomatic build automator

34136cf @noreturn -> never

30 days ago

b931c30 os::BUFSIZ -> os::BUFSZ; *void -> *opaque

a month ago


A simple and unix-idiomatic build automator.

a set of nesting-dolls. each is a hare.


haredo is a build automator - an alternative to e.g. make(1) and redo(1).

Problems with make:

  • Hard to learn its strange syntax
  • Source code is complex (~40,000 lines)
  • Makefiles are frequently very bulky
  • Builds that crash or are killed halfway through can produce invalid state

Problems with redo:

  • Hard to learn because the commands obscure their function
  • Source code is a little complex (~4,000 lines)
  • Uses an external database to store dependency relations

haredo solves all of these problems:

  • Script syntax is plain shell script
  • Only one command with few extraneous rules
  • Source code is extremely simple (~400 lines)
  • .do files are short and modular like in redo
  • Builds its dependency tree on the fly, uses no database
  • Doesn't break the build state when interrupted

haredo additionally uses the properties of unix-like operating systems extremely idiomatically:

  • processes and child processes build targets and their dependencies respectively
  • environment variables are used to communicate with child builds
  • exit status codes are used to communicate with the parent build
  • parent directories in the file tree are used as defaults when finding .do files
  • the "last-modified" timestamp on files is used to detect changes.
  • shell arguments provide contextual information to .do files
  • temporary files and atomic filesystem operations prevent broken builds
  • uses a unix pipe as a simple jobs queue


The process for haredo boils down to this:

for each target argument:
	find and run its .do script
	if a .do script cannot be found, give a warning
return true if any of the arguments are newer than their parent, else false.

.do files are written in plain shell script, and will be run using sh -e to exit on error. The typical structure of a .do script is as follows:

# assemble the dependencies
deps="dep1 dep2"

# run the build on dependencies, and check if they are newer
if haredo $deps
	# build the target

The above script will only build the target if the result of running haredo on its dependencies gives a truthy result -- which only happens when one of them is newer.


haredo [-options] targets... [++ sources...]

Detailed usage information can be found in the man page.


Requires scdoc(1) to build the man page, and a Hare install to build the executable.

git clone https://git.sr.ht/~autumnull/haredo
cd haredo
./bootstrap.sh install
haredo test
# haredo uninstall


Please send patches and bug reports to ~autumnull/haredo-devel@lists.sr.ht.

General discussion of haredo happens on ~autumnull/haredo@lists.sr.ht.