# Makefile for C++, Flex, Bison applications.
# Works with gmake.

# Commands:
CC = gcc
CPP = g++
LEX = flex
YAC = bison
LD = g++
TAR = tar
RM = rm

# Command Flags:
LDFLAGS =
CFLAGS =
CPPFLAGS = -O3
LEXFLAGS = -t -s
YACFLAGS = -d

#####################################################################
# Recipes:

# This line makes Solaris make forget its hopeless built-in recipes
.SUFFIXES:

# Even so, it is not possible to get Solaris make to accept
# a working default rule for making a final executable. (It doesn't
# have a $^ dynamic macro.)  Use 'gmake' instead!



# Recipes for Compilation:

# Procude an executable from a list of .o files, having the same name
# as the first .o dependency
%:	%.o
	$(LD) $(LDFLAGS) -o $@ $^

# Compile a .c file to .o form
%.o:	%.c
	$(CC) $(CFLAGS) -c -o $@ $<

# Compile a .cpp file to .o form
%.o:	%.cpp
	$(CPP) $(CPPFLAGS) -c -o $@ $<

# Produce a .cpp file given a flex source file (.l)
%.cpp:	%.l
	$(LEX) $(LEXFLAGS) $< >$@

# Guide bison to produce a .cpp, not a .c, from a .y
# If we tried to name the result xxx.cpp directly, the .h file
# name would be garbled.
%.tab.cpp %.tab.h:	%.y
	$(YAC) $(YACFLAGS) -o$*.tab.c $<
	$(RM) -f $*.tab.cpp
	mv $*.tab.c $*.tab.cpp

# Produce a .d dependency file (a gmake include file listing all
# current local includes) for a .cpp source file
%.d:	%.cpp
	$(SHELL) -ec '$(CPP) $(CPPFLAGS) -MM $< \
	| sed '\''s/$*\.o/& $@/'\'' >$@'




# Recipes for Listings:

# Print a listing to a file under Linux

# ASCII ".txt" files
%.ps:	%.txt
	a2ps -r --columns=2 -C --chars-per-line=85 --tabsize=4 -b --output=- \
		$< >$@

# No extension is assumed to be ASCII
%.ps:	%
	a2ps -r --columns=2 -C --chars-per-line=85 --tabsize=4 -b --output=- \
		$< >$@

# ".cpp" listings
%_cpp.ps:	%.cpp
	a2ps -r --columns=2 -C --chars-per-line=85 --tabsize=4 -b --output=- \
		$< >$@

# ".h" header files
%_h.ps:	%.h
	a2ps -r --columns=2 -C --chars-per-line=85 --tabsize=4 -b --output=- \
		$< >$@

# ".l" flex files
%_l.ps:	%.l
	a2ps -r --columns=2 -C --chars-per-line=85 --tabsize=4 -b --output=- \
		$< >$@

# ".y" bison files
%_y.ps:	%.y
	a2ps -r --columns=2 -C --chars-per-line=85 --tabsize=4 -b --output=- \
		$< >$@


# Convert a .ps listing to .pdf
%.pdf:	%.ps
	ps2pdf $<

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

# Dependencies:

# Sources and headers for the main application. The first source listed
# must be the name of the final executable.
cppsources = main.cpp
headers =

# Executables:
# FIRST RULE = Default target
main:	$(cppsources:.cpp=.o) simple.o simple.tab.o

# Force main.o to be compiled every time, since it encompasses a date and
# time stamp.
main.o:	FORCE

# Rules for all the other .o files generated from .cpp ones
# are all included automatically below in the include statement.

# Flex and bison dependencies
simple.cpp:	simple.l simple.tab.h
simple.tab.cpp simple.tab.h:	simple.y

# Modules:

# The module dependencies are generated automatically to insure that the
# dependent header files are always up-to-date.  The header dependencies
# for %.cpp are stored in file %.d, which is re-generated whenever this
# list could have changed.  All of these .d files are included here.
# Each .d file has a dependency like "main.o main.d:  main.cpp main.h".
include $(cppsources:.cpp=.d)



# pseudo-targets
clean:	FORCE
	$(RM) -f simple.cpp *.o *.d *.ps *.pdf *.tab.*

archive:	FORCE
	$(RM) -f simple.tgz
	$(TAR) czf simple.tgz makefile *.h *.cpp *.l *.y *.txt


printall:	$(cppsources:.cpp=_cpp.ps) $(headers:.h=_h.ps) simple_l.ps simple_y.ps makefile.ps FORCE

# Rules to form postscript listing files
$(cppsources:.cpp=_cpp.ps):	%_cpp.ps:	%.cpp
$(headers:.h=_h.ps):	%_h.ps:	%.h
makefile.ps:	makefile
simple_l.ps:	simple.l
simple_y.ps:	simple.y

# A phoney target to force activation of some rules
FORCE:
