#; ACL2 Version 2.9 -- A Computational Logic for Applicative Common Lisp
#; Copyright (C) 2004  University of Texas at Austin

#; This version of ACL2 is a descendent of ACL2 Version 1.9, Copyright
#; (C) 1997 Computational Logic, Inc.  See the documentation topic NOTES-2-0.

#; This program 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 2 of the License, or
#; (at your option) any later version.

#; This program 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, write to the Free Software
#; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

#; Written by:  Matt Kaufmann               and J Strother Moore
#; email:       Kaufmann@cs.utexas.edu      and Moore@cs.utexas.edu
#; Department of Computer Sciences
#; University of Texas at Austin
#; Austin, TX 78712-1188 U.S.A.

#; Adapted from makefiles for IHS and data-structures library, which were
#; created by Bishop Brock.

#; NOTE:  Target "all" causes a recursive invocation of make with ACL2 set to
#; its current value.  These recursive invocations of make thus have ACL2 set
#; on the command line, which overrides any values of ACL2 set in those files.
#; This should not cause any problems unless you try to do something fancy; see
#; the comment for example just above target .exercises.cert in
#; books/case-studies/ivy/ivy-v2/ivy-sources/Makefile from the ACL2
#; distribution.

# Success can be determined by checking for the absence of ** in the log.

#################### Editable variables ####################

# The ACL2 macro defines how to run ACL2.  The default command below prints
# runtime statistics for the certification, and runs it `nice' in an attempt to
# lessen interference with interactive jobs.  We normally inhibit most output
# during certification to speed up the proofs.  Edit as necessary.  The setting
# below reflects an assumption regarding where this makefile will be executed,
# namely, directly under books/.  This assumption can of course be overridden
# by specifying ACL2=acl2 (or change acl2 to your saved image) on the command
# line.

ACL2 = ../../saved_acl2

# Fix problem with sh on some Linux systems:
ifeq ($(OSTYPE),linux)
	SHELL = bash
	ACL2 = ../../saved_acl2
endif
ifeq ($(OSTYPE),linux-gnu)
	SHELL = bash
	ACL2 = ../../saved_acl2
endif

# Inhibit all output except the summary (which can be useful for tracking down problems).
# Set this to "" if you do want the output.

INHIBIT = (assign inhibit-output-lst (list (quote prove) (quote proof-tree) (quote warning) (quote observation) (quote event)))

# Support for make dependencies:  should be a list of book names without
# the .lisp suffix.  Can be overridden on the command line or in a file
# that includes this file.

BOOKS = $(patsubst %.lisp, %, $(wildcard *.lisp))

#################### END of editable variables ####################

# We should really check that following is not empty.  It is the same as
# books, but with .cert suffixes.  This variable should not be overridden;
# it is computed as needed from BOOKS.

BOOKS_CERT   = $(patsubst %, %.cert, $(BOOKS))
BOOKS_FASL   = $(patsubst %, %.fasl, $(BOOKS))
BOOKS_FAS   = $(patsubst %, %.fas, $(BOOKS))
BOOKS_SPARCF = $(patsubst %, %.sparcf, $(BOOKS))
BOOKS_UFSL = $(patsubst %, %.ufsl, $(BOOKS))
BOOKS_DFSL = $(patsubst %, %.dfsl, $(BOOKS))
BOOKS_X86F = $(patsubst %, %.x86f, $(BOOKS))
BOOKS_O      = $(patsubst %, %.o, $(BOOKS))

#  This tells make to expect `suffix rules' for these file suffixes.

.SUFFIXES: .cert .lisp .date

#  This rule tells how to get <book>.cert from <book>.lisp, either by running
#  ACL2 on the <book>.acl2 file (if it exists) or using the default command
#  to certify at ground zero.  Note that some Lisps execute (LP) upon startup
#  and some do not, and some (e.g., OpenMCL) might not even start in the ACL2
#  package, which can cause a problem if .acl2 files in our regressions suite
#  execute (LP) instead of (ACL2::LP).  We deal with these issues below.

.lisp.cert:
	@echo "Making $*.cert on `date`"
	@rm -f $*.cert
	@date > $*.date
	@echo '(acl2::value :q)' > workxxx
	@echo '(in-package "ACL2")' >> workxxx
	@echo '(acl2::lp)' >> workxxx
	@echo '$(INHIBIT)' >> workxxx
	@if \
	  [ -f $*.acl2 ] ; \
	then \
	  cat $*.acl2 >> workxxx ; \
	elif \
	  [ -f cert.acl2 ] ; \
	then \
	  cat cert.acl2 >> workxxx ; \
	  echo '(certify-book "$*" ? $(COMPILE_FLG))' >> workxxx ; \
	else \
	  echo '(certify-book! "$*" 0 $(COMPILE_FLG))' >> workxxx ; \
	fi
	@echo '(acl2::value :q)' >> workxxx ; \
	echo '(acl2::exit-lisp)' >> workxxx ; \
	$(ACL2) < workxxx > $*.out
	@rm -f workxxx
	@(ls -al $*.cert) || echo "**CERTIFICATION FAILED**"
	@$(MAKE) -s -f Makefile $*.date

#  This rule checks to insure that the make was successful, where success
#  means that the <book>.cert file was created.

.date.cert:
	echo 'The make for the book $*.lisp seems to have failed.'
	rm $*.date
	false

#  This rule certifies every book in BOOKS.  If the dependencies are set up
#  correctly then the order of the books in BOOKS won't matter.

all:
	echo 'Using ACL2=$(ACL2)'
	$(MAKE) -s -f Makefile $(BOOKS_CERT) INHIBIT='$(INHIBIT)' ACL2='$(ACL2)'

# The following rules are useful when books have been certified in one lisp,
# but we would also like their compiled files to exist in the other lisp.

fasl:
	echo 'Using ACL2=$(ACL2)'
	$(MAKE) -s -f Makefile $(BOOKS_FASL) INHIBIT='$(INHIBIT)' ACL2='$(ACL2)'

%.fasl: %.cert
	echo '(acl2::value :q) (acl2::lp) (ld `((include-book "$(patsubst %.fasl,%,$(@))" :load-compiled-file :comp))) (acl2::value :q) (acl2::exit-lisp)' | $(ACL2)

fas:
	echo 'Using ACL2=$(ACL2)'
	$(MAKE) -s -f Makefile $(BOOKS_FAS) INHIBIT='$(INHIBIT)' ACL2='$(ACL2)'

# For CLISP, apparently only the first echoed form is evaluated.  So do not give multiple forms.
%.fas: %.cert
	echo '(ld `((include-book "$(patsubst %.fas,%,$(@))" :load-compiled-file :comp)))' | $(ACL2)

sparcf:
	echo 'Using ACL2=$(ACL2)'
	$(MAKE) -s -f Makefile $(BOOKS_SPARCF) INHIBIT='$(INHIBIT)' ACL2='$(ACL2)'

%.sparcf: %.cert
	echo '(acl2::value :q) (acl2::lp) (ld `((include-book "$(patsubst %.sparcf,%,$(@))" :load-compiled-file :comp))) (acl2::value :q) (acl2::exit-lisp)' | $(ACL2)

ufsl:
	echo 'Using ACL2=$(ACL2)'
	$(MAKE) -s -f Makefile $(BOOKS_UFSL) INHIBIT='$(INHIBIT)' ACL2='$(ACL2)'

%.ufsl: %.cert
	echo '(acl2::value :q) (acl2::lp) (ld `((include-book "$(patsubst %.ufsl,%,$(@))" :load-compiled-file :comp))) (acl2::value :q) (acl2::exit-lisp)' | $(ACL2)

x86f:
	echo 'Using ACL2=$(ACL2)'
	$(MAKE) -s -f Makefile $(BOOKS_X86F) INHIBIT='$(INHIBIT)' ACL2='$(ACL2)'

%.x86f: %.cert
	echo '(acl2::value :q) (acl2::lp) (ld `((include-book "$(patsubst %.x86f,%,$(@))" :load-compiled-file :comp))) (acl2::value :q) (acl2::exit-lisp)' | $(ACL2)

dfsl:
	echo 'Using ACL2=$(ACL2)'
	$(MAKE) -s -f Makefile $(BOOKS_DFSL) INHIBIT='$(INHIBIT)' ACL2='$(ACL2)'

%.dfsl: %.cert
	echo '(acl2::value :q) (acl2::lp) (ld `((include-book "$(patsubst %.dfsl,%,$(@))" :load-compiled-file :comp))) (acl2::value :q) (acl2::exit-lisp)' | $(ACL2)

o:
	echo 'Using ACL2=$(ACL2)'
	$(MAKE) -s -f Makefile $(BOOKS_O) INHIBIT='$(INHIBIT)' ACL2='$(ACL2)'

%.o: %.cert
	echo '(acl2::value :q) (acl2::lp) (ld `((include-book "$(patsubst %.o,%,$(@))" :load-compiled-file :comp))) (acl2::value :q) (acl2::exit-lisp)' | $(ACL2)

#  This rule prints make dependency commands to the screen.  For best
#  results run as `make -s dependencies'.

dependencies: 
	for book in $(BOOKS) ; \
	do \
	(echo "" ;  echo "$$book.cert: $$book.lisp" ; \
	egrep '^[^;]*(include-book|INCLUDE-BOOK)[ \t]*\".*\"' \
	`if [ -f $$book.acl2 ]; then echo "$$book.acl2"; fi` $$book.lisp) | \
	sed "s/[^\"]*\"/$$book.cert: /" | sed 's/".*/.cert/' ;\
	done

clean:
	rm -f *.cert
	rm -f *.o
	rm -f *.h
	rm -f *.c
	rm -f *.lib
	rm -f *.fasl
	rm -f *.fas
	rm -f *.sbin
	rm -f *.lbin
	rm -f *.pfsl
	rm -f *.cfsl
	rm -f *.bin
	rm -f *.sparcf
	rm -f *.ufsl
	rm -f *.dfsl
	rm -f *.x86f
	rm -f *.axpf
	rm -f *.out
	rm -f *.date
	rm -f *.log
	rm -f TMP.*
	rm -f TMP1.*
	rm -f workxxx
