#
# This file is part of Barista.
# Copyright (C) 2007-2014 Xavier Clerc.
#
# Barista is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Barista 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
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

include Makefile.config

# PATHS

PATH_BASE=$(shell pwd)
PATH_BUILD=$(PATH_BASE)/_build
PATH_OCAMLDOC=$(PATH_BASE)/ocamldoc
PATH_OCAMLJAR=$(PATH_OCAML_PREFIX)/bin/ocamljar.opt
PATH_SRC=$(PATH_BASE)/src
PATH_TESTS=$(PATH_BASE)/tests
PATH_INSTALL=$(PATH_OCAML_PREFIX)/lib/ocaml/barista


# DEFINITIONS

PROJECT_NAME=barista
OCAMLBUILD=$(PATH_OCAML_PREFIX)/bin/ocamlbuild
OCAMLBUILD_ENV=WARNINGS=$(WARNINGS) PATH_OCAML_PREFIX=$(PATH_OCAML_PREFIX)
OCAMLBUILD_FLAGS=-classic-display -no-links
MODULES_ODOCL=$(PROJECT_NAME).odocl
MODULES_MLPACK=$(PROJECT_NAME)Library.mlpack


# TARGETS

default:
	@echo "available targets:"
	@echo "  byte        compiles bytecode version"
	@echo "  native      compiles native version"
	@echo "  all         compiles bytecode, and native versions if available"
	@echo "  doc         generates ocamldoc documentations"
	@echo "  tests       runs tests"
	@echo "  generate    generates files needed for build"
	@echo "  clean       deletes all produced files (excluding documentation)"
	@echo "  veryclean   deletes all produced files (including documentation)"
	@echo "  install     copies executable and library files (bytecode and native versions)"
	@echo "  ocamljava   compiles all files (ocamljava version)"
	@echo "  installl-only-ocamljava ..."
	@echo "  ...         copies executable and library files (ocamljava version)"

byte: generate
	$(OCAMLBUILD_ENV) $(OCAMLBUILD) $(OCAMLBUILD_FLAGS) \
	  $(PROJECT_NAME)Library.cma \
	  $(PROJECT_NAME).byte

native: generate
	$(OCAMLBUILD_ENV) $(OCAMLBUILD) $(OCAMLBUILD_FLAGS) \
	  $(PROJECT_NAME)Library.cmxa \
	  $(PROJECT_NAME).native

all: generate
	$(OCAMLBUILD_ENV) $(OCAMLBUILD) $(OCAMLBUILD_FLAGS) \
	  $(PROJECT_NAME)Library.otarget
	$(OCAMLBUILD_ENV) $(OCAMLBUILD) $(OCAMLBUILD_FLAGS) \
	  $(PROJECT_NAME).byte
	(test -x $(PATH_OCAML_PREFIX)/bin/ocamlopt && \
	  $(OCAMLBUILD_ENV) $(OCAMLBUILD) $(OCAMLBUILD_FLAGS) \
	    $(PROJECT_NAME).native)

doc:
	$(OCAMLBUILD_ENV) $(OCAMLBUILD) $(OCAMLBUILD_FLAGS) \
	  $(PROJECT_NAME).docdir/index.html
	cp $(PATH_BUILD)/$(PROJECT_NAME).docdir/*.html \
	  $(PATH_BUILD)/$(PROJECT_NAME).docdir/*.css \
	  $(PATH_OCAMLDOC)

tests:
	test -f $(PATH_TESTS)/Makefile && \
	  (cd $(PATH_TESTS) && $(MAKE) $(MAKE_QUIET) all && cd ..) \
	  || true

generate:
	cd syntax && $(MAKE) compile && cd ..
	echo '$(PROJECT_NAME)Library.cma' > $(PROJECT_NAME)Library.itarget
	(test -x $(PATH_OCAML_PREFIX)/bin/ocamlopt && \
	  echo '$(PROJECT_NAME)Library.cmxa' >> $(PROJECT_NAME)Library.itarget) || true

clean:
	cd syntax && $(MAKE) clean && cd ..
	$(OCAMLBUILD) $(OCAMLBUILD_FLAGS) -clean
	test -f $(PATH_TESTS)/Makefile && (cd $(PATH_TESTS) && \
	  $(MAKE) $(MAKE_QUIET) clean && cd ..) || true
	rm -f $(MODULES_ODOCL) $(MODULES_MLPACK) $(PROJECT_NAME)Library.itarget

veryclean: clean
	rm -f $(PATH_OCAMLDOC)/*.html $(PATH_OCAMLDOC)/*.css

install:
	if [ -x "$(PATH_OCAMLFIND)" ]; then \
	  $(PATH_OCAMLFIND) query $(PROJECT_NAME) && $(PATH_OCAMLFIND) remove $(PROJECT_NAME) || true; \
	  $(PATH_OCAMLFIND) install $(PROJECT_NAME) META -optional $(PATH_BUILD)/$(PROJECT_NAME)Library.cm* $(PATH_BUILD)/$(PROJECT_NAME)Library.a $(PATH_BUILD)/$(PROJECT_NAME)Library.o $(PATH_BUILD)/src/driver/$(PROJECT_NAME).byte $(PATH_BUILD)/src/driver/$(PROJECT_NAME).native; \
	else \
	  mkdir -p $(PATH_INSTALL); \
	  for ext in cmi cma cmxa a cmx; do \
	    test -f $(PATH_BUILD)/$(PROJECT_NAME)Library.$$ext && \
	      cp $(PATH_BUILD)/$(PROJECT_NAME)Library.$$ext $(PATH_INSTALL) \
	      || true; \
	  done; \
	  for ext in byte native; do \
	    test -f $(PATH_BUILD)/src/driver/$(PROJECT_NAME).$$ext && \
	    cp $(PATH_BUILD)/src/driver/$(PROJECT_NAME).$$ext $(PATH_OCAML_PREFIX)/bin \
	    || true; \
	  done; \
	  if [ -x "$(PATH_OCAML_PREFIX)/bin/barista.native" ]; then \
	    ln -s -f $(PATH_OCAML_PREFIX)/bin/barista.native $(PATH_OCAML_PREFIX)/bin/barista; \
	  else \
	    ln -s -f $(PATH_OCAML_PREFIX)/bin/barista.byte $(PATH_OCAML_PREFIX)/bin/barista; \
	  fi \
	fi

ocamljava: generate
	$(OCAMLBUILD_ENV) $(OCAMLBUILD) $(OCAMLBUILD_FLAGS) \
	  $(PROJECT_NAME)Library.cmja \
	  $(PROJECT_NAME).jar
	if [ -x $(PATH_OCAMLJAR) ]; then \
	  mv $(PATH_BUILD)/src/driver/$(PROJECT_NAME).jar \
	    $(PATH_BUILD)/src/driver/$(PROJECT_NAME)-unopt.jar; \
	  $(PATH_OCAMLJAR) $(PATH_BUILD)/src/driver/$(PROJECT_NAME)-unopt.jar \
	    $(PATH_BUILD)/src/driver/$(PROJECT_NAME).jar; \
	fi

install-only-ocamljava:
	mkdir -p $(PATH_INSTALL);
	for ext in cmi cmja ja cmj; do \
	  test -f $(PATH_BUILD)/$(PROJECT_NAME)Library.$$ext && \
	    cp $(PATH_BUILD)/$(PROJECT_NAME)Library.$$ext $(PATH_INSTALL) \
	    || true; \
	done
	for ext in jar; do \
	  test -f $(PATH_BUILD)/src/driver/$(PROJECT_NAME).$$ext && \
	    cp $(PATH_BUILD)/src/driver/$(PROJECT_NAME).$$ext $(PATH_OCAML_PREFIX)/bin \
	    || true; \
	done

.PHONY: default
.PHONY: byte
.PHONY: native
.PHONY: all
.PHONY: doc
.PHONY: tests
.PHONY: generate
.PHONY: clean
.PHONY: veryclean
.PHONY: install
.PHONY: ocamljava
.PHONY: install-only-ocamljava
