##
## Makefile for CCCC - a C and C++ Code Counter
##
## derived from an original makefile generated by the pccts genmk utility
##

## see lower on this page for a description of what the CONF variable does
## for the moment we are just looking to see if we can set it to an
## appropriate value

ifeq "$(CONF)" ""
CONF=DJGPP
endif

ifeq "$(OSTYPE)" "Linux"
CONF=LINUX
endif

ifeq "$(OSTYPE)" "OSF"
CONF=OSF
endif



## the sections below configure the make for the various machines
## which I do builds on
##
## each stanza is gated on a value of the variable CONF
## note that the sections mix freely differences due to the nature of
## the operating system and differences due to the configuration of the
## particular machine in use
## 
## the first stanza (which is selected if the CONF variable is empty)
## contains a template of all of the definitions which will be required

ifeq "$(CONF)" ""

## where to find components of PCCTS
PCCTS =          ## the root directory where PCCTS is installed
PCCTS_H =        ## the directory where PCCTS support code is
PCCTS_BIN =      ## the directory where the antlr and dlg binaries are

## compiler to use and associated flags 
CCC =		 ## C++ compiler
LD = 		 ## linker
CFLAGS =	 ## compiler flags
LDFLAGS = 	 ## linker flags
CPPEXT =	 ## the extension on C++ files generate by PCCTS

COPY = 		 ## the operating system command for copying a file
CCCC_BIN =       ## the name of the cccc binary
INSTALL_BINDIR = ## the location where the binary is to be installed
INSTALL_LIBDIR = ## the location where the .dat files are to be installed
endif

ifeq "$(CONF)" "LINUX"

## when I packaged PCCTS for Linux, I made it install into /usr/bin and 
## /usr/lib, but now I prefer to run it from under the directory where I
## installed the source distribution
## the binaries are not on my path, but why would I want to run them 
## from the command line anyway
PCCTS =         /usr/local/src/pccts
PCCTS_H =       $(PCCTS)/h
PCCTS_BIN =     $(PCCTS)/bin

## using the GNU C++ compiler
## we need working templates - I use version 2.7.2, I am not sure whether
## versions earlier than 2.7 are OK
CCC=g++
LD=g++ 
CFLAGS =	-g -I/usr/include/g++-include -I. -I$(PCCTS_H) 
LDFLAGS =	-g -static
CPPEXT=cpp

COPY = 		 cp
CCCC_BIN =       cccc
INSTALL_BINDIR = /usr/local/bin
INSTALL_LIBDIR = /usr/local/lib/cccc

endif

ifeq "$(CONF)" "DJGPP"

PCCTS =         c:/pccts
PCCTS_H =       $(PCCTS)/h
PCCTS_BIN =     $(PCCTS)/bin

## using the DJGPP port of GNU C++ to the DPMI 32 bit DOS environment
## NB binaries generated using this compiler WILL NOT WORK unless
## a suitable DPMI server is present - WfW 3.11, WinNT, Win95 and OS/2
## should all provide the right facilities in their respective DOS boxes,
## while recent versions of Linux/DosEmu may be OK (but why wouldn't you
## use the Linux version)
## NB Linux seems to give excellent protection to prevent runaway processes
## compromising the stability of the system - the same cannot be said
## of Windows (WfW 3.11 at least), where bugs in CCCC.EXE have been known
## to crash program manager or cause reboots of the whole machine
## ****SO PLEASE SAVE YOUR WORK IN ALL APPLICATIONS BEFORE RUNNING CCCC.EXE****
## ****SO PLEASE SAVE YOUR WORK IN ALL APPLICATIONS BEFORE RUNNING CCCC.EXE****
## ****SO PLEASE SAVE YOUR WORK IN ALL APPLICATIONS BEFORE RUNNING CCCC.EXE****
## ****SO PLEASE SAVE YOUR WORK IN ALL APPLICATIONS BEFORE RUNNING CCCC.EXE****
## ****SO PLEASE SAVE YOUR WORK IN ALL APPLICATIONS BEFORE RUNNING CCCC.EXE****
## consider yourself warned!!!
CCC=gcc
LD=gxx
CFLAGS =        -DPC -I$(PCCTS_H) 
LDFLAGS =       -static
CPPEXT=cpp

COPY = 		 copy
CCCC_BIN =       cccc.exe
INSTALL_BINDIR = c:\cccc
INSTALL_LIBDIR = c:\cccc

endif

ifeq "$(CONF)" "OSF"

PCCTS =         /iocs3/pccts
PCCTS_H =       $(PCCTS)
PCCTS_BIN =     /usr/local/bin

CCC=cxx -x cxx -define_templates
LD=cxx
CFLAGS =	-g -I. -I$(PCCTS_H) -DOSF_TEMPLATES -DEXPAND_TEMPLATES -nocleanup
LDFLAGS =	-g 

## the version of PCCTS on this machine is configured to generate C++ 
## implementation files with the extension cxx
CPPEXT=cxx

COPY = 		 cp
CCCC_BIN =       cccc
INSTALL_BINDIR = /usr/local/bin
INSTALL_LIBDIR = /usr/local/lib/cccc


endif


## locations and flags for antlr and dlg (don't change the flags)
ANTLR =		$(PCCTS_BIN)/antlr
DLG =		$(PCCTS_BIN)/dlg
AFLAGS =	-CC -gd -ge -gt -gh -rl 10000 
DFLAGS =	-C2 -i -CC 


## list of files generated by the PCCTS utilities
ANTLR_SPAWN =   cccc.$(CPPEXT) Parser.$(CPPEXT) Parser.h tokens.h parser.dlg
DLG_SPAWN =     DLGLexer.$(CPPEXT) DLGLexer.h

## the source files of the project itself
USR_G =		cccc.g

USR_C =		ccccmain.cc cccc_ast.cc cccc_tok.cc cccc_met.cc cccc_utl.cc \
		cccc_db.cc cccc_stg.cc cccc_htm.cc cccc_tbl.cc \
		cccc_new.cc 

USR_H =		cccc.h cccc_ast.h cccc_tok.h cccc_met.h cccc_utl.h \
			cccc_db.h cccc_stg.h cccc_htm.h cccc_tbl.h

## configuration/runtime data files
USR_DAT = 	cccc_tmt.dat cccc_inf.dat cccc_met.dat

## documentation 
USR_TXT =	readme.txt

## all source files
USR_SOURCE = 	makefile $(USR_G) $(USR_H) $(USR_C) $(USR_DAT) $(USR_TXT)

## the final executable is linked from 3 groups of object files:

# object files compiled from PCCTS support code which does not change
PCCTS_OBJ =	AParser.o DLexerBase.o ASTBase.o PCCTSAST.o ATokenBuffer.o 

# object files compiled from C++ files generated by anltr and dlg
SPAWN_OBJ =     cccc.o DLGLexer.o Parser.o

# object files compiled from .cc files which are part of the cccc source
USR_OBJ =	ccccmain.o cccc_utl.o cccc_stg.o cccc_db.o cccc_met.o \
		cccc_htm.o cccc_ast.o cccc_tok.o cccc_tbl.o cccc_new.o

ALL_OBJ = $(SPAWN_OBJ) $(USR_OBJ) $(PCCTS_OBJ) 

VPATH = $(PCCTS_H)


all: $(USR_G) $(ANLTR_SPAWN) $(DLG_SPAWN) $(USR_H) $(USR_C) cccc


cccc : $(ALL_OBJ)
	$(LD) -o cccc $(LDFLAGS) $(ALL_OBJ) $(LD_EXTRA_LIBS)

$(USR_OBJ): $(USR_H) tokens.h Parser.h DLGLexer.h

.SUFFIXES: .cc .o .cpp .cxx 


.cc.o:
	$(CCC) -c $(CFLAGS) -o $*.o $<

.cpp.o:
	$(CCC) -c $(CFLAGS) -o $*.o $<

.cxx.o:
	$(CCC) -c $(CFLAGS) -o $*.o $<


ifneq "$(PCCTS_BIN)" ""
## the rule for running the PCCTS tools to regenerate the C++ files
## which implement the parser and lexical analyser
## notice that this rule can be supressed by not defining the symbol 
## $(PCCTS_BIN) which tells make where to find the binaries of the PCCTS tools
## this means that you can build cccc even if you haven't been able to 
## build PCCTS, although you do need the support files in $(PCCTS_H)
$(ANTLR_SPAWN) $(DLG_SPAWN) : cccc.g
	-rm $(SPAWN_OBJ)
	$(ANTLR) $(AFLAGS) cccc.g
	$(DLG) $(DFLAGS) parser.dlg
endif

# touch enables us to mark everything up to date to avoid enormous 
# recompilations (particularly after checking everything in and out of RCS)

touch:
	touch cccc.g
	touch *.cpp
	touch *.cxx
	touch *.cc
	touch *.h
	touch *.o
	touch cccc

clean:
	rm -f *~ *.o core

ci:
	-ci $(CI_FLAGS) $(USR_SOURCE)

co:
	co -l $(USR_SOURCE)

cico: ci co


TODAY:=$(shell date +%y%m%d)

## part of my backup target copies all useful files to a new directory on
## my MS/DOS C: drive so that I can attempt a build with DJGPP

backup: copy_to_dos
	-tar czvf sr$(TODAY).tgz  *.g *.cc *.h makefile *.htm *.dat *.txt 
	-tar czvf rc$(TODAY).tgz  RCS/*,v 
	cp *$(TODAY).tgz /mnt/floppy

DOSDIR:=/mnt/dosc/cccc/$(TODAY)
copy_to_dos:
	-mkdir $(DOSDIR) 
	-cp $(USR_SOURCE) $(DOSDIR)


## installation target
install :
	$(COPY) $(CCCC_BIN) $(INSTALL_BINDIR)
	-mkdir $(INSTALL_LIBDIR)
	$(COPY) *.dat $(INSTALL_LIBDIR)


## distribution archives
VER = 204

unix_archive :
	strip cccc
	tar czvf cccc_$(VER).tar.gz $(USR_SOURCE) cccc

dos_archive :
	zip -k cccc_$(VER).zip $(USR_SOURCE) cccc.exe

## libcccc.a is not used in building the final binary, but it helps when
## making test rigs
library:
	@make -k $(USR_O)
	ar r libcccc.a cccc*.o
	ar d libcccc.a ccccmain.o

## this cross-reference report is useful for finding unreferenced rules
xref: 
	antlr -CC -gt -cr -o /tmp cccc.g > cccc.xref
	grep "{ }" cccc.xref


## the linking rules include the undefined variable $(LD_EXTRA_LIBS)
## this allows us to include any arbitrary extra libraries in the link
## overriding the default implementations of library functions
## one area where this is useful is in linking with special debugging
## versions of the malloc library

## Electric Fence by Bruce Perens, 
## available from ftp:://sunsite.unc.edu/pub/Linux/devel/lang/c/
cccc.ef : cccc
	-mv -f cccc cccc.old
	make LD_EXTRA_LIBS=-lefence
	-mv -f cccc cccc.ef
	-mv cccc.old cccc

## Dmalloc by Gray Watson, available from ftp://ftp.letters.com/src/dmalloc
cccc.dm :
	-mv -f cccc cccc.old
	make LD_EXTRA_LIBS=-ldmalloc
	-mv -f cccc cccc.dm
	-mv cccc.old cccc

## GNU malloc
## (I don't think this is any different from the malloc in Linux libc.a)
cccc.gm :
	-mv -f cccc cccc.old
	make LD_EXTRA_LIBS=/usr/local/lib/libmalloc.a
	-mv -f cccc cccc.gm
	-mv cccc.old cccc















