-
Notifications
You must be signed in to change notification settings - Fork 130
/
redo.1
245 lines (244 loc) · 8.62 KB
/
redo.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
.TH REDO 1 2011-12-31 "Redo 0.10" "User Commands"
.ad l
.nh
.SH NAME
redo - rebuild target files when source files have changed
.SH SYNOPSIS
redo [options...] [targets...]
.SH DESCRIPTION
redo is a simple yet powerful tool for rebuilding target
files, and any of their dependencies, based on a set of
rules. The rules are encoded in simple \fBsh\fR(1) scripts
called '.do scripts.'
.PP
redo supports GNU \fBmake\fR(1)-style parallel builds using the
\fB-j\fR option; in fact, redo's parallel jobserver is compatible
with GNU Make, so redo and make can share build tokens with
each other. redo can call a sub-make (eg. to build a
subproject that uses Makefiles) or vice versa (eg. if a
make-based project needs to build a redo-based subproject).
.PP
Unlike make, redo does not have any special syntax of its
own; each \fItarget\fR is built by running a .do file, which is
simply a shell script that redo executes for you with a
particular environment and command-line arguments.
.PP
If no \fItargets\fR are specified, redo pretends you specified
exactly one target named \fBall\fR.
.PP
Note that redo \fIalways\fR rebuilds the given targets
(although it may skip rebuilding the targets' dependencies
if they are up to date). If you only want to rebuild
targets that are not up to date, use \fBredo-ifchange\fR(1)
instead.
.PP
A .do script can call redo recursively to build its
dependencies.
.SH OPTIONS
-j, --jobs=\fImaxjobs\fR
: execute at most \fImaxjobs\fR .do scripts in parallel. The
default value is 1.
.PP
-d, --debug
: print dependency checks as they happen. You can use
this to figure out why a particular target is/isn't being
rebuilt when your .do script calls it using
\fBredo-ifchange\fR.
.PP
-v, --verbose
: pass the -v option to /bin/sh when executing scripts.
This normally causes the shell to echo the .do script lines
to stderr as it reads them. Most shells will print the
exact source line (eg. \fBecho $3\fR) and not the
substituted value of variables (eg. \fBecho
mytarget.redo.tmp\fR).
.PP
-x, --xtrace
: pass the -x option to /bin/sh when executing scripts.
This normally causes the shell to echo exactly which
commands are being executed. Most shells will print
the substituted variables (eg. \fBecho
mytarget.redo.tmp\fR) and not the original source line
(eg. \fBecho $3\fR).
.PP
-k, --keep-going
: keep building as many targets as possible even if some
of them return an error. If one target fails, any
target that depends on it also cannot be built, of course.
.PP
--shuffle
: randomize the order in which requested targets are
built. Normally, if you run \fBredo a b c\fR, the targets
will be built exactly in that order: first \fBa\fR, then
\fBb\fR, then \fBc\fR. But if you use \fB-j\fR, they might end up
being built in parallel, so it isn't safe to rely on
this precise ordering. Using \fB--shuffle\fR, redo will
build its targets in random order even without \fB-j\fR,
which makes it easier to find accidental dependency
problems of this sort. NOTE: if you really just want
to guarantee that \fBa\fR is built, then \fBb\fR, then \fBc\fR, you
can just run three \fBredo\fR commands consecutively.
Because your .do script is just a script, it will not
be accidentally parallelized.
.PP
--debug-locks
: print messages about acquiring, releasing, and waiting
on locks. Because redo can be highly parallelized,
one instance may end up waiting for a target to be
built by some other instance before it can continue.
If you suspect this is causing troubles, use this
option to see which instance is waiting and when.
.PP
--debug-pids
: add the process id of the particular redo instance to each
output message. This makes it easier to figure out
which sub-instance of redo is doing what.
.PP
--old-args
: old versions of redo provided different definitions of
the $1 and $2 parameters to .do scripts. The new
version is compatible with djb's original
specification. This option goes back to the old
definitions so you can use .do scripts you haven't yet
converted to the new style.
.SH DISCUSSION
The core of redo is extremely simple. When you type \fBredo
targetname\fR, then it will search for a matching .do file
based on a simple algorithm. For example, given a target
named \fBmytarget.a.b.c.d\fR, redo will look for a .do file in
the following order:
.IP " \[bu] " 3
mytarget.a.b.c.d.do
.IP " \[bu] " 3
default.a.b.c.d.do
.IP " \[bu] " 3
default.b.c.d.do
.IP " \[bu] " 3
default.c.d.do
.IP " \[bu] " 3
default.d.do
.IP " \[bu] " 3
default.do
.PP
In all cases, the .do file must be in the same directory as
the target file, or in one of the target's parent
directories. For example, if given a target named
\fB../a/b/xtarget.y\fR, redo will look for a .do file in the
following order:
.IP " \[bu] " 3
$PWD/../a/b/xtarget.y
.IP " \[bu] " 3
$PWD/../a/b/default.y.do
.IP " \[bu] " 3
$PWD/../a/b/default.do
.IP " \[bu] " 3
$PWD/../a/default.y.do
.IP " \[bu] " 3
$PWD/../a/default.do
.IP " \[bu] " 3
$PWD/../default.y.do
.IP " \[bu] " 3
$PWD/../default.do
.PP
The first matching .do file is executed as a \fB/bin/sh\fR
script. The .do script is always executed with the current
working directory set to the directory containing the .do
file. Because of that rule, the
following two commands always have exactly identical
behaviour:
.RS +4n
.nf
.PP
redo path/to/target
cd path/to && redo target
.fi
.RE
.PP
(Note: in \fBmake\fR(1), these commands have confusingly
different semantics. The first command would look for a
target named \fBpath/to/target\fR in \fB./Makefile\fR, while the
second command would look for a target named \fBtarget\fR in
\fB./path/to/Makefile\fR. The two Makefiles might give
completely different results, and it's likely that the
first command would have incomplete dependency information.
redo does not have this problem.)
.PP
The three arguments passed to the .do script are:
.IP " \[bu] " 3
$1: the target name (eg. mytarget.a.b)
.IP " \[bu] " 3
$2: the basename of the target, minus its extension (eg. mytarget)
.IP " \[bu] " 3
$3: a temporary filename that the .do script should write
its output to.
.PP
Instead of using $3, the .do script may also write the
produced data to stdout.
.PP
If the .do file is in the same directory as the target, $1
is guaranteed to be a simple filename (with no path
component). If the .do file is in a parent directory of
the target, $1 and $3 will be relative paths (ie. will
contain slashes).
.PP
redo is designed to update its targets atomically, and only
if the do script succeeds (ie. returns a zero exit code).
Thus, you should never write directly to the target file,
only to $3 or stdout.
.PP
Normally, a .do script will call other .do scripts
recursively, by running either \fBredo\fR (which will always
build the sub-target) or \fBredo-ifchange\fR (which only
rebuilds the sub-target if its dependencies have changed).
.PP
Running \fBredo-ifchange\fR is also the way your .do script
declares dependencies on other targets; any target that is
\fBredo-ifchange\fRd during your .do script's execution is both
executed (if needed) and added as a dependency.
.PP
You may have heard that 'recursive make is considered
harmful' (http://miller.emu.id.au/pmiller/books/rmch/).
Unlike \fBmake\fR(1), redo does correct locking, state
management, and global dependency checking, so none of the
arguments in that essay apply to redo. In fact, recursive
redo is really the only kind of redo.
.SH "RELATED COMMANDS"
When writing a .do script, it will probably need to run
one or more of the following commands:
.PP
\fBredo\fR
: to build a sub-target unconditionally.
.PP
\fBredo-ifchange\fR
: to build a sub-target only if the sub-target's
dependencies have changed.
.PP
\fBredo-ifcreate\fR
: to tell redo that the current target must be rebuilt if
a particular file gets created.
.PP
\fBredo-always\fR
: to tell redo that the current target must always be
rebuilt, even if someone calls it using \fBredo-ifchange\fR.
(This might happen if the current target has
dependencies other than the contents of files.)
.PP
\fBredo-stamp\fR
: to tell redo that even though the current target has
been rebuilt, it may not actually be any different from
the previous version, so targets that depend on it
might not need to be rebuilt. Often used in
conjunction with \fBredo-always\fR to reduce the impact of
always rebuilding a target.
.SH CREDITS
The original concept for \fBredo\fR was created by D. J.
Bernstein and documented on his web site
(http://cr.yp.to/redo.html). This independent implementation
was created by Avery Pennarun and you can find its source
code at http://github.com/apenwarr/redo.
.SH "SEE ALSO"
\fBsh\fR(1), \fBmake\fR(1),
\fBredo-ifchange\fR(1), \fBredo-ifcreate\fR(1), \fBredo-always\fR(1),
\fBredo-stamp\fR(1)
.SH AUTHOR
Avery Pennarun \\<apenwarr@gmail.com>