Path: utzoo!mnetor!uunet!husc6!cmcl2!brl-adm!umd5!ames!amdahl!dlb!megatest!djones From: djones@megatest.UUCP (Dave Jones) Newsgroups: comp.lang.c Subject: Makefile Maker Message-ID: <176@goofy.megatest.UUCP> Date: 23 Dec 87 03:28:48 GMT Organization: Megatest Corporation, San Jose, Ca Lines: 91 Keywords: make Makefile The problem with make -- well ONE of the problems with make -- is that it requires the user to specify the dependencies. What you really want is something that keeps up with the dependencies automatically as they change. You want to use a data-base, but the Makefile IS its own data-base. HEY! THAT'S IT! Let's cause the Makefile to update itself each time a dependency might have changed. We will need a program which removes dependency spec's from a Makefile, and one which creates new dependency spec's. In Sun-3 land, cc -M will make the new dependencies. It's quite easy to write a little program to do it, if your cc doesn't have the feature. If you have the source to cpp, just hack that. I've done so, and it's easy. Let's call the one which removes dependencies "remove_depends". (One follows at the end of this letter, in C++. Absolutely free.) Again easy. If you speak sed or awk, (I don't), you can probably write it in a line or two. The here is a paradigm for your Makefile: # Is this self-modifying code? If so, sue me. ################################################## FILES = foo.o bar.o foobar.o foozle.o libFoo.a: $(FILES) ar cru libFoo.a $(FILES) ranlib libFoo.a .c.o: remove_depends $*.o < Makefile > NewMakefile cc -M $(CFLAGS) $< >> NewMakefile mv NewMakefile Makefile $(CC) $(CFLAGS) -.o $< # dependency specs will magically appear below /* This can be used as "remove_depends" */ #include #include /* This program filters out all lines prefixed by argv[1]. ** */ void maybe_quit() { if(cin.rdstate() != _good) exit(cin.rdstate() == _eof ? 0 : -1); } main(int argc, char** argv) { if(argc == 1) { cerr << "Need a parameter\n"; exit(1); } const int name_len = strlen(argv[1]) + 1; char* name = new char[name_len]; strcpy(name,argv[1]); char* prefix = new char[name_len]; while(1) { cin.get(prefix, name_len); maybe_quit(); const int compares = ( strcmp(name, prefix) == 0 ); /* flush prefix */ if(!compares) cout << prefix; /* flush remainder of line */ char ch; do { cin.get(ch); maybe_quit(); if( !compares ) cout.put(ch); } while( ch != '\n'); } }