# Makefile for C Threads library.
#
# Parameters for "generic" rules:
#
#	LIB		C thread library
#			libthreads.a, libco_threads.a, or libtask_threads.a
#	IMPL		implementation option
#			MTHREAD, COROUTINE, or MTASK
#	PROFILE		profiling switch
#			(null, -p, or -pg)
#
# Implicit parameters:
#
#	machine		machine type, set by make
#
# A random value of LIB is given here so that
# the Makefile will be syntactically correct.
# The actual value of LIB will always be passed
# on the command line in a recursive call to make.

LIB = unknown.a

COMMONFLAGS = -I. -DDEBUG -D$(IMPL)
CFLAGS = -g -MD $(COMMONFLAGS) $(PROFILE)
LINTFLAGS = -u $(COMMONFLAGS)

# Use the following definition to enable inline expansion.
INLINE = ./cthread_inline
# Use the following definition to disable inline expansion.
# INLINE = cat

.SUFFIXES: .c .o

.c.o:
	$(CC) $(CFLAGS) -S $*.c
# The Sun assembler requires an input file.
	$(MV) $*.s $*.S
	$(INLINE) $*.S > $*.s
	$(AS) -o $@ $*.s
	$(RM) $(RMFLAGS) $*.s $*.S

SRCS = cprocs.c cthreads.c malloc.c \
       mig_support.c stack.c sync.c \
       time.c ipc.c unix.c \
       machine/spin.c machine/thread.c

OBJS = $(LIB)(cprocs.o) $(LIB)(cthreads.o) $(LIB)(malloc.o) \
       $(LIB)(mig_support.o) $(LIB)(stack.o) $(LIB)(sync.o) \
       $(LIB)(time.o) $(LIB)(ipc.o) $(LIB)(unix.o) \
       $(LIB)(mach_traps.o) \
       $(LIB)(spin.o) $(LIB)(thread.o) \
       $(LIB)(csw.o) $(LIB)(lock.o)

DSTDIR = /usr/mach
I = -c -d -v

TH_LIB = threads
CO_LIB = co_threads
TA_LIB = task_threads

all: thread coroutine

all.prof: thread.prof coroutine.prof

all.lint: thread.lint coroutine.lint

all.llib: thread.llib coroutine.llib

thread:
	$(MAKE) $(MFLAGS) LIB=lib$(TH_LIB).a IMPL=MTHREAD lib

thread.prof:
	$(MAKE) $(MFLAGS) LIB=lib$(TH_LIB)_p.a IMPL=MTHREAD PROFILE=-pg lib

thread.lint:
	$(MAKE) $(MFLAGS) LIB=lib$(TH_LIB).a IMPL=MTHREAD lint

thread.llib:
	$(MAKE) $(MFLAGS) LIB=$(TH_LIB) IMPL=MTHREAD llib

coroutine:
	$(MAKE) $(MFLAGS) LIB=lib$(CO_LIB).a IMPL=COROUTINE lib

coroutine.prof:
	$(MAKE) $(MFLAGS) LIB=lib$(CO_LIB)_p.a IMPL=COROUTINE PROFILE=-pg lib

coroutine.lint:
	$(MAKE) $(MFLAGS) LIB=lib$(CO_LIB).a IMPL=COROUTINE lint

coroutine.llib:
	$(MAKE) $(MFLAGS) LIB=$(CO_LIB) IMPL=COROUTINE llib

task:
	$(MAKE) $(MFLAGS) LIB=lib$(TA_LIB).a IMPL=MTASK lib

task.prof:
	$(MAKE) $(MFLAGS) LIB=lib$(TA_LIB)_p.a IMPL=MTASK PROFILE=-pg lib

task.lint:
	$(MAKE) $(MFLAGS) LIB=lib$(TA_LIB).a IMPL=MTASK lint

task.llib:
	$(MAKE) $(MFLAGS) LIB=$(TA_LIB) IMPL=MTASK llib

include: machine ckdir
	mach_install $I cthreads.h $(DSTDIR)/include
	mach_install $I machine/cthreads.h $(DSTDIR)/include

install: machine all all.prof all.llib ckdir
	mach_install $I cthreads.h $(DSTDIR)/include
	mach_install $I -r lib$(TH_LIB).a $(DSTDIR)/lib
	mach_install $I -r lib$(TH_LIB)_p.a $(DSTDIR)/lib
	mach_install $I llib-l$(TH_LIB).ln $(DSTDIR)/lib/lint
	mach_install $I -r lib$(CO_LIB).a $(DSTDIR)/lib
	mach_install $I -r lib$(CO_LIB)_p.a $(DSTDIR)/lib
	mach_install $I llib-l$(CO_LIB).ln $(DSTDIR)/lib/lint

machine:
	-@if [ -d machine ]; then true; else ln -s $(machine) machine; fi

ckdir:
	-@if [ -d $(DSTDIR)/include ]; then true; else mkdir $(DSTDIR)/include; fi
	-@if [ -d $(DSTDIR)/include/machine ]; then true; else ln -s $(DSTDIR)/include/machine $(machine); fi
	-@if [ -d $(DSTDIR)/lib ]; then true; else mkdir $(DSTDIR)/lib; fi

clean:
	$(RM) $(RMFLAGS) a.out core errs *.d *.S *.o *.BAK *.CKP

# The following are the "generic" rules,
# parameterized by LIB, IMPL, and PROFILE.

lib: $(LIB)

$(LIB): $(OBJS)
	$(AR) r$(ARFLAGS) $(LIB) $?
	$(RANLIB) $(LIB)
	$(RM) $(RMFLAGS) $?
# Avoid complaints from md in case Makedep doesn't exist yet.
	touch Makedep$(IMPL)
	md -m Makedep$(IMPL) -d *.d
# Massage dependency file to reflect object files within library.
	cp Makedep$(IMPL) Makedep$(IMPL).BAK
	sed 's/^[^ #$$]*\.o/$$(LIB)(&)/' < Makedep$(IMPL).BAK > Makedep$(IMPL)
	rm Makedep$(IMPL).BAK

$(LIB)(mach_traps.o): mach_traps.c
# The Sun assembler requires an input file.
	$(CC) $(CFLAGS) -E mach_traps.c | sed -f mach_traps.sed > mach_traps.s
	$(AS) -o mach_traps.o mach_traps.s
	$(RM) $(RMFLAGS) mach_traps.s

$(LIB)(spin.o): machine/spin.c
	$(CC) $(CFLAGS) -c machine/spin.c

$(LIB)(thread.o): machine/thread.c
	$(CC) $(CFLAGS) -c machine/thread.c

$(LIB)(csw.o): machine/csw.s
	-if [ $(IMPL) = COROUTINE ]; then \
		$(AS) -o csw.o machine/csw.s ; \
	else \
		$(AS) -o csw.o /dev/null ; \
	fi

$(LIB)(lock.o): machine/lock.s
	-if [ $(IMPL) = COROUTINE ]; then \
		$(AS) -o lock.o /dev/null ; \
	else \
		$(AS) -o lock.o machine/lock.s ; \
	fi

lint:
	$(LINT) $(LINTFLAGS) $(SRCS) -lmach

llib:
	$(LINT) $(LINTFLAGS) -C$(LIB) $(SRCS)

-include Makedep$(IMPL)
