[Edit: Note that these are heredoc examples showing how to create the do scripts.]
These are just shell scripts and can be extended as much as necesary.
For instance, one can create a dependency on the compiler flags with these changes:
cat <<EOF | install -m 0755 /dev/stdin cc
#!/bin/sh
g++ -c "\$@"
EOF
# sed -i 's/^\(redo-ifchange.\+\)/\1 cc/' *.do
# sed -i 's}g++ -c}./cc}' *.do
sed calls could be combined; separated here for readablility.
CXX=g++ isn't necessary either; make already knows about $(CXX) and how to link C++ programs. Also, I think you wanted .o, not o.
And compared to that Makefile, the redo scripts you list don't seem simpler at all. I've seen reasonably compelling arguments for redo, but that wasn't one.
> CXX=g++ isn't necessary either; make already knows about $(CXX) and how to link C++ programs.
You're right, of course.
> Also, I think you wanted .o, not o.
I would, yes, but I copied the Makefile ;)
Should have been clearer; I meant that redo is simpler (and more reliable) than make.
For simple projects, redo scripts are a bit longer. However, as the projects grow, the redo scripts reach an asymptote whereas Makefiles don't.
The only way to reduce the growth in make is to add functions and implicit rules
which get ugly real fast.
In general, I found CMake quite useable for my needs, and quite clean. It also required less build system code than redo. CMake fits quite nicely into a (C or C++) project which consists of many binaries and libraries which can depend on each other.
redo might be simpler and more reliable, but shell isn't. And redo is encouraging even more work to be done in shell. Additionally, the redo version is more verbose and harder to read. While fancier tasks will make's version look horrible relatively quickly, they won't make redo's version look any better.
> redo might be simpler and more reliable, but shell isn't.
Not quite sure what you mean here. The scripts don't do anything complicated and redo catches errors that could occur.
As for readability, etc, I suppose it's relative.
Simple makefiles do read very nicely. Unfortunately, they aren't always simple and hairy makefiles are just horrible to write, read and maintain. I've had no such problems with do scripts.
It's actually quite simple. You write a short shell script to produce the output you need and redo handles the dependencies.
For example, the shell script named "banana.x.do" is expected to produce the content for the file named "banana.x".
When you say
# redo banana.x
redo invokes banana.x.do with the command:
sh -x banana.x.do banana.x banana XXX > ZZZ
so banana.x.do is invoked with three arguments and its output is redirected to a file.
$1 denotes the target file
$2 denotes the target file without its extension
$3 is a temp file: XXX, in this case.
banana.x.do is expected to either produce output in $3 or write to stdout, but not both. If there are no failures redo will chose the correct one, rename the output to banana.x and update the dependency database.
If banana.x depends on grape.y, you add the line
redo-ifchange grape.y
to the banana.x.do, creating a dependency.
redo will rebuild grape.y (recursively) when necessary.
The only other commands I haven't mentioned are init and redo-ifcreate, which are obvious and rarely used, respectively.
I think the big difference between redo and make is that make requires knowledge of dependencies up front, and this is sometimes tricky to get right.
"as you can see in default.o.do, you can declare a dependency after building the program. In C, you get your best dependency information by trying to actually build, since that's how you find out which headers you need. redo is based on the following simple insight: you don't actually care what the dependencies are before you build the target; if the target doesn't exist, you obviously need to build it. Then, the build script itself can provide the dependency information however it wants; unlike in make, you don't need a special dependency syntax at all. You can even declare some of your dependencies after building, which makes C-style autodependencies much simpler."
These are just shell scripts and can be extended as much as necesary. For instance, one can create a dependency on the compiler flags with these changes:
sed calls could be combined; separated here for readablility.[1] https://github.com/gyepisam/redux