# Makefile for Target Communications port.  This also performs
# the splitlib function to convert .lib to .c/.h files; creates
# archive file(s), and generates variations for other targets
# including makefiles.
#
# Make targets:
#   all  - compile all demos on Linux.  Do this first, and test.
#   archives - create archive .tar and .zip files in libout subdirectory,
#     including customized makefiles and tc_conf.h files.  Do this
#     after completion of test run, for back-propagation into source
#     tree and distributions.
#   clean - delete all re-buildable files (but not archives).

# Where to put output zip/tar files.
LIBOUT = libout

# Working directory for archive source files
TMPOUT = tmpout

# The main configuration header.
CONFIG = tc_conf.h
CONFIG_LIB = tc_conf.lib

# Platforms that we know how to build for (or at least package BOM).
# Note that these become makefile targets.  When adding a new target
# platform, you must create two script files named mkmf_<platform> and
# conf_<platform>.  These respectively generate a customized makefile
# and a customized configuration header file for the platform.  You
# will also need to add the platform target name to the makefile
# targets (below) under "Build deliverables for each platform".  Also,
# you should create archive_<platform> makefile variables as appropriate,
# which detemine the bill of materials for the deliverable.
PLATFORMS = linux solaris bc

# other input files (for unix-type builds including Linux/solaris)
TC_SYSV = tc.c tc.h tc_sysv.c

# other inputs for non-unix builds
TC_BC = tc.c tc.h i386ser.c tc_386ex.c tc_386ex.h

# Input Dynamic C libraries.  These are divided into 2 categories:
#   LIBEXE: the ones which generate both .c and .h files;
#   LIBH: the ones which only generate .h files (no executable code)
# Put the name without the ".lib" suffix.
TC_LIBEXE = tc_xtc dm_xtc xbuf dm_tcp dm_fs dm_var dm_log tc_wd dm_wd dm_smtp
TC_LIBH = tc_defs tc_conf tc_tcp tc_fs tc_var tc_log

# Demonstration executables
DEMOS = act_open pas_open udp_echo dns_look tcp_time var wd fs_gen smtp log100

# For each demo, create a variable of the same name which lists all
# required subsystem(s) for the demo.  Available subsystem names are
# ss_wd, ss_tcp, ss_var, ss_log, ss_smtp, ss_fs.
act_open = $(sort $(ss_tcp))
pas_open = $(sort $(ss_tcp))
udp_echo = $(sort $(ss_tcp))
dns_look = $(sort $(ss_tcp))
tcp_time = $(sort $(ss_tcp))
var = $(sort $(ss_var))
wd = $(sort $(ss_wd))
fs_gen = $(sort $(ss_fs))
log100 = $(sort $(ss_log))
smtp = $(sort $(ss_smtp))

# do it again for Borland C, which expects .obj suffixes not .o (sigh).
act_open_x = $(act_open:.o=.obj)
pas_open_x = $(pas_open:.o=.obj)
udp_echo_x = $(udp_echo:.o=.obj)
dns_look_x = $(dns_look:.o=.obj)
tcp_time_x = $(tcp_time:.o=.obj)
var_x = $(var:.o=.obj)
wd_x = $(wd:.o=.obj)
fs_gen_x = $(fs_gen:.o=.obj)
log100_x = $(log100:.o=.obj)
smtp_x = $(smtp:.o=.obj)


# For each subsystem, list the .o (from library) files which are
# required for that subsystem.
ss_xtc = tc_xtc.o dm_xtc.o xbuf.o
ss_wd = tc_wd.o dm_wd.o
ss_tcp = $(ss_xtc) dm_tcp.o
ss_var = $(ss_xtc) dm_var.o
ss_log = $(ss_xtc) dm_log.o
ss_smtp = $(ss_tcp) dm_smtp.o
ss_fs = $(ss_xtc) dm_fs.o


# Where to find the splitlib processor.  Yes, right here!
DCSIMDIR = .

CC = gcc
LDFLAGS += -lm 
INCDIRS += 
DEFINES += -Wall -Wmissing-prototypes
CPPFLAGS += -g $(INCDIRS)

# Important!  Export all variables defined herein so that they are
# accessible by mkmf_* script commands.
export


# Computed variables - do not change!
tc_objs = $(addsuffix .o,$(TC_LIBEXE))
tc_bcobjs = $(addsuffix .obj,$(TC_LIBEXE))
tc_hdrs = $(addsuffix .h,$(TC_LIBEXE) $(TC_LIBH))
tc_cfiles = $(addsuffix .c,$(TC_LIBEXE))
tc_othobj = $(patsubst %.c,%.o,$(filter %.c,$(TC_SYSV)))
tc_demobj = $(addsuffix .o,$(DEMOS))
tc_demo_exe = $(addsuffix .exe,$(DEMOS))
tc_demo_src = $(addsuffix .c,$(DEMOS))
configs = $(addprefix conf_,$(PLATFORMS))

.PHONY:	clean all archives $(PLATFORMS) $(configs)

.SUFFIXES: .lib

.lib.h:
	$(DCSIMDIR)/splitlib -h $*.lib

.lib.c:
	$(DCSIMDIR)/splitlib -c -x $(CONFIG) $*.lib

# Note: the .linux_conf prerequisite ensures that a valid linux version of
# the config header is created before the rest of the demos are built.
all:	$(DCSIMDIR)/splitlib .linux_conf $(DEMOS)

$(DCSIMDIR)/splitlib: $(DCSIMDIR)/splitlib.c
	cd $(DCSIMDIR); $(CC) -o splitlib splitlib.c

archive_all = $(tc_hdrs) $(tc_cfiles) $(tc_demo_src) \
		$(TC_SYSV) $(TC_BC) Makefile makefile.* README*
archive_tools = $(DCSIMDIR)/splitlib.c \
		$(configs) $(addprefix mkmf_,$(PLATFORMS))
# Don't mention the sample source in the following: it is processed separately
# before adding to the archive.
archive_linux = $(tc_hdrs) $(tc_cfiles) \
		$(TC_SYSV) makefile.linux README README.linux
archive_solaris = $(tc_hdrs) $(tc_cfiles) \
		$(TC_SYSV) makefile.solaris README README.solaris
archive_bc = $(tc_hdrs) $(tc_cfiles) \
		$(TC_BC) makefile.bc README README.bc


archives:	$(DCSIMDIR)/splitlib $(PLATFORMS)
	tar cf $(LIBOUT)/tc_all.tar $(archive_all) $(archive_tools)
	zip $(LIBOUT)/tc_all.zip $(archive_all) $(archive_tools)
	

#--------------------------------------------------
# Build deliverables for each platform.
# Add new targets here, depending on whether a .tar or a .zip
# archive is to be created.  Specify the archive contents by creating
# and archive_<platform> variable as above.
linux solaris:	% : conf_%
	cd $(TMPOUT); rm -rf *; mkdir dm
	rm -f makefile.$@
	./mkmf_$@ >makefile.$@
	cp $(archive_$@) $(TMPOUT)/dm
	for i in $(tc_demo_src); do $(DCSIMDIR)/splitlib -c $$i >$(TMPOUT)/dm/$$i; done
	cd $(TMPOUT)/dm; for i in *; do \
		tr -d '\015' <$$i >/tmp/split.nodos; \
		cp /tmp/split.nodos $$i; \
		done
	cd $(TMPOUT); tar cf ../$(LIBOUT)/tc_$@.tar dm

bc:		% : conf_%
	cd $(TMPOUT); rm -rf *
	rm -f makefile.$@
	./mkmf_$@ >makefile.$@
	cp $(archive_$@) $(TMPOUT)
	for i in $(tc_demo_src); do $(DCSIMDIR)/splitlib -c $$i >$(TMPOUT)/$$i; done
	cd $(TMPOUT); for i in *; do \
		../$(DCSIMDIR)/splitlib -d $$i >/tmp/split.dos; \
		cp /tmp/split.dos $$i; \
		done
	cd $(TMPOUT); zip ../$(LIBOUT)/tc_$@.zip *

#--------------------------------------------------

# Make the customized tc_conf.h file for each platform.  Expects a
# script called conf_<platform> to exist, which takes the existing
# tc_conf.h file and edits it appropriately.  1st script parameter
# is the name of the configuration header file.
$(configs):
	$(DCSIMDIR)/splitlib -h $(CONFIG_LIB)
	./$@ $(CONFIG)

.linux_conf:	$(CONFIG)
	$(DCSIMDIR)/splitlib -h $(CONFIG_LIB)
	./conf_linux $(CONFIG)
	touch .linux_conf
	

$(DEMOS):	% : %.o $(tc_othobj) $(tc_objs)
	$(CC) -o $@ $(LDFLAGS) $< $(tc_othobj) $($@)


$(tc_demobj):	%.o : %.c $(tc_hdrs)

$(tc_hdrs):	%.h : %.lib

$(tc_cfiles):	%.c : %.lib

$(tc_objs):	$(tc_hdrs)

tc.o:		tc.c tc.h $(CONFIG) tc_defs.h
tc_sysv.o:	tc_sysv.c tc.h $(CONFIG) tc_defs.h


clean:
	rm -rf *.o $(DEMOS) $(tc_cfiles) $(tc_hdrs) archive
