# Makefile
#############################################################################
# To compile with the ODBC interface you will need the unixODBC package
# installed (unixODBC-2.2.9 or later on FreeBSD,...) and uncomment the
# following line.
# DB=-DWITH_ODBC -I/usr/local/include -L/usr/local/lib


######## C++ Compiler and linker

#### GCC 2.95 and later

## Uncomment at most one of the following entries!
#  (-O1 is required for some warning invoked by -W, and it is indeed
#  faster than -O0 as of 2001-08-30 on i386-unknown-freebsd4.3.)
# CODE=-DBISON_DEBUG           # for debugging the parsers
# CODE=-g                      # for debugging
# CODE=-O3                     # for fast checking and tracing
# CODE=-O3 -DNDEBUG -g -pg     # for profiling
# CODE=-O3 -DNDEBUG -DTIMERS   # for benchmarks with detailed timing analysis
# CODE=-O3 -DNDEBUG -DHEURISTICSTATS   # for benchmarks with heuristic stats
# CODE=-O3 -DNDEBUG            # for benchmarks and demos
#CODE=-O1 -DCHECK_OPT=3
#CODE=-O3 -DNDEBUG -DCHECK_OPT=3
#CODE=-Wstrict-aliasing=2 -DNDEBUG -g -O2 -fstrict-aliasing

WARN=-Wall -W -Wcast-align -Wcast-qual -Wconversion \
     -Woverloaded-virtual -Wpointer-arith -Wwrite-strings
# -D_GLIBCXX_DEBUG
# -Wold-style-cast -Winline -Weffc++ -Wshadow -Wredundant-decls -Wundef

#GCC=/space/rguenther/install/tmp/bin/g++
#GCC=g++
#GCC=/usr/bin/g++
#GCC=gccvs

CXX=$(GCC) -c -ansi -pedantic  -fno-exceptions $(WARN) $(CODE) $(CODE2) $(DB)
LINK=$(GCC)
LINKFLAGS=-o $@ -lm
LIBS=

#### Sun C++ 5.0
# CXX=/sw/cpp/SUNWspro/bin/CC -c +w2 -O4
# LINK=CC

#### Borland C++ 5.0

# CXX=bcc32 -c -P -4 -Ix:\bc5\include
# LINK=tlink

.C.o:
	$(CXX) $< -o $@

######## lex and yacc

# BUG-FIX: lex[SunOS 4.1.3] creates lots of C code that make gcc (C++ mode) 
#          choke.
LEX=flex

# BUG-FIX: yacc[SunOS 4.1.3] creates non-standard C code by providing
#          wrong prototypes for malloc() and realloc(). 
# -y makes bison filename compatible with yacc
YACC=bison -y

######## jade

JADE=jade

# STYLESHEETS=/usr/share/sgml/docbook/docbook-dsssl-stylesheets-1.64
STYLESHEETS=/usr/local/share/sgml/docbook/dsssl/modular/
# Stylesheet for HTML
HTMLSTYLE=$(STYLESHEETS)/html/docbook.dsl
# Additional flags passed to HTML stylesheet
JADE_HTMLFLAGS=-V nochunks

# Stylesheet for TeX
TEXSTYLE=$(STYLESHEETS)/print/docbook.dsl
# Additional flags passed to TeX stylesheet
JADE_TEXFLAGS=

DLVWEBMANUAL=/web/proj/dlv/man/dlv.html
DLVKWEBMANUAL=/web/proj/dlv/man/dlvk.html

#############################################################################
# It should not be necessary to apply changes to anything below this...     #

########## dl itself 

DLVBINARY="dl"

all: buildinfo dl

buildinfo:
	printf "Building with ${GCC} CODE=${CODE} CODE2=${CODE2}\n"

release: buildinfo dl
	ls -la ${DLVBINARY}
	strip ${DLVBINARY}
	ls -la ${DLVBINARY}
	if [ "`./${DLVBINARY} -v | egrep '2.95.[234]'`" = "" ]; then \
	  echo ""; \
	  echo "We are supposed to use 2.95.[234], aren't we?"; \
	  exit 1; \
	fi
	if [ "`./${DLVBINARY} -v | grep 'build BEN/'`" = "" ]; then \
	  echo ""; \
	  echo "We are supposed to use release BEN versions, aren't we?"; \
	  exit 1; \
	fi

## Invididual modules and special development targets

MODULES=dl.o satz.o scanner.o safety.o rewrite.o rewrite-magic.o \
	grounding.o grounding_sub.o grounding-prop.o generate.o check.o odbc.o stats.o \
	diag_scanner.o diag.o sql_scanner.o sql.o plan_scanner.o plan.o \
	inheritance.o

dl: $(MODULES)
	# Link statically, unless we are building with the ODBC interface
	# or running on FreeBSD or Darwin/MacOS X.
	L=$(LIBS); \
	if [ x"$(DB)"x != xx ]; then \
	  L="$${L} $(DB) -lodbc"; \
	  if [ `uname -s` = "FreeBSD" ]; then \
	    L="$${L} -liconv"; \
	  fi ; \
	elif [ `uname -s` != "Darwin" ] \
	  && [ "`uname -sr | sed -e 's/\..*//'`" != "FreeBSD 6" ]; then \
	  L="$${L} "; \
	fi ; \
	echo "Linking with additional options: $${L}" ; \
	$(LINK) $(MODULES) $(LINKFLAGS) $${L}

# Link without checking any dependencies.
linkonly:
	$(LINK) $(MODULES) $(LINKFLAGS) -o dl 


dl.h: dltypes.h interpret.h ginterpret.h
	touch dl.h

dltypes.h: builtin.h names.h literal.h rule.h grule.h program.h
	touch dltypes.h

interpret.h: atomset.h
	touch interpret.h

generate.h: indent.h timer.h generate-counters.h generate-pt.h
	touch generate.h

ginterpret.h: gatomset.h
	touch ginterpret.h

stats.h: timer.h
	touch stats.h

inheritance.h: dl.h
	touch inheritance.h

dl.o: dl.C LICENSE.h parser2.c dl.h depgraph.h stats.h odbc.h grounding.h generate.h diag.h sql.h

satz.o: satz.C dl.h

safety.o: safety.C dl.h 

rewrite.o: rewrite.C dl.h

rewrite-magic.o: rewrite-magic.C dl.h

grounding.o: grounding.C dl.h depgraph.h grounding.h grounding-body.h grounding-dictionary.h builtin.h

grounding_sub.o: grounding_sub.C dl.h depgraph.h grounding.h grounding-body.h grounding-dictionary.h builtin.h

grounding-prop.o: grounding-prop.C dl.h

generate.o: generate.C dl.h check.h depgraph.h generate.h generate-pt.h

check.o: check.C dl.h check.h depgraph.h indent.h generate.h

odbc.o: odbc.C odbc.h

stats.o: stats.C dl.h stats.h

diag.o: diag.C diag_parser2.c dl.h diag.h generate.h

sql.o: sql.C sql_parser2.c dl.h sql.h

plan.o: plan.C plan_parser2.c dl.h depgraph.h plan.h generate.h

parser2.o: parser2.c builtin.h

inheritance.o: inheritance.C inheritance.h dl.h

LICENSE.h: LICENSE
	sed -e 's#"#\\"#g' -e 's#\(.*\)#"\1\\n"#g' LICENSE > $@

## scanner & parser

parser.h: parser.y  dl.h
	$(YACC) -d -o parser.c parser.y
	rm -f parser.c

parser2.c: parser.y  dl.h
	$(YACC) -o parser.tmp parser.y
	sed -e 's#parse error#syntax error#g' parser.tmp > parser2.c
	rm -f parser.tmp

scanner2.c: scanner.l  parser.h dl.h
	$(LEX) $(LFLAGS) -o$@ scanner.l

scanner.o: scanner.C  scanner2.c
	$(CXX) scanner.C -o $@


diag_parser.h: diag_parser.y  dl.h diag.h
	$(YACC) -p diagyy -d -o diag_parser.c diag_parser.y
	rm -f diag_parser.c

diag_parser2.c: diag_parser.y  dl.h diag.h
	$(YACC) -p diagyy -o diag_parser.tmp diag_parser.y
	sed -e 's#parse error#syntax error#g' diag_parser.tmp > diag_parser2.c
	rm -f diag_parser.tmp

diag_scanner2.c: diag_scanner.l  diag_parser.h dl.h diag.h
	$(LEX) $(LFLAGS) -Pdiagyy -o$@ diag_scanner.l

diag_scanner.o: diag_scanner.C  diag_scanner2.c
	$(CXX) diag_scanner.C -o $@


sql_parser.h: sql_parser.y  dl.h sql.h
	$(YACC) -p sqlyy -d -o sql_parser.c sql_parser.y
	rm -f sql_parser.c

sql_parser2.c: sql_parser.y  dl.h sql.h
	$(YACC) -p sqlyy -o sql_parser.tmp sql_parser.y
	sed -e 's#parse error#syntax error#g' sql_parser.tmp > sql_parser2.c
	rm -f sql_parser.tmp

sql_scanner2.c: sql_scanner.l  sql_parser.h  dl.h sql.h
	$(LEX) $(LFLAGS) -Psqlyy -o$@ sql_scanner.l

sql_scanner.o: sql_scanner.C  sql_scanner2.c
	$(CXX) sql_scanner.C -o $@


plan_parser.h: plan_parser.y  dl.h plan.h
	$(YACC) -p planyy -d -o plan_parser.c plan_parser.y
	rm -f plan_parser.c

plan_parser2.c: plan_parser.y  dl.h plan.h
	$(YACC) -p planyy -o plan_parser.tmp plan_parser.y
	sed -e 's#parse error#syntax error#g' plan_parser.tmp > plan_parser2.c
	rm -f plan_parser.tmp

plan_scanner2.c: plan_scanner.l  plan_parser.h dl.h plan.h
	$(LEX) $(LFLAGS) -Pplanyy -o$@ plan_scanner.l

plan_scanner.o: plan_scanner.C  plan_scanner2.c
	$(CXX) plan_scanner.C -o $@

########## Clean

clean.tmp:
	rm -f tmp.* nohup.out
	rm -f core dl.core dlvtests/core dlvtests/dl.core

clean.tex:
	rm -f *.aux
	rm -f *.log
	rm -f *.toc
	rm -f *.bbl
	rm -f *.blg
	rm -f *.ps

clean: clean.tmp clean.tex
	rm -f lex.yy.c
	rm -f y.tab.*
	rm -f dlv.tex dlv.fot dlv.html
	rm -f *.o a.out
	rm -f *.rpo
	rm -f gmon.out
# Win32 (Borland C++)
	rm -f *.obj
	rm -f *.bak
	rm -f *.obr
	rm -f *.~de
	rm -f dl.m?t

distclean: clean
	rm -f dlv.tar.gz
	rm -f *scanner2.c
	rm -f *parser2.c
	rm -f *parser.h
	rm -f *.ps
	rm -f dl dlrdb esql_test
	rm -f LICENSE.h

########## Testing

test:
	if [ -d dlvtests ]; then \
	  if [ -z "${dlv_testee}" ]; then \
	    dlv_testee="`pwd`/dl"; \
	    export dlv_testee; \
	    echo "Setting dlv_testee to $${dlv_testee}"; \
	  fi; \
	  if [ -n "${MAKE}" ]; then \
	    MAKE=${MAKE}; \
	    export MAKE; \
	  fi; \
	  dlvtests/test; \
	else \
	  echo "You need to check out the dlvtests module as a subdirectory of"; \
          echo "(or have an appropriate symlink called dlvtests in) this directory."; \
	fi

########## Packaging 

lexyacc: parser.h parser2.c scanner2.c  diag_parser.h diag_parser2.c diag_scanner2.c  sql_parser.h sql_parser2.c sql_scanner2.c  plan_parser.h plan_parser2.c plan_scanner2.c

tar: lexyacc
	rm -f dlv.tar dlv.tar.gz
	tar cvf dlv.tar Makefile *.C *.c *.h *.y *.l  gui*  *.sgml  README* LICENSE
	gzip dlv.tar

bench-tar: lexyacc tar
	gunzip dlv.tar
	tar uvf dlv.tar dlvbench/*
	gzip dlv.tar

tests-tar: lexyacc tar 
	gunzip dlv.tar
	tar uvf dlv.tar dlvtests/*
	gzip dlv.tar

full-tar: lexyacc tar
	gunzip dlv.tar
	tar uvf dlv.tar dlvbench/* dlvtests/*
	gzip dlv.tar

########## Documentation

dlv.html: dlv.sgml
	$(JADE) $(JADE_HTMLFLAGS) -d $(HTMLSTYLE) -t sgml $? >$@

dlvk.html: dlvk.sgml
	$(JADE) $(JADE_HTMLFLAGS) -d $(HTMLSTYLE) -t sgml $? >$@

dlv.tex: dlv.sgml
	$(JADE) $(JADE_TEXFLAGS) -d $(TEXSTYLE) -t tex $?

dlvk.tex: dlvk.sgml
	$(JADE) $(JADE_TEXFLAGS) -d $(TEXSTYLE) -t tex $?

depgraph.dvi: depgraph.h
	grep -v /////// depgraph.h | promote > tmp.h
	doc++ -o depgraph.tex -p -t tmp.h
	rm -f tmp.h
	latex depgraph.tex

########## Installation

install-web: dlv.html dlvk.html
	sed -e 's/.Revision: \([0-9.]*\) ./\1/' dlv.html > $(DLVWEBMANUAL)
	chgrp datalog $(DLVWEBMANUAL)
	chmod g+w $(DLVWEBMANUAL)
	sed -e 's/.Revision: \([0-9.]*\) ./\1/' dlvk.html > $(DLVKWEBMANUAL)
	chgrp datalog $(DLVKWEBMANUAL)
	chmod g+w $(DLVKWEBMANUAL)

install-release:
	# Below, f is the names of the file itself and l is the link that
	# will point to it.  We first remove the old link and then try to
	# create a new one if possible. 
	if [ -n "${RELEASE}" ]; then \
	  echo "Creating links for release ${RELEASE}:"; \
	  cd /web/proj/dlv; \
	  for p in \
	           powerpc-apple-darwin \
	           sparc-sun-solaris2.9 \
	           i386-unknown-freebsd4.10 \
	           i386-linux-elf-static \
	           cygwin ; \
	  do \
	    f="dlv.$$p:${RELEASE}"; \
	    l="dlv.$$p.bin"; \
	    rm -f "$$l"; \
	    if [ -f "$$f" ]; then \
	      echo "$$f."; \
	      ln -s "$$f" "$$l"; \
	    else \
	      echo "$$f -- NOT FOUND!"; \
	    fi; \
	  done; \
	  if [ -f dlv.cygwin.bin ]; then \
	    mv dlv.cygwin.bin dlv.cygwin.exe; \
	  fi ; \
	fi
