To bad I'm not using git. I still want a zip file of a directory. Really, don't say "use a command like" actually show me exactly how you would accomplish that task, using (gnu) make, in an efficient and cross-platform way without causing unnecessary target rebuilds. You can't? Now you see why make is insufficient.
Let's assume for sake of argument that you are right (although as ori_b shows, you are not). Why do you expect this functionality from _make_ specifically? Nobody ever claimed it can do everything. In fact, it's a good thing it doesn't even try to do tasks for which other, purpose-built tools exist. Creating compressed archives is a very different task from managing dependency graphs. Make was built for, and excels at, the latter. For the former there are better choices (and they can be called from make if need be).
> Creating compressed archives is a very different task from managing dependency graphs.
What? Creating a compressed archive is exactly the sort of thing that Make was designed for. A binary file or library, if you squint the right way, is just an archive of object files, which are just transformations of .c files.
Make's biggest problems for me (and the reason that I'm slowly gravitating towards writing a replacement for my own purposes) come from the fact that it can't handle inferring dependency graphs correctly. The usual 'gcc -M' hacks that work for C source don't work for code where dependency tracking is more than just an optimization. For C, remember, as long as you have the appropriate headers and .c files, you can build a .o file completely order-independent.
If you have a dependency digraph that looks like this:
a -> b, c, d
b -> c, d
c -> d
d
Then you need to build in this order:
d, c, b, a
Without some way of explicitly generating these dependencies ahead of time (which, I admit, is doable), you can't get make to do this properly. The best hack I can think of would look something like this:
depfile: $(SOURCES)
update-deps -o $@ $?
include depfile
But at that point, you're pretty much generating a makefile with another tool, scanning all changed sourcs, at which point you might as well move on to just building the DAG and running the build on them while you're at it.
Actually creating the archive is not make's job, which is what bjourne seems to be complaining about. Collecting a list of files and passing to a command is what make does. It doesn't care if that command is a compiler or an archiver, nor should it.
Regarding your chained dependencies, how do you expect _any_ tool to figure this out without either being told or examining the inputs (which implies knowledge of their formats)? Relegating this to an external tool seems perfectly appropriate to me.
Note, $? will only include the prerequisites that are newer than the zipfile, and therefore, will only update the files that have changed. You will not be re-zipping things repeatedly.
That's for trying, but 1. doesn't work unless you have zip installed, 2. doesn't recurse the whole directory tree, 3. doesn't rebuild the target if a file is renamed or deleted, 4. uses volatile time stamps instead of content hashes to detect targets needing update. And is GNU make specific. Then what if you want bz2 compression instead of zip?
1. Are you seriously complaining over make itself not creating the zip file, duplicating the functionality of the 'zip' tool?
2-3. This command does what you want: zip -R -FS foo.zip '*.c'
4. In practice timestamps work just fine unless you deliberately sabotage them. To use content hashes, the hashes of the input files when creating a target would need to be stored somewhere for future reference. This storage place could just as easily be corrupted. Make is a build tool, not a VCS. Treat it as such.
Yes, some things are specific to GNU make, but it is the de facto standard, something waf can only dream of. If you're going to complain about something being non-standard, your suggested alternative should be more of a standard, not less.
Want a zip file? Use a command like "git archive -o foo.zip HEAD".
Why do you insist on having a single tool do all your tasks? A good craftsman has an arsenal of tools and picks the right one for each job.