# -*- Mode: makefile -*- 

# Makefile for the cil wrapper
# @do_not_edit@ Makefile.in
#
# author: George Necula

#
# If you want to add extra CIL features, you do not always need to change 
# this file. Just invoke 
#        ./configure EXTRASRCDIRS=/home/foodir EXTRAFEATURES="foo bar"
# This will add two features that must be defined in foo.ml and bar.ml
# 

# Debugging. Set ECHO= to debug this Makefile 
.PHONY: setup quickbuild doc distrib machdep cilversion
ECHO = @

# It is important to build quickbuild first,to generate the proper dependencies
all:  quickbuild setup

# Now add the defines for the CIL features
include Makefile.features


# look out for outdated Makefile; if it's out of date, this will automatically
# re-run ./config.status, then re-exec make with the same arguments
Makefile: config.status Makefile.in 
	./$<

config.status: configure
	./$@ --recheck

configure: configure.in aclocal.m4
	autoconf

ocamlutil/perfcount.c: config.status ocamlutil/perfcount.c.in
	./$<

@DEFAULT_COMPILER@=1



ifdef RELEASE
  NATIVECAML := 1
  UNSAFE     := 1
endif

ifndef ARCHOS
   ARCHOS=@ARCHOS@
endif

ifndef MINGW
   MINGW=@MINGW@
endif

# Put here all the byproducts of make
OBJDIR      := obj/$(ARCHOS)
DEPENDDIR   := obj/.depend

CILLY_FEATURES :=
ifdef USE_BLOCKINGGRAPH
  CILLY_FEATURES += blockinggraph
endif
ifdef USE_ZRAPP
  CILLY_FEATURES += rmciltmps zrapp
endif
ifdef USE_LLVM
  CILLY_FEATURES += llvmutils llvmgen llvmssa llvm
endif
# Add the EXTRAFEATURES
CILLY_FEATURES += @EXTRAFEATURES@

    # Now rules to make cilly
CILLY_LIBRARY_MODULES = pretty inthash errormsg alpha trace stats util clist \
              cilutil escape longarray growArray\
              cabs cabshelper cabsvisit whitetrack cprint lexerhack machdep machdepenv cparser clexer  \
              cilversion cil cillower formatparse formatlex formatcil cabs2cil \
              patch frontc check mergecil cildump \
              ciltools dataflow dominators bitmap ssa \
              usedef logcalls logcalls2 logwrites rmtmps \
              canon_lval setp uref golf olf myptranal ptranal \
			  alloc trans_alloc callgraph mycallgraph epicenter heapify \
              heapify_separate canonicalize heap oneret partial simplemem \
			  simplify dataslicing sfi expcompare cfg liveness \
			  reachingdefs deadcodeelim availexps \
              availexpslv predabst filetools dumpfile \
              testcil \
	      $(CILLY_FEATURES) \
	      ciloptions feature_config
# ww: we don't want "main" in an external cil library (cil.cma),
# otherwise every program that links against that library will get
# main's argument checking and whatnot ...
CILLY_MODULES = $(CILLY_LIBRARY_MODULES) main
CILLY_CMODULES = perfcount
CILLY_LIBS     = unix str

SOURCEDIRS  += src src/frontc src/ext src/ext/pta ocamlutil @EXTRASRCDIRS@
MLLS        += clexer.mll formatlex.mll
MLYS        += cparser.mly formatparse.mly
MODULES     += $(CILLY_MODULES) libmaincil

BEFOREDEPS += $(OBJDIR)/machdep.ml
BEFOREDEPS += $(OBJDIR)/cilversion.ml
BEFOREDEPS += $(OBJDIR)/feature_config.ml

    # Include now the common set of rules for OCAML
include ocamlutil/Makefile.ocaml

OBEXEEXT = $(EXEEXT:asm=native)
ocamlbuild:
	ocamlbuild -X obj -X doc -X test src/main$(OBEXEEXT) src/cil.$(CMXA)
	cp _build/src/main$(OBEXEEXT) $(OBJDIR)/cilly$(EXE)
	cp _build/src/cil.$(CMXA) $(OBJDIR)/

   # Now the rule to make cilly

cilly: $(OBJDIR)/cilly$(EXE)
$(OBJDIR)/cilly$(EXE) : $(CILLY_MODULES:%=$(OBJDIR)/%.$(CMO)) \
                        $(CILLY_CMODULES:%=$(OBJDIR)/%.$(CMC))
	@$(NARRATIVE) "Linking $(COMPILETOWHAT) $@ $(LINKMSG)"
	$(AT)$(CAMLLINK) -verbose -o $@ \
                    $(CILLY_LIBS:%=%.$(CMXA)) \
                    $(CILLY_LIBS:%=-cclib -l%) \
                    $^


quickbuild: cilversion machdep cilly lib/Cilly.pm

# Setup also makes the native code versions
#
# sm: cillib is only built with NATIVECAML=1 because it builds libcil.o,
# which requires native-code .cmx compiled modules... could break it
# into two targets so we build cil.cma both ways, but no one is using
# cil.cma now so I'll leave it alone
setup: cilversion machdep
	$(MAKE) cilly NATIVECAML= 
	$(MAKE) cilly NATIVECAML=1
	$(MAKE) cillib NATIVECAML=
	$(MAKE) cillib NATIVECAML=1

# Create the machine dependency module
# If the cl command cannot be run then the MSVC part will be identical to GCC
.PHONY : machdep 
machdep: $(OBJDIR)/machdep.ml 
$(OBJDIR)/machdep.ml : src/machdep-ml.c configure.in Makefile.in
	rm -f $@
	mkdir -p $(OBJDIR)
	echo "(* This module was generated automatically by code in Makefile and $(<F) *)" >$@
# Now generate the type definition
	echo "type mach = {" >> $@ 
	echo "  version_major: int;     (* Major version number *)"    >> $@
	echo "  version_minor: int;     (* Minor version number *)"    >> $@
	echo "  version: string;        (* gcc version string *)"      >> $@
	echo "  underscore_name: bool;  (* If assembly names have leading underscore *)" >> $@
	echo "  sizeof_short: int;      (* Size of \"short\" *)"       >> $@
	echo "  sizeof_int: int;        (* Size of \"int\" *)"         >> $@
	echo "  sizeof_bool: int;       (* Size of \"_Bool\" *)"       >> $@
	echo "  sizeof_long: int ;      (* Size of \"long\" *)"        >> $@
	echo "  sizeof_longlong: int;   (* Size of \"long long\" *)"   >> $@
	echo "  sizeof_ptr: int;        (* Size of pointers *)"        >> $@
	echo "  sizeof_enum: int;       (* Size of enum types *)"      >> $@
	echo "  sizeof_float: int;      (* Size of \"float\" *)"       >> $@
	echo "  sizeof_double: int;     (* Size of \"double\" *)"      >> $@
	echo "  sizeof_longdouble: int; (* Size of \"long double\" *)" >> $@
	echo "  sizeof_void: int;       (* Size of \"void\" *)"        >> $@
	echo "  sizeof_fun: int;        (* Size of function *)"        >> $@
	echo "  size_t: string;         (* Type of \"sizeof(T)\" *)"   >> $@
	echo "  wchar_t: string;        (* Type of \"wchar_t\" *)"     >> $@ 
	echo "  alignof_short: int;     (* Alignment of \"short\" *)"  >> $@
	echo "  alignof_int: int;       (* Alignment of \"int\" *)"    >> $@
	echo "  alignof_bool: int;      (* Alignment of \"_Bool\" *)"    >> $@
	echo "  alignof_long: int;      (* Alignment of \"long\" *)"   >> $@
	echo "  alignof_longlong: int;  (* Alignment of \"long long\" *)" >> $@
	echo "  alignof_ptr: int;       (* Alignment of pointers *)"   >> $@
	echo "  alignof_enum: int;      (* Alignment of enum types *)" >> $@
	echo "  alignof_float: int;     (* Alignment of \"float\" *)"  >> $@
	echo "  alignof_double: int;    (* Alignment of \"double\" *)" >> $@
	echo "  alignof_longdouble: int;  (* Alignment of \"long double\" *)" >> $@
	echo "  alignof_str: int;       (* Alignment of strings *)" >> $@
	echo "  alignof_fun: int;       (* Alignment of function *)" >> $@
	echo "  alignof_aligned: int;   (* Alignment of anything with the \"aligned\" attribute *)" >> $@
	echo "  char_is_unsigned: bool; (* Whether \"char\" is unsigned *)">> $@
	echo "  const_string_literals: bool; (* Whether string literals have const chars *)">> $@
	echo "  little_endian: bool; (* whether the machine is little endian *)">>$@
	echo "  __thread_is_keyword: bool; (* whether __thread is a keyword *)">>$@
	echo "  __builtin_va_list: bool; (* whether __builtin_va_list is builtin (gccism) *)">>$@
	echo "}" >> $@ 	
	if gcc -D_GNUCC $< -o $(OBJDIR)/machdep-ml.exe ;then \
	    echo "machdep-ml.exe created succesfully." \
	;else \
            rm -f $@; exit 1 \
        ;fi 
	echo "let gcc = {" >>$@
	$(OBJDIR)/machdep-ml.exe >>$@
	echo "}"          >>$@
	if cl /D_MSVC $< /Fe$(OBJDIR)/machdep-ml.exe /Fo$(OBJDIR)/machdep-ml.obj ;then \
           echo "let hasMSVC = true" >>$@ \
        ;else \
           echo "let hasMSVC = false" >>$@ ;fi
	echo "let msvc = {" >>$@
	$(OBJDIR)/machdep-ml.exe >>$@
	echo "}"          >>$@
	echo "let theMachine : mach ref = ref gcc" >>$@


lib/Cilly.pm: lib/Cilly.pm.in src/machdep-ml.c configure.in Makefile.in
	cp lib/Cilly.pm.in lib/Cilly.pm
	if gcc -m32 -D_GNUCC src/machdep-ml.c -o $(OBJDIR)/machdep-ml32.exe ;then \
	  sed -i -e "s|nogcc32model|`$(OBJDIR)/machdep-ml32.exe --env`|" lib/Cilly.pm; \
	fi
	if gcc -m64 -D_GNUCC src/machdep-ml.c -o $(OBJDIR)/machdep-ml64.exe ;then \
	  sed -i -e "s|nogcc64model|`$(OBJDIR)/machdep-ml64.exe --env`|" lib/Cilly.pm; \
	fi

#
# Create the version information module
.PHONY: cilversion
cilversion: $(OBJDIR)/cilversion.ml
$(OBJDIR)/cilversion.ml: src/cilversion.ml.in config.status
	rm -f $@
	./config.status --file=$@:$<

# build two libraries
.PHONY: cillib libcil
ifeq ($(NATIVECAML),1)
cillib: $(OBJDIR)/cil.$(CMXA) $(OBJDIR)/libcil.o lib/Cilly.pm
else
cillib: $(OBJDIR)/cil.$(CMXA) lib/Cilly.pm
endif


$(OBJDIR)/feature_config.ml: config.status
	rm -f $(OBJDIR)/feature_config.*
	echo "(* This module was generated automatically by code in Makefile.in *)" >$@
# The Cilly feature options. A list of Cil.featureDescr 
	echo "open Cil"   >>$@ 
	echo "let features : featureDescr list = [" >> $@
ifdef USE_BLOCKINGGRAPH
	echo "   Blockinggraph.feature;" >> $@  
endif
ifdef USE_RAND
	echo "   Rand.feature;" >> $@  
endif
ifdef USE_ARITHABS
	echo "   Arithabs.feature;" >>$@
endif
ifdef USE_ZRAPP
	echo "   Zrapp.feature;" >> $@  
endif
ifdef USE_LLVM
	echo "   Llvm.feature;" >> $@  
endif
# Now the extra features, with the first letter capitalized
	echo " (* EXTRAFEATURES: *)" >> $@  
	echo \
          $(foreach f,@EXTRAFEATURES@, \
             "\n   "`echo $f | cut -c 1 | tr "[a-z]" "[A-Z]"``echo $f | cut -c 2-`".feature;") \
	| perl -pe 's/\\n/\n/g' >> $@
	echo "]"   >>$@ 






OCAML_CIL_LIB_MODULES := $(CILLY_LIBRARY_MODULES) 
OCAML_CIL_LIB_CMODULES := perfcount

# list of modules to use for building a library; remove 'main'
# and add 'libmaincil'
OCAML_CIL_C_LIB_MODULES := $(CILLY_MODULES:main=) libmaincil

# Build an OCAML library (CMA / CMXA) that exports our Cil stuff
$(OBJDIR)/cil.$(CMXA): $(OCAML_CIL_LIB_CMODULES:%=$(OBJDIR)/lib%.a) \
                       $(OCAML_CIL_LIB_MODULES:%=$(OBJDIR)/%.$(CMO))
	$(CAMLLINK) -a -o $@ -ccopt -L$(pkglibdir) \
               $(OCAML_CIL_LIB_CMODULES:%=-cclib -l%) \
               $(OCAML_CIL_LIB_MODULES:%=$(OBJDIR)/%.$(CMO))

$(OBJDIR)/libperfcount.a: %: %($(OBJDIR)/perfcount.$(CMC))
	ranlib $@

# sm: for Simon: build a library of CIL functions which can
# be called from C code; this is like the target above, except
# it is callable from C instead of from Ocaml
ifeq ($(NATIVECAML),1)
$(OBJDIR)/libcil.o: $(OCAML_CIL_LIB_CMODULES:%=$(OBJDIR)/lib%.a) \
                    $(OCAML_CIL_LIB_MODULES:%=$(OBJDIR)/%.$(CMO))
	ocamlopt -output-obj -o $@ $(CILLY_LIBS:%=%.cmxa) $^
else
$(OBJDIR)/libcil.o:
	@echo "Can only build $@ when NATIVECAML is 1."
	exit 2
endif

# Test cil
ifdef _MSVC
TESTCILARG=--MSVC --testcil "bash msvctestcil"
else
TESTCILARG=       --testcil "bash gcctestcil"
endif

.PHONY: testcil
testcil: $(OBJDIR)/cilly$(EXE)
	       cd test; ../$(OBJDIR)/cilly$(EXE) $(TESTCILARG)

.PHONY: odoc texdoc pdfdoc

###
### DOCUMENTATION
###
### The following are available
###
###   make doc  - creates the documentation
###   make publish_doc - creates the documentation and puts it on the web page

ODOC_FILES =        ocamlutil/pretty.mli ocamlutil/errormsg.mli \
                    ocamlutil/clist.mli \
	  	    ocamlutil/stats.mli src/cil.mli src/formatcil.mli \
                    ocamlutil/alpha.mli src/cillower.mli \
                    src/ext/cfg.mli src/ext/dataflow.mli \
                    src/ext/dominators.mli


# Documentation generated by "ocamldoc"
odoc: $(OBJDIR)/pretty.cmi $(OBJDIR)/cil.cmi
	-rm -rf doc/html/cil/api doc/html/cil/api-latex
	-mkdir -p doc/html/cil/api
	-mkdir -p doc/html/cil/api-latex
	-rm -f doc/ocamldoc.sty
	ocamldoc -d doc/html/cil/api -v -stars \
             -html \
             -t "CIL API Documentation (version @CIL_VERSION@)" \
	     -I $(OBJDIR) -hide Pervasives $(ODOC_FILES)

doc/cilpp.tex: doc/cilcode.pl doc/cil.tex lib/Cilly.pm
	-rm -rf doc/html/cil
	-mkdir doc/html/cil
	-mkdir doc/html/cil/examples
	cd doc; perl cilcode.pl cil.tex >cilpp.tex.tmp
	mv doc/cilpp.tex.tmp $@

# Documentation generated from latex files using "hevea"
texdoc: doc/cilpp.tex
# Create the version document
	cd doc/html/cil; echo "\def\cilversion{@CIL_VERSION@}" >cil.version.tex
	cd doc/html/cil; echo "\def\ccuredversion{@CCURED_VERSION@}" >>cil.version.tex
	cd doc/html/cil; hevea -exec xxdate.exe ../../cilpp
	cd doc/html/cil; hevea -exec xxdate.exe ../../cilpp
	cd doc/html/cil; mv cilpp.html cil.html
	cd doc/html/cil; hacha -o ciltoc.html cil.html
	cp -f doc/index.html doc/html/cil/index.html
	cp -f doc/header.html doc/html/cil

pdfdoc: doc/cilpp.tex $(OBJDIR)/pretty.cmi $(OBJDIR)/cil.cmi
	cd doc; echo "\def\cilversion{@CIL_VERSION@}" >cil.version.tex
	cd doc; echo "\def\ccuredversion{@CCURED_VERSION@}" >>cil.version.tex
	cd doc; pdflatex cilpp.tex; pdflatex cilpp.tex
	cd doc; mv cilpp.pdf html/cil/CIL.pdf
	ocamldoc -o doc/cil-api.tex.tmp -v -stars \
             -latex \
             -t "CIL API Documentation (version @CIL_VERSION@)" \
	     -I $(OBJDIR) -hide Pervasives $(ODOC_FILES)
	sed -e 's/\\usepackage\[T1\]{fontenc}/\\setlength{\\pdfpagewidth}{\\paperwidth} \\setlength{\\pdfpageheight}{\\paperheight}/' doc/cil-api.tex.tmp >doc/cil-api.tex
	rm doc/cil-api.tex.tmp

	cd doc ; TEXINPUTS="$$TEXINPUTS:/usr/local/lib/ocaml/ocamldoc:/usr/lib/ocaml/ocamldoc" pdflatex cil-api.tex
	cd doc ; mv cil-api.pdf html/cil/CIL-API.pdf


# You should usually run this twice to get all of the references linked
# correctly.
doc: texdoc pdfdoc odoc


#----------------------------------------------------------------------
# Generate the CIL distribution
# This will create a file cil.tar.gz. It includes the HTML documentation 
# so that people can use it even if they don't have ocamldoc, hevea etc. 

.PHONY: distrib distrib-nocheck checkdistrib
CIL_TAR_GZ:=cil-@CIL_VERSION@.tar.gz
## Make a distribution and check it
distrib: distrib-nocheck checkdistrib

# Work in a temporary directory
TEMP_DIR = TEMP_cil-distrib

# The tar archive members will be relative to this directory
TOP_DIR = $(TEMP_DIR)/cil

DISTRIB_ROOT = README LICENSE INSTALL Makefile.in  \
               config.h.in config.mk.in Makefile.gcc Makefile.msvc \
	       configure configure.in install-sh config.guess config.sub \
	       cil.spec cil.spec.in \
	       _tags \
	       aclocal.m4 \
	       cil.itarget \
	       doc/cil.odocl \
	       myocamlbuild.ml

DISTRIB_SRC = cilutil.ml cil.ml cil.mli check.ml check.mli \
	      rmtmps.ml rmtmps.mli formatlex.mll formatparse.mly \
	      formatcil.mli formatcil.ml testcil.ml \
	      mergecil.ml mergecil.mli main.ml machdep-ml.c.in machdepenv.ml \
	      ciloptions.ml ciloptions.mli libmaincil.ml \
	      escape.ml escape.mli cillower.mli cillower.ml \
	      _tags \
	      cil.mllib \
	      cilversion.ml.in

DISTRIB_OCAMLUTIL = pretty.ml pretty.mli errormsg.ml errormsg.mli \
                    trace.ml trace.mli stats.ml stats.mli util.ml util.mli \
                    inthash.ml inthash.mli alpha.ml alpha.mli \
		    intmap.ml intmap.mli clist.ml clist.mli \
                    longarray.ml longarray.mli \
                    growArray.ml growArray.mli \
                    bitmap.ml bitmap.mli \
                    perfcount.c.in Makefile.ocaml \
                    _tags


DISTRIB_SRC_FRONTC = cabs.ml cabshelper.ml cprint.ml clexer.mli clexer.mll \
		     cparser.mly whitetrack.mli whitetrack.ml lexerhack.ml \
		     cabs2cil.ml cabs2cil.mli frontc.ml frontc.mli \
	             cabsvisit.mli cabsvisit.ml patch.mli patch.ml

DISTRIB_SRC_EXT = logcalls.ml logcalls.mli \
                  astslicer.ml heap.ml partial.ml \
                  logwrites.ml heapify.ml callgraph.ml callgraph.mli \
                  epicenter.ml usedef.ml ciltools.ml \
                  deadcodeelim.ml availexps.ml \
                  dataflow.ml dataflow.mli \
		  dominators.ml dominators.mli \
		  ssa.ml ssa.mli \
	          stackoverflow.mli stackoverflow.ml \
	          canonicalize.ml canonicalize.mli \
	          oneret.ml oneret.mli sfi.ml \
	          simplemem.ml simplify.ml simplify.mli \
	          blockinggraph.ml blockinggraph.mli \
		  dataslicing.ml dataslicing.mli \
		  _tags \
		  reachingdefs.ml \
		  cfg.ml cfg.mli \
		  liveness.ml \
		  expcompare.ml \
		  availexpslv.ml \
		  predabst.ml \
		  llvm.ml llvmgen.ml llvmssa.ml llvmutils.ml

DISTRIB_SRC_EXT_PTA = setp.ml setp.mli golf.ml golf.mli \
                      ptranal.ml ptranal.mli \
	              steensgaard.mli steensgaard.ml \
                      uref.ml uref.mli olf.ml olf.mli

DISTRIB_LIB = Cilly.pm.in KeptFile.pm OutputFile.pm TempFile.pm

DISTRIB_BIN = CilConfig.pm.in cilly cilly.bat.in \
              patcher patcher.bat.in test-bad teetwo

DISTRIB_SMALL1=hello.c func.c init.c init1.c wchar1.c vararg1.c testharness.h 

distrib-nocheck: $(DISTRIB_ROOT) doc
        # Create the distribution from scratch
	rm -rf $(TEMP_DIR)
	mkdir $(TEMP_DIR)

	rm -rf $(CIL_TAR_GZ)
	mkdir $(TOP_DIR) \
              $(TOP_DIR)/bin \
              $(TOP_DIR)/doc \
              $(TOP_DIR)/doc/api \
              $(TOP_DIR)/debian \
              $(TOP_DIR)/lib \
              $(TOP_DIR)/obj \
              $(TOP_DIR)/obj/.depend \
              $(TOP_DIR)/src \
              $(TOP_DIR)/src/frontc \
              $(TOP_DIR)/src/ext \
              $(TOP_DIR)/src/ext/pta \
              $(TOP_DIR)/test \
              $(TOP_DIR)/test/small1 \
              $(TOP_DIR)/ocamlutil

	cp $(patsubst %,%,$(DISTRIB_ROOT)) $(TOP_DIR)

	cp $(patsubst %,src/%,$(DISTRIB_SRC)) $(TOP_DIR)/src
	cp $(patsubst %,ocamlutil/%,$(DISTRIB_OCAMLUTIL)) $(TOP_DIR)/ocamlutil
	cp $(patsubst %,src/ext/%,$(DISTRIB_SRC_EXT)) $(TOP_DIR)/src/ext
	cp $(patsubst %,src/ext/pta/%,$(DISTRIB_SRC_EXT_PTA)) \
                                      $(TOP_DIR)/src/ext/pta
	cp $(patsubst %,src/frontc/%,$(DISTRIB_SRC_FRONTC)) \
		$(TOP_DIR)/src/frontc
	cp $(patsubst %,lib/%,$(DISTRIB_LIB)) $(TOP_DIR)/lib
	cp $(patsubst %,bin/%,$(DISTRIB_BIN)) $(TOP_DIR)/bin
	cp $(patsubst %,test/small1/%,$(DISTRIB_SMALL1)) $(TOP_DIR)/test/small1

	cp -r doc/html/cil/* $(TOP_DIR)/doc
	cp debian/* $(TOP_DIR)/debian

# Delete all Subversion metadata directories
	find $(TEMP_DIR) -name .svn -print0 | xargs -0 rm -rf

# Now make the TAR ball
	cd $(TEMP_DIR); tar cfz $(CIL_TAR_GZ) cil
	mv $(TEMP_DIR)/$(CIL_TAR_GZ) .

#	rm -rf $(TEMP_DIR)

## Check a distribution
checkdistrib:
	cd $(TOP_DIR) && ./configure && \
           $(MAKE) && $(MAKE) quicktest

distclean: clean
	rm -f src/frontc/cparser.output
	rm -f src/formatparse.output
	rm -f ocamlutil/perfcount.c
	rm -f bin/cilly.bat
	rm -f bin/patcher.bat
	rm -f bin/CilConfig.pm
	rm -f config.log
	rm -f config.h
	rm -f Makefile

## Publish the distribution
CILHTMLDEST=/var/www/cil
publish_distrib: publish_doc
	if test -d $(CILHTMLDEST); then \
           cp -rf doc/html/cil/* $(CILHTMLDEST); \
           cp -f $(CIL_TAR_GZ) $(CILHTMLDEST)/distrib; \
           ln -sf $(CILHTMLDEST)/distrib/$(CIL_TAR_GZ) $(CILHTMLDEST)/distrib/cil-latest.tar.gz ; \
           echo "Publish succeeded"; \
	else \
	   error "Cannot publish because $(CILHTMLDEST) does not exist" ; \
        fi

publish_doc: doc
	if test -d $(CILHTMLDEST); then \
           cp -rf doc/html/cil/* $(CILHTMLDEST); echo "Done publishing doc"; \
	else \
	   error "Cannot publish because $(CILHTMLDEST) does not exist" ; \
        fi

cleancheck:
	rm -f test/small1/*.o
	rm -f test/small1/hello
	rm -f test/small1/vararg1
	rm -f test/small1/wchar1

clean: cleancaml cleancheck


# Now include the compiler specific stuff
ifdef _MSVC
  include Makefile.msvc
else
  ifdef _GNUCC
    include Makefile.gcc
  endif
endif

test/%: 
	bin/cilly $(CONLY) test/small1/$*.c $(OBJOUT)test/small1/$*.o

testrun/%: 
	bin/cilly test/small1/$*.c $(OBJOUT)test/small1/$*
	test/small1/$*



.PHONY: quicktest
quicktest: $(patsubst %,test/%,func init init1) \
           $(patsubst %,testrun/%,hello wchar1 vararg1)

.PHONY: check
check: quicktest

############# Binary distribution ################
.PHONY: bindistrb checkbindistrib

BINCIL_TAR_GZ:=cil-win32-@CIL_VERSION@.tar.gz

# Work in a temporary directory
BINTEMP_DIR = TEMP_cil-bindistrib

# The tar archive members will be relative to this directory
BINTOP_DIR = $(BINTEMP_DIR)/cil

BINDISTRIB_ROOT = README LICENSE

BINDISTRIB_LIB = Cilly.pm KeptFile.pm OutputFile.pm TempFile.pm

BINDISTRIB_BIN = CilConfig.pm.in cilly cilly.bat.in \
              patcher patcher.bat.in

BINDISTRIB_OBJ = cilly.byte.exe cilly.asm.exe

BINDISTRIB_SMALL1=hello.c 

bindistrib-nocheck: $(BINDISTRIB_ROOT) obj/x86_WIN32/cilly.asm.exe
        # Create the distribution from scratch
	rm -rf $(BINTEMP_DIR)
	mkdir $(BINTEMP_DIR)

	mkdir $(BINTOP_DIR) \
              $(BINTOP_DIR)/obj \
              $(BINTOP_DIR)/doc \
	      $(BINTOP_DIR)/lib \
	      $(BINTOP_DIR)/bin \
	      $(BINTOP_DIR)/doc/api \
              $(BINTOP_DIR)/obj/.depend \
              $(BINTOP_DIR)/obj/x86_WIN32 \
              $(BINTOP_DIR)/test \
              $(BINTOP_DIR)/test/small1 

	cp $(patsubst %,%,$(BINDISTRIB_ROOT)) $(BINTOP_DIR)
	cp $(patsubst %,lib/%,$(BINDISTRIB_LIB)) $(BINTOP_DIR)/lib
	cat bin/CilConfig.pm.in \
            | sed -e "s|@||g" \
            | sed -e "s|CC|cl|" \
            | sed -e "s|DEFAULT_CIL_MODE|MSVC|" \
            | sed -e "s|ARCHOS|x86_WIN32|" \
               > $(BINTOP_DIR)/bin/CilConfig.pm
	cat bin/patcher.bat.in | sed -e "s|@||g" >$(BINTOP_DIR)/bin/patcher.bat
	cp bin/patcher $(BINTOP_DIR)/bin
	cp bin/cilly $(BINTOP_DIR)/bin
	cat bin/cilly.bat.in | sed -e "s|@||g" > $(BINTOP_DIR)/bin/cilly.bat
	cp $(patsubst %,test/small1/%,$(BINDISTRIB_SMALL1)) \
                                                 $(BINTOP_DIR)/test/small1
	cp $(patsubst %,obj/x86_WIN32/%,$(BINDISTRIB_OBJ)) \
                                       $(BINTOP_DIR)/obj/x86_WIN32

	cp -r doc/html/cil/* $(BINTOP_DIR)/doc
# Delete all CVS directories
	if find $(BINTEMP_DIR) -name CVS -print >cvss.txt ; then \
            rm -rf `cat cvss.txt` ;fi
# Now make the TAR ball
	cd $(BINTEMP_DIR); tar cfz $(BINCIL_TAR_GZ) cil
	mv $(BINTEMP_DIR)/$(BINCIL_TAR_GZ) .

#	rm -rf $(TEMP_DIR)

## Check a distribution
checkbindistrib:

########################################################################


INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@

prefix = @prefix@
exec_prefix = @exec_prefix@
datarootdir = @datarootdir@
libdir = @libdir@
pkglibdir = $(libdir)/cil
datadir = @datadir@
pkgdatadir = $(datadir)/cil

all_distrib := $(DISTRIB_OCAMLUTIL) $(DISTRIB_SRC) $(DISTRIB_SRC_FRONTC) $(DISTRIB_SRC_EXT) $(DISTRIB_SRC_EXT_PTA)
all_ml      := $(filter %.ml,  $(all_distrib))
all_mli     := $(filter %.mli, $(all_distrib))
install_ml  := $(filter $(OCAML_CIL_LIB_MODULES:=.ml), $(all_ml))
install_cmx := $(install_ml:%.ml=$(OBJDIR)/%.cmx)
install_mli := $(filter $(OCAML_CIL_LIB_MODULES:=.mli), $(all_mli))
install_cmi := $(install_mli:%.mli=$(OBJDIR)/%.cmi)
install_cmx := $(install_mli:%.mli=$(OBJDIR)/%.cmx)
install_cma := $(addprefix $(OBJDIR)/cil., cma cmxa a)
install_lib := $(OCAML_CIL_LIB_CMODULES:%=$(OBJDIR)/lib%.a)

install: $(install_cmi) $(install_cma) $(install_lib)
	$(INSTALL) -d $(DESTDIR)$(pkglibdir)
	$(INSTALL_DATA) $(install_cma) $(DESTDIR)$(pkglibdir)
	$(INSTALL_DATA) $(install_cmi) $(DESTDIR)$(pkglibdir)
	$(INSTALL_DATA) $(install_cmx) $(DESTDIR)$(pkglibdir)
	$(INSTALL_DATA) $(install_lib) $(DESTDIR)$(pkglibdir)
	$(INSTALL) -d $(DESTDIR)$(pkgdatadir)
	$(INSTALL_DATA) $(addprefix lib/, $(filter %.pm, $(DISTRIB_LIB))) $(DESTDIR)$(pkgdatadir)

cil.spec: cil.spec.in
	./config.status $@

rpms: distrib
	rpmbuild -ta $(CIL_TAR_GZ)

install-findlib: $(install_cmi) $(install_cma) $(install_cmx)
	ocamlfind install cil META $(install_cma) $(install_cmi) $(install_cmx)

uninstall-findlib:
	ocamlfind remove cil
