fabricate: The better "make". Finds dependencies automatically for any language.
code.google.com
code.google.com
files.o : files.c defs.h buffer.h command.h
cc -c files.c
I don't know a programmer beyond the introductory level that still writes this in their make file. :-p files.c: defs.h buffer.h command.h
and there are tools such as makedepend (for C and OCaml, off the top of my head) that generate those listings automatically, so you just add this to the Makefile: include (autogenerated dependency listing file)
While the mandatory tab in Make syntax is a genuine wart, make has been around long enough that there are several other tools that know how to work with it.(Now, having the scan for access time changes added as a warning to Make might not be a bad idea. "WARNING: You forgot this dependency")
I'd prefer an improved from-scratch 2nd-generation tool instead of using one that simply wraps around a complicated 1st-gen one that I'd rather not touch.
Make has more warts than just the tab characters. Lots of obscurely-named variables, for starters.
Are you talking about make or just GNU make? The $< $* $$@ stuff comes from gmake. Make itself is pretty simple. Here's a good tutorial: http://www.freebsd.org/doc/en/books/pmake/
A lot of the seemingly esoteric stuff in Makefiles is there to make porting feasible (and the rest is autogenerated by autoconf, automake, etc.). Not just which files an operation depends on, but e.g. the options used for building shared libraries correctly on this platform, paths for libraries, etc. While the build system will remember what it found as dependencies, it still needs to know what to find the first time. (It will note header files as dependencies, though.)
Most of these make replacements start with design decisions (like using Python) that pretty much rule out ever reaching what make does best, and which is essential to get my build times improved by at least a factor of 6.
Using a tool (like CMake) to generate your Makefiles is an excellent solution, heck, even a Python script that generated a Makefile and then ran make would be to prefer over this tool.
But look at the build file example on the fabricate page, it is a user supplied build file with a build function which calls a compile function which loops over sources. Having the fabricate system take input like that and do parallel execution is as hard as solving the halting problem.
Seriously, as vr said, Python's not stopping us. And I imagine it wouldn't be too hard to add code to spawn off a few background tasks based on the dependency list.
How does it know which drives and directories to scan for recently modified files? Scanning all of them would take a while.
It looks like it checks for files modified specifically by its subprocesses.
If scanning atimes is too slow or unreliable, perhaps fabricate could be updated to use procmon?
I've hacked it to print the actual file names on CreateFile() calls, but it's failing because it doesn't recurse and trace sub-processes. It should be theoretically possible by hooking CreateProcess(), but it's probably hard.
setup(dirs=['.', '../lib']) setup(runner='strace_runner')So, instead of writing a program to do the build I would rather see a simple DSL that allows me to specify just the minimal amount of configuration to get things going.
For example building the example on the fabricate wiki page, should not be more complicated than:
:program programname : program.c utils.c
(This is actually an a-a-p recipe that will do the same. Throw this in a main.aap file and you get everything that fabricate does, build, dependency checks, clean, etc.)I don't mind to script the build when things get more complex. But only then and only when there really is no simple built-in alternative.
Fabricate seems to be more like ant in the Java world. Where you specify in detail what your build should do. Most people have agreed by now that it is a waste of time and instead use Maven, which completely works on simple conventions and standard rules.
Make has its quirks, lots of them. But it wouldn't be the most popular build-tool in the world if it was all wrong. So, my hint to the next guy trying to reinvent it: Take a very close look at Make first and then improve on it. Don't start in a clean-room because then you're doomed to repeat build-system history, including all the past mistakes (edit: unless you're Linus Torvalds, perhaps).
Also the build-system is an area where a sane DSL makes perfect sense. Don't make me write procedural code by default. I don't want to see lines like the following in my build-scripts:
objects = ' '.join(s + '.o' for s in sources)However, as soon as you start adding more complex stuff the fabricate gets much easier to work with and maintain. Make's $< $@ stuff, but also because you're forced into a targets-are-files mould, and because you don't have a real programming language to work in.
The problem with this and other Python build tools is They are a huge pain to use on older systems that either don't have a recent enough version of Python installed or don't have Python installed at all. It's just not as portable as Make is in that respect.
I was using an up to date TeX install. My advisor wasn't. To placate him, I had to copy all of my packages, and all the packages they referred to, and so on down the line so that he could compile my papers. I did this entirely within make + some small shell scripts. The fact that I could write scanners for %.tex and %.sty and %.cls and have GNU make (obviously) automagically use them to build the dependency scripts I instructed it to include was immensely convenient. This is not impossible to do procedurally, but it was inconvenient, and the all-make solution had the attractive side that whenever there were bugfixes to the packages they got automatically included in what I was doing.
A better example, come to think of it, is the typical LaTeX woe; you can't build the final .dvi until you have accurate page numbers, references, tables of contents, indexes. You get all of those by--building the .dvi. So there's a strange circular dependency here. Make doesn't deal with this especially well, although it can be done. Ant and SCons don't even try.