PREFIX=
	if $(not $(defined PREFIX))
		value /usr/local
	else
		value $(PREFIX)
ENABLE_DEBUG=
	if $(not $(defined ENABLE_DEBUG))
		value false
	else
		value $(ENABLE_DEBUG)

ENABLE_NATIVE=
	if $(not $(defined ENABLE_NATIVE))
		value true
	else
		value $(ENABLE_NATIVE)

# behavior as traditional cpp
CPPFLAGS=-traditional-cpp

if $(file-exists VERSION)
	VERSION=$(shell head -1 VERSION)
	export
else
	VERSION=local-HEAD
	export

Shell. +=
    ocaml-clean(argv) =
      rm -f *.cm[aiox] *.o *.omc *.opt *.run *~ $(argv) *.cmxa *.a *.spot *.spit *.annot *.runner

# ------------------------------
# camlp4 rules
# ------------------------------
public.UseCamlp4(files) =
	protected.CAMLP4CMO = $(addprefix $(ROOT)/camlp4/,$(addsuffix .cmo,$(files)))
	OCAMLPPFLAGS+=-pp 'camlp4o $(CAMLP4CMO)'
	OCAMLDEPFLAGS+=-pp 'camlp4o $(CAMLP4CMO)'
	export

	.SCANNER: scan-ocaml-%.ml: %.ml $(CAMLP4CMO)

# ------------------------------
# package
# ------------------------------
public.MyOCamlPackage(name, files) =
   # XXX: JYH: these variables should be marked private in 0.9.9
   protected.OFILES   = $(addsuffix $(EXT_OBJ), $(files))
   protected.CMOFILES = $(addsuffix .cmo, $(files))
   protected.CMXFILES = $(addsuffix .cmx, $(files))

   protected.OBJ       = $(file $(name)$(EXT_OBJ))
   protected.CMO       = $(file $(name).cmo)
   protected.CMX       = $(file $(name).cmx)
   protected.CMI       = $(file $(name).cmi)
   protected.MLI       = $(file $(name).mli)

   protected.BYTE_TARGETS   = $(CMO)
   protected.NATIVE_TARGETS = $(CMX) $(OBJ)

   protected.TARGETS = $(CMI)
   if $(NATIVE_ENABLED)
       TARGETS += $(NATIVE_TARGETS)
       export

   if $(BYTE_ENABLED)
       TARGETS += $(BYTE_TARGETS)
       export

   #
   # Link commands
   #
   protected.BYTE_DEPS = $(CMOFILES)
   if $(and $(not $(NATIVE_ENABLED)), $(target-exists $(MLI)))
      BYTE_DEPS += $(CMI)
      export
   else
      BYTE_TARGETS += $(CMI)
      export

   protected.NATIVE_DEPS = $(CMXFILES) $(OFILES)
   if $(target-exists $(MLI))
      NATIVE_DEPS += $(CMI)
      export
   else
      NATIVE_TARGETS += $(CMI)
      export

   if $(target-exists $(MLI))
      $(CMI): $(MLI) :scanner: scan-ocaml-$(name).mli
           $(OCamlC) -c $<
   elseif $(NATIVE_ENABLED)
      $(NATIVE_TARGETS) $(CMI): $(NATIVE_DEPS)
           $(OCAMLFIND) $(OCAMLOPTLINK) $(LAZY_OCAMLFINDFLAGS) $(PREFIXED_OCAMLPACKS) $(OCAMLFLAGS) \
               $(OCAMLOPTFLAGS) $(OCAML_LIB_FLAGS) -pack -o $(CMX) $(OCamlLinkSort $(CMXFILES))
   else
      $(BYTE_TARGETS) $(CMI): $(BYTE_DEPS)
           $(OCAMLFIND) $(OCAMLC) $(LAZY_OCAMLFINDFLAGS) $(PREFIXED_OCAMLPACKS) $(OCAMLFLAGS) \
               $(OCAMLCFLAGS) $(OCAML_LIB_FLAGS) -pack -o $(CMO) $(OCamlLinkSort $(CMOFILES))

   return $(TARGETS)


# ------------------------------
# ounit
# ------------------------------
OUNIT_SRC_DIR=../src/
OUNIT_LIBS[]=

Shell. +=
    ounit-postproc(argv) =
      (grep "FAIL\|ERROR\|Error\|Fail" && exit 1) || exit 0

public.OUnitTest(name,files) =
	protected.test_file = $(addsuffix Test,$(name))
	protected.target    = $(addsuffix -runner,$(test_file))
	protected.src_files = $(addprefix $(OUNIT_SRC_DIR),$(files))

	.PHONY: check check-$(name) clean check-detail-$(name) check-detail
	OCamlProgram($(target), $(test_file) $(src_files) $(OUNIT_LIBS))

	check-$(name): $(target)
		$(addprefix ./,$(target))

	check-$(name): $(target)
		$(addprefix ./,$(target))
	check-detail-$(name): $(target)
		($(addprefix ./,$(target)) -verbose ; true) | tee -a $(ROOT)/unittest.log

	check: check-$(name)
	check-detail: check-detail-$(name)

	export

# ------------------------------
# other rules
# ------------------------------t
%.mli : %.mlip
    @rm -f $@
    @echo "(* CAUTION: this is a generated file.  If you edit it, all changes will be lost! *)" > $@
    $(CPP) $(CPPFLAGS) $*.mlip >> $@
    @chmod 444 $@

.SCANNER: %.mli : %.mlip
    $(CPP) $(CPPFLAGS) -M $< ;  true

%.ml: %.mlp
    @rm -f $@
    @echo "(* CAUTION: this is a generated file.  If you edit it, all changes will be lost! *)" > $@
    $(CPP) $(CPPFLAGS) $*.mlp >> $@
    @chmod 444 $@

.SCANNER: %.ml : %.mlp
    $(CPP) $(CPPFLAGS) -M $< /dev/null ; true

USE_OCAMLFIND = true

if $(not $(OCAMLFIND_EXISTS))
   eprintln('This project requires ocamlfind, but is was not found.')
   eprintln('You need to install ocamlfind and run "omake --configure".')
   exit 1

.PHONY: all install config clean distclean

# ------------------------------
# config
# ------------------------------
config: OMakefile.config config.ml

.INCLUDE: OMakefile.config
	if $(mem config,$(TARGETS))
		rm -f $@
		if $(and $(defined RELATIVE),$(RELATIVE))
			echo LIB_DIR=$(PREFIX) >> $@
			echo SHARE_DIR=$(PREFIX) >> $@
			echo BIN_DIR=$(PREFIX) >> $@
		else
			if $(not $(defined LIB_DIR))
				echo LIB_DIR=$(PREFIX)/lib/habc >> $@
			else
				echo LIB_DIR=$(LIB_DIR) >> $@
			if $(not $(defined SHARE_DIR))
				echo SHARE_DIR=$(PREFIX)/share/habc >> $@
			else
				echo SHARE_DIR=$(SHARE_DIR) >> $@
			if $(not $(defined BIN_DIR))
				echo BIN_DIR=$(PREFIX)/bin >> $@
			else
				echo BIN_DIR=$(BIN_DIR) >> $@

	        if $(shell-success-null ocamlc$(if $(OCAMLC_OPT_EXISTS), .opt) -annot)
			@echo "static.OCAMLFLAGS +=-annot" >> $@
		else
			@echo "static.OCAMLFLAGS +=-dtypes" >> $@
		if $(ENABLE_DEBUG)
			@echo "static.OCAMLFLAGS +=-g" >> $@
		if $(ENABLE_NATIVE)
			@echo "static.NATIVE_ENABLED = true"  >> $@
			@echo "static.BYTE_ENABLED   = false" >> $@
		else
			@echo "static.NATIVE_ENABLED = false" >> $@
			@echo "static.BYTE_ENABLED   = true"  >> $@


	if $(not $(file-exists OMakefile.config))
		@echo "Please refer to the installation instructions in file README.mkdn."
		@echo "If you've just unpacked the distribution, something like"
		@echo "   omake config"
	        @echo "   omake all"
		@echo "   omake install"
		@echo "should work.  But see the file README.mkdn for more details."

config.ml:
	if $(mem config,$(TARGETS))
		rm -f $@
		echo 'let version = "$(VERSION)"' >> $@
		if $(and $(defined RELATIVE),$(RELATIVE))
			@echo 'let bin_dir   = Str.global_replace (Str.regexp "\\\\") "/" (Filename.dirname Sys.executable_name)' >> $@
			@echo 'let share_dir = bin_dir' >> $@
			@echo 'let lib_dir   = bin_dir' >> $@
		else
			@echo 'let bin_dir   = "$(ocaml-escaped  $(BIN_DIR))"' >> $@
			@echo 'let share_dir = "$(ocaml-escaped  $(SHARE_DIR))"' >> $@
			@echo 'let lib_dir   = "$(ocaml-escaped  $(LIB_DIR))"' >> $@
		@echo 'let default_includes = [lib_dir;"."]' >> $@
		@echo 'let default_template = share_dir ^ "/template.xml"' >> $@
		@echo 'let path_sep="$(PATHSEP)"' >> $@
		@echo 'let exe="$(EXE)"' >> $@


################################################
USE_OCAMLFIND = true
if $(not $(OCAMLFIND_EXISTS))
    eprintln('This project requires ocamlfind, but is was not found.')
    eprintln('You need to install ocamlfind and run "omake --configure".')
    exit 1

OCAMLINCLUDES += $(ROOT)
.SUBDIRS: scm xml driver base lib camlp4

# ------------------------------
# all
# ------------------------------
habc-scm$(EXE): scm/src/habc-scm$(EXE)
	ln-or-cp $^ .

habc-xml$(EXE): xml/src/habc-xml$(EXE)
	ln-or-cp $^ .

habc$(EXE) : driver/src/habc$(EXE)
	ln-or-cp $^ .

PROGRAM = habc$(EXE) habc-xml$(EXE) habc-scm$(EXE)

all: config $(PROGRAM) lib

.DEFAULT: all

# ------------------------------
# install
# ------------------------------
install: $(PROGRAM)
	mkdir -p $(BIN_DIR)
	mkdir -p $(LIB_DIR)
	mkdir -p $(SHARE_DIR)
	mkdir -p $(SHARE_DIR)/example
	$(INSTALL) $(PROGRAM)   $(BIN_DIR)
	$(INSTALL) share/habc/* $(SHARE_DIR)
	$(INSTALL) example/*    $(SHARE_DIR)/example/
	$(INSTALL) lib/habc/*   $(LIB_DIR)
	if $(or $(equal Win32,$(OSTYPE)),$(equal Cygwin,$(OSTYPE)))
		$(INSTALL) win32/swfmill/* $(BIN_DIR)/
		$(INSTALL) README.mkdn $(BIN_DIR)/

# ------------------------------
# clean
# ------------------------------
clean:
	ocaml-clean *.abc $(PROGRAM)

distclean: clean
	ocaml-clean *.abc $(PROGRAM) OMakefile.config base/config.ml

# ------------------------------
# example
# ------------------------------
%.swf: example/%.scm all
	./habc -o $(removesuffix $@) $<
