gmake
Pass "--jobserver-auth=X,Y" arguments through $MAKEFLAGS variable.
Beware that only --jobserver-style=pipe protocol is supported!
+ => https://www.gnu.org/software/make/manual/html_node/POSIX-Jobserver.html\r
none
Pass "X,Y" arguments through $REDO_JS_FD variable.
Used by default, if $REDO_MAKE is not set.
--- /dev/null
+A [Env] REDO_LOGS\r
+A [Env] REDO_SILENT\r
+stderr of the running targets can be kept on the disk by specifying -k
+option (or by setting $REDO_LOGS=1 environment variable) to redo. You
+can simultaneously use also -s option ($REDO_SILENT=1) to silence stderr
+output, but still keeping it on the disk for possible further debug
+investigation. *Only* the latest build is kept, previous one is
+overwritten.
+
+ $ redo -xx -k -s build-the-whole-huge-project
+
+Logs are stored in corresponding .redo/tgt.log file.
+Each line of it is prefixed with
+=> http://cr.yp.to/libtai/tai64.html TAI64N timestamp\r
+that you can decode with tai64nlocal utility from
+ => http://cr.yp.to/daemontools.html daemontools\r
+or similar one:
+ go install go.cypherpunks.su/tai64n/v4/cmd/tai64nlocal@latest
+
+When -k is in use, all environment variables, working directory, command
+line arguments, start/finish times, duration, participated PIDs, return
+codes are also saved in corresponding .redo/tgt.log.rec file.
+
+You can view any target's output with [cmd/redo-log] command (possibly
+piping to tai64nlocal). -c option also shows how exactly it was started,
+when started/finished and how long did it take.
+
+-r option enables recursive serialized indented output. When you run
+redo in parallel, then all stderr (if no (-s)ilence was enabled) is
+printed as it appears, mixing output from all commands, that is hard to
+read and investigate. Serialized redo-log output rearranges output. I
+will take example from original apenwarr's idea
+=> https://apenwarr.ca/log/20181106 article\r
+Serialized output will look like this:
+
+ $ redo-log -r A
+ A: ...A stuff...
+ A: redo-ifchange J
+ J: > redo J
+ J: > ...J stuff...
+ J: > redo-ifchange X Y
+ X: > > redo X
+ X: > > ...X stuff...
+ X: > > done X
+ J: > > redo Y
+ Y: > > ...Y stuff...
+ Z: > > > redo Z
+ Z: > > > ...Z stuff...
+ Z: > > > done Z
+ Y: > > ...more Y stuff...
+ Y: > > done Y
+ J: > ...more J stuff...
+ J: > done J
+ A: ...more A stuff...
+
+It will output depth first logs. It can rearrange some "events" (redo
+invocations): failed targets will be at the very end, because they are
+the most interesting ones for the human.
+
+Pay attention that recursive output is more CPU hungry. Single target
+output is literally copying of .redo/tgt.log file to stdout.
--- /dev/null
+Usage: goredo -symlinks
+
+goredo expects to be called through the symbolic link to it.
+Available commands: redo, redo-affects, redo-always, redo-cleanup,
+redo-dep2rec, redo-depfix, redo-dot, redo-ifchange, redo-ifcreate,
+redo-inode, redo-log, redo-ood, redo-sources, redo-stamp,
+redo-targets, redo-whichdo.
-Forcefully and sequentially build specified targets. This is the main
-command you will explicitly use from the command line. If no targets are
-given, then "all" target will be used by default.
+Usage: redo [-j X] [-k] [-s] [-x|-xx] [target ...]
+
+Unline redo-ifchange, forcefully and *sequentially* build specified targets.
+If no targets specified, then use "all" one.
-It is not in other distributions, but it is some kind of opposite
-of [cmd/redo-sources] -- shows the targets that will be affected
-by specified files change.
+Usage: redo-affects target [...]
+
+List all targets that will be affected by changing the specified ones.
-Record current target as an always-do dependency. By definition it
-should be always build. goredo tries to build it once per run.
-Also look at [FAQ/redo-always].
+Usage: redo-always
+
+Always build current target. Unusable outside .do.
+By definition it should be always build.
+goredo tries to build it once per run.
-Removes either temporary ("tmp"), log files ("log"), lock files ("lock"),
-or everything related to goredo ("full").
+Usage: redo-cleanup [-n] {full,log,lock,tmp} [...]
+
+Remove either temporary ("tmp"), log files ("log"), lock files ("lock"),
+or everything (including .redo directories) related to goredo ("full").
-Convert specified .dep ([State]) file to recfile on stdout.
+Usage: redo-dep2rec .redo/file.dep
+
+Convert binary .dep file to recfile and write it to stdout.
Aimed to be used mainly for debugging purposes.
+Usage: redo-depfix
+
+Traverse over all .redo directories beneath and recalculate each target's
+inode and hash information, rewriting dependency files. If dependency has
+legacy .rec format, then it will be converted to .dep one.
+
When you copy your worktree to different place, then copied files
ctime will change. And because recorded dependency information
differs from updated ctimes, out-of-date algorithm will fallback to
rereading the whole files for hash calculation, that is much slower.
-If you do not want to rebuild your targets from the ground, then
-redo-depfix can traverse through all dependency files and recalculate
-dependency information.
+If you do not want to rebuild your targets from the ground, you can
+use that command.
Also if it finds legacy .rec dependency files, it converts them to
binary format.
-Dependency graph generator.
+Usage: redo-dot target [...]
+
+Write dependency DOT graph to stdout.
=> https://en.wikipedia.org/wiki/DOT_(graph_description_language) DOT\r
For example to visualize your dependencies with GraphViz:
-Rebuild specified targets if they are out-of-date and record them as
+Usage: redo-ifchange [-j X] [-k] [-s] [-x|-xx] target [...]
+
+(Re)build specified targets if they are out-of-date and record them as
a dependency for the currently run target. This is the main command
you will use in .do files.
-Record the non-existent file dependency for the currently run
-target. Target will be rebuilt if any of the given files appear.
-Can be used only inside .do file.
+Usage: redo-ifcreate target [...]
+
+Record ifcreate dependency for current target.
+Target will be rebuilt if any of the given files appear.
+Unusable outside .do.
--- /dev/null
+Usage: redo-inode target [...]
+
+Just calculate inode information about each target and print in recfile format.
-A [Env] REDO_LOGS\r
-A [Env] REDO_SILENT\r
-stderr of the running targets can be kept on the disk by specifying -k
-option (or by setting $REDO_LOGS=1 environment variable) to redo. You
-can simultaneously use also -s option ($REDO_SILENT=1) to silence stderr
-output, but still keeping it on the disk for possible further debug
-investigation. *Only* the latest build is kept, previous one is
-overwritten.
+Usage: redo-log [-c] [-r] target [| tai64nlocal]
- $ redo -xx -k -s build-the-whole-huge-project
-
-Logs are stored in corresponding .redo/tgt.log file.
-Each line of it is prefixed with
-=> http://cr.yp.to/libtai/tai64.html TAI64N timestamp\r
-that you can decode with tai64nlocal utility from
- => http://cr.yp.to/daemontools.html daemontools\r
-or similar one:
- go install go.cypherpunks.su/tai64n/v4/cmd/tai64nlocal@latest
-
-When -k is in use, all environment variables, working directory, command
-line arguments, start/finish times, duration, participated PIDs, return
-codes are also saved in corresponding .redo/tgt.log.rec file.
-
-You can view any target's output with redo-log command (possibly piping
-to tai64nlocal). -c option also shows how exactly it was started, when
-started/finished and how long did it take.
-
--r option enables recursive serialized indented output. When you run
-redo in parallel, then all stderr (if no (-s)ilence was enabled) is
-printed as it appears, mixing output from all commands, that is hard to
-read and investigate. Serialized redo-log output rearranges output. I
-will take example from original apenwarr's idea
-=> https://apenwarr.ca/log/20181106 article\r
-Serialized output will look like this:
-
- $ redo-log -r A
- A: ...A stuff...
- A: redo-ifchange J
- J: > redo J
- J: > ...J stuff...
- J: > redo-ifchange X Y
- X: > > redo X
- X: > > ...X stuff...
- X: > > done X
- J: > > redo Y
- Y: > > ...Y stuff...
- Z: > > > redo Z
- Z: > > > ...Z stuff...
- Z: > > > done Z
- Y: > > ...more Y stuff...
- Y: > > done Y
- J: > ...more J stuff...
- J: > done J
- A: ...more A stuff...
-
-It will output depth first logs. It can rearrange some "events" (redo
-invocations): failed targets will be at the very end, because they are
-the most interesting ones for the human.
-
-Pay attention that recursive output is more CPU hungry. Single target
-output is literally copying of .redo/tgt.log file to stdout.
+Display kept target's stderr with TAI64N timestamped lines. Only the
+last build is kept. You must enable stderr keeping with either -k,
+or REDO_LOGS=1. -c option show the exact command invoked, start and
+finish time. -r option recursively and linearly show also all deeper
+redo calls and their [Logs].
-Similarly to [cmd/redo-targets] shows the targets, but only out-of-date ones.
+Usage: redo-ood [target ...]
+
+Similar to redo-targets, but lists out-of-date ones.
+Usage: redo-sources [target ...]
+
Recursively show all source files the given targets depend on.
-Record "stamp" dependency. It reads stdin and stores its hash
-in the dependency database. It is not used anyhow, it is dummy.
-Read about [Stamping] in the FAQ. It is left only for
-compatibility with some other implementations.
+Usage: redo-stamp <[$3]
+
+Record stamp dependency for current target. Unusable outside .do.
+It reads stdin and stores its hash in the dependency database.
+It is not used anyhow, it is dummy, left only for compatibility
+with some other implementations.
-Show all known targets, possibly limited by specified directories.
+Usage: redo-targets [target ...]
+
+List all currently known targets, possibly limited by specified directories.
-Display .do search paths for specified target (similar to apenwarr/redo):
+Usage: redo-whichdo target
+
+Display .do search paths for specified target. Exits successfully
+if the last .do in output if the found existing one.
+Similar to apenwarr/redo:
$ redo-whichdo x/y/a.b.o
x/y/a.b.o.do
package main
import (
+ "embed"
"flag"
"fmt"
"os"
+ "strings"
)
const (
- Version = "2.8.0"
+ Version = "2.8.1"
Warranty = `Copyright (C) 2020-2026 Sergey Matveev
This program is free software: you can redistribute it and/or modify
along with this program. If not, see <http://www.gnu.org/licenses/>.`
)
-func usage(cmd string) {
- var d string
- switch cmd {
- case CmdNameRedo:
- d = `Usage: redo [-j X] [-k] [-s] [-x|-xx] [options] [target ...]
-
-Forcefully and *sequentially* build specified targets.
-If no targets specified, then use "all" one.`
- case CmdNameRedoIfchange:
- d = `Usage: redo-ifchange [-j X] [-k] [-s] [-x|-xx] target [...]
-
-Build specified targets in parallel, if they are changed.
-Record them as dependencies for current target.`
- case CmdNameRedoIfcreate:
- d = `Usage: redo-ifcreate target [...]
-
-Record ifcreate dependency for current target. Unusable outside .do.`
- case CmdNameRedoAlways:
- d = `Usage: redo-always
-
-Always build current target. Unusable outside .do.`
- case CmdNameRedoCleanup:
- d = `Usage: redo-cleanup [-n] {full,log,lock,tmp} [...]
-
-Remove either all of goredo's related temporary files, or kept stderr
-logs, or lock files, or everything (including .redo directories) related.`
- case CmdNameRedoLog:
- d = `Usage: redo-log [-c] [-r] target [ | tai64nlocal ]
-
-Display kept target's stderr with TAI64N timestamped lines. Only the
-last build is kept. You must enable stderr keeping with either -logs,
-or REDO_LOGS=1. -c option show the exact command invoked, start and
-finish time. -r option recursively and linearly show also all deeper
-redo calls and their logs.`
- case CmdNameRedoDot:
- d = `Usage: redo-dot target [...]
-
-Write dependency DOT graph to stdout.`
- case CmdNameRedoStamp:
- d = `Usage: redo-stamp < [$3]
-
-Record stamp dependency for current target. Unusable outside .do.
-Stamp dependency does not play any role, as all targets are hashed
-anyway.`
- case CmdNameRedoWhichdo:
- d = `Usage: redo-whichdo target
-
-Display .do search paths for specified target. Exits successfully
-if the last .do in output if the found existing one.`
- case CmdNameRedoTargets:
- d = `Usage: redo-targets [target ...]
+//go:embed doc/cmd/goredo doc/cmd/redo*
+var cmdDocs embed.FS
-List all currently known targets.`
- case CmdNameRedoSources:
- d = `Usage: redo-sources [target ...]
-
-List all currently known source files.`
- case CmdNameRedoOOD:
- d = `Usage: redo-ood [target ...]
-
-List all currently known out-of-date targets.`
- case CmdNameRedoAffects:
- d = `Usage: redo-affects target [...]
-
-List all targets that will be affected by changing the specified ones.`
- case CmdNameRedoDep2Rec:
- d = `Usage: redo-dep2rec .../.redo/file.dep
-
-Convert binary .dep file to recfile and write it to stdout.`
- case CmdNameRedoDepFix:
- d = `Usage: redo-depfix
-
-Traverse over all .redo directories beneath and recalculate each target's
-inode and hash information, rewriting dependency files. If dependency has
-legacy .rec format, then it will be converted to .dep one.`
- case CmdNameRedoInode:
- d = `Usage: redo-inode target [...]
-
-Just calculate inode information about each target and print in recfile format.`
- default:
- d = `Usage: goredo -symlinks
-
-goredo expects to be called through the symbolic link to it.
-Available commands: redo, redo-affects, redo-always, redo-cleanup,
-redo-dep2rec, redo-depfix, redo-dot, redo-ifchange, redo-ifcreate,
-redo-inode, redo-log, redo-ood, redo-sources, redo-stamp,
-redo-targets, redo-whichdo.`
+func usage(cmd string) {
+ data, err := cmdDocs.ReadFile("doc/cmd/" + cmd)
+ if err != nil {
+ data, _ = cmdDocs.ReadFile("doc/cmd/goredo")
+ }
+ for line := range strings.SplitSeq(string(data), "\n") {
+ if len(line) > 0 && line[len(line)-1] == '\r' {
+ continue
+ }
+ fmt.Fprintln(os.Stderr, line)
}
- fmt.Fprintf(os.Stderr, "%s\n\nCommon options:\n", d)
+ fmt.Fprintln(os.Stderr, "Common options:")
flag.PrintDefaults()
fmt.Fprintln(os.Stderr, `
Additional environment variables: