TESTROOTDIR ?= .
TESTOBJDIR ?= testobj
#TESTOBJDIR ?= /tmp/testobj_nlcc1
#TESTOBJDIR ?= $(HOME)/tmp/testobj_nlcc1

CC ?= cc

CPP ?= cc
CC1 ?= cc
AS ?= cc
AR ?= ar
LD ?= cc

TESTSETDIR = $(TESTROOTDIR)/testset

TESTLIBDIR = $(TESTROOTDIR)/lib
TESTLIBOBJS = $(TESTLIBDIR)/lib.o

TESTLIB = libtest.a

all :		test

include $(TESTROOTDIR)/Makefile.variable
include $(TESTROOTDIR)/Makefile.op1
include $(TESTROOTDIR)/Makefile.op2
include $(TESTROOTDIR)/Makefile.type
include $(TESTROOTDIR)/Makefile.sizeof
include $(TESTROOTDIR)/Makefile.for
include $(TESTROOTDIR)/Makefile.while
include $(TESTROOTDIR)/Makefile.dowhile
include $(TESTROOTDIR)/Makefile.switch
include $(TESTROOTDIR)/Makefile.cond
include $(TESTROOTDIR)/Makefile.pointer
include $(TESTROOTDIR)/Makefile.array
include $(TESTROOTDIR)/Makefile.string
include $(TESTROOTDIR)/Makefile.function
include $(TESTROOTDIR)/Makefile.struct
include $(TESTROOTDIR)/Makefile.union
include $(TESTROOTDIR)/Makefile.enum
include $(TESTROOTDIR)/Makefile.typedef
include $(TESTROOTDIR)/Makefile.bitfield
include $(TESTROOTDIR)/Makefile.vararg
include $(TESTROOTDIR)/Makefile.libc

NSRC = $(CSRC:$(TESTSETDIR)/%=$(TESTOBJDIR)/%)

COBJ = $(CSRC:.c=.co)
CEXE = $(CSRC:.c=.cexe)
COUT = $(CSRC:.c=.cout)
NASM = $(NSRC:.c=.s)
NOBJ = $(NSRC:.c=.no)
NEXE = $(NSRC:.c=.nexe)
NOUT = $(NSRC:.c=.nout)

GFLAGS  = -O0 -Wall
GFLAGS += -g
#GFLAGS += -m32 # for 32bit executable
GFLAGS += $(GOPTFLAGS)

CFLAGS  =
CFLAGS += -fno-inline
CFLAGS += $(COPTFLAGS)

AFLAGS  =
AFLAGS += $(AOPTFLAGS)

LFLAGS  = -L. -ltest
#LFLAGS += -static # To save test directory size, do not use static linking
LFLAGS += $(LOPTFLAGS)

ARFLAGS = ruc
#ARFLAGS = rDc
ARFLAGS += $(AROPTFLAGS)

.SUFFIXES:
.SUFFIXES: .nout .nexe .no .s .cout .cexe .co .o .c
.PRECIOUS: $(TESTLIBOBJS) $(COBJ) $(CEXE) $(NSRC) $(NASM) $(NOBJ) $(NEXE)

test :		nout

testset :	.testset

.testset :
		$(MAKE) allclean
		$(MAKE) cout
		$(MAKE) cobj.clean
		$(MAKE) cexe.clean
		$(MAKE) clean

$(TESTLIB) :	$(TESTLIBOBJS)
		$(AR) $(ARFLAGS) $(TESTLIB) $(TESTLIBOBJS)

$(CEXE) :	$(TESTLIB)

$(NEXE) :	$(TESTLIB)

$(NSRC) :
		mkdir -p `dirname $@`
		cp $(@:$(TESTOBJDIR)/%=$(TESTSETDIR)/%) $@

.c.o :
		$(CC) $(GFLAGS) $(CFLAGS) $< -c -o $@

.c.co :
		$(CC) $(GFLAGS) $(CFLAGS) $< -c -o $@

.co.cexe :
		$(CC) $< $(GFLAGS) $(LFLAGS) -o $@

.cexe.cout :
		$< > $@

.c.s :
		$(CC1) $< -o $@

.s.no :
		$(AS) $(GFLAGS) $(AFLAGS) $< -o $@

.no.nexe :
		$(LD) $< $(GFLAGS) $(LFLAGS) -o $@

.nexe.nout :
		$< > $@
		diff -u -U 30 $(@:$(TESTOBJDIR)/%.nout=$(TESTSETDIR)/%.cout) $@

cobj :		$(COBJ)

cexe :		$(CEXE)

cout :		$(COUT)

nsrc :		$(NSRC)

nasm :		$(NASM)

nobj :		$(NOBJ)

nexe :		$(NEXE)

nout :		$(NOUT)

lib.clean :
		rm -f $(TESTLIBOBJS) $(TESTLIB)

cobj.clean :
		rm -f $(COBJ)

cexe.clean :
		rm -f $(CEXE)

cout.clean :
		rm -f $(COUT)

nsrc.clean :
		rm -f $(NSRC)

nasm.clean :
		rm -f $(NASM)

nobj.clean :
		rm -f $(NOBJ)

nexe.clean :
		rm -f $(NEXE)

nout.clean :
		rm -f $(NOUT)

clean :		lib.clean nsrc.clean nasm.clean nobj.clean nexe.clean nout.clean
		rm -fR $(TESTOBJDIR)

allclean :	clean cobj.clean cexe.clean cout.clean
