####
$(error error message)
$(warning warning message)
####
The following short makefile can automatically parse the C programming files and generate the .d file describing the dependence on .h files.
####
objects = foo.d bar.d
all : $(objects)
$(objects) : %.d : %.c
rm -f $@ ; /
gcc -M $< > $@.$$$$ ; /
sed 's,[ ]*/($*/)/.o[ :]*,/1/.o $@ : ,g' < $@.$$$$ > $@ ; /
rm -f $@.$$$$
####
#include <stdio.h>
main()
{
int c;
char buf[BUFSIZ];
setbuf (stdout, buf);
while ((c = getchar()) != EOF)
putchar (c);
}
Unfortunately, this program is wrong, for a subtle reason.
To see where the trouble lies, ask when the buffer is flushed for the last time. Answer: after the main
program has finished, as part of the cleaning up that the library does before handing control back to the
operating system. But by that time, the buffer has already been freed!
There are two ways to prevent this sort of trouble.
First, make the buffer static, either by declaring it explicitly as static:
static char buf[BUFSIZ];
or by moving the declaration outside the main program entirely.
Another possibility is to allocate the buffer dynamically and never free it:
char *malloc();
setbuf (stdout, malloc (BUFSIZ));
Note that in this latter case, it is unnecessary to check if malloc was successful, because if it fails it will return a null pointer. A null pointer is an acceptable second argument to setbuf; it requests that stdout be unbuffered. This will work slowly, but it will work.
####
foo := a.o b.o c.o
bar := $(foo:.o=.c)
or bar := $(foo:%.o=%.c)
####
SOURCES := $(wildcard /tmp/*.c )