########################## User's variables #####################
#
# The Caml sources (including camlyacc and camllex source files)

SOURCES = types.ml parser.mly lexer.mll basic.ml symbol.ml value.ml signal.ml beam.ml faustexp.ml interpreter.ml preprocess.ml main.ml preprocess_stubs.cpp

# The executable file to generate

EXEC = mrfausti

# Path to ocaml include header files
export OCAML_INCLUDE_PATH

# Path to sndfile library
#SNDFILE_PATH = /home/wang/Desktop/libsndfile-ocaml
export SNDFILE_PATH

# Path to Faust.mr2
FAUST_PATH = faust-0.9.47mr3

# Path to preprocessor library
PREPROCESSOR_PATH = $(FAUST_PATH)/compiler

# Path to preprocessor header files
PREPROCESSOR_INCLUDE_PATH = $(PREPROCESSOR_PATH)/headers

# Path to the interpretor documentation
OCAML_DOC_PATH = ../documentation

########################## Advanced user's variables #####################
#
# The Caml compilers.
# You may fix here the path to access the Caml compiler on your machine
# You may also have to add various -I options.
CAMLC = ocamlc
CAMLOPT = ocamlopt
CAMLDEP = ocamldep
CAMLLEX = ocamllex
CAMLYACC = ocamlyacc
CAMLDOC = ocamldoc
CC = g++

# The list of Caml libraries needed by the program
# For instance:
# LIBS=$(WITHGRAPHICS) $(WITHUNIX) $(WITHSTR) $(WITHNUMS) $(WITHTHREADS)\
# $(WITHDBM)

LIBS = $(WITHSNDFILE) $(WITHUNIX)

# Should be set to -INCLUDE if you use any of the libraries above
# or if any C code have to be linked with your program
# (irrelevant for ocamlopt)

# INCLUDE=-INCLUDE

INCLUDE = -I $(SNDFILE_PATH)

# Default setting of the WITH* variables. Should be changed if your
# local libraries are not found by the compiler.
#WITHGRAPHICS =graphics.cma -cclib -lgraphics -cclib -L/usr/X11R6/lib -cclib -lX11

#WITHUNIX =unix.cma -cclib -lunix

#WITHSTR =str.cma -cclib -lstr

#WITHNUMS =nums.cma -cclib -lnums

#WITHTHREADS =threads.cma -cclib -lthreads

#WITHDBM =dbm.cma -cclib -lmldbm -cclib -lndbm

WITHUNIX =unix.cma

WITHSNDFILE = sndfile.cma

# c++ wrap options
GPP_CALL = -cc "g++"

# The list of options for each compiler
CAMLC_OPTIONS = $(GPP_CALL) $(INCLUDE) $(LIBS) 

CAMLOPT_OPTIONS = -p $(GPP_CALL) $(INCLUDE) $(LIBS:.cma=.cmxa) 

CAMLDOC_OPTIONS = -d $(OCAML_DOC_PATH) -html $(INCLUDE)
CC_OPTIONS = -c -I$(PREPROCESSOR_INCLUDE_PATH) -I$(OCAML_INCLUDE_PATH)

################ End of user's variables #####################


##############################################################
################ This part should be generic
################ Nothing to set up or fix here
##############################################################

all:: .depend.input .depend preprocessor $(EXEC)

opt : .depend.input .depend preprocessor $(EXEC).opt

doc : document

#ocamlc -INCLUDE other options graphics.cma other files -cclib -lgraphics -cclib -lX11
#ocamlc -thread -INCLUDE other options threads.cma other files -cclib -lthreads
#ocamlc -INCLUDE other options str.cma other files -cclib -lstr
#ocamlc -INCLUDE other options nums.cma other files -cclib -lnums
#ocamlc -INCLUDE other options unix.cma other files -cclib -lunix
#ocamlc -INCLUDE other options dbm.cma other files -cclib -lmldbm -cclib -lndbm

SMLIY = $(SOURCES:.mly=.ml)
SMLIYL = $(SMLIY:.mll=.ml)
SMLYL = $(filter %.ml, $(SMLIYL))
OBJS = $(SMLYL:.ml=.cmo)
OPTOBJS = $(OBJS:.cmo=.cmx)

CSOURCES = $(filter %.cpp, $(SOURCES))
COBJS = $(CSOURCES:.cpp=.o)
CLIBS = $(PREPROCESSOR_PATH)/preprocess.a

PARSER_MLY = $(filter %.mly, $(SOURCES))
LEXER_MLL = $(filter %.mll, $(SOURCES))
MIDDLE_ML = $(PARSER_MLY:.mly=.ml) $(LEXER_MLL:.mll=.ml)

preprocessor:
	@(cd $(FAUST_PATH) && $(MAKE))

$(EXEC): $(OBJS) $(COBJS)
	$(CAMLC) $(CAMLC_OPTIONS) -o $(EXEC) $(OBJS) $(COBJS) $(CLIBS)

$(EXEC).opt: $(OPTOBJS) $(COBJS)
	$(CAMLOPT) $(CAMLOPT_OPTIONS) -o $(EXEC) $(OPTOBJS) $(COBJS) $(CLIBS)

document: $(SMLYL) $(OBJS)
	$(CAMLDOC) $(CAMLDOC_OPTIONS) $(SMLYL)

main.cmo: main.ml
	$(CAMLC) $(INCLUDE) -c $<

main.cmx: main.ml
	$(CAMLOPT) $(INCLUDE) -c $<

preprocess.cmo: preprocess.ml
	$(CAMLC) $(GPP_CALL) -c $<

preprocess.cmx: preprocess.ml
	$(CAMLOPT) $(GPP_CALL) -c $<

preprocess_stubs.o: preprocess_stubs.cpp
	$(CC) $(CC_OPTIONS) $< 

.SUFFIXES: .ml .mli .cmo .cmi .cmx .mll .mly 

.ml.cmo:
	$(CAMLC) -c $<

.mli.cmi:
	$(CAMLC) -c $<

.ml.cmx:
	$(CAMLOPT) -c $<

.mll.cmo:
	$(CAMLLEX) $<
	$(CAMLC) -c $*.ml

.mll.cmx:
	$(CAMLLEX) $<
	$(CAMLOPT) -c $*.ml

.mly.cmo:
	$(CAMLYACC) $<
	$(CAMLC) -c $*.mli
	$(CAMLC) -c $*.ml

.mly.cmx:
	$(CAMLYACC) $<
	$(CAMLOPT) -c $*.mli
	$(CAMLOPT) -c $*.ml

.mly.cmi:
	$(CAMLYACC) $<
	$(CAMLC) -c $*.mli

.mll.ml:
	$(CAMLLEX) $<

.mly.ml:
	$(CAMLYACC) $<

clean::
	rm -f *.cm[iox] *~ .*~ #*#
	rm -f $(MIDDLE_ML) *.o *.mli .depend*

mrproper: clean
	rm -f $(EXEC)*

.depend.input: Makefile
	@echo -n '--Checking Ocaml input files: '
	@(ls $(SMLIY) $(SMLIY:.ml=.mli) 2>/dev/null || true) \
	     >  .depend.new
	@diff .depend.new .depend.input 2>/dev/null 1>/dev/null && \
	    (echo 'unchanged'; rm -f .depend.new) || \
	    (echo 'changed'; mv .depend.new .depend.input)

depend: .depend

.depend:: $(SMLIY) .depend.input
	@echo '--Re-building dependencies'
	$(CAMLDEP) $(SMLIY) $(SMLIY:.ml=.mli) > .depend

include .depend