Change definitions of $1,$2,$3 to match djb's redo.

If you use "redo --old-args", it will switch back to the old
(apenwarr-style) arguments for now, to give you time to update your .do
scripts.  This option will go away eventually.

Note: minimal/do doesn't understand the --old-args option.  If you're using
minimal/do in your project, keep using the old one until you update your use
of $1/$2, and then update to the new one.

apenwarr-style default.o.do:
   $1      foo
   $2      .o
   $3      whatever.tmp

djb-style default.o.do:
   $1      foo.o
   $2      foo
   $3      whatever.tmp

apenwarr-style foo.o.do:
   $1      foo.o
   $2      ""
   $3      whatever.tmp

djb-style foo.o.do:
   $1      foo.o
   $2      foo.o  (I think?)
   $3      whatever.tmp
This commit is contained in:
Avery Pennarun 2011-12-31 02:45:38 -05:00
commit 21f88094d5
27 changed files with 84 additions and 68 deletions

View file

@ -1,2 +1,2 @@
redo-ifchange md-to-man $1.md.tmp redo-ifchange md-to-man $2.md.tmp
. ./md-to-man $1 $2 $3 . ./md-to-man $1 $2 $3

View file

@ -1,3 +1,3 @@
redo-ifchange ../version/vars $1.md redo-ifchange ../version/vars $2.md
. ../version/vars . ../version/vars
sed -e "s/%VERSION%/$TAG/" -e "s/%DATE%/$DATE/" $1.md sed -e "s/%VERSION%/$TAG/" -e "s/%DATE%/$DATE/" $2.md

View file

@ -1,8 +1,8 @@
redo-ifchange md2man.py redo-ifchange md2man.py
if ./md2man.py </dev/null >/dev/null; then if ./md2man.py </dev/null >/dev/null; then
echo './md2man.py $1.md.tmp' echo './md2man.py $2.md.tmp'
else else
echo "Warning: md2man.py missing modules; can't generate manpages." >&2 echo "Warning: md2man.py missing modules; can't generate manpages." >&2
echo "Warning: try this: sudo easy_install markdown BeautifulSoup" >&2 echo "Warning: try this: sudo easy_install markdown BeautifulSoup" >&2
echo 'echo Skipping: $1.1 >&2' echo 'echo Skipping: $2.1 >&2'
fi fi

View file

@ -48,10 +48,10 @@ of .h files it depends on. You can pass this information
along to redo-ifchange, so if any of those headers are along to redo-ifchange, so if any of those headers are
changed or deleted, your .c file will be rebuilt: changed or deleted, your .c file will be rebuilt:
redo-ifchange $1.c redo-ifchange $2.c
gcc -o $3 -c $1.c \ gcc -o $3 -c $2.c \
-MMD -MF $1.deps -MMD -MF $2.deps
read DEPS <$1.deps read DEPS <$2.deps
redo-ifchange ${DEPS#*:} redo-ifchange ${DEPS#*:}
This is much less confusing than the equivalent This is much less confusing than the equivalent

View file

@ -104,6 +104,14 @@ dependencies.
output message. This makes it easier to figure out output message. This makes it easier to figure out
which sub-instance of redo is doing what. which sub-instance of redo is doing what.
--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.
# DISCUSSION # DISCUSSION
@ -156,8 +164,8 @@ redo does not have this problem.)
The three arguments passed to the .do script are: The three arguments passed to the .do script are:
- $1: the basename of the target (eg. mytarget.a.b) - $1: the target name (eg. mytarget.a.b)
- $2: the extension of the target, if any (eg. .c.d) - $2: the basename of the target, minus its extension (eg. mytarget)
- $3: a temporary filename that the .do script should write - $3: a temporary filename that the .do script should write
its output to. its output to.
@ -165,7 +173,7 @@ Instead of using $3, the .do script may also write the
produced data to stdout. produced data to stdout.
If the .do file is in the same directory as the target, $1 If the .do file is in the same directory as the target, $1
and $3 are guaranteed to be simple filenames (with no path is guaranteed to be a simple filename (with no path
component). If the .do file is in a parent directory of component). If the .do file is in a parent directory of
the target, $1 and $3 will be relative paths (ie. will the target, $1 and $3 will be relative paths (ie. will
contain slashes). contain slashes).

View file

@ -77,9 +77,9 @@ The easiest way to show it is with an example.
Create a file called default.o.do: Create a file called default.o.do:
redo-ifchange $1.c redo-ifchange $2.c
gcc -MD -MF $1.d -c -o $3 $1.c gcc -MD -MF $2.d -c -o $3 $2.c
read DEPS <$1.d read DEPS <$2.d
redo-ifchange ${DEPS#*:} redo-ifchange ${DEPS#*:}
Create a file called myprog.do: Create a file called myprog.do:
@ -293,34 +293,30 @@ To activate it, you can add a line like this to your .bashrc:
# What are the three parameters ($1, $2, $3) to a .do file? # What are the three parameters ($1, $2, $3) to a .do file?
FIXME: NOTE: These definitions have changed since the earliest
These definitions might change. It turns out that (pre-0.10) versions of redo. The new definitions match
djb's original definitions differ from these and we should what djb's original redo implementation did.
probably change ours in order to maintain compatibility.
(In his version, $1 is always the name of the target, and
$2 is the target with the extension removed.)
$1 is the name of the target, with the extension removed, $1 is the name of the target file.
if any.
$2 is the extension of the target, including the leading $2 is the basename of the target, minus the extension, if
dot. any.
$3 is the name of a temporary file that will be renamed to $3 is the name of a temporary file that will be renamed to
the target filename atomically if your .do file returns a the target filename atomically if your .do file returns a
zero (success) exit code. zero (success) exit code.
In a file called `chicken.a.b.c.do` that builds a file called In a file called `chicken.a.b.c.do` that builds a file called
`chicken.a.b.c`, $1 is `chicken.a.b.c`, $2 is blank, and $3 is a `chicken.a.b.c`, $1 and $2 are `chicken.a.b.c`, and $3 is a
temporary name like `chicken.a.b.c.tmp`. You might have expected temporary name like `chicken.a.b.c.tmp`. You might have expected
$1 to be just `chicken`, but that's not possible, because $2 to be just `chicken`, but that's not possible, because
redo doesn't know which portion of the filename is the redo doesn't know which portion of the filename is the
"extension." Is it `.c`, `.b.c`, or `.a.b.c`? "extension." Is it `.c`, `.b.c`, or `.a.b.c`?
.do files starting with `default.` are special; they can .do files starting with `default.` are special; they can
build any target ending with the given extension. So let's build any target ending with the given extension. So let's
say we have a file named `default.c.do` building a file say we have a file named `default.c.do` building a file
called `chicken.a.b.c`. $1 is `chicken.a.b`, $2 is `.c`, called `chicken.a.b.c`. $1 is `chicken.a.b.c`, $2 is `chicken.a.b`,
and $3 is a temporary name like `chicken.a.b.c.tmp`. and $3 is a temporary name like `chicken.a.b.c.tmp`.
You should use $1 and $2 only in constructing input You should use $1 and $2 only in constructing input
@ -333,11 +329,8 @@ to stdout instead of $3 if you want.)
For example, you could compile a .c file into a .o file For example, you could compile a .c file into a .o file
like this, from a script named `default.o.do`: like this, from a script named `default.o.do`:
redo-ifchange $1.c redo-ifchange $2.c
gcc -o $3 -c $1.c gcc -o $3 -c $2.c
Note that $2, the output file's .o extension, is rarely useful
since you always know what it is.
# Why not named variables like $FILE, $EXT, $OUT instead of $1, $2, $3? # Why not named variables like $FILE, $EXT, $OUT instead of $1, $2, $3?
@ -762,7 +755,7 @@ So we haven't thought about this enough yet.
Note that it's *okay* for a .do file to produce targets Note that it's *okay* for a .do file to produce targets
other than the advertised one; you just have to be careful. other than the advertised one; you just have to be careful.
You could have a default.javac.do that runs 'javac You could have a default.javac.do that runs 'javac
$1.java', and then have your program depend on a bunch of .javac $2.java', and then have your program depend on a bunch of .javac
files. Just be careful not to depend on the .class files files. Just be careful not to depend on the .class files
themselves, since redo won't know how to regenerate them. themselves, since redo won't know how to regenerate them.
@ -848,12 +841,12 @@ create a file called `compile.do`:
redo-ifchange config.sh redo-ifchange config.sh
. ./config.sh . ./config.sh
echo "gcc -c -o \$3 $1.c $CFLAGS" >$3 echo "gcc -c -o \$3 $2.c $CFLAGS" >$3
chmod a+x $3 chmod a+x $3
Then, your `default.o.do` can simply look like this: Then, your `default.o.do` can simply look like this:
redo-ifchange compile $1.c redo-ifchange compile $2.c
./compile $1 $2 $3 ./compile $1 $2 $3
This is not only elegant, it's useful too. With make, you have to always This is not only elegant, it's useful too. With make, you have to always
@ -884,7 +877,7 @@ look something like this:
redo-ifchange config.sh redo-ifchange config.sh
. ./config.sh . ./config.sh
cat <<-EOF cat <<-EOF
[ -e "\$1.cc" ] && EXT=.cc || EXT=.c [ -e "\$2.cc" ] && EXT=.cc || EXT=.c
gcc -o "\$3" -c "\$1\$EXT" -Wall $CFLAGS gcc -o "\$3" -c "\$1\$EXT" -Wall $CFLAGS
EOF EOF
chmod a+x "$3" chmod a+x "$3"

View file

@ -1,2 +1,7 @@
if [ "$1,$2" != "_all,_all" ]; then
echo "ERROR: old-style redo args detected: don't use --old-args." >&2
exit 1
fi
redo-ifchange redo-sh redo-ifchange redo-sh
redo-ifchange version/all Documentation/all redo-ifchange version/all Documentation/all

View file

@ -141,10 +141,16 @@ class BuildJob:
close_on_exec(ffd, True) close_on_exec(ffd, True)
self.f = os.fdopen(ffd, 'w+') self.f = os.fdopen(ffd, 'w+')
# this will run in the dofile's directory, so use only basenames here # this will run in the dofile's directory, so use only basenames here
if vars.OLD_ARGS:
arg1 = basename # target name (no extension)
arg2 = ext # extension (if any), including leading dot
else:
arg1 = basename + ext # target name (including extension)
arg2 = basename # target name (without extension)
argv = ['sh', '-e', argv = ['sh', '-e',
dofile, dofile,
basename, # target name (no extension) arg1,
ext, # extension (if any), including leading dot arg2,
# temp output file name # temp output file name
state.relpath(os.path.abspath(self.tmpname2), dodir), state.relpath(os.path.abspath(self.tmpname2), dodir),
] ]

View file

@ -121,7 +121,7 @@ _do()
fi fi
[ ! -e "$DO_BUILT" ] || [ ! -d "$(dirname "$target")" ] || [ ! -e "$DO_BUILT" ] || [ ! -d "$(dirname "$target")" ] ||
: >>"$target.did" : >>"$target.did"
( _run_dofile "$base" "$ext" "$tmp.tmp" ) ( _run_dofile "$target" "$base" "$tmp.tmp" )
rv=$? rv=$?
if [ $rv != 0 ]; then if [ $rv != 0 ]; then
printf "do: %s%s\n" "$DO_DEPTH" \ printf "do: %s%s\n" "$DO_DEPTH" \

View file

@ -15,6 +15,7 @@ shuffle randomize the build order to find dependency bugs
debug-locks print messages about file locking (useful for debugging) debug-locks print messages about file locking (useful for debugging)
debug-pids print process ids as part of log messages (useful for debugging) debug-pids print process ids as part of log messages (useful for debugging)
version print the current version and exit version print the current version and exit
old-args use old-style definitions of $1,$2,$3 (deprecated)
""" """
o = options.Options(optspec) o = options.Options(optspec)
(opt, flags, extra) = o.parse(sys.argv[1:]) (opt, flags, extra) = o.parse(sys.argv[1:])
@ -39,6 +40,8 @@ if opt.debug_locks:
os.environ['REDO_DEBUG_LOCKS'] = '1' os.environ['REDO_DEBUG_LOCKS'] = '1'
if opt.debug_pids: if opt.debug_pids:
os.environ['REDO_DEBUG_PIDS'] = '1' os.environ['REDO_DEBUG_PIDS'] = '1'
if opt.old_args:
os.environ['REDO_OLD_ARGS'] = '1'
import vars_init import vars_init
vars_init.init(targets) vars_init.init(targets)

View file

@ -1,3 +1,3 @@
DEPS=$(./seq 100 | sed 's/$/.n2/') DEPS=$(./seq 100 | sed 's/$/.n2/')
redo-ifchange $DEPS redo-ifchange $DEPS
echo n1-$1 echo n1-$2

View file

@ -1,6 +1,6 @@
echo n2-$1 echo n2-$2
echo $1 >>$1.count echo $2 >>$2.count
echo $1 >>in.countall echo $2 >>in.countall
# we deliberately use 'redo' here instead of redo-ifchange, because this *heavily* # we deliberately use 'redo' here instead of redo-ifchange, because this *heavily*
# stresses redo's locking when building in parallel. We end up with 100 # stresses redo's locking when building in parallel. We end up with 100

View file

@ -1,3 +1,3 @@
[ "$1" = "test" ] [ "$1" = "test.args" ]
[ "$2" = ".args" ] [ "$2" = "test" ]
[ "$3" != "test.args" ] [ "$3" != "test.args" ]

View file

@ -1,3 +1,3 @@
redo-ifchange $1$2.c redo-ifchange $1.c
echo c.do echo c.do
cat $1$2.c cat $1.c

View file

@ -1,10 +1,10 @@
if [ -e "$1$2.a" -o -e "default$2.a" ]; then if [ -e "$1.a" -o -e "default${1#$2}.a" ]; then
redo-ifchange "$1$2.a" redo-ifchange "$1.a"
echo a-to-b echo a-to-b
cat "$1$2.a" cat "$1.a"
else else
redo-ifchange "$1$2.b" redo-ifchange "$1.b"
echo b-to-b echo b-to-b
cat "$1$2.b" cat "$1.b"
fi fi
../sleep 1.1 ../sleep 1.1

View file

@ -1,4 +1,4 @@
redo-ifchange $1$2.b redo-ifchange $1.b
echo b-to-cc echo b-to-cc
cat $1$2.b cat $1.b
../sleep 1.2 ../sleep 1.2

View file

@ -1,4 +1,4 @@
redo-ifchange $1$2.c redo-ifchange $1.c
echo c-to-c echo c-to-c
cat $1$2.c cat $1.c
../sleep 1.3 ../sleep 1.3

View file

@ -1 +1 @@
echo default.y.z $1 $2 echo default.y.z $2 ${1#$2}

View file

@ -1 +1 @@
echo file $1 $2 echo file $2 ${1#$2}

View file

@ -1 +1 @@
echo default $1 $2 echo default $2 ${1#$2}

View file

@ -1,2 +1,2 @@
echo default.x.y.z $1 $2 echo default.x.y.z $2 ${1#$2}

View file

@ -1 +1 @@
echo default.z $1 $2 echo default.z $2 ${1#$2}

View file

@ -1 +1 @@
echo root $1 $2 "$(dirname $3)" echo root $2 ${1#$2} "$(dirname $3)"

View file

@ -1,3 +1,3 @@
redo-ifchange $1.in redo-ifchange $2.in
echo $$ echo $$
echo $$ >>$1.log echo $$ >>$2.log

View file

@ -2,8 +2,8 @@ redo-ifchange config.sh
. ./config.sh . ./config.sh
exec >$3 exec >$3
cat <<-EOF cat <<-EOF
redo-ifchange \$1.c redo-ifchange \$2.c
gcc $CFLAGS -MD -MF \$3.deps -o \$3 -c \$1.c gcc $CFLAGS -MD -MF \$3.deps -o \$3 -c \$2.c
read DEPS <\$3.deps read DEPS <\$3.deps
rm -f \$3.deps rm -f \$3.deps
redo-ifchange \${DEPS#*:} redo-ifchange \${DEPS#*:}

View file

@ -1,3 +1,3 @@
[ "$1" = "test2.args" ] [ "$1" = "test2.args" ]
[ "$2" = "" ] [ "$2" = "test2.args" ]
[ "$3" != "test2.args" ] [ "$3" != "test2.args" ]

View file

@ -13,6 +13,7 @@ DEPTH = os.environ.get('REDO_DEPTH', '')
DEBUG = atoi(os.environ.get('REDO_DEBUG', '')) DEBUG = atoi(os.environ.get('REDO_DEBUG', ''))
DEBUG_LOCKS = os.environ.get('REDO_DEBUG_LOCKS', '') and 1 or 0 DEBUG_LOCKS = os.environ.get('REDO_DEBUG_LOCKS', '') and 1 or 0
DEBUG_PIDS = os.environ.get('REDO_DEBUG_PIDS', '') and 1 or 0 DEBUG_PIDS = os.environ.get('REDO_DEBUG_PIDS', '') and 1 or 0
OLD_ARGS = os.environ.get('REDO_OLD_ARGS', '') and 1 or 0
VERBOSE = os.environ.get('REDO_VERBOSE', '') and 1 or 0 VERBOSE = os.environ.get('REDO_VERBOSE', '') and 1 or 0
XTRACE = os.environ.get('REDO_XTRACE', '') and 1 or 0 XTRACE = os.environ.get('REDO_XTRACE', '') and 1 or 0
KEEP_GOING = os.environ.get('REDO_KEEP_GOING', '') and 1 or 0 KEEP_GOING = os.environ.get('REDO_KEEP_GOING', '') and 1 or 0