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

# PATHS

PATH_BASE=$(shell pwd)
PATH_SRC_ML=$(PATH_BASE)/src/ocaml
PATH_SRC_C=$(PATH_BASE)/src/c
PATH_BIN=$(PATH_BASE)/bin
PATH_DOC=$(PATH_BASE)/ocamldoc
PATH_OCAML_LIB=/usr/local/lib/ocaml/caml
PATH_OCAML_BIN=/usr/local/bin
PATH_GCC_BIN=/usr/bin


# DEFINITIONS

OCAMLC=$(PATH_OCAML_BIN)/ocamlc
OCAMLOPT=$(PATH_OCAML_BIN)/ocamlopt
OCAMLJAVA=$(PATH_OCAML_BIN)/ocamljava
JAVA_FLAGS=-java-package 'fr.x9c.cadmium.library'
OCAMLDOC=$(PATH_OCAML_BIN)/ocamldoc
OCAMLDEP=$(PATH_OCAML_BIN)/ocamldep
OCAMLMKLIB=$(PATH_OCAML_BIN)/ocamlmklib
OCAML_COMPILE_FLAGS=-w A -I $(PATH_SRC_ML)
MODULES=cadmium cadmiumObj cadmiumMath cadmiumJDBC cadmiumXML
LIBRARY=cadmiumLibrary
OCAML_DOC_TITLE=Cadmium
SERVLET_MODULES=cadmiumServlet
SERVLET_LIBRARY=cadmiumServletLibrary
SWIXML_MODULES=cadmiumSwiXml cadmiumSwiXmlObj
SWIXML_LIBRARY=cadmiumSwiXmlLibrary

GCC=$(PATH_GCC_BIN)/gcc -m32
GCC_COMPILE_FLAGS=-Wall -I $(PATH_OCAML_LIB)
GCC_ADDITIONAL_FLAGS=
OBJECTS=cadmium
SERVLET_OBJECTS=servlet
SWIXML_OBJECTS=swixml

INSTALL_DIR_BASE=$(shell $(OCAMLC) -where)
INSTALL_DIR=$(INSTALL_DIR_BASE)/cadmium

CMI_FILES=$(patsubst %,$(PATH_SRC_ML)/%.cmi,$(MODULES)) \
          $(patsubst %,$(PATH_SRC_ML)/%.cmi,$(SERVLET_MODULES)) \
          $(patsubst %,$(PATH_SRC_ML)/%.cmi,$(SWIXML_MODULES))
CMO_FILES=$(patsubst %,$(PATH_SRC_ML)/%.cmo,$(MODULES)) \
          $(patsubst %,$(PATH_SRC_ML)/%.cmo,$(SERVLET_MODULES)) \
          $(patsubst %,$(PATH_SRC_ML)/%.cmo,$(SWIXML_MODULES))
CMX_FILES=$(patsubst %,$(PATH_SRC_ML)/%.cmx,$(MODULES)) \
          $(patsubst %,$(PATH_SRC_ML)/%.cmx,$(SERVLET_MODULES)) \
          $(patsubst %,$(PATH_SRC_ML)/%.cmx,$(SWIXML_MODULES))
CMJ_FILES=$(patsubst %,$(PATH_SRC_ML)/%.cmj,$(MODULES)) \
          $(patsubst %,$(PATH_SRC_ML)/%.cmj,$(SERVLET_MODULES)) \
          $(patsubst %,$(PATH_SRC_ML)/%.cmj,$(SWIXML_MODULES))
O_FILES=$(patsubst %,$(PATH_SRC_C)/%.o,$(OBJECTS)) \
        $(patsubst %,$(PATH_SRC_C)/%.o,$(SERVLET_OBJECTS)) \
        $(patsubst %,$(PATH_SRC_C)/%.o,$(SWIXML_OBJECTS))


# TARGETS

default:
	@echo 'available targets:'
	@echo '  all        compiles all files'
	@echo '  library    compiles support library (C)'
	@echo '  cma        compiles support and bytecode libraries'
	@echo '  cmxa       compiles support and native libraries'
	@echo '  cmja       compiles support and Cafesterol libraries'
	@echo '  html-doc   generates html documentation'
	@echo '  clean-all  deletes all produced files (including documentation)'
	@echo '  clean      deletes all produced files (excluding documentation)'
	@echo '  clean-doc  deletes documentation files'
	@echo '  install    copies library files to OCaml directory'
	@echo '  depend     generates dependency files'


all: clean-all library cma cmxa cmja html-doc

library: $(O_FILES)
	$(OCAMLMKLIB) -o $(LIBRARY) -oc cadmium $(PATH_SRC_C)/cadmium.o
	mv *.a *.so $(PATH_BIN)
	$(OCAMLMKLIB) -o $(SERVLET_LIBRARY) -oc servlet $(PATH_SRC_C)/servlet.o
	mv *.a *.so $(PATH_BIN)
	$(OCAMLMKLIB) -o $(SWIXML_LIBRARY) -oc swixml $(PATH_SRC_C)/swixml.o
	mv *.a *.so $(PATH_BIN)

cma: library $(CMI_FILES) $(CMO_FILES)
	$(OCAMLMKLIB) -o $(LIBRARY) -oc cadmium $(patsubst %,$(PATH_SRC_ML)/%.cmo,$(MODULES))
	mv $(LIBRARY).cma $(PATH_BIN)
	$(OCAMLMKLIB) -o $(SERVLET_LIBRARY) -oc servlet $(patsubst %,$(PATH_SRC_ML)/%.cmo,$(SERVLET_MODULES))
	mv $(SERVLET_LIBRARY).cma $(PATH_BIN)
	$(OCAMLMKLIB) -o $(SWIXML_LIBRARY) -oc swixml $(patsubst %,$(PATH_SRC_ML)/%.cmo,$(SWIXML_MODULES))
	mv $(SWIXML_LIBRARY).cma $(PATH_BIN)

cmxa: library $(CMI_FILES) $(CMX_FILES)
	$(OCAMLMKLIB) -o $(LIBRARY) -oc cadmium $(patsubst %,$(PATH_SRC_ML)/%.cmx,$(MODULES))
	mv $(LIBRARY).cmxa $(LIBRARY).a $(PATH_BIN)
	$(OCAMLMKLIB) -o $(SERVLET_LIBRARY) -oc servlet $(patsubst %,$(PATH_SRC_ML)/%.cmx,$(SERVLET_MODULES))
	mv $(SERVLET_LIBRARY).cmxa $(SERVLET_LIBRARY).a $(PATH_BIN)
	$(OCAMLMKLIB) -o $(SWIXML_LIBRARY) -oc swixml $(patsubst %,$(PATH_SRC_ML)/%.cmx,$(SWIXML_MODULES))
	mv $(SWIXML_LIBRARY).cmxa $(SWIXML_LIBRARY).a $(PATH_BIN)

cmja: $(CMI_FILES) $(CMJ_FILES)
	$(OCAMLJAVA) $(JAVA_FLAGS) -a -o $(LIBRARY).cmja $(patsubst %,$(PATH_SRC_ML)/%.cmj,$(MODULES))
	mv $(LIBRARY).cmja $(PATH_BIN)
	mv $(LIBRARY).jar $(PATH_BIN)
	$(OCAMLJAVA) $(JAVA_FLAGS) -a -o $(SERVLET_LIBRARY).cmja $(patsubst %,$(PATH_SRC_ML)/%.cmj,$(SERVLET_MODULES))
	mv $(SERVLET_LIBRARY).cmja $(PATH_BIN)
	mv $(SERVLET_LIBRARY).jar $(PATH_BIN)
	$(OCAMLJAVA) $(JAVA_FLAGS) -a -o $(SWIXML_LIBRARY).cmja $(patsubst %,$(PATH_SRC_ML)/%.cmj,$(SWIXML_MODULES))
	mv $(SWIXML_LIBRARY).cmja $(PATH_BIN)
	mv $(SWIXML_LIBRARY).jar $(PATH_BIN)

html-doc:
	$(OCAMLDOC) -sort -html -t '$(OCAML_DOC_TITLE)' -d $(PATH_DOC) -I $(PATH_SRC_ML) $(PATH_SRC_ML)/*.mli

clean-all: clean clean-doc

clean:
	rm -f $(PATH_SRC_ML)/*.cm*
	rm -f $(PATH_SRC_ML)/*.o
	rm -f $(PATH_SRC_ML)/*.jo
	rm -f $(PATH_SRC_C)/*.o
	rm -f $(PATH_BIN)/*.*

clean-doc:
	rm -f $(PATH_DOC)/*.html
	rm -f $(PATH_DOC)/*.css

install:
	mkdir -p $(INSTALL_DIR)
	cp $(PATH_BIN)/*.* $(CMI_FILES) $(CMX_FILES) $(CMJ_FILES) $(CMI_FILES:.cmi=.mli) $(INSTALL_DIR)
	if test `grep -s -c '$(INSTALL_DIR)$$' $(INSTALL_DIR_BASE)/ld.conf` = 0; \
	then echo '$(INSTALL_DIR)' >> $(INSTALL_DIR_BASE)/ld.conf; fi


# GENERIC TARGETS

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

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

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

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

.ml.cmj:
	$(OCAMLJAVA) $(JAVA_FLAGS) $(OCAML_COMPILE_FLAGS) -c $<

.c.o:
	$(GCC) $(GCC_COMPILE_FLAGS) $(GCC_ADDITIONAL_FLAGS) -c $< -o $@


# DEPENDENCIES

depend::
	$(OCAMLDEP) -I $(PATH_SRC_ML) $(PATH_SRC_ML)/*.ml* > depend
	$(OCAMLDEP) -I $(PATH_SRC_ML) $(PATH_SRC_ML)/*.ml* | sed 's/\.cmx/\.cmj/g' > depend.cafesterol

include depend
include depend.cafesterol
