## Copyright (c) 1991-2002, The Numerical Algorithms Group Ltd.
## All rights reserved.
## Copyright (C) 2007-2008, Gabriel Dos Reis.
## All rights reserved.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions are
## met:
##
##     - Redistributions of source code must retain the above copyright
##       notice, this list of conditions and the following disclaimer.
##
##     - Redistributions in binary form must reproduce the above copyright
##       notice, this list of conditions and the following disclaimer in
##       the documentation and/or other materials provided with the
##       distribution.
##
##     - Neither the name of The Numerical ALgorithms Group Ltd. nor the
##       names of its contributors may be used to endorse or promote products
##       derived from this software without specific prior written permission.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
## IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
## PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
## OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
## LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
## NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
## SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##

##
## Abstract:
##   OpenAxiom is built in layers. The first layer is contructed into
##   an image called `bootsys'. The `bootsys' image is used
##   to translate Boot code to Common Lisp code.  Since a Boot coded
##   interpreter is needed to translate the code for the Boot coded
##   interpreter we have a ``boot-strapping'' problem.  In order to get
##   the whole process to start we need certain files kept in 
##   common lisp form. This directory contains those files.
##

## We start with a Lisp image created in a previous build step (src/lisp).
## That image is used to build Boot translator executable through the
## entire bootstrap process.

AXIOM_LOCAL_LISP_sources = initial-env.lisp
AXIOM_LOCAL_LISP = ../lisp/lisp$(EXEEXT)


## FASLs that comprises `bootsys'
boot_SOURCES = initial-env.lisp $(boot_sources)
boot_sources = tokens.boot includer.boot scanner.boot \
	pile.boot ast.boot parser.boot  translator.boot
boot_clisp = $(boot_sources:.boot=.clisp)
boot_objects = initial-env.$(LNKEXT) $(boot_sources:.boot=.$(LNKEXT))

oa_target_bootdir = $(axiom_targetdir)/boot
ifeq (@axiom_lisp_flavor@,ecl)
oa_boot_linkset = $(oa_target_bootdir)/linkset
else
oa_boot_linkset = 
endif

# Garbage produced by GCL during compilation
boot_data = $(boot_sources:.boot=.data)
boot_fn = $(boot_sources:.boot=.fn)

# reference to this directory from toplevel
subdir = src/boot/
 
## Make rule toplevel entry points.
.PHONY: all-ax all-boot
all: all-ax all-boot

all-ax all-boot: stamp

stamp: $(axiom_target_bindir)/bootsys$(EXEEXT) $(oa_boot_linkset)
	@rm -f stamp
	$(STAMP) $@

## The final `bootsys' image.
$(axiom_target_bindir)/bootsys$(EXEEXT): stage2/bootsys$(EXEEXT)
	$(mkdir_p) $(axiom_target_bindir)
	cp -p $< $@

$(oa_boot_linkset): $(addprefix $(oa_target_bootdir)/, $(boot_objects))
	rm -f $@
	echo '($(patsubst %, "%", $(boot_objects)))' > $@

$(oa_target_bootdir)/%.$(LNKEXT): stage2/%.$(LNKEXT) $(oa_target_bootdir)
	cp $< $@

$(oa_target_bootdir):
	$(mkdir_p) $(oa_target_bootdir)

.PRECIOUS: strap/%.$(FASLEXT)
.PRECIOUS: strap/%.$(LNKEXT)

##
## The bootstrapping `bootsys' image.
##

# The bootstrapping Lisp code is cached in the subdirectory strap/.
# It is built first, followed by stage 1, and stage 2 `bootsys' images.
strap_boot_clisp = $(addprefix strap/, $(boot_clisp))

strap_boot_objects = \
	$(addprefix strap/, $(boot_objects))

strap/stamp: strap/bootsys$(EXEEXT)
	@rm -f $@
	@$(STAMP) $@

strap/bootsys$(EXEEXT): $(strap_boot_objects)
	$(AXIOM_LOCAL_LISP) -- --make --main="|AxiomCore|::|topLevel|"\
		--system=$(axiom_targetdir) \
		--prologue='(pushnew :open-axiom-boot *features*)' \
		 --output=$@ --load-directory=strap $(strap_boot_objects)


$(strap_boot_objects): $(AXIOM_LOCAL_LISP)

##
## Stage 1 `bootsys' image.
##

.PRECIOUS: stage1/%.$(FASLEXT)
.PRECIOUS: stage1/%.$(LNKEXT)
.PRECIOUS: stage1/%.clisp

stage1_boot_clisp = $(addprefix stage1/, $(boot_clisp))

stage1_boot_objects = \
	$(addprefix stage1/, $(boot_objects))

stage1/stamp: stage1/bootsys$(EXEEXT)
	rm -f $@
	$(STAMP) $@

stage1/bootsys$(EXEEXT): $(stage1_boot_objects)
	$(AXIOM_LOCAL_LISP) -- --make --main="|AxiomCore|::|topLevel|" \
		--system=$(axiom_targetdir) \
		--prologue='(pushnew :open-axiom-boot *features*)' \
		 --output=$@ --load-directory=stage1 $(stage1_boot_objects)

stage1/%.clisp: %.boot strap/stamp stage1/.started
	strap/bootsys -- --translate --import=skip --output=$@ $<


##
## Stage 2 `bootsys' image.
##

.PRECIOUS: stage2/%.$(FASLEXT)
.PRECIOUS: stage2/%.$(LNKEXT)
.PRECIOUS: stage2/%.clisp

stage2_boot_clisp = $(addprefix stage2/, $(boot_clisp))

stage2_boot_objects = \
	$(addprefix stage2/, $(boot_objects))

stage2/stamp: stage2/bootsys$(EXEEXT)
	@echo Building stage 2
	$(STAMP) $@

stage2/bootsys$(EXEEXT): $(stage2_boot_objects)
	$(AXIOM_LOCAL_LISP) -- --make --main="|AxiomCore|::|topLevel|" \
		--system=$(axiom_targetdir) \
		--prologue='(pushnew :open-axiom-boot *features*)' \
		--output=$@ --load-directory=stage2 $(stage2_boot_objects)

stage2/%.clisp: %.boot stage1/stamp stage2/.started
	stage1/bootsys -- --translate --import=skip --output=$@ $<

##
## Generic rules for compiling FASLs
##

.PRECIOUS: %/.started
%/.started:
	$(mkdir_p) $*
	$(STAMP) $@

## Dependency for various modules.  
## FIXME: This should be automatically extracted from the
## Boot source file at packaging time.

%/initial-env.$(LNKEXT): initial-env.lisp %/.started
	$(AXIOM_LOCAL_LISP) -- --compile --output=$@ $<

%/tokens.$(LNKEXT): %/tokens.clisp %/initial-env.$(LNKEXT)
	$(AXIOM_LOCAL_LISP) -- --output=$@ --compile --load-directory=$* $<

%/includer.$(LNKEXT): %/includer.clisp %/tokens.$(LNKEXT)
	$(AXIOM_LOCAL_LISP) -- --output=$@ --compile --load-directory=$* $<

%/scanner.$(LNKEXT): %/scanner.clisp %/tokens.$(LNKEXT) %/includer.$(LNKEXT)
	$(AXIOM_LOCAL_LISP) -- --output=$@ --compile --load-directory=$* $<

%/pile.$(LNKEXT): %/pile.clisp %/scanner.$(LNKEXT) %/includer.$(LNKEXT)
	$(AXIOM_LOCAL_LISP) -- --output=$@ --compile --load-directory=$* $<

%/ast.$(LNKEXT): %/ast.clisp %/includer.$(LNKEXT)
	$(AXIOM_LOCAL_LISP) -- --output=$@ --compile --load-directory=$* $<

%/parser.$(LNKEXT): %/parser.clisp %/ast.$(LNKEXT) %/scanner.$(LNKEXT) \
		 %/includer.$(LNKEXT)
	$(AXIOM_LOCAL_LISP) -- --output=$@ --compile --load-directory=$* $<

%/translator.$(LNKEXT): %/translator.clisp %/parser.$(LNKEXT) \
		%/ast.$(LNKEXT) %/pile.$(LNKEXT) %/scanner.$(LNKEXT) \
		%/includer.$(LNKEXT)
	$(AXIOM_LOCAL_LISP) -- --output=$@ --compile --load-directory=$* $<


##
## Cleaning mess
##

mostlyclean-local:
	@rm -f $(axiom_target_bindir)/bootsys$(EXEEXT)
	@rm -rf prev-stage
	@rm -rf strap stage1 stage2
	@rm -rf $(oa_target_bootdir)
	@rm -f *.data *.fn
	@rm -f stamp

clean-local: mostlyclean-local
	@rm -f *.clisp

distclean-local: clean-local