# Mf-base
# Copyright 1984-2017 Cisco Systems, Inc.
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
# http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

include Mf-config

MAKEFLAGS += --no-print-directory

# the following flags control various compiler options.  flags prefixed by an x
# separately control the options used while compiling a cross compiler.

# o determines the optimize level
o = 3

# d is the debug level at which the system should be built
d = 0

# cl determines the commonization level
cl = (commonization-level)

# i determines whether inspector-information is generated: f for false, t for true
i = f

# cp0 determines the number of cp0 (source optimizer) iterations run
cp0 = 2

# fc determines whether fasl objects are compressed
fc = t

# xf determines the compression format
xf = (compress-format)

# xl determine the compression level
xl = (compress-level)

# p (xp) determines whether source profiling is enabled: f for false, t for true.
p = f
xp = f

# bp (xpb) determines whether binary profiling is enabled: f for false, t for true.
bp = f
xbp = f

# c determines whether covin files are generated: f for false, t for true.
c = f

# loadspd determines whether source-profile data is loaded: f for false, t for true
loadspd = f

# dumpspd determines whether source-profile data is dumped: f for false, t for true
dumpspd = f

# loadbpd determines whether binary-profile data is loaded: f for false, t for true
loadbpd = f

# dumpbpd determines whether binary-profile data is dumped: f for false, t for true
dumpbpd = f

# compile determines the entry point for compilng files
# another useful value for this is compile-with-asm, defined in debug.ss
compile = compile-file

# pdhtml determines whether profile-dump-html is called at the end of a build
pdhtml = f

# gac determines whether cost-center allocation counts are generated: f for false, t for true
gac = f

# gic determines whether cost-center instruction counts are generated: f for false, t for true
gic = f

# pps determines whether pass timings are printed
pps = f

# Explicit ".exe" needed for WSL
ifeq ($(OS),Windows_NT)
  ExeSuffix = .exe
else
  ExeSuffix =
endif

# The following control where files sit and typically don't need to be changed, except
# that Scheme and SCHEMEHEAPDIRS are set by Mf-cross to point to the host Scheme
# implementation
Scheme = ../bin/$m/scheme${ExeSuffix}
export SCHEMEHEAPDIRS=../boot/%m
export CHEZSCHEMELIBDIRS=.

# Define the libdirs separator character
ifeq ($(OS),Windows_NT)
  dirsep = ;
else
  dirsep = :
endif

ProfileDumpSource = source.pd
ProfileDumpBlock = block.pd
PetiteBootRel = boot/$m/petite.boot
PetiteBoot = ../${PetiteBootRel}
SchemeBootRel = boot/$m/scheme.boot
SchemeBoot = ../${SchemeBootRel}
Cheader = ../boot/$m/scheme.h
Cequates = ../boot/$m/equates.h
Cgcocd = ../boot/$m/gc-ocd.inc
Cgcoce = ../boot/$m/gc-oce.inc
Cgcpar = ../boot/$m/gc-par.inc
Cheapcheck = ../boot/$m/heapcheck.inc
Revision = ../boot/$m/revision

# The following controls the patch files loaded before compiling, typically used only
# to load a new compiler for cross compilation
patchfile =
patch = patch

# putting cpnanopass.patch early for maximum make --jobs=2 benefit
patchobj = patch.patch cpnanopass.patch cpprim.patch cprep.patch cpcheck.patch\
 cp0.patch cpvalid.patch cptypes.patch cpcommonize.patch cpletrec.patch\
 reloc.patch\
 compile.patch fasl.patch vfasl.patch syntax.patch env.patch\
 read.patch interpret.patch ftype.patch strip.patch\
 ubify.patch back.patch

#ordering constraints:
#first: library, prims, mathprims, front, 5_?
#last: back
#newhash before read
#io before read
#event before 4
#ftype after syntax
#layout and record before strnum (first define-record)
#date before 7
#(there may be other constraints as well)

basesrc =\
 library.ss prims.ss mathprims.ss record.ss 5_1.ss 5_2.ss 5_3.ss\
 strnum.ss bytevector.ss 5_4.ss 5_6.ss 5_7.ss\
 event.ss 4.ss front.ss foreign.ss 6.ss print.ss newhash.ss\
 format.ss date.ss 7.ss cafe.ss trace.ss engine.ss\
 interpret.ss cprep.ss cpcheck.ss cp0.ss cpvalid.ss  cptypes.ss cpcommonize.ss cpletrec.ss inspect.ss\
 enum.ss io.ss read.ss primvars.ss syntax.ss costctr.ss expeditor.ss\
 exceptions.ss pretty.ss env.ss\
 fasl.ss vfasl.ss reloc.ss pdhtml.ss strip.ss ftype.ss back.ss

baseobj = ${basesrc:%.ss=%.$m}

compilersrc =\
 cpnanopass.ss cpprim.ss compile.ss cback.ss

compilerobj = ${compilersrc:%.ss=%.$m}

src = ${basesrc} ${compilersrc}
obj = ${baseobj} ${compilerobj}
asm = $(basesrc:%.ss=%.asm)

macroobj =\
 cmacros.so priminfo.so primvars.so env.so setup.so

allsrc =\
 ${basesrc} ${compilersrc} cmacros.ss ${archincludes} setup.ss debug.ss priminfo.ss primdata.ss layout.ss\
 base-lang.ss expand-lang.ss primref.ss types.ss io-types.ss fasl-helpers.ss hashtable-types.ss\
 np-languages.ss fxmap.ss cptypes-lattice.ss strip-types.ss np-register.ss np-info.ss np-help.ss

# doit uses a different Scheme process to compile each target
doit: ${PetiteBoot} ${SchemeBoot} ${Cheader} ${Cequates} ${Cgcocd} ${Cgcoce} ${Cgcpar} ${Cheapcheck} ${Revision}

# all uses a single Scheme process to compile all targets.  this is typically
# faster when most of the targets need to be recompiled.
all: bootall ${Cheader} ${Cequates} ${Cgcocd} ${Cgcoce} ${Cgcpar} ${Cheapcheck} ${Revision}

# allx runs all up to three times and checks to see if the new boot file is the
# same as the last, i.e., the system is properly bootstrapped.
allx: prettyclean saveboot
	$(MAKE) all
	if $(MAKE) checkboot > /dev/null 2>&1; then echo fine ; else\
          $(MAKE) prettyclean saveboot &&\
          $(MAKE) all &&\
          if $(MAKE) checkboot > /dev/null 2>&1; then echo fine ; else\
            $(MAKE) prettyclean saveboot &&\
            $(MAKE) all &&\
            $(MAKE) checkboot ;\
          fi\
        fi
	$(MAKE) restoreboot
ifneq ($(OS),Windows_NT)
	$(MAKE) resetbootlinks
endif

# bootstrap runs allx if any sources have changed since the last bootstrap
bootstrap: ${allsrc} | ${Revision}
	$(MAKE) allx
	touch bootstrap

# source eagerly creates links to most of the files that might be needed
source: ${allsrc} mkheader.ss mkgc.ss script.all

# profiled goes through the involved process of building a profile-optimized boot file
profiled:
	$(MAKE) profileclean
	$(MAKE) all p=t
	$(MAKE) prettyclean
	$(MAKE) io.$m dumpspd=t
	$(MAKE) prettyclean
	$(MAKE) all loadspd=t bp=t PetiteBoot=../boot/$m/xpetite.boot SchemeBoot=../boot/$m/xscheme.boot
	$(MAKE) prettyclean
	$(MAKE) io.$m loadspd=t dumpbpd=t Scheme="../bin/$m/scheme -b ../boot/$m/xpetite.boot -b ../boot/$m/xscheme.boot"
	rm -f ../boot/$m/xpetite.boot ../boot/$m/xscheme.boot
	$(MAKE) prettyclean
	$(MAKE) all loadspd=t loadbpd=t

# clean removes the products of the targets above
clean: profileclean
	rm -f bootstrap
	rm -f Make.out

# the remaining targets are typically not useful except to support those above

.SUFFIXES:
.SUFFIXES: .ss .$m .patch .so .asm

.ss.$m:
	echo '(reset-handler abort)'\
             '(optimize-level $o)'\
             '(debug-level $d)'\
             '(commonization-level $(cl))'\
             '(fasl-compressed #$(fc))'\
             '(compress-format $(xf))'\
             '(compress-level $(xl))'\
             '(when #$p (compile-profile (quote source)))'\
             '(when #$(bp) (compile-profile (quote block)))'\
             '(when #$(loadspd) (profile-load-data "${ProfileDumpSource}"))'\
             '(when #$(loadbpd) (profile-load-data "${ProfileDumpBlock}"))'\
             '(generate-inspector-information #$i)'\
             '(generate-allocation-counts #${gac})'\
             '(generate-instruction-counts #${gic})'\
             '(generate-covin-files #$c)'\
             '(run-cp0 (lambda (cp0 x)'\
             '           (do ([i ${cp0} (fx- i 1)] [x x (cp0 x)])'\
             '               ((fx= i 0) x))))'\
             '(collect-trip-bytes (expt 2 24))'\
             '(collect-request-handler (lambda () (collect 0 1)))'\
             '(collect 1 2)'\
             '(delete-file "$*.covin")'\
             '(time (${compile} "$*.ss" "$*.$m" (quote $m)))'\
             '(printf "    ~a bytes peak memory use~n" (maximum-memory-bytes))' \
             '(when #${pdhtml} (profile-dump-html))'\
             '(when #${dumpspd} (profile-dump-data "${ProfileDumpSource}"))'\
             '(when #${dumpbpd} (profile-dump-data "${ProfileDumpBlock}"))'\
             | ${Scheme} -q ${macroobj} ${patchfile}

.ss.asm:
	echo '(reset-handler abort)'\
             '(optimize-level $o)'\
             '(debug-level $d)'\
             '(commonization-level $(cl))'\
             '(fasl-compressed #$(fc))'\
             '(compress-format $(xf))'\
             '(compress-level $(xl))'\
             '(when #$p (compile-profile (quote source)))'\
             '(when #$(bp) (compile-profile (quote block)))'\
             '(when #$(loadspd) (profile-load-data "${ProfileDumpSource}"))'\
             '(when #$(loadbpd) (profile-load-data "${ProfileDumpBlock}"))'\
             '(generate-inspector-information #$i)'\
             '(generate-allocation-counts #${gac})'\
             '(generate-instruction-counts #${gic})'\
             '(generate-covin-files #$c)'\
             '(run-cp0 (lambda (cp0 x)'\
             '           (do ([i ${cp0} (fx- i 1)] [x x (cp0 x)])'\
             '               ((fx= i 0) x))))'\
             '(collect-trip-bytes (expt 2 24))'\
             '(collect-request-handler (lambda () (collect 0 1)))'\
             '(collect 1 2)'\
             '(print-gensym (quote pretty/suffix))'\
             '(delete-file "$*.covin")'\
             '(compile-with-asm "$*.ss" "$*.$m" (quote $m))'\
             '(when #${pdhtml} (profile-dump-html))'\
             '(when #${dumpspd} (profile-dump-data "${ProfileDumpSource}"))'\
             '(when #${dumpbpd} (profile-dump-data "${ProfileDumpBlock}"))'\
             | ${Scheme} -q ${macroobj} ${patchfile}

.ss.so:
	echo '(reset-handler abort)'\
             '(base-exception-handler (lambda (c) (fresh-line) (display-condition c) (newline) (reset)))'\
	     '(keyboard-interrupt-handler (lambda () (display "interrupted---aborting\n") (reset)))'\
             '(optimize-level $o)'\
             '(debug-level $d)'\
             '(commonization-level $(cl))'\
             '(fasl-compressed #$(fc))'\
             '(compress-format $(xf))'\
             '(compress-level $(xl))'\
             '(generate-inspector-information #$i)'\
             '(subset-mode (quote system))'\
             '(compile-file "$*.ss" "$*.so")'\
             | ${Scheme} -q cmacros.so priminfo.so

.ss.patch:
	echo '(reset-handler abort)'\
             '(optimize-level $o)'\
             '(debug-level $d)'\
             '(commonization-level $(cl))'\
             '(fasl-compressed #$(fc))'\
             '(compress-format $(xf))'\
             '(compress-level $(xl))'\
             '(when #$(xp) (compile-profile (quote source)))'\
             '(when #$(xbp) (compile-profile (quote block)))'\
             '(generate-inspector-information #$i)'\
             '(run-cp0 (lambda (cp0 x)'\
             '           (do ([i ${cp0} (fx- i 1)] [x x (cp0 x)])'\
             '               ((fx= i 0) x))))'\
             '(collect-trip-bytes (expt 2 24))'\
             '(collect-request-handler (lambda () (collect 0 1)))'\
             '(collect 1 2)'\
             '(time (${compile} "$*.ss" "$*.patch" (quote $m)))'\
             '(printf "    ~a bytes peak memory use~n" (maximum-memory-bytes))' \
             | ${Scheme} -q ${macroobj}

saveboot:
	cp -p -f ${PetiteBoot} ../boot/$m/sbb
	cp -p -f ${SchemeBoot} ../boot/$m/scb

checkboot:
	@echo '(reset-handler abort)'\
              '(base-exception-handler (lambda (c) (fresh-line) (display-condition c) (newline) (reset)))'\
              '(begin'\
                 '(#%$$fasl-file-equal? "../boot/$m/sbb" "../boot/$m/petite.boot" #t)'\
                 '(#%$$fasl-file-equal? "../boot/$m/scb" "../boot/$m/scheme.boot" #t)'\
                 '(printf "bootfile comparison succeeded\n"))'\
             | ../bin/$m/scheme${ExeSuffix} -b ../boot/$m/sbb -q

xcheckboot: ${macroobj} ${patchfile}
	@echo '(reset-handler abort)'\
              '(base-exception-handler (lambda (c) (fresh-line) (display-condition c) (newline) (reset)))'\
              '(begin'\
                 '(#%$$fasl-file-equal? "../boot/$m/sbb" "../boot/$m/petite.boot" #t)'\
                 '(#%$$fasl-file-equal? "../boot/$m/scb" "../boot/$m/scheme.boot" #t)'\
                 '(printf "bootfile comparison succeeded\n"))'\
             | ${Scheme} -q ${macroobj} ${patchfile}

restoreboot:
	-mv -f ../boot/$m/sbb ${PetiteBoot}
	-mv -f ../boot/$m/scb ${SchemeBoot}

resetbootlinks:
	-@echo '(reset-handler abort)'\
               '(for-each'\
                  '(lambda (fn)'\
                     '(let ([fn (format "../~a" fn)]'\
                           '[bn (format "$upupbootdir/~a" fn)]'\
                           '[q  (integer->char 34)])'\
                        '(unless (file-symbolic-link? fn)'\
                           '(when (guard (c [else #f]) (#%$$fasl-file-equal? bn fn))'\
                              '(system (format "ln -sf ~a~a~a ~a" q fn q fn))'\
                              '(void)))))'\
                  '(list (quote ${SchemeBootRel}) (quote ${PetiteBootRel})))'\
             | ${Scheme} -q

keepbootfiles:
	for x in `echo scheme.boot petite.boot scheme.h equates.h gc-oce.inc gc-ocd.inc gc-par.inc heapcheck.inc` ; do\
          if [ ! -h ../boot/$(m)/$$x ] ; then \
            mv -f ../boot/$(m)/$$x ../../boot/$(m)/$$x ;\
          elif [ "${upupupbootdir}" != "../../.." ] ; then \
            cp ../boot/$(m)/$$x ../../boot/$(m)/$$x ;\
          fi ;\
        done

${PetiteBoot}: ${macroobj} ${patchfile} ${baseobj}
	echo '(reset-handler abort)'\
             '(generate-covin-files #$c)'\
             '(delete-file (string-append (path-root "${PetiteBoot}") ".covin"))'\
             '(apply #%$$make-boot-file "${PetiteBoot}" (quote $m) (quote ())'\
             '  (map symbol->string (quote (${baseobj}))))'\
             | ${Scheme} -q ${macroobj} ${patchfile}

${SchemeBoot}: ${macroobj} ${patchfile} ${compilerobj}
	echo '(reset-handler abort)'\
             '(generate-covin-files #$c)'\
             '(delete-file (string-append (path-root "${SchemeBoot}") ".covin"))'\
             '(apply #%$$make-boot-file "${SchemeBoot}" (quote $m) (quote ("petite"))'\
             '  (map symbol->string (quote (${compilerobj}))))'\
             | ${Scheme} -q ${macroobj} ${patchfile}

cmacros.so: cmacros.ss machine.def default.def layout.ss
	echo '(reset-handler abort)'\
             '(base-exception-handler (lambda (c) (fresh-line) (display-condition c) (newline) (reset)))'\
             '(keyboard-interrupt-handler (lambda () (display "interrupted---aborting\n") (reset)))'\
             '(optimize-level $o)'\
             '(debug-level $d)'\
             '(commonization-level $(cl))'\
             '(fasl-compressed #$(fc))'\
             '(compress-format $(xf))'\
             '(compress-level $(xl))'\
             '(generate-inspector-information #$i)'\
             '(subset-mode (quote system))'\
             '(compile-file "$*.ss" "$*.so")'\
             | ${Scheme} -q

priminfo.so: priminfo.ss primdata.ss cmacros.so
	echo '(reset-handler abort)'\
             '(base-exception-handler (lambda (c) (fresh-line) (display-condition c) (newline) (reset)))'\
             '(keyboard-interrupt-handler (lambda () (display "interrupted---aborting\n") (reset)))'\
             '(optimize-level $o)'\
             '(debug-level $d)'\
             '(commonization-level $(cl))'\
             '(fasl-compressed #$(fc))'\
             '(compress-format $(xf))'\
             '(compress-level $(xl))'\
             '(generate-inspector-information #$i)'\
             '(subset-mode (quote system))'\
             '(compile-file "$*.ss" "$*.so")'\
             | ${Scheme} -q cmacros.so

# supply primvars.so as well as cmacros.so
mkheader.so: mkheader.ss cmacros.so primvars.so env.so
	echo '(reset-handler abort)'\
             '(base-exception-handler (lambda (c) (fresh-line) (display-condition c) (newline) (reset)))'\
             '(keyboard-interrupt-handler (lambda () (display "interrupted---aborting\n") (reset)))'\
             '(optimize-level $o)'\
             '(debug-level $d)'\
             '(commonization-level $(cl))'\
             '(fasl-compressed #$(fc))'\
             '(compress-format $(xf))'\
             '(compress-level $(xl))'\
             '(generate-inspector-information #$i)'\
             '(subset-mode (quote system))'\
             '(compile-file "$*.ss" "$*.so")'\
             | ${Scheme} -q cmacros.so priminfo.so primvars.so env.so

mkgc.so: mkgc.ss mkheader.so cmacros.so primvars.so env.so
	echo '(reset-handler abort)'\
             '(base-exception-handler (lambda (c) (fresh-line) (display-condition c) (newline) (reset)))'\
             '(keyboard-interrupt-handler (lambda () (display "interrupted---aborting\n") (reset)))'\
             '(optimize-level 0)'\
             '(debug-level $d)'\
             '(commonization-level $(cl))'\
             '(fasl-compressed #$(fc))'\
             '(compress-format $(xf))'\
             '(compress-level $(xl))'\
             '(generate-inspector-information #$i)'\
             '(subset-mode (quote system))'\
             '(compile-file "$*.ss" "$*.so")'\
             | ${Scheme} -q cmacros.so priminfo.so primvars.so env.so mkheader.so

nanopass.so: $(shell echo ../nanopass/nanopass/*) ../nanopass/nanopass.ss
	echo '(reset-handler abort)'\
             '(base-exception-handler (lambda (c) (fresh-line) (display-condition c) (newline) (reset)))'\
             '(keyboard-interrupt-handler (lambda () (display "interrupted---aborting\n") (reset)))'\
             '(optimize-level $o)'\
             '(debug-level $d)'\
             '(commonization-level $(cl))'\
             '(fasl-compressed #$(fc))'\
             '(compress-format $(xf))'\
             '(compress-level $(xl))'\
             '(generate-inspector-information #$i)'\
             '(collect-trip-bytes (expt 2 24))'\
             '(collect-request-handler (lambda () (collect 0 1)))'\
             '(collect 1 2)'\
             '(compile-library "../nanopass/nanopass.ss" "nanopass.so")'\
             | ${Scheme} -q --libdirs "../nanopass${dirsep}${dirsep}." --compile-imported-libraries

rootsrc = $(shell cd "${upupsrcdir}"/s; echo *)
${rootsrc}:
ifeq ($(OS),Windows_NT)
	cp -p "${upupsrcdir}"/s/$@ $@
else
	ln -s "${upupsrcdir}"/s/$@ $@
endif

script.all: Mf-base

script.all makescript:
	echo '(reset-handler abort)'\
             '(for-each load (command-line-arguments))'\
             '(optimize-level $o)'\
             '(debug-level $d)'\
             '(commonization-level $(cl))'\
             '(fasl-compressed #$(fc))'\
             '(compress-format $(xf))'\
             '(compress-level $(xl))'\
             '(when #$p (compile-profile (quote source)))'\
             '(when #$(bp) (compile-profile (quote block)))'\
             '(when #$(loadspd) (profile-load-data "${ProfileDumpSource}"))'\
             '(when #$(loadbpd) (profile-load-data "${ProfileDumpBlock}"))'\
             '(generate-inspector-information #$i)'\
             '(generate-allocation-counts #${gac})'\
             '(generate-instruction-counts #${gic})'\
             '(#%$$enable-pass-timing #${pps})'\
             '(generate-covin-files #$c)'\
             '(run-cp0 (lambda (cp0 x)'\
             '           (do ([i ${cp0} (fx- i 1)] [x x (cp0 x)])'\
             '               ((fx= i 0) x))))'\
             '(collect-trip-bytes (expt 2 24))'\
             '(collect-request-handler (lambda () (collect 0 1)))'\
             '(for-each (lambda (x) (delete-file (string-append (path-root (symbol->string x)) ".covin"))) (quote (${obj})))'\
             '(time (for-each (lambda (x y)'\
             '                   (collect 1 2)'\
             '                   (${compile} (symbol->string x)'\
             '                                 (symbol->string y)'\
             '                                 (quote $m)))'\
             '                (quote (${src}))'\
             '                (quote (${obj}))))'\
             '(printf "    ~a bytes peak memory use~n" (maximum-memory-bytes))' \
             '(when #${pps} (#%$$print-pass-stats))'\
             '(delete-file (string-append (path-root "${PetiteBoot}") ".covin"))'\
             '(apply #%$$make-boot-file "${PetiteBoot}" (quote $m) (quote ())'\
             '  (map symbol->string (quote (${baseobj}))))'\
             '(delete-file (string-append (path-root "${SchemeBoot}") ".covin"))'\
             '(apply #%$$make-boot-file "${SchemeBoot}" (quote $m) (quote ("petite"))'\
             '  (map symbol->string (quote (${compilerobj}))))'\
             '(when #${pdhtml} (profile-dump-html))'\
             '(when #${dumpspd} (profile-dump-data "${ProfileDumpSource}"))'\
             '(when #${dumpbpd} (profile-dump-data "${ProfileDumpBlock}"))'\
             > script.all

script-static.all:
	echo '(reset-handler abort)'\
             '(for-each load (command-line-arguments))'\
             '(optimize-level $o)'\
             '(debug-level $d)'\
             '(commonization-level $(cl))'\
             '(fasl-compressed #$(fc))'\
             '(compress-format $(xf))'\
             '(compress-level $(xl))'\
             '(when #$p (compile-profile (quote source)))'\
             '(when #$(bp) (compile-profile (quote block)))'\
             '(generate-inspector-information #$i)'\
             '(generate-allocation-counts #${gac})'\
             '(generate-instruction-counts #${gic})'\
             '(generate-covin-files #$c)'\
             '(run-cp0 (lambda (cp0 x)'\
             '           (do ([i ${cp0} (fx- i 1)] [x x (cp0 x)])'\
             '               ((fx= i 0) x))))'\
             '(for-each (lambda (x) (delete-file (string-append (path-root (symbol->string x)) ".covin"))) (quote (${obj})))'\
             '(compile-with-setup-closure-counts (quote (${closure-opt})) (quote (${src})) (quote (${obj})) (quote $m) #$r)'\
             '(delete-file (string-append (path-root "${PetiteBoot}") ".covin"))'\
             '(apply #%$$make-boot-file "${PetiteBoot}" (quote $m) (quote ())'\
             '  (map symbol->string (quote (${baseobj}))))'\
             '(delete-file (string-append (path-root "${SchemeBoot}") ".covin"))'\
             '(apply #%$$make-boot-file "${SchemeBoot}" (quote $m) (quote ("petite"))'\
             '  (map symbol->string (quote (${compilerobj}))))'\
             '(when #${pdhtml} (profile-dump-html))'\
             > script-static.all

script-dynamic.all:
	echo '(reset-handler abort)'\
             '(for-each load (command-line-arguments))'\
             '(optimize-level $o)'\
             '(debug-level $d)'\
             '(commonization-level $(cl))'\
             '(fasl-compressed #$(fc))'\
             '(compress-format $(xf))'\
             '(compress-level $(xl))'\
             '(when #$p (compile-profile (quote source)))'\
             '(when #$(bp) (compile-profile (quote block)))'\
             '(generate-inspector-information #$i)'\
             '(generate-allocation-counts #${gac})'\
             '(generate-instruction-counts #${gic})'\
             '(generate-covin-files #$c)'\
             '(run-cp0 (lambda (cp0 x)'\
             '           (do ([i ${cp0} (fx- i 1)] [x x (cp0 x)])'\
             '               ((fx= i 0) x))))'\
             '(for-each (lambda (x) (delete-file (string-append (path-root (symbol->string x)) ".covin"))) (quote (${obj})))'\
             '(compile-with-closure-counts (quote (${closure-opt})) (quote (${src})) (quote (${obj})) (quote $m) #$r)'\
             '(delete-file (string-append (path-root "${PetiteBoot}") ".covin"))'\
             '(apply #%$$make-boot-file "${PetiteBoot}" (quote $m) (quote ())'\
             '  (map symbol->string (quote (${baseobj}))))'\
             '(delete-file (string-append (path-root "${SchemeBoot}") ".covin"))'\
             '(apply #%$$make-boot-file "${SchemeBoot}" (quote $m) (quote ("petite"))'\
             '  (map symbol->string (quote (${compilerobj}))))'\
             '(when #${pdhtml} (profile-dump-html))'\
             > script-dynamic.all

closure-counts:  ${allsrc} ${patchfile} ${macroobj} nanopass.so base-lang.ss expand-lang.ss primref.ss types.ss io-types.ss fasl-helpers.ss hashtable-types.ss script-static.all script-dynamic.all
	${Scheme} -q ${macroobj} ${patchfile} --script script-static.all
	$(MAKE) ${PetiteBoot} ${SchemeBoot}
	${Scheme} -q ${macroobj} ${patchfile} --script script-dynamic.all
	$(MAKE) all

bootall: ${allsrc} ${patchfile} ${macroobj} nanopass.so makescript
	${Scheme} -q ${macroobj} ${patchfile} --script script.all

${patch}: ${patchobj}
	rm -f ${patch}
	cat ${patchobj} > ${patch}

${asm} ${obj} mkheader.so: ${macroobj} nanopass.so base-lang.ss expand-lang.ss primref.ss types.ss io-types.ss fasl-helpers.ss hashtable-types.ss ${patchfile}
primvars.so setup.so mkheader.so env.so: cmacros.so priminfo.so primref.ss
setup.so: debug.ss
strip.so: strip-types.ss
vfasl.so: strip-types.ss

${patchobj}: ${macroobj} nanopass.so base-lang.ss expand-lang.ss primref.ss types.ss io-types.ss fasl-helpers.ss hashtable-types.ss strip-types.ss env.ss fxmap.ss cptypes-lattice.ss 
cpnanopass.$m cpnanopass.patch cpnanopass.so cpprim.$m cpprim.patch: nanopass.so np-languages.ss np-register.ss np-info.ss np-help.ss ${archincludes}
cptypes.$m: fxmap.ss cptypes-lattice.ss
5_4.$m: ../unicode/unicode-char-cases.ss ../unicode/unicode-charinfo.ss
strip.$m: strip-types.ss
vfasl.$m: strip-types.ss

${Cheader}: mkheader.so ${macroobj} nanopass.so base-lang.ss expand-lang.ss primref.ss types.ss io-types.ss fasl-helpers.ss hashtable-types.ss
	(if [ -r ${Cheader} ]; then mv -f ${Cheader} ${Cheader}.bak; fi)
	echo '(reset-handler abort)'\
             '(mkscheme.h "${Cheader}" (quote $m))' |\
         ${Scheme} -q ${macroobj} mkheader.so
	(if `cmp -s ${Cheader} ${Cheader}.bak`;\
          then mv -f ${Cheader}.bak ${Cheader};\
          else rm -f ${Cheader}.bak; fi)

${Cequates}: mkheader.so ${macroobj} nanopass.so base-lang.ss expand-lang.ss primref.ss types.ss io-types.ss fasl-helpers.ss hashtable-types.ss
	(if [ -r ${Cequates} ]; then mv -f ${Cequates} ${Cequates}.bak; fi)
	echo '(reset-handler abort)'\
             '(mkequates.h "${Cequates}")' |\
         ${Scheme} -q ${macroobj} mkheader.so
	(if `cmp -s ${Cequates} ${Cequates}.bak`;\
          then mv -f ${Cequates}.bak ${Cequates};\
          else rm -f ${Cequates}.bak; fi)

${Cgcocd}: mkgc.so ${macroobj} nanopass.so base-lang.ss expand-lang.ss primref.ss types.ss io-types.ss fasl-helpers.ss hashtable-types.ss
	(if [ -r ${Cgcocd} ]; then mv -f ${Cgcocd} ${Cgcocd}.bak; fi)
	echo '(reset-handler abort)'\
             '(mkgc-ocd.inc "${Cgcocd}")' |\
         ${Scheme} -q ${macroobj} mkheader.so mkgc.so
	(if `cmp -s ${Cgcocd} ${Cgcocd}.bak`;\
          then mv -f ${Cgcocd}.bak ${Cgcocd};\
          else rm -f ${Cgcocd}.bak; fi)

${Cgcoce}: mkgc.so ${macroobj} nanopass.so base-lang.ss expand-lang.ss primref.ss types.ss io-types.ss fasl-helpers.ss hashtable-types.ss
	(if [ -r ${Cgcoce} ]; then mv -f ${Cgcoce} ${Cgcoce}.bak; fi)
	echo '(reset-handler abort)'\
             '(mkgc-oce.inc "${Cgcoce}")' |\
         ${Scheme} -q ${macroobj} mkheader.so mkgc.so
	(if `cmp -s ${Cgcoce} ${Cgcoce}.bak`;\
          then mv -f ${Cgcoce}.bak ${Cgcoce};\
          else rm -f ${Cgcoce}.bak; fi)

${Cgcpar}: mkgc.so ${macroobj} nanopass.so base-lang.ss expand-lang.ss primref.ss types.ss io-types.ss fasl-helpers.ss hashtable-types.ss
	(if [ -r ${Cgcpar} ]; then mv -f ${Cgcpar} ${Cgcpar}.bak; fi)
	echo '(reset-handler abort)'\
             '(mkgc-par.inc "${Cgcpar}")' |\
         ${Scheme} -q ${macroobj} mkheader.so mkgc.so
	(if `cmp -s ${Cgcpar} ${Cgcpar}.bak`;\
          then mv -f ${Cgcpar}.bak ${Cgcpar};\
          else rm -f ${Cgcpar}.bak; fi)

${Cheapcheck}: mkgc.so ${macroobj} nanopass.so base-lang.ss expand-lang.ss primref.ss types.ss io-types.ss fasl-helpers.ss hashtable-types.ss
	(if [ -r ${Cheapcheck} ]; then mv -f ${Cheapcheck} ${Cheapcheck}.bak; fi)
	echo '(reset-handler abort)'\
             '(mkheapcheck.inc "${Cheapcheck}")' |\
         ${Scheme} -q ${macroobj} mkheader.so mkgc.so
	(if `cmp -s ${Cheapcheck} ${Cheapcheck}.bak`;\
          then mv -f ${Cheapcheck}.bak ${Cheapcheck};\
          else rm -f ${Cheapcheck}.bak; fi)

.PHONY: ${Revision}
${Revision}: update-revision
	@./update-revision > ${Revision}

examples:
	( cd ../examples && ${MAKE} all Scheme="${Scheme}" SchemeArg="../s/${patchfile}" )

prettyclean:
	rm -f *.$m xpatch ${patch} *.patch *.so *.covin *.asm script.all header.tmp *.html
	rm -rf nanopass

profileclean: prettyclean
	rm -f ${ProfileDumpSource} ${ProfileDumpBlock}

.PHONY: reset
reset:
	$(MAKE) reset-one FILE=petite.boot
	$(MAKE) reset-one FILE=scheme.boot
	$(MAKE) reset-one FILE=equates.h
	$(MAKE) reset-one FILE=scheme.h
	$(MAKE) reset-one FILE=gc-oce.inc
	$(MAKE) reset-one FILE=gc-ocd.inc
	$(MAKE) reset-one FILE=gc-par.inc
	$(MAKE) reset-one FILE=heapcheck.inc

.PHONY: reset-one
reset-one:
	if [ -f ../boot/${m}/${FILE} ] ; then rm ../boot/${m}/${FILE} ; fi
	if [ ! -h ../boot/${m}/${FILE} ] ; then ln -s "${upupupbootdir}"/boot/${m}/${FILE} ../boot/${m}/${FILE} ; fi

.PHONY: run
run:
	env SCHEMEHEAPDIRS=../boot/$m/ ../bin/$m/scheme $(ARGS)
