#-include config/Makefile

OCAML_VERSION := $(shell ocamlc -version)
OCAML_SOURCE := /usr/src/ocaml-source-$(OCAML_VERSION).tar.bz2
OCAML_SRCDIR := ocaml-$(OCAML_VERSION)

DUCE_VERSION := $(shell head -n1 VERSION)
DUCE_SRCDIR := ocamlduce-$(DUCE_VERSION)

DUCE_LIBDIR := $(LIBDIR)/ocamlduce

BASE_BYT := ocamlc ocamldoc/ocamldoc tools/ocamldep
BYT := ocaml $(BASE_BYT)
OPT := ocamlopt ocamlopt.opt $(addsuffix .opt,$(BASE_BYT))

MLI := toplevel/toploop.mli toplevel/topdirs.mli \
  toplevel/topmain.mli otherlibs/ocamlduce/ocamlduce.mli

CMI := $(MLI:.mli=.cmi) otherlibs/ocamlduce/cduce_types.cmi

CMA := otherlibs/ocamlduce/ocamlduce.cma
CMXA := $(CMA:.cma=.cmxa) $(CMA:.cma=.a)
CMXS := $(CMA:.cma=.cmxs)

TOPCMO := toplevel/toploop.cmo toplevel/topdirs.cmo \
  toplevel/topmain.cmo toplevel/topstart.cmo \

TOPCMA := toplevel/toplevellib.cma

DIR_PATCHES := parsing typing utils bytecomp asmcomp driver toplevel ocamldoc tools
BUILD_PATCH := myocamlbuild.ml myocamlbuild_config.mli _tags

DUCED_FILES := LICENSE README Makefile Changes
DUCEP_FILES := META.in VERSION ocamlducefind mkocamlduce.sh

all:
	@echo "===> Please explicit what you want <==="

prepare:
	tar xf $(OCAML_SOURCE)
	cp -PpR $(DUCEP_FILES) $(OCAML_SRCDIR)
	cp -PpR ocamlduce $(OCAML_SRCDIR)/otherlibs
	cd $(OCAML_SRCDIR) && for X in ../patches/*.diff; do patch -p1 < $$X; done
	for X in $(DUCED_FILES); do cp $$X $(OCAML_SRCDIR)/$$X.ocamlduce; done
	sed '\@^#-include config/Makefile@s/^#//' $(OCAML_SRCDIR)/Makefile.ocamlduce > $(OCAML_SRCDIR)/Makefile.ocamlduce.new
	mv $(OCAML_SRCDIR)/Makefile.ocamlduce.new $(OCAML_SRCDIR)/Makefile.ocamlduce

config/Makefile:
	@echo "===> You should probably run ./configure yourself, trying on my own... <==="
	$(shell sed -ne '1s@^.*\(./configure.*\)$$@\1@p' $(shell ocamlc -where)/Makefile.config)

world: config/Makefile
	MAKE="$(MAKE)" CFLAGS="$(CFLAGS)" ./mkocamlduce.sh

world.opt: config/Makefile
	MAKE="$(MAKE)" CFLAGS="$(CFLAGS)" HAS_NATIVE=y ./mkocamlduce.sh

META: META.in
	sed 's/%VER%/$(DUCE_VERSION)/' $< > $@

installcommon-stamp: META
	@echo "===> Installing common files... <==="
	install -m 755 -d $(BINDIR)
	install -m 755 -d $(DUCE_LIBDIR)
	install -m 755 ocamlducefind $(BINDIR)
	install -m 644 META $(DUCE_LIBDIR)
	install -m 644 $(addprefix _build/,$(MLI)) $(DUCE_LIBDIR)
	install -m 644 $(addprefix _build/,$(CMI)) $(DUCE_LIBDIR)

installbyte: installcommon-stamp
	@echo "===> Installing non-native files... <==="
	for X in $(BYT); do Y=$${X##*/}; Y=$${Y#ocaml}; install -m 755 _build/$$X $(BINDIR)/ocamlduce$$Y; done
	install -m 644 $(addprefix _build/,$(TOPCMO)) $(DUCE_LIBDIR)
	install -m 644 $(addprefix _build/,$(TOPCMA)) $(DUCE_LIBDIR)
	install -m 644 $(addprefix _build/,$(CMA)) $(DUCE_LIBDIR)

installopt: installcommon-stamp
	@echo "===> Installing native files... <==="
	for X in $(OPT); do Y=$${X##*/}; Y=$${Y#ocaml}; install -m 755 _build/$$X $(BINDIR)/ocamlduce$$Y; done
	install -m 644 $(addprefix _build/,$(CMXA) $(CMXS)) $(DUCE_LIBDIR)

clean:
	build/distclean.sh
	rm -f META

dist:
	git clean -dxf
	touch config/Makefile
	mkdir -p $(DUCE_SRCDIR)/patches
	for X in $(DIR_PATCHES); do git diff upstream -- $$X > $(DUCE_SRCDIR)/patches/$$X.diff; done
	git diff upstream -- $(BUILD_PATCH) > $(DUCE_SRCDIR)/patches/build.diff
	for X in $(DUCED_FILES); do cp -a $$X.ocamlduce $(DUCE_SRCDIR)/$$X; done
	cp -t $(DUCE_SRCDIR) -a otherlibs/ocamlduce
	cp -t $(DUCE_SRCDIR) -a $(DUCEP_FILES)
	sed -i '\@^-include config/Makefile@s/^/#/' $(DUCE_SRCDIR)/Makefile
	tar czf $(DUCE_SRCDIR).tar.gz $(DUCE_SRCDIR)


.PHONY: all installbyte installopt clean dist prepare world world.opt

SRC = \
 misc/custom.ml \
 misc/encodings.ml \
 misc/imap.ml \
 misc/state.ml \
 misc/upool.ml \
 misc/ns.ml \
 types/sortedList.ml \
 types/atoms.ml \
 misc/bool.ml \
 types/chars.ml \
 types/ident.ml \
 types/intervals.ml \
 misc/inttbl.ml \
 types/normal.ml \
 misc/pretty.ml \
 misc/stats.ml \
 types/compunit.ml \
 types/types.ml \
 types/sequence.ml \
 types/sample.ml \
 compile/auto_pat.ml \
 types/patterns.ml \
 runtime/value.ml \
 runtime/run_dispatch.ml \
 runtime/explain.ml \
 typing/typepat.ml \
 runtime/serial.ml

.PHONY: update-cduce
update-cduce:
	cd otherlibs/ocamlduce && \
	for i in $(SRC) $(SRC:.ml=.mli); do \
	  if test -f $(CDUCE_DIR)/$$i; then cp --remove-destination $(CDUCE_DIR)/$$i .; else :; fi \
	done
