# @(#) makefile 1.21@(#) 95/01/23 #
# Makefile for ExFilter 1.1.2

SHELL=/bin/sh

.KEEP_STATE:

# V gives the code version we are producing.
V=1.1.2

#--------------------------------------------------------------------------
# Compute architecture types we can generate.

# ARCH is the applications architecture.
# KARCH is the kernel architecture.
# OSTYPE is the OS name, eg SunOS.
# OSMREV is the major revision level of the OS, eg 4 for SunOS 4.1.x,
#     5 for SunOS 5.x.
ARCH:sh=/bin/arch
KARCH:sh=/bin/arch -k
OSTYPE:sh=/bin/uname -s
OSMREV:sh=case `/bin/uname -s` in \
    SunOS) \
        case `/bin/uname -r` in 4.1*) echo 4;; 5*) echo 5;; *) exit 1;; esac;;\
    *) \
        exit 1;; \
    esac

# APPSARCH is the fully-qualified architechture (FQA) for non-kernel parts.
# KAPPSARCH is the FQA for kernel-dependent parts.
APPSARCH=$(ARCH)-$(OSTYPE)-$(OSMREV)
KAPPSARCH=$(ARCH)-$(KARCH)-$(OSTYPE)-$(OSMREV)

# GCC is localtion of gcc driver.
GCC=/usr/local/bin/gcc/bin/gcc

#--------------------------------------------------------------------------
# Compute target names and set default (`all') target.

# TARGETO is the name of the optimised executable.
# TARGETG is the name of the optimised gcc-compiled executable.
TARGETO=ExFilter.O.$(APPSARCH)
TARGETG=ExFilter.G.$(APPSARCH)

ALLTARGETS= \
     $(TARGETO) $(TARGETG)

all: $(ALLTARGETS)
	@(echo Made:; echo '    '`echo $(ALLTARGETS)`.) | fmt -c

# TARFILE is a list of files to go in the tar archive for distribution.
TARFILEsrc=\
	ExFilter.O.sun3-SunOS-4 \
	ExFilter.O.sun4-SunOS-4 \
	ExFilter.G.sun4-SunOS-4 \
	spec.dvi \
	unsupported/dp-2.3-patchlevel2-DamonMods.tar.Z \
	unsupported/sping \
	unsupported/100359-06.tar.Z

distribution.tar.gz: $(TARFILEsrc)
	@rm -f $@
	tar cvf - $(TARFILEsrc) | gzip -9 -v > $@

#--------------------------------------------------------------------------
# Cleaning up, making distributions, etc.

clean: FORCE
	rm -f obj/*.o $(ALLTARGETS)

tidy: FORCE
	rm -f obj/*.o *.c *.h strings

FORCE:

#--------------------------------------------------------------------------
# List source files, headers and standard suffixes.

# FOR RELEASE CODE WE PUT IN EXPLICIT TARGETS NAMING WHICH VERSIONS OF
# THE SOURCE FILES WE USE.

# SOURCETREE is the directory containing the main SCCS-controlled
# source tree from which we extract our source.
SOURCETREE=../..

route.c: $(SOURCETREE)/SCCS
	sccs get -r1.178 $(SOURCETREE)/$(@F) -G$@

stats.c: $(SOURCETREE)/SCCS
	sccs get -r1.7 $(SOURCETREE)/$(@F) -G$@

muxmsgU.c: $(SOURCETREE)/SCCS
	sccs get -r1.18 $(SOURCETREE)/$(@F) -G$@

muxmsgC.c: $(SOURCETREE)/SCCS
	sccs get -r1.13 $(SOURCETREE)/$(@F) -G$@

rtconfig.c: $(SOURCETREE)/SCCS
	sccs get -r1.35 $(SOURCETREE)/$(@F) -G$@

ifconfig.c: $(SOURCETREE)/SCCS
	sccs get -r1.27 $(SOURCETREE)/$(@F) -G$@

hci.c: $(SOURCETREE)/SCCS
	sccs get -r1.114 $(SOURCETREE)/$(@F) -G$@

main.c: $(SOURCETREE)/SCCS
	sccs get -r1.130 $(SOURCETREE)/$(@F) -G$@

version.c: $(SOURCETREE)/SCCS
	sccs get -r1.2 $(SOURCETREE)/$(@F) -G$@

conffile.h: $(SOURCETREE)/SCCS
	sccs get -r1.39 $(SOURCETREE)/$(@F) -G$@

filter.h: $(SOURCETREE)/SCCS
	sccs get -r1.82 $(SOURCETREE)/$(@F) -G$@

muxmsg.h: $(SOURCETREE)/SCCS
	sccs get -r1.18 $(SOURCETREE)/$(@F) -G$@

queue.h: $(SOURCETREE)/SCCS
	sccs get -r1.20 $(SOURCETREE)/$(@F) -G$@

route.h: $(SOURCETREE)/SCCS
	sccs get -r1.38 $(SOURCETREE)/$(@F) -G$@

stats.h: $(SOURCETREE)/SCCS
	sccs get -r1.36 $(SOURCETREE)/$(@F) -G$@

verbosity.h: $(SOURCETREE)/SCCS
	sccs get -r1.12 $(SOURCETREE)/$(@F) -G$@

#--------------------------------------------------------------------------
# CSRC is a list of the C source files.
# The most-used routines should be in files towards the start of the
# list so that pages from the end of the code area can be dropped more
# easily.  Those routines should be towards the start of their files.
CSRC=route.c stats.c muxmsgU.c muxmsgC.c \
	rtconfig.c ifconfig.c hci.c \
	main.c version.c

# CHDR is a list of the C header files.
CHDR= conffile.h filter.h muxmsg.h queue.h route.h stats.h verbosity.h

#--------------------------------------------------------------------------
# OD is the base directory for all the (intermediate) object files.
OD=obj

# OBJOE is the ending for maximally-optimised object files.
# OBJGE is the ending for maximally-optimised gcc object files.
OBJOE=.O.$(APPSARCH).o
OBJGE=.G.$(APPSARCH).o

# OBJSO is a list of executables for the current optimised target.
# OBJSG is a list of executables for the current optimised gcc target.
OBJSO=$(CSRC:%.c=$(OD)/%$(OBJOE))
OBJSG=$(CSRC:%.c=$(OD)/%$(OBJGE))

#--------------------------------------------------------------------------
# Force some explicit dependencies.

# Make all the objects depend on all the headers.
$(OBJSO) $(OBJSG): $(CHDR)

# Force ``version'' to depend on all headers since it includes the SCCS IDs
# of the headers for version identification.
version$(OBJOE) version$(OBJGE): $(CHDR)

#--------------------------------------------------------------------------
# CFLAGS is the common set of flags passed to non-optimised, optimised
# and linted code.  This flags are used for all .c compilations.
CFLAGS=-D$(ARCH) -DNO_MUX

#--------------------------------------------------------------------------
# Generating optimised version, (TARGETO).

# COFLAGS is the set of C flags for the optimised version
# (all of normal flags + optimisation that won't change anything that
# lint cares about, ie no conditional-compilation changes EXCEPT
# the elimination of extra*internal* consistency checking with
# -DNO_PARANOIA).
#
# For first user release, compile with paranoid internal checking.
COFLAGS = $(CFLAGS) -O2 # -DNO_PARANOIA

# CGFLAGS is the set of C flags passed to the optimised gcc version
# instead of COFLAGS.  Just like COFLAGS, none of the switches in
# here should change any conditional compilation items in the source
# so semantically the executables are exactly the same as non-optimised
# and native-optimised ones. -DNO_PARANOIA is allowed.
#
# The first line choses which warnings to enable, and the general environment.
# The second line sets the optimisation options we use.
# The third line sets options to ensure we can safely link with /bin/cc code
# and the SunOS 4.1.x and 5.x kernels.
CGFLAGS = $(CFLAGS) -DNO_PARANOIA \
        -Wall -Wno-comment -ansi -fverbose-asm \
        -O2 -fomit-frame-pointer -funroll-loops -finline-functions \
        -fpcc-struct-return -fvolatile-global

# strings is the extracted-strings database and depends on all the source
# (non-kernel) C files.
#
# Note that the STREAMS module is *not* optimised using the strings
# database.
#
# We move the existing database out of the way while we build a new
# one from scratch.  If the new and the old differ we keep the new
# (possibly optimal) one, else we restore the old one, keeping its
# datestamp.
#
# We make the strings database after preprocessing with the native
# C compiler---gcc compilation should not generate extra strings.

# The strings database is too valuable to loose!
.PRECIOUS: strings

strings: $(CHDR) $(CSRC)
	@if [ -f strings ]; then mv -f strings strings.old; fi
	cc -E $(COFLAGS) $(CSRC) | xstr -c -
	@if cmp -s strings strings.old; then \
		echo Preserving old strings database. ; \
		mv -f strings.old strings; \
	 else \
		echo Discarding old strings database. ; \
	 fi

# xs.$(ARCH).o is made from strings separately to allow it to be built after
# we've tried building all the real .o files that we care about.
#
# Make the data read-only and shared (and in the text segment).
#
# This alone doesn't need CFLAGS.
$(OD)/xs.$(ARCH).o: strings
	xstr
	cc -c -R xs.c -o $(OD)/xs.$(ARCH).o
	@rm -f xs.c

# Report any new strings added at compile time, presumably from
# conditionally-compiled code and/or from headers.
$(OD)/%$(OBJOE): strings %.c
	@echo Optimising cc compile $(@:$(OD)/%$(OBJOE)=%.c) to $@.
	@cc -E $(COFLAGS) $(DEBUG_FLAGS) $(@:$(OD)/%$(OBJOE)=%.c) | \
		xstr -v -c - && \
		cc -c $(COFLAGS) $(DEBUG_FLAGS) -o $@ x.c
	@rm -f x.c

# GCC code.
# We share our strings database with the non-gcc code.
# Report any new strings added at compile time, presumably from
# conditionally-compiled code and/or from headers.
$(OD)/%$(OBJGE): strings %.c
	@echo Optimising gcc compile $(@:$(OD)/%$(OBJGE)=%.c) to $@.
	@$(GCC) -E $(CGFLAGS) $(DEBUG_FLAGS) $(@:$(OD)/%$(OBJGE)=%.c) | \
		xstr -v -c - && \
		$(GCC) -c $(CGFLAGS) $(DEBUG_FLAGS) -o $@ x.c
	@rm -f x.c

# xs.$(ARCH).o is the shared strings library and is last to get all the other
# .o files compiled first.
$(TARGETO): $(OBJSO) $(OD)/xs.$(ARCH).o
	cc $(COFLAGS) $(DEBUG_FLAGS) -o $@ $(OD)/xs.$(ARCH).o $(OBJSO)
	strip $@

# GCC optimised target.
# xs.$(ARCH).o is the shared strings library and is last to get all the other
# .o files compiled first.
$(TARGETG): $(OBJSG) $(OD)/xs.$(ARCH).o
	$(GCC) $(CGFLAGS) $(DEBUG_FLAGS) -o $@ $(OD)/xs.$(ARCH).o $(OBJSG)
	strip $@
