[net.unix] Make and libraries - YA Augmented make solution.

daveb@rtech.UUCP (Dave Brower) (08/01/85)

The solution I'm currently using to get updated libraries done is as
follows. It requires the use of the SV Augmented make, which is
available on BSD with Doug Gwyn's emulator package.  It updates the
library in one pass, never recompiles a .o if a previous attempt blew
up, and is suitable for use with machine made makefiles.  (I'm using a
hacked version of the spms mkmf program that came on the BSD user
contributed software tape (thanks to Peter Nicklin)).

The magic/trick is the use of a recursive make to generate all the .o
files.  The cost is the expense of firing up the second make process. 
The benefit, ESPECIALLY for large projects, is that you keep all the
transformation rules in one file, rather than having them all over the
place.  The any.mk file usually has the definition of every transform
you can conceive.  The .DEFAULT rule in the master makefile lets you say
things like 'make junk.o' when junk.c is a test file you stuck in the
directory, calling any.mk to actually figure out what to do.

Here is a section of a makefile used to update a library:

	ANYMK		= /usr/new/lib/any.mk

	DOANY		= $(MAKE) -f $(ANYMK) $(GLOBALS)

	GLOBALS		= \
			CFLAGS="$(CFLAGS)" \
			FFLAGS="$(FFLAGS)" \
			LINTFLAGS="$(LINTFLAGS)" \
			SCFLAGS="$(SCFLAGS)"

	LIB		= libfoo.a
	
	SRCS		= \
			foo.c \
			boo.c \
			goo.y \
			fred.qc \
			bill.qc
	
	LIBOBJS		= \
			$(LIB)(foo.o) \
			$(LIB)(boo.o) \
			$(LIB)(goo.o) \
			$(LIB)(fred.o) \
			$(LIB)(bill.o)
	
	$(LIB)::	$(LIBOBJS)
			$(DOANY) $?
			ar rvu $(LIB) $?
	# ranlib here if relevant
			rm -f $?
	
	.DEFAULT:
			@echo Default rules for $@:
			@$(DOANY) $@

	# toss builtin rules, but add one to silence complaints
	.SUFFIXES:
	.SUFFIXES:	.garbage

And here is a sample any.mk:

	.SUFFIXES:	.s .c .y .qc
	
	.qc.o:;		@eqc $<
			@$(CC) $(CFLAGS) -c $*.c
			@-rm -f $*.c
	
	.c.o:;		@echo "$<:"
			@$(CC) -c $(CFLAGS) $<
	
	# moves the parser tables to shared text space:
	.y.o:;		@echo "$<:"
			@yacc -d $<
			@mv y.tab.h $*.h
			:yyfix
			$(CC) $(CFLAGS) -S rodata.c
			:rofix rodata.s
			$(CC) -c $(CFLAGS) rodata.s y.tab.c
			$(LD) -r y.tab.o rodata.o -o $@
			-rm -f rodata* y.tab.c y.tab.o
	
	.s.o:;		@echo "$<:"
			@$(CPP) $(SCFLAGS) $*.s $*.i
			@$(AS) $*.i -o $*.o
			@-rm -f $*.i
	
	.s.i:;		@$(CPP) $(SCFLAGS) $*.s $*.i
	
	.f.o:;		@$(F77) $(FFLAGS) -c $*.f
	
	# Action:  Just specify the target you want to make.
	default:;	@echo Usage:  make -f any.mk [target ...]

-- 
{amdahl|dual|sun|zehntel}\		| Our three main weapons are FEAR,
{ucbvax|decvax}!mtxinu---->!rtech!daveb | SURPRISE, and an almost
ihnp4!{phoenix|amdahl}___/		| fanatical DEVOTION to the pope!