#
# This file is part of Cafesterol.
# Copyright (C) 2007-2010 Xavier Clerc.
#
# Cafesterol is free software; you can redistribute it and/or modify
# it under the terms of the Q Public License v1.0 as published by
# Trolltech (with a change to choice of law).
#
# Cafesterol is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# Q Public License for more details.
#
# You should have received a copy of the Q Public License
# along with this program.  If not, see
# <http://qt.nokia.com/doc/4.0/qpl.html>.
#

include config/Makefile
include stdlib/StdlibModules

OCAMLC=./ocamlc
OCAMLOPT=./ocamlopt
OCAMLJAVA=./ocamljava -java-package 'ocaml.compilers'
COMPFLAGS=-w Ae $(INCLUDES)

BOOTDIR=$(shell pwd)/boot-ocamljava

OTHERLIBS=unix bigarray dbm graph num str systhreads dynlink labltk

INCLUDES=-I utils -I parsing -I typing -I bytecomp -I asmcomp -I javacomp \
         -I driver -I toplevel -I +zip -I +barista

UTILS=utils/misc.cmo utils/tbl.cmo utils/config.cmo \
  utils/clflags.cmo utils/terminfo.cmo utils/ccomp.cmo utils/warnings.cmo \
  utils/consistbl.cmo

OPTUTILS=$(UTILS)

PARSING=parsing/linenum.cmo parsing/location.cmo parsing/longident.cmo \
  parsing/syntaxerr.cmo parsing/parser.cmo \
  parsing/lexer.cmo parsing/parse.cmo parsing/printast.cmo

TYPING=typing/unused_var.cmo typing/ident.cmo typing/path.cmo \
  typing/primitive.cmo typing/types.cmo \
  typing/btype.cmo typing/oprint.cmo \
  typing/subst.cmo typing/predef.cmo \
  typing/datarepr.cmo typing/env.cmo \
  typing/typedtree.cmo typing/ctype.cmo \
  typing/printtyp.cmo typing/includeclass.cmo \
  typing/mtype.cmo typing/includecore.cmo \
  typing/includemod.cmo typing/parmatch.cmo \
  typing/typetexp.cmo typing/stypes.cmo typing/typecore.cmo \
  typing/typedecl.cmo typing/typeclass.cmo \
  typing/typemod.cmo

COMP=bytecomp/lambda.cmo bytecomp/printlambda.cmo \
  bytecomp/typeopt.cmo bytecomp/switch.cmo bytecomp/matching.cmo \
  bytecomp/translobj.cmo bytecomp/translcore.cmo \
  bytecomp/translclass.cmo bytecomp/translmod.cmo \
  bytecomp/simplif.cmo bytecomp/runtimedef.cmo

BYTECOMP=bytecomp/meta.cmo bytecomp/instruct.cmo bytecomp/bytegen.cmo \
  bytecomp/printinstr.cmo bytecomp/opcodes.cmo bytecomp/emitcode.cmo \
  bytecomp/bytesections.cmo bytecomp/dll.cmo bytecomp/symtable.cmo \
  bytecomp/bytelink.cmo bytecomp/bytelibrarian.cmo bytecomp/bytepackager.cmo

ASMCOMP=asmcomp/arch.cmo asmcomp/debuginfo.cmo \
  asmcomp/cmm.cmo asmcomp/printcmm.cmo \
  asmcomp/reg.cmo asmcomp/mach.cmo asmcomp/proc.cmo \
  asmcomp/clambda.cmo asmcomp/compilenv.cmo \
  asmcomp/closure.cmo asmcomp/cmmgen.cmo \
  asmcomp/printmach.cmo asmcomp/selectgen.cmo asmcomp/selection.cmo \
  asmcomp/comballoc.cmo asmcomp/liveness.cmo \
  asmcomp/spill.cmo asmcomp/split.cmo \
  asmcomp/interf.cmo asmcomp/coloring.cmo \
  asmcomp/reloadgen.cmo asmcomp/reload.cmo \
  asmcomp/printlinear.cmo asmcomp/linearize.cmo \
  asmcomp/schedgen.cmo asmcomp/scheduling.cmo \
  asmcomp/emitaux.cmo asmcomp/emit.cmo asmcomp/asmgen.cmo \
  asmcomp/asmlink.cmo asmcomp/asmlibrarian.cmo asmcomp/asmpackager.cmo

JAVACOMP=utils/jclflags.cmo utils/jconfig.cmo utils/jcomp.cmo \
  javacomp/jlambda.cmo javacomp/printjlambda.cmo javacomp/macroinstr.cmo \
  javacomp/printminstr.cmo javacomp/bytecodeutils.cmo \
  javacomp/cadmiumprimitives.cmo javacomp/bytecodeprimitive.cmo \
  javacomp/jcompilenv.cmo javacomp/bytecodegen.cmo javacomp/javalink.cmo \
  javacomp/javalibrarian.cmo javacomp/jclosure.cmo javacomp/javagen.cmo \
  javacomp/javapackager.cmo

DRIVER=driver/pparse.cmo driver/errors.cmo driver/compile.cmo \
  driver/main_args.cmo driver/main.cmo

OPTDRIVER= driver/pparse.cmo driver/opterrors.cmo driver/optcompile.cmo \
  driver/optmain.cmo

JAVADRIVER=driver/pparse.cmo driver/javaerrors.cmo driver/javacompile.cmo \
  driver/javamain.cmo

TOPLEVEL=driver/pparse.cmo driver/errors.cmo driver/compile.cmo \
  toplevel/genprintval.cmo toplevel/toploop.cmo toplevel/trace.cmo \
  toplevel/topdirs.cmo toplevel/scriptloop.cmo toplevel/scriptmain.cmo

TOPOBJS=$(UTILS) $(PARSING) $(TYPING) $(COMP) $(BYTECOMP) $(TOPLEVEL)

COMPOBJS=$(UTILS) $(PARSING) $(TYPING) $(COMP) $(BYTECOMP) $(DRIVER)

JAVAOBJS=$(UTILS) $(PARSING) $(TYPING) $(COMP) $(JAVACOMP) $(JAVADRIVER)

OPTOBJS=$(OPTUTILS) $(PARSING) $(TYPING) $(COMP) $(ASMCOMP) $(OPTDRIVER)


CMO_FILES=asmcomp/debuginfo.cmo $(JAVAOBJS)

CMI_FILES=$(patsubst %.cmo,%.cmi,$(CMO_FILES))

CMX_FILES=$(patsubst %.cmo,%.cmx,$(CMO_FILES))

CMJ_FILES=$(patsubst %.cmo,%.cmj,$(CMO_FILES))

CMA_FILES=bigarray.cma camomile.cma unix.cma zip.cma str.cma baristaLibrary.cma

CMXA_FILES=$(patsubst %.cma,%.cmxa,$(CMA_FILES))

CMJA_FILES=$(patsubst %.cma,%.cmja,$(CMA_FILES))


all: ocamljava ocamljava.opt script stdlib otherlibraries

ocamljava: $(CMI_FILES) $(CMO_FILES)
	$(OCAMLC) -I +zip -I +barista -o ocamljava $(CMA_FILES) $(CMO_FILES)

ocamljava.opt: $(CMI_FILES) $(CMX_FILES)
	$(OCAMLOPT) -I +zip -I +barista -o ocamljava.opt $(CMXA_FILES) $(CMX_FILES)

stdlib: FORCE
	cd stdlib && $(MAKE) -f Makefile-cafesterol all && cd ..

otherlibraries: FORCE
	for i in $(OTHERLIBS); do \
	  (cd otherlibs/$$i && $(MAKE) -f Makefile-cafesterol) || exit $$?; \
	done

install: FORCE
	cp ocamljava ocamljava.opt $(BINDIR)
	cd stdlib && $(MAKE) -f Makefile-cafesterol install && cd ..
	for i in $(OTHERLIBS); do \
	  (cd otherlibs/$$i && $(MAKE) -f Makefile-cafesterol install) || exit $$?; \
	done

script: $(TOPOBJS:.cmo=.cmi) $(TOPOBJS) toplevel/scriptstart.cmo
	$(OCAMLC) -o script $(TOPOBJS) toplevel/scriptstart.cmo

compilers: ocamlc.jar ocamlopt.jar ocamljava.jar

ocamlc.jar: $(COMPOBJS:.cmo=.cmj)
	$(OCAMLJAVA) -o ocamlc.jar $(COMPOBJS:.cmo=.cmj)
	$(OCAMLJAVA) -standalone -o ocamlc-standalone.jar -cadmium-parameter embedded=on $(COMPOBJS:.cmo=.cmj)

ocamlopt.jar: $(OPTOBJS:.cmo=.cmj)
	$(OCAMLJAVA) -o ocamlopt.jar $(OPTOBJS:.cmo=.cmj)
	$(OCAMLJAVA) -standalone -o ocamlopt-standalone.jar -cadmium-parameter embedded=on $(OPTOBJS:.cmo=.cmj)

ocamljava.jar: $(CMI_FILES) $(CMJ_FILES)
	$(OCAMLJAVA) -cadmium-parameter exitStoppingJVM=off -I +zip -I +barista -o ocamljava.jar $(CMJA_FILES) $(CMJ_FILES)
	$(OCAMLJAVA) -standalone -cadmium-parameter exitStoppingJVM=off -cadmium-parameter embedded=on -I +zip -I +barista -o ocamljava-standalone.jar $(CMJA_FILES) $(CMJ_FILES)

install-compilers: FORCE
	cp ocamlc.jar ocamlopt.jar ocamljava.jar $(BINDIR)
	cp ocamlc-standalone.jar ocamlopt-standalone.jar ocamljava-standalone.jar $(BINDIR)

tools: FORCE
	cd debugger && $(MAKE) -f Makefile-cafesterol && cd ..
	cd tools && $(MAKE) -f Makefile-cafesterol && cd ..
	cd ocamldoc && $(MAKE) -f Makefile-cafesterol && cd ..
	cd lex && $(MAKE) -f Makefile-cafesterol && cd ..
	mkdir -p $(BOOTDIR)
	cd ocamlbuild && $(MAKE) INSTALL_BIN=$(BOOTDIR) INSTALL_LIB=$(BOOTDIR) -f Makefile-cafesterol prepare compile install && cd ..
	cd ocamlbuild && $(MAKE) INSTALL_BIN=$(BINDIR) INSTALL_LIB=$(LIBDIR)/ocamlbuild -f Makefile-cafesterol compile restore && cd ..

install-tools: FORCE
	cd debugger && $(MAKE) -f Makefile-cafesterol install && cd ..
	cd tools && $(MAKE) -f Makefile-cafesterol install && cd ..
	cd ocamldoc && $(MAKE) -f Makefile-cafesterol install && cd ..
	cd lex && $(MAKE) -f Makefile-cafesterol install && cd ..
	cd ocamlbuild && $(MAKE) -f Makefile-cafesterol INSTALL_BIN=$(BINDIR) INSTALL_LIB=$(LIBDIR)/ocamlbuild install && cd ..

camlp4: FORCE
	cp _tags tags
	echo '<camlp4/Camlp4Bin-standalone.jar> or <camlp4/{mkcamlp4,boot/camlp4boot}-standalone.jar>: use_dynlink' >> _tags
	echo '<camlp4/**/*.cmj*> or <camlp4/**/*.jar>: java-package(ocaml.tools.camlp4)' >> _tags
	cp ocamljava.opt _build
	mv camlp4/Camlp4Bin.ml camlp4/Camlp4Bin.ml.old
	sed -e 's/cmxs/cmjs/g' camlp4/Camlp4Bin.ml.old > camlp4/Camlp4Bin.ml
	cp $(LIBDIR)/ocamlrun.jar _build
	rm -f _build/myocamlbuild
	cp myocamlbuild.ml myocamlbuild.old
	patch -b -f -p1 < myocamlbuild-patch
	chmod +x ./build/camlp4-java-only.sh
	./build/camlp4-java-only.sh
	mv -f tags _tags
	mv -f myocamlbuild.old myocamlbuild.ml
	mv -f camlp4/Camlp4Bin.ml.old camlp4/Camlp4Bin.ml

install-camlp4: FORCE
	chmod +x ./build/java-partial-install.sh
	./build/java-partial-install.sh

clean:
	cd debugger && $(MAKE) -f Makefile-cafesterol clean && cd ..
	cd lex && $(MAKE) -f Makefile-cafesterol clean && cd ..
	cd ocamlbuild && $(MAKE) -f Makefile-cafesterol clean && cd ..
	cd ocamldoc && $(MAKE) -f Makefile-cafesterol clean && cd ..
	for d in bigarray dbm dynlink graph labltk num str systhreads unix; do \
	  cd otherlibs/$$d && $(MAKE) -f Makefile-cafesterol clean && cd ../..; \
	done
	cd stdlib && $(MAKE) -f Makefile-cafesterol clean && cd ..
	cd tools && $(MAKE) -f Makefile-cafesterol clean && cd ..
	rm -fr _build
	for d in utils parsing typing bytecomp asmcomp driver toplevel tools; do \
	  rm -f $$d/*.cmj* $$d/*.annot $$d/*.jo $$d/*.jar $$d/*~; \
	done
	rm -f *~


.SUFFIXES: .ml .mli .cmo .cmx .cmj .cmi

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

.ml.cmx:
	$(OCAMLOPT) $(COMPFLAGS) -c $<

.ml.cmj:
	$(OCAMLJAVA) $(COMPFLAGS) -c $<

.mli.cmi:
	$(OCAMLC) $(COMPFLAGS) -c $<

FORCE:
