#OCAMLARGS  = -g  # Uncomment if debugging
CXX       ?= g++
COQC       = coqc

INCLUDES = src,src/pfterm,src/coqparser,src/parser,src/learn
SOURCES := $(shell find src/) src/config.ml

# linker flags for static build
LFLAGS = -cc,$(CXX),-ccopt,-static-libgcc,-ccopt,-static-libstdc++


################################################################################
## Default targets

all: bin/satallax satallax.native thasher.native simpler.native

clean: satallax-clean minisat-clean minisatinterface-clean picosat-clean coq-clean eprover-clean doc-clean archive-clean


################################################################################
## Satallax

reset_config:
	cp src/config.default src/config.ml

bin/satallax: satallax.native
	cp $< $@

satallax-clean:
	-rm -r _build *.byte *.native bin/satallax src/config.ml

src/config.ml: minisat picosat eprover
	./configure

satallax.byte: $(SOURCES) minisatinterface
	ocamlbuild $@ -Is $(INCLUDES) -libs unix,nums -lflags ../lib/dllminisatinterface.so

satallax.native: $(SOURCES) minisatinterface
	ocamlbuild $@ -Is $(INCLUDES) -libs unix,nums -lflags ../lib/libminisatinterface.a,$(LFLAGS)

satallaxcoqtac.native: $(SOURCES) minisatinterface
	ocamlbuild $@ -Is $(INCLUDES) -libs unix,nums -lflags ../lib/libminisatinterface.a,$(LFLAGS)

fhasher.native: $(SOURCES)
	ocamlbuild $@ -Is $(INCLUDES) -libs unix,nums -lflags $(LFLAGS)

thasher.native: $(SOURCES)
	ocamlbuild $@ -Is $(INCLUDES) -libs unix,nums -lflags $(LFLAGS)

tune.native: $(SOURCES)
	ocamlbuild $@ -Is $(INCLUDES) -libs unix,nums -lflags $(LFLAGS)

simpler.native: $(SOURCES)
	ocamlbuild $@ -Is $(INCLUDES) -libs unix,nums -lflags $(LFLAGS)


################################################################################
## Minisat

MROOT := $(shell pwd)/minisat

minisat: minisat/core/Solver.o minisat/simp/SimpSolver.o

minisat-clean:
	-rm minisat/core/Solver.o minisat/simp/SimpSolver.o

minisat/core/Solver.o:
	export MROOT=$(MROOT); $(MAKE) -C minisat/core/ Solver.o

minisat/simp/SimpSolver.o:
	export MROOT=$(MROOT); $(MAKE) -C minisat/simp/ SimpSolver.o


################################################################################
## Minisat interface

minisatinterface: lib lib/dllminisatinterface.so lib/libminisatinterface.a

minisatinterface-clean:
	-rm -R lib/

lib:
	mkdir -p lib

lib/minisatinterface.cmo: src/minisatinterface.ml
	ocamlc $(OCAMLARGS) -I lib -c $< -o $@
	rm src/minisatinterface.cm?

lib/dllminisatinterface.so: minisat lib/minisatinterface.cmo lib/Ointerface.o
	ocamlmklib -o lib/minisatinterface minisat/core/Solver.o minisat/simp/SimpSolver.o lib/Ointerface.o -lstdc++

lib/libminisatinterface.a: minisat lib/minisatinterface.cmo lib/Ointerface.o
	ocamlmklib -o lib/minisatinterface minisat/core/Solver.o minisat/simp/SimpSolver.o lib/Ointerface.o -ccopt '-static-libgcc -static-libstdc++'

lib/Ointerface.o: src/minisat-interface/Ointerface.cc
	$(CXX) -static-libgcc -static-libstdc++ -c -fPIC -Wall -D __STDC_LIMIT_MACROS -D __STDC_FORMAT_MACROS -Iminisat -I"`ocamlc -where`" $< -o $@


################################################################################
## Picosat

picosat-clean:
	-$(MAKE) -C picosat-936 clean
	-rm bin/picomus

bin/picomus: picosat-936/picomus
	cp $< $@

picosat: bin/picomus

picosat-936/picomus:
	cd picosat-936 && ./configure && make


################################################################################
## Coq

COQ_SOURCES := $(shell find itp/ -name *.v)

coq-clean:
	-$(MAKE) -C itp/coq clean
	-$(MAKE) -C itp/coq2 clean
	-rm itp/coq/Makefile itp/coq2/Makefile

coq: $(COQ_SOURCES)
	cd itp/coq; coq_makefile *.v -arg -nois > Makefile; $(MAKE)
	cd itp/coq2; coq_makefile *.v -arg -nois > Makefile; $(MAKE)


################################################################################
## E-Prover

bin/eprover: E/PROVER/eprover
	cp $< $@

eprover: bin/eprover

# To keep Git from reporting automatic changes to Makefile.vars caused by
# ./configure, keep a clean Makefile.vars.template that is copied on demand.
E/Makefile.vars: E/Makefile.vars.template
	cp $< $@

eprover-clean: E/Makefile.vars
	-$(MAKE) -C E clean
	-rm E/Makefile.vars
	-rm bin/eprover

E/PROVER/eprover: E/Makefile.vars
	cd E && ./configure
	make -C E


################################################################################
## Documentation

MARKDOWN_SOURCES := $(shell find doc/ -name *.md)
MARKDOWN_OUTPUT := $(patsubst %.md,%.html,$(MARKDOWN_SOURCES))

doc: $(MARKDOWN_OUTPUT)

doc-clean:
	-rm $(MARKDOWN_OUTPUT)

doc/%.html: doc/%.md
	pandoc $< --base-header-level=2 -f markdown-auto_identifiers -s -o $@


################################################################################
## Archives

archive-clean:
	-rm satallax*.tar.gz

ARCHIVE_SOURCES := bin/ doc/ E/ itp/ minisat/ modes/ picosat-936/ problems/ src/ \
  configure INSTALL LICENSE Makefile README test

satallax-%-bin.tar.gz: bin/satallax bin/eprover
	tar cvzf $@ bin/ modes/

satallax-%-src.tar.gz: clean
	tar cvzf $@ --transform 's,^,satallax-$*/,' $(ARCHIVE_SOURCES)

