A shell script version of djb's redo build system
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 to0
$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
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.
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
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>
.
If you ever run into issues and just want to rebuild the entire system, remove
the .redo
directory and run redo
again.
Try out the example code, redo example
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
As with djb's description, this script is released as Public Domain.
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.