diff --git a/Documentation/redo-ifchange.md b/Documentation/redo-ifchange.md index 0e53e7e..81722b0 100644 --- a/Documentation/redo-ifchange.md +++ b/Documentation/redo-ifchange.md @@ -38,7 +38,7 @@ redo-ifchange returns only after all the given *targets* are known to be up to date. -# TIP +# TIP 1 You don't have to run redo-ifchange *before* generating your target; you can generate your target first, then @@ -60,6 +60,24 @@ requires that you declare all your dependencies before running the target build commands. +# TIP 2 + +Try to list as many dependencies as possible in a single +call to redo-ifchange. Every time you run redo-ifchange, +the shell has to fork+exec it, which takes time. Plus redo +can only parallelize your build if you give it multiple +targets to build at once. It's fine to have a couple of +separate redo-ifchange invocations for a particular target +when necessary (as in TIP 1 above), but try to keep it to a +minimum. For example here's a trick for generating a list +of targets, but redo-ifchanging them all at once: + + for d in *.c; do + echo ${d%.c}.o + done | + xargs redo-ifchange + + # REDO Part of the `redo`(1) suite. diff --git a/README.md b/README.md index 69835f0..3796b35 100644 --- a/README.md +++ b/README.md @@ -269,7 +269,7 @@ instead. Since you didn't `redo-ifchange default.od`, changes to default.od won't cause everything to rebuild. -# Can I set my dircolors to highlight .do files? +# Can I set my dircolors to highlight .do files in ls output? Yes! At first, having a bunch of .do files in each directory feels like a bit of a nuisance, but once you get @@ -518,6 +518,35 @@ It is almost certainly possible to do it much more nicely than I have, so if you do, please send it in! +# Is it better to run redo-ifchange once per dependency or just once? + +The obvious way to write a list of dependencies might be +something like this: + + for d in *.c; do + redo-ifchange ${d%.c}.o + done + +But it turns out that's very non-optimal. First of all, it +forces all your dependencies to be built in order +(redo-ifchange doesn't return until it has finished +building), which makes -j parallelism a lot less useful. +And secondly, it forks and execs redo-ifchange over and +over, which can waste CPU time unnecessarily. + +A better way is something like this: + + for d in *.c; do + echo ${d%.c}.o + done | + xargs redo-ifchange + +That only runs redo-ifchange once (or maybe a few times, if +there are really a *lot* of dependencies and xargs has to +split it up), which saves fork/exec time and allows for +parallelism. + + # If a target didn't change, how do I prevent dependents from being rebuilt? For example, running ./configure creates a bunch of files including