/redo

A shell script version of djb's redo build system

Primary LanguageShell

redo

A shell script version of djb's redo build system

Usage

redo is rather simple to use. Just write a shell script and everything written to stdout is sent to the target.

# hello.txt.do
echo "Hello World"

Executing redo hello.txt looks for the script hello.txt.do. If it has never been run, has been modified or the output doesn't exist, the script will run and hello.txt will be created.

$ echo "echo \"Hello World\"" > hello.txt.do
$ redo hello.txt
redo hello.txt
$ cat hello.txt
Hello World

If your script requires a output file rather than stdout the following variables can be used:

  • $1 - Not used, set to 0
  • $2 - Target name (hello.txt for hello.txt.do)
  • $3 - Temporary file that will be moved to Target once completed

Rather than requiring every target to have its own do script, you can can create a generic script based on the file extension.

# default.txt.do
pandoc -t plain $2.markdown

If no do file exists with the specif name, the generic default name will be tested.

$ echo "This is **bold**" > test.markdown
$ redo test.txt
redo test.txt
$ cat test.txt
This is BOLD

Dependencies

Adding build dependencies requires a single line redo-ifchange <list of deps>.

# quux.do
DEPS="foo.o bar.o"
redo-ifchange $DEPS
gcc -o $3 $DEPS

If you attempt to redo quux the system will check for changes in foo.o and bar.o. If these files are targets and generated by redo, then their dependencies will be checked. redo will traverse the dependency tree and only rebuild what is required.

Dependencies are rebuilt based on file changes, using hashes, rather than timestamps.

Required Creates

If you need a file to not exist prior to building, use the redo-ifcreate <list of deps> command. If any file in the list exists when rebuilding the current target, the build will fail. If it doesn't exist it will be built using a direct or generic do script. If that doesn't work, and error is thrown.

# common.h.do
redo-ifcreate version.txt
echo "#define VERSION $(cat version.txt)"

If redo common.h is run and version.txt exits then it will fail. Otherwise you should see:

$ redo common.h
redo version.txt
redoo common.h

Return Codes

If a line in a do script does not return 0, its return code is passed up to the initial execution of redo <list of targets>.

Troubleshooting

If you ever run into issues and just want to rebuild the entire system, remove the .redo directory and run redo again.

Example

Try out the example code, redo example

Installation

Easiest way is to just modify install.do and run it with sh

$ /bin/sh ./install.do
Password:
$ ls /usr/local/bin/redo*
/usr/local/bin/redo  /usr/local/bin/redo-ifchange  /usr/local/bin/redo-ifcreate

License

As with djb's description, this script is released as Public Domain.

More Info

For more information about redo see djb's site.

A youtube video by jekor goes through creating a version of redo written in Haskell.

This thesis paper by A. Grosskurth goes through many build systems and then details redo.