C + Make
Chris Torek
chris at mimsy.umd.edu
Mon Sep 17 01:30:30 AEST 1990
I wrote:
>>I have two recommendations ... 1. Put the dependency-making in a
>>separate program.
In article <0949 at sheol.UUCP> throopw at sheol.UUCP (Wayne Throop) writes:
>Much as I am aware of the dangers of disagreeing with somebody as
>usually-correct as Chris, I disagree slightly here. My experience
>says that packing all the dependency-making into a single step
>seperated from the construction step is very bad for information
>hiding, and makes for monolithic, hard-to-maintain, hard-to-enhance
>dependency "expert systems".
Hmm, well, would you prefer `in separate programs'? I.e., `mkdep-C'
extracts information on C source files, `mkdep-EP' extracts Extended
Pascal information (cannot do ANSI Standard Pascal since it has no
inclusion mechanism!), `mkdep-KCL' extracts Kyoto Common Lisp information,
and so forth. In the case of the Berkeley source tree, the C-only
mkdep handles at least 95% of the job, i.e., it is `good enough'.
>In fact, Chris' second rule:
>> Do not make `mkdep' edit the makefile. [.. instead ..]
>> make -f Makefile -f .depend <original args>
>... obliquely illustrates part of the problem with the first rule.
>The dependency occurs in a single massive step before the "real"
>work of construction begins. Thus, any source that is generated
>"on the fly" (like yacc or lex, but more complicated... for example
>computing a perfect hash literal array, or whatever) must be
>treated as a stylized special case in the dependency check. The
>natural way of computing the dependencies of the output files
>using the method of an existing subcase won't work because the
>files don't exist yet.
True. In the case of lex and yacc files, one cheats: since the output
from both these programs is a C file (which has not expanded any
`#include's---that is, if foo.y yaccs to foo.c and foo.y `#include's
foo.h, then foo.o depends on foo.c and foo.h, but foo.c does not depend
on foo.h) one adds the C files to the list of `things for mkdep' and
makes the `depend' rule depend on the .c files themselves. I.e.:
# Makefile for foo, built from foo.y->foo.c->foo.o and aux.c->aux.o
CSRCS= foo.c aux.c
OBJS= foo.o aux.o
all: foo
foo: ${OBJS}
${CC} ${LDFLAGS} -o $@ ${OBJS}
clean:
rm -f ${OBJS} foo a.out core
depend: ${CSRCS}
mkdep ${CSRCS}
Note that foo.y need not be mentioned at all: `make' keys off its
existence, plus make's implicit rule for `.y' -> `.c'.
>Not that this problem is insoluable. I've seen it solved. It's just
>that the solution, while effective, seems not to have an audience.
>
>( The basic notion of the solution is that the construction engine must
> construct the dependency graph on the fly... quite doable, trust me. )
Indeed. Unfortunately, this requires the construction engine (`make')
to have access to the actual dependency information, which means either
pushing all those rules from mkdep-* into `make' itself, or else an
incestuous relationship between the compiler(s) and `make'. The latter
is certainly more maintainable (what else but the program that creates
an output file knows for certain what inputs were used?), and can be
quite efficient---the dependency information for any one source is correct
if and only if the corresponding output file exists, and if not that
output needs rebuilding anyway---but, unfortunately, this is MUCH more
work to add to a system that does not already have it.
(Too, it has the drawback of requiring that there be room in every
output file for the information needed by `make', or else that output
files come in pairs: foo.o and .depend.foo.o, or some such. Which is
`better' is to some extent a matter of taste. One can argue that every
`object' file should in fact be a directory: foo.o/text, foo.o/data,
foo.o/symbols, foo.o/debug, foo.o/depend.... Let the file system work
for you.)
In any case, it is important that a makefile---even one as minimal as a
source list (`bill of materials', as it were) for a system like the one
above---not be altered by the dependency-update step, because such a
file *is* a source file, just as much as any C program. If you are
using a revision control system, you will not want revisions made
merely to reflect automatically-derived changes.
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750)
Domain: chris at cs.umd.edu Path: uunet!mimsy!chris
More information about the Comp.lang.c
mailing list