# Makefile for TALC
#
# This file is considerable cleaned up from initial versions written by Dave.
# Should old stuff in the initial makefile be needed, retrieve version 1.6.
# NG 22 Dec 97
#
# Next major cleanup by Dan in Version 1.36 -- retrieve earlier version for
# kml-related targets.
# THIS FILE NOW RELIES VERY HEAVILY ON GNUMAKE! 
# DG 12 Jan 99

# Now in Version 1.37 we can compile to native.	 To do native profiling, must
# be under UNIX (due to limitation of caml).

# To build with profiling, do: make <target> PROFILE=X
# This will strip out line directives in lex/yacc files, due to an ocamlcp
# bug.

#################### Configuration
# N.B. Requires MASM 6.11 and Visual C++ to build the runtime

# note: native/profile combination is not supported under Windows as of 
#	ocaml version 2.01

ifdef NATIVE
OCAMLC	= ocamlopt
OCAMLI	= ocamlopt
OBJSUFF = cmx
LIBSUFF = cmxa
   ifdef PROFILE
      FLAGS = -p -w s
   else
      FLAGS = -w s
   endif
else
OBJSUFF = cmo
OCAMLI = ocamlc # cannot use ocamlcp for some reason
LIBSUFF = cma
   ifdef PROFILE
      OCAMLC = ocamlcp
      FLAGS  = -w s
   else
      OCAMLC = ocamlc
      FLAGS  = -w s
   endif
endif

OCAMLLEX  = ocamllex
OCAMLYACC = ocamlyacc -v
COMPFLAGS = $(INCLUDES) $(FLAGS)
LINKFLAGS = $(COMPFLAGS)
TARGETDIR = build

######################################################################
# O/S Stuff

# NG: This is a hack and probably ought to be replaced by something more
#     robust.  To determine the O/S we see if the environment variable WINDIR
#     is defined, if so, we assume Win32, if not, we assume a *nix.

ifdef WINDIR

# Assume Windows NT/98/95/3.x
O=obj
A=lib
ASM=ml /nologo /coff
CC=cl /nologo
EMACS=emacs

else

# Assume some kind of Unix
O=o
A=a
CC=gcc -Wall -O2 -ggdb
EMACS=emacs-19	# CUCS has 20 as default

endif

######################################################################

all: talc popcorn scheme

world: all runtime scheme_runtime doc/tal.elc

#################### Util

UTIL_BASE = utilities splay dict set xarray stringchan binout bitmatrix \
	    numtypes
COMPUTIL_BASE = identifier

UTIL	 = $(addprefix util/,	  $(addsuffix .$(OBJSUFF), $(UTIL_BASE)))
COMPUTIL = $(addprefix computil/, $(addsuffix .$(OBJSUFF), $(COMPUTIL_BASE)))

$(TARGETDIR)/util.$(LIBSUFF):  $(COMPUTIL) $(UTIL)
	$(OCAMLC) $(LINKFLAGS) -a -o $@ $^

################### Gcd
 # this is the top-level directory, but we don't include talc.ml since it
 # isn't generic.

GCD_BASE = lineno gcdfec gcdfe gcd

GCDLIB = $(addprefix toplevel/, $(addsuffix .$(OBJSUFF), $(GCD_BASE)))

$(TARGETDIR)/gcd.$(LIBSUFF): $(GCDLIB)
	$(OCAMLC) $(LINKFLAGS) -a -o $@ $^

#################### Tal

TALLIB_BASE = tal talctxt talpp talout

TALLIB = $(addprefix talx86/, $(addsuffix .$(OBJSUFF), $(TALLIB_BASE)))

$(TARGETDIR)/tal.$(LIBSUFF): $(TALLIB)
	$(OCAMLC) $(LINKFLAGS) -a -o $@ $^

#################### Talcomp

TALCOMPLIB_BASE = talparser tallex talcon talverify tallinkchk objfile \
		talasmx86 talasm coff elf talbe	  

TALCOMPLIB = $(addprefix talx86/, $(addsuffix .$(OBJSUFF), $(TALCOMPLIB_BASE)))

$(TARGETDIR)/talcomp.$(LIBSUFF): $(TALCOMPLIB)
	$(OCAMLC) $(LINKFLAGS) -a -o $@ $^

#################### Cfg

CFG_BASE = talutil cfg cfginstr cfgliveness cfgopt

CFG = $(addprefix cfg/, $(addsuffix .$(OBJSUFF), $(CFG_BASE)))

$(TARGETDIR)/cfg.$(LIBSUFF): $(CFG)
	$(OCAMLC) $(LINKFLAGS) -a -o $@ $^

#################### Regalloc

REGALLOC_BASE = regifg regrewrite regalloc

REGALLOC = $(addprefix regalloc/, $(addsuffix .$(OBJSUFF), $(REGALLOC_BASE)))

$(TARGETDIR)/regalloc.$(LIBSUFF): $(REGALLOC)
	$(OCAMLC) $(LINKFLAGS) -a -o $@ $^

REGOBJS = \
   $(addprefix $(TARGETDIR)/, $(addsuffix .$(LIBSUFF), util tal)) \
   $(addprefix talx86/, $(addsuffix .$(OBJSUFF),       talcon talverify)) \
   $(addprefix $(TARGETDIR)/, $(addsuffix .$(LIBSUFF), cfg regalloc)) \

#################### talc.exe

TALCOBJS = $(addprefix $(TARGETDIR)/, $(addsuffix .$(LIBSUFF), \
	     util tal gcd talcomp)) \
	    toplevel/talc.$(OBJSUFF)

talc: $(TARGETDIR)/talc.exe

$(TARGETDIR)/talc.exe: $(TALCOBJS)
	$(OCAMLC) $(LINKFLAGS) -o $@ $^ 

#################### Popcorn

POPCORN_BASE = poperr popsyntax popparse poplex poptype poppeep \
	       popcompile popcorn

POPOBJS = $(addprefix $(TARGETDIR)/, $(addsuffix .$(LIBSUFF), util tal gcd)) \
	  $(addprefix talx86/, talcon.$(OBJSUFF)) \
	  $(addprefix popcorn/, $(addsuffix .$(OBJSUFF), $(POPCORN_BASE)))

popcorn: $(TARGETDIR)/popcorn.exe

$(TARGETDIR)/popcorn.exe: $(POPOBJS)
	$(OCAMLC) $(LINKFLAGS) -o $@ $^

#################### Scheme

SCHEME_BASE = sast sil sparse slex scomp scheme

SCHEMEOBJS= $(addprefix $(TARGETDIR)/, $(addsuffix .$(LIBSUFF), util tal gcd)) \
	    $(addprefix scheme/, $(addsuffix .$(OBJSUFF), $(SCHEME_BASE)))

scheme: $(TARGETDIR)/scheme.exe

$(TARGETDIR)/scheme.exe: $(SCHEMEOBJS) 
	$(OCAMLC) $(LINKFLAGS) -o $@ $^

#################### Runtimes

RUNTIME_BASE = tal_start tal_util stdlib pop_runtime cyclonelib

RUNTIME=$(addprefix runtime/, gc.$(A) $(addsuffix .$(O), $(RUNTIME_BASE)))

runtime: $(RUNTIME)

SCHEME_RUNTIME = scheme/sclib.$(O)

scheme_runtime: $(SCHEME_RUNTIME)

######################################################################
# Templates

%.ml: %.mll
	$(OCAMLLEX) $< 

%.ml %.mli: %.mly
	$(OCAMLYACC) $< 

%.cmi: %.mli
	$(OCAMLI) -c $(COMPFLAGS) $<

%.cmo %.cmx: %.ml
	$(OCAMLC) -c $(COMPFLAGS) $<

%.obj: %.asm
	$(ASM) /Fo$@ /c $< 

%.o: %.tal $(TARGETDIR)/talc.exe
	$(TARGETDIR)/talc.exe -c --TALC --elf $<

%.obj: %.c
	$(CC) /Fo$@ /c $<

%.o: %.c
	$(CC) -c -o $@ $<

%.elc: %.el
	$(EMACS) -batch -f batch-byte-compile $<

######################################################################
# Administration

DIRS = util computil talx86 runtime toplevel popcorn scheme cfg regalloc

INCLUDES = $(patsubst %, -I %, $(DIRS))

SOURCES = $(addsuffix /*.ml,  $(DIRS)) \
	  $(addsuffix /*.mli, $(DIRS))

LEXFILES  = toplevel/lineno talx86/tallex popcorn/poplex scheme/slex
YACCFILES = talx86/talparser popcorn/popparse scheme/sparse

GENERATINGFILES = $(addsuffix .mll, $(LEXFILES))\
		  $(addsuffix .mly, $(YACCFILES))

GENFILES = $(addsuffix .ml,  $(LEXFILES) $(YACCFILES)) \
	   $(addsuffix .mli, $(YACCFILES))

TMP_SUFF = cmo cmi cmx obj o output exe

clean:
	for i in $(DIRS); do \
	  (cd $$i; rm -f *~ $(addprefix *., $(TMP_SUFF))) \
	done
	cd $(TARGETDIR); rm -f *.exe *.cma *.cmxa *.lib
	rm -f $(GENFILES) *~
	cd tests/popcorn; make clean
	cd tests/cyclone; make clean
	cd tests/scheme;  rm -f *.obj *.o *.lst *.exe *.tal *.tali *~
	cd tests/talx86;  rm -f *.obj *.o *.lst *.exe *~
	cd doc;		  rm -f *.aux *.dvi *.log *.elc

depend: $(GENFILES)
	ocamldep $(INCLUDES) $(SOURCES) > .depend

include .depend

# This is stuff for stripping out the ^M from NT files shipped to UNIX.
# It is a brittle script (if 2 people use it at the same time then you
# could corrupt your data).  Use at your own risk.

strip:
	for i in $(SOURCES); do ./stripm $$i; done
	cd runtime; for i in *.inc *.c *.asm *.tali; do ../stripm $$i; done
	cd doc; for i in *.tex *.el; do ../stripm $$i; done
	cd tests/popcorn; for i in *.pop; do ../../stripm $$i; done
	cd tests/scheme; for i in *.s *.ss; do ../../stripm $$i; done
	for i in $(GENERATINGFILES); do ./stripm $$i; done
	for i in .depend README INSTALL popcorn/README popcorn/CHANGES.txt \
		 popcorn/TODO talx86/TODO scheme/*.ss; do \
	  ./stripm $$i \
	done

# EOF: Makefile
