# Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
#     1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
#     2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014,
#     2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Massachusetts
#     Institute of Technology
#
# This file is part of MIT/GNU Scheme.
#
# MIT/GNU Scheme 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.
#
# MIT/GNU Scheme 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 MIT/GNU Scheme; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
# 02110-1301, USA.

# **** BEGIN BOILERPLATE ****

SHELL = @SHELL@

@SET_MAKE@

srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@

bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datarootdir = @datarootdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include

DESTDIR =
top_builddir = @top_builddir@

INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@

LN_S = @LN_S@
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/microcode/mkinstalldirs

# **** END BOILERPLATE ****

.PHONY: default-target
default-target: @DEFAULT_TARGET@

LIARC_BOOT_BUNDLES = compiler cref sf star-parser
LIARC_BUNDLES = $(LIARC_BOOT_BUNDLES) ffi sos ssp xml

SUBDIRS = $(INSTALLED_SUBDIRS) xdoc
INSTALLED_SUBDIRS = microcode runtime libraries $(OPTION_SUBDIRS) $(LIARC_BUNDLES)
BASICS_SUBDIRS = microcode runtime $(LIARC_BUNDLES)
OPTION_SUBDIRS = @OPTION_SUBDIRS@

MIT_SCHEME_EXE = @MIT_SCHEME_EXE@
AUXDIR_NAME = @AUXDIR_NAME@
AUXDIR = @AUXDIR@

MAKE_IN_SUBDIRS = \
	f () { t=$$1; shift; for d; do (cd "$$d" && $(MAKE) "$$t"); done; }; f

@IF_LIARC@NO_LIARC = \#;
@IF_CROSS@COMPILER_SETTINGS_CROSS = \
@IF_CROSS@	$(NO_LIARC)(set! compiler:cross-compiling? true)
@IF_CROSS@SF_SETTINGS_CROSS = \
@IF_CROSS@	$(NO_LIARC)(set! sf/cross-compiling? true) \
@IF_CROSS@	$(NO_LIARC)(set! package/cross-compiling? true) \
@IF_CROSS@	(set! target-bytes-per-object \
@IF_CROSS@	      (lambda () @mit_scheme_target_bytes_per_object@))
@IF_LIARC@COMPILER_SETTINGS_LIARC = (set! compiler:invoke-c-compiler? false)

TOOL_COMPILER_HEAP = @HOST_COMPILER_HEAP@   # XXX rename

@IF_CROSS@TOOL_COMPILER_BAND = --band tools/compiler.com
@IF_NATIVE@TOOL_COMPILER_BAND = # default band

@IF_CROSS@TOOL_SYNTAXER_BAND = --band tools/syntaxer.com
@IF_NATIVE@TOOL_SYNTAXER_BAND = --band runtime.com

@IF_CROSS@TOOL_RUNTIME_ONLY_BAND = --band tools/runtime.com
@IF_NATIVE@TOOL_RUNTIME_ONLY_BAND = --band runtime.com

TOOL_COMPILER_LOAD = # nothing, always from the band
@IF_CROSS@TOOL_SYNTAXER_LOAD = # nothing, included in the band
@IF_NATIVE@TOOL_SYNTAXER_LOAD = --eval '(load-option (quote SF))'

TOOL_COMPILER_SETTINGS = \
	$(SF_SETTINGS_CROSS) \
	$(COMPILER_SETTINGS_CROSS) \
	$(COMPILER_SETTINGS_LIARC)

TOOL_SYNTAXER_SETTINGS = \
	$(SF_SETTINGS_CROSS)

TOOL_MIT_SCHEME = '$(MIT_SCHEME_EXE)' --batch-mode $(TOOL_COMPILER_HEAP)
@IF_CROSS@TOOL_OPTIONS = --no-init-file # host adapter loaded in toolchain
@IF_NATIVE@TOOL_OPTIONS = --no-init-file --load runtime/host-adapter.scm

TOOL_COMPILER = $(TOOL_MIT_SCHEME) $(TOOL_COMPILER_BAND) $(TOOL_OPTIONS) \
  $(TOOL_COMPILER_LOAD) --eval '(begin $(TOOL_COMPILER_SETTINGS))'
TOOL_SYNTAXER = $(TOOL_MIT_SCHEME) $(TOOL_SYNTAXER_BAND) $(TOOL_SYNTAXER_LOAD) \
  $(TOOL_OPTIONS) --eval '(begin $(TOOL_SYNTAXER_SETTINGS))'
TOOL_RUNTIME_ONLY = $(TOOL_MIT_SCHEME) $(TOOL_RUNTIME_ONLY_BAND) \
  $(TOOL_OPTIONS)

# Convert host fasl files to target fasl files.
TOOL_CROSS_HOST = $(TOOL_COMPILER) \
  --eval '(begin $(NO_LIARC)(load "etc/crossbin"))' \
  --eval '(begin $(NO_LIARC)(apply convert fasl-format:@mit_scheme_native_code@ (cdr (member "--" (command-line)))))' \
  --eval '(%exit 0)' \
  --

@IF_CROSS@CROSS_HOST = $(TOOL_CROSS_HOST)
@IF_NATIVE@CROSS_HOST = @:

# This rule is for LIARC.
.SUFFIXES: .bld .pkd .c
.pkd.c .bld.c: $(TOOLCHAIN)
	echo '(cbf "$<")' | $(TOOL_COMPILER)

# The basics and everything that can be cross-compiled -- anything that
# uses $(TOOL_...) -- depends on $(TOOLCHAIN).
@IF_CROSS@TOOLCHAIN = stamp_toolchain

@IF_SVM_COMPILER@stamp_toolchain: compiler/machines/svm/svm1-defns.h
stamp_toolchain: runtime/host-adapter.scm
	+$(MAKE) toolchain

.PHONY: toolchain
toolchain:
	+$(MAKE) -f Makefile.tools
	echo done > stamp_toolchain

.PHONY: toolclean
toolclean:
	+$(MAKE) -f Makefile.tools clean
	-rm -f stamp_toolchain

# Plugins all depend on $(PLUGINS_TOOLCHAIN) to make sure that they can
# use the newly built system to compile themselves.
#
# XXX We should be able to cross-compile plugins too.
PLUGINS_TOOLCHAIN = lib/all.com lib/runtime.com microcode/scheme \
	$(CREF_DEPENDS_TARGET) \
	$(FFI_DEPENDS_TARGET) \
	$(STAR_PARSER_DEPENDS_TARGET) \
	# end of PLUGINS_TOOLCHAIN

# LIARC bundle rules depend on $(LIARC_TOOLCHAIN) for
# extract-liarc-decls.
#
# XXX WARNING: The rules for gen-nonce and extract-liarc-decls do not
# intersect with any others.  If they did, this would be unsafe with
# parallel makes.
LIARC_TOOLCHAIN = stamp_liarc-toolchain
stamp_liarc-toolchain:
	+(cd microcode && $(MAKE) gen-nonce extract-liarc-decls)
	echo done > $@

### For the subsystems, we have several rules:
###
###	compile-SUBSYS: compile to .coms; needed for this to be loadable
###	syntax-SUBSYS: syntax; needed, in principle, to use macros from this
###	bundle-SUBSYS: generate LIARC bundle
###
### We also define:
###
###	<SUBSYS>_CREF_TARGETS: dependencies for users of the cref
###	<SUBSYS>_HOST_TARGETS: targets to make on the cross-compiler host
###	<SUBSYS>_LIARC_TARGETS: liarc targets to make on the target system
###	<SUBSYS>_DEPEND_TARGETS: dependencies for using macros from it
###
### Conditionally setting the variable <SUBSYS>_DEPEND_TARGETS to
### compile-SUBSYS or stamp_cross-finished is a kludge that arises
### because we don't have a reasonable way for a cross-compiler to load
### macros from upstream subsystems.
###
### Since make expands variables on dependency lines as it reads them,
### the subsystems must be written topologically sorted in dependency
### order, not alphabetically.  Sorry.

################
# Runtime
################

RUNTIME_CREF_TARGETS = syntax-runtime
RUNTIME_HOST_TARGETS = compile-runtime $(RUNTIME_HOST_LIARC_TARGETS)
@IF_LIARC@RUNTIME_HOST_LIARC_TARGETS = runtime/runtime-unx.c
@IF_LIARC@RUNTIME_LIARC_TARGETS = # nothing, statically linked into microcode
@IF_NATIVE@RUNTIME_DEPEND_TARGETS = $(RUNTIME_HOST_TARGETS) $(RUNTIME_LIARC_TARGETS)
@IF_CROSS@RUNTIME_DEPEND_TARGETS = stamp_cross-finished

.PHONY: compile-runtime
compile-runtime: syntax-runtime
compile-runtime: $(TOOLCHAIN)
	(echo '(with-working-directory-pathname "runtime"' && \
	 echo '  (lambda () (load "runtime.cbf")))') \
	| $(TOOL_COMPILER)
	$(CROSS_HOST) runtime

.PHONY: syntax-runtime
syntax-runtime: $(TOOLCHAIN)
	(echo '(with-working-directory-pathname "runtime"' && \
	 echo '  (lambda () (load "runtime.sf")))') \
	| $(TOOL_COMPILER)

runtime/runtime-unx.pkd: $(RUNTIME_CREF_TARGETS)

################
# SF
################

SF_CREF_TARGETS = syntax-sf
SF_HOST_TARGETS = compile-sf $(SF_HOST_LIARC_TARGETS)
@IF_LIARC@SF_HOST_LIARC_TARGETS = sf/sf-unx.c
@IF_LIARC@SF_LIARC_TARGETS = bundle-sf
@IF_NATIVE@SF_DEPEND_TARGETS = $(SF_HOST_TARGETS) $(SF_LIARC_TARGETS)
@IF_CROSS@SF_DEPEND_TARGETS = stamp_cross-finished

.PHONY: compile-sf
compile-sf: syntax-sf
compile-sf: $(TOOLCHAIN)
	(echo '(with-working-directory-pathname "sf"' && \
	 echo '  (lambda () (load "sf.cbf")))') \
	| $(TOOL_COMPILER)
	$(CROSS_HOST) sf

.PHONY: syntax-sf
syntax-sf: $(RUNTIME_CREF_TARGETS)
syntax-sf: $(TOOLCHAIN)
	(echo '(with-working-directory-pathname "sf"' && \
	 echo '  (lambda () (load "sf.sf")))') \
	| $(TOOL_COMPILER)

.PHONY: bundle-sf
bundle-sf: $(LIARC_TOOLCHAIN)
@IF_NATIVE@bundle-sf: $(SF_HOST_TARGETS)
@IF_CROSS@bundle-sf: stamp_cross-host
	+(cd sf && $(MAKE) compile-liarc-bundle)
sf/sf-unx.pkd: $(SF_CREF_TARGETS)

#################
# Compiler (LIAR)
#################

COMPILER_CREF_TARGETS = syntax-compiler
COMPILER_HOST_TARGETS = compile-compiler $(COMPILER_HOST_LIARC_TARGETS)
@IF_LIARC@COMPILER_HOST_LIARC_TARGETS = compiler/compiler-unx.c
@IF_LIARC@COMPILER_LIARC_TARGETS = bundle-compiler
@IF_NATIVE@COMPILER_DEPEND_TARGETS = $(COMPILER_HOST_TARGETS) $(COMPILER_LIARC_TARGETS)
@IF_CROSS@COMPILER_DEPEND_TARGETS = stamp_cross-finished

.PHONY: syntax-compiler
syntax-compiler: $(RUNTIME_CREF_TARGETS)
syntax-compiler: $(SF_CREF_TARGETS)
syntax-compiler: $(TOOLCHAIN)
@IF_SVM_COMPILER@syntax-compiler: compiler/machines/svm/svm1-defns.h
	(echo '(with-working-directory-pathname "compiler"' && \
	 echo '  (lambda ()' && \
	 echo '    $(SF_SETTINGS_CROSS)' && \
	 echo '    (load "compiler.sf")))') \
	| $(TOOL_SYNTAXER)

.PHONY: compile-compiler
compile-compiler: compile-compiler-back
compile-compiler: compile-compiler-base
compile-compiler: compile-compiler-fggen
compile-compiler: compile-compiler-fgopt
compile-compiler: compile-compiler-machine
compile-compiler: compile-compiler-rtlbase
compile-compiler: compile-compiler-rtlgen
compile-compiler: compile-compiler-rtlopt
	$(CROSS_HOST) compiler

.PHONY: compile-compiler-back
compile-compiler-back: syntax-compiler
compile-compiler-back: $(TOOLCHAIN)
	echo '(compile-directory "compiler/back")' | $(TOOL_COMPILER)
	$(CROSS_HOST) compiler/back

.PHONY: compile-compiler-base
compile-compiler-base: syntax-compiler
compile-compiler-base: $(TOOLCHAIN)
	echo '(compile-directory "compiler/base")' | $(TOOL_COMPILER)
	$(CROSS_HOST) compiler/base

.PHONY: compile-compiler-fggen
compile-compiler-fggen: syntax-compiler
compile-compiler-fggen: $(TOOLCHAIN)
	echo '(compile-directory "compiler/fggen")' | $(TOOL_COMPILER)
	$(CROSS_HOST) compiler/fggen

.PHONY: compile-compiler-fgopt
compile-compiler-fgopt: syntax-compiler
compile-compiler-fgopt: $(TOOLCHAIN)
	echo '(compile-directory "compiler/fgopt")' | $(TOOL_COMPILER)
	$(CROSS_HOST) compiler/fgopt

.PHONY: compile-compiler-machine
compile-compiler-machine: syntax-compiler
compile-compiler-machine: $(TOOLCHAIN)
	echo '(compile-directory "compiler/machine")' | $(TOOL_COMPILER)
	$(CROSS_HOST) compiler/machine

.PHONY: compile-compiler-rtlbase
compile-compiler-rtlbase: syntax-compiler
compile-compiler-rtlbase: $(TOOLCHAIN)
	echo '(compile-directory "compiler/rtlbase")' | $(TOOL_COMPILER)
	$(CROSS_HOST) compiler/rtlbase

.PHONY: compile-compiler-rtlgen
compile-compiler-rtlgen: syntax-compiler
compile-compiler-rtlgen: $(TOOLCHAIN)
	echo '(compile-directory "compiler/rtlgen")' | $(TOOL_COMPILER)
	$(CROSS_HOST) compiler/rtlgen

.PHONY: compile-compiler-rtlopt
compile-compiler-rtlopt: syntax-compiler
compile-compiler-rtlopt: $(TOOLCHAIN)
	echo '(compile-directory "compiler/rtlopt")' | $(TOOL_COMPILER)
	$(CROSS_HOST) compiler/rtlopt

.PHONY: bundle-compiler
bundle-compiler: $(LIARC_TOOLCHAIN)
@IF_NATIVE@bundle-compiler: $(COMPILER_HOST_TARGETS)
@IF_CROSS@bundle-compiler: stamp_cross-host
	+(cd compiler && $(MAKE) compile-liarc-bundle)
compiler/compiler-unx.pkd: $(COMPILER_CREF_TARGETS)

compiler/machines/svm/svm1-defns.h: \
	  compiler/machines/svm/assembler-rules.scm \
	  compiler/machines/svm/machine.scm \
	  compiler/machines/svm/assembler-compiler.scm \
	  compiler/machines/svm/assembler-runtime.scm \
	  compiler/machines/svm/compile-assembler.scm
	(echo '(with-working-directory-pathname "compiler/machines/svm"' && \
	 echo '  (lambda () (load "compile-assembler")))') \
	| '$(MIT_SCHEME_EXE)' --band runtime.com --batch-mode --no-init-file

################
# CREF
################

CREF_CREF_TARGETS = syntax-cref
CREF_HOST_TARGETS = compile-cref $(CREF_HOST_LIARC_TARGETS)
@IF_LIARC@CREF_HOST_LIARC_TARGETS = cref/cref-unx.c
@IF_LIARC@CREF_LIARC_TARGETS = bundle-cref
@IF_NATIVE@CREF_DEPEND_TARGETS = $(CREF_HOST_TARGETS) $(CREF_LIARC_TARGETS)
@IF_CROSS@CREF_DEPEND_TARGETS = stamp_cross-finished

.PHONY: compile-cref
compile-cref: syntax-cref
compile-cref: $(TOOLCHAIN)
	(echo '(with-working-directory-pathname "cref"' && \
	 echo '  (lambda () (load "cref.cbf")))') \
	| $(TOOL_COMPILER)
	$(CROSS_HOST) cref

.PHONY: syntax-cref
syntax-cref: $(RUNTIME_CREF_TARGETS)
syntax-cref: $(TOOLCHAIN)
	(echo '(with-working-directory-pathname "cref"' && \
	 echo '  (lambda () (load "cref.sf")))') \
	| $(TOOL_COMPILER)

.PHONY: bundle-cref
bundle-cref: $(LIARC_TOOLCHAIN)
@IF_NATIVE@bundle-cref: $(CREF_HOST_TARGETS)
@IF_CROSS@bundle-cref: stamp_cross-host
	+(cd cref && $(MAKE) compile-liarc-bundle)
cref/cref-unx.pkd: $(CREF_CREF_TARGETS)

################
# *PARSER
################

STAR_PARSER_CREF_TARGETS = compile-star-parser # no separate syntax step
STAR_PARSER_HOST_TARGETS = compile-star-parser $(STAR_PARSER_HOST_LIARC_TARGETS)
@IF_LIARC@STAR_PARSER_HOST_LIARC_TARGETS = star-parser/parser-unx.c
@IF_LIARC@STAR_PARSER_LIARC_TARGETS = bundle-star-parser
@IF_NATIVE@STAR_PARSER_DEPEND_TARGETS = $(STAR_PARSER_HOST_TARGETS) $(STAR_PARSER_LIARC_TARGETS)
@IF_CROSS@STAR_PARSER_DEPEND_TARGETS = stamp_cross-finished

.PHONY: compile-star-parser
compile-star-parser: $(RUNTIME_CREF_TARGETS)
compile-star-parser: $(TOOLCHAIN)
	(echo '(with-working-directory-pathname "star-parser"' && \
	 echo '  (lambda () (load "compile")))') \
	| $(TOOL_COMPILER)
	$(CROSS_HOST) star-parser

.PHONY: bundle-star-parser
bundle-star-parser: $(LIARC_TOOLCHAIN)
@IF_NATIVE@bundle-star-parser: $(STAR_PARSER_HOST_TARGETS)
@IF_CROSS@bundle-star-parser: stamp_cross-host
	+(cd star-parser && $(MAKE) compile-liarc-bundle)
star-parser/parser-unx.pkd: $(STAR_PARSER_CREF_TARGETS)

### More stuff we build with tools.  We could build it with the newly
### built compiler in the native case, but we want to avoid having to
### do that to encourage cross-compilation.

################
# FFI
################

FFI_CREF_TARGETS = compile-ffi # no separate syntax step
FFI_HOST_TARGETS = compile-ffi $(FFI_HOST_LIARC_TARGETS)
@IF_LIARC@FFI_HOST_LIARC_TARGETS = ffi/ffi-unx.c
@IF_LIARC@FFI_LIARC_TARGETS = bundle-ffi
@IF_NATIVE@FFI_DEPEND_TARGETS = $(FFI_HOST_TARGETS) $(FFI_LIARC_TARGETS)
@IF_CROSS@FFI_DEPEND_TARGETS = stamp_cross-finished

.PHONY: compile-ffi
compile-ffi: $(RUNTIME_CREF_TARGETS)
compile-ffi: $(TOOLCHAIN)
	(echo '(with-working-directory-pathname "ffi"' && \
	 echo '  (lambda () (load "compile.scm")))') \
	| $(TOOL_COMPILER)
	$(CROSS_HOST) ffi

.PHONY: bundle-ffi
bundle-ffi: $(LIARC_TOOLCHAIN)
@IF_NATIVE@bundle-ffi: $(FFI_HOST_TARGETS)
@IF_CROSS@bundle-ffi: stamp_cross-host
	+(cd ffi && $(MAKE) compile-liarc-bundle)
ffi/ffi-unx.pkd: $(FFI_CREF_TARGETS)

################
# SOS
################

SOS_CREF_TARGETS = compile-sos # no separate syntax step
SOS_HOST_TARGETS = compile-sos $(SOS_HOST_LIARC_TARGETS)
@IF_LIARC@SOS_HOST_LIARC_TARGETS = sos/sos-unx.c
@IF_LIARC@SOS_LIARC_TARGETS = bundle-sos
@IF_NATIVE@SOS_DEPEND_TARGETS = $(SOS_HOST_TARGETS) $(SOS_LIARC_TARGETS)
@IF_CROSS@SOS_DEPEND_TARGETS = stamp_cross-finished

.PHONY: compile-sos
compile-sos: $(RUNTIME_CREF_TARGETS)
compile-sos: $(TOOLCHAIN)
	(echo '(with-working-directory-pathname "sos"' && \
	 echo '  (lambda () (load "compile")))') \
	| $(TOOL_COMPILER)
	$(CROSS_HOST) sos

.PHONY: bundle-sos
bundle-sos: $(LIARC_TOOLCHAIN)
@IF_NATIVE@bundle-sos: $(SOS_HOST_TARGETS)
@IF_CROSS@bundle-sos: stamp_cross-host
	+(cd sos && $(MAKE) compile-liarc-bundle)
sos/sos-unx.pkd: $(SOS_CREF_TARGETS)

################
# XML
################

XML_CREF_TARGETS = compile-xml # no separate syntax step
XML_HOST_TARGETS = compile-xml $(XML_HOST_LIARC_TARGETS)
@IF_LIARC@XML_HOST_LIARC_TARGETS = xml/xml-unx.c
@IF_LIARC@XML_LIARC_TARGETS = bundle-xml
@IF_NATIVE@XML_DEPEND_TARGETS = $(XML_HOST_TARGETS) $(XML_LIARC_TARGETS)
@IF_CROSS@XML_DEPEND_TARGETS = stamp_cross-finished

.PHONY: compile-xml
compile-xml: $(RUNTIME_CREF_TARGETS)
compile-xml: $(SOS_CREF_TARGETS)
compile-xml: $(STAR_PARSER_CREF_TARGETS)
compile-xml: $(TOOLCHAIN)
	(echo '(with-working-directory-pathname "xml"' && \
	 echo '  (lambda () (load "compile")))') \
	| $(TOOL_COMPILER)
	$(CROSS_HOST) xml

.PHONY: bundle-xml
bundle-xml: $(LIARC_TOOLCHAIN)
@IF_NATIVE@bundle-xml: $(XML_HOST_TARGETS)
@IF_CROSS@bundle-xml: stamp_cross-host
	+(cd xml && $(MAKE) compile-liarc-bundle)
xml/xml-unx.pkd: $(XML_CREF_TARGETS)

################
# SSP
################

SSP_CREF_TARGETS = compile-ssp # no separate syntax step
SSP_HOST_TARGETS = compile-ssp $(SSP_HOST_LIARC_TARGETS)
@IF_LIARC@SSP_HOST_LIARC_TARGETS = ssp/ssp-unx.c
@IF_LIARC@SSP_LIARC_TARGETS = bundle-ssp
@IF_NATIVE@SSP_DEPEND_TARGETS = $(SSP_HOST_TARGETS) $(SSP_LIARC_TARGETS)
@IF_CROSS@SSP_DEPEND_TARGETS = stamp_cross-finished

.PHONY: compile-ssp
compile-ssp: $(RUNTIME_CREF_TARGETS)
compile-ssp: $(XML_CREF_TARGETS)
compile-ssp: $(TOOLCHAIN)
	(echo '(with-working-directory-pathname "ssp"' && \
	 echo '  (lambda () (load "compile")))') \
	| $(TOOL_COMPILER)
	$(CROSS_HOST) ssp

.PHONY: bundle-ssp
bundle-ssp: $(LIARC_TOOLCHAIN)
@IF_NATIVE@bundle-ssp: $(SSP_HOST_TARGETS)
@IF_CROSS@bundle-ssp: stamp_cross-host
	+(cd ssp && $(MAKE) compile-liarc-bundle)
ssp/ssp-unx.pkd: $(SSP_CREF_TARGETS)

### Targets built on the target by the native compiler because we don't
### have a way to load macro definitions of an object-program into a
### cross-compiler.  We should have a way to do that, and eliminate
### these.

################
# Libraries
################

.PHONY: compile-libraries
compile-libraries: lib/all.com
compile-libraries: microcode/scheme
	(echo '(with-working-directory-pathname "libraries"' && \
	 echo '  (lambda () (load "compile")))') \
	| ./run-build --batch-mode --no-init-file

################
# blowfish
################

@IF_BLOWFISH@BLOWFISH_BUILD_TARGETS = compile-blowfish
BLOWFISH_DEPEND_TARGETS = compile-blowfish

.PHONY: compile-blowfish
compile-blowfish: $(PLUGINS_TOOLCHAIN)
	+(cd blowfish && $(MAKE))

.PHONY: compile-blowfish-c
compile-blowfish-c:
	+(cd blowfish && $(MAKE))

################
# gdbm
################

@IF_GDBM@GDBM_BUILD_TARGETS = compile-gdbm
GDBM_DEPEND_TARGETS = compile-gdbm

.PHONY: compile-gdbm
compile-gdbm: $(PLUGINS_TOOLCHAIN)
	+(cd gdbm && $(MAKE))

.PHONY: compile-gdbm-c
compile-gdbm-c:
	+(cd gdbm && $(MAKE))

################
# pgsql
################

@IF_PGSQL@PGSQL_BUILD_TARGETS = compile-pgsql
PGSQL_DEPEND_TARGETS = compile-pgsql

.PHONY: compile-pgsql
compile-pgsql: $(PLUGINS_TOOLCHAIN)
	+(cd pgsql && $(MAKE))

.PHONY: compile-pgsql-c
compile-pgsql-c:
	+(cd pgsql && $(MAKE))

################
# X11
################

@IF_X11@X11_BUILD_TARGETS = compile-x11
X11_DEPEND_TARGETS = compile-x11

.PHONY: compile-x11
compile-x11: $(PLUGINS_TOOLCHAIN)
	+(cd x11 && $(MAKE))

.PHONY: compile-x11-c
compile-x11-c:
	+(cd x11 && $(MAKE))

################
# edwin
################

@IF_EDWIN@EDWIN_BUILD_TARGETS = compile-edwin
EDWIN_DEPEND_TARGETS = compile-edwin

.PHONY: compile-edwin
compile-edwin: $(PLUGINS_TOOLCHAIN)
compile-edwin: $(XML_DEPEND_TARGETS)
@IF_BLOWFISH@compile-edwin: $(BLOWFISH_DEPEND_TARGETS)
@IF_GDBM@compile-edwin: $(GDBM_DEPEND_TARGETS)
@IF_X11@compile-edwin: $(X11_DEPEND_TARGETS)
	+(cd edwin && $(MAKE))

################
# imail
################

@IF_IMAIL@IMAIL_BUILD_TARGETS = compile-imail
IMAIL_DEPEND_TARGETS = compile-imail

.PHONY: compile-imail
compile-imail: $(PLUGINS_TOOLCHAIN)
compile-imail: $(EDWIN_DEPEND_TARGETS)
compile-imail: $(SOS_DEPEND_TARGETS)
	+(cd imail && $(MAKE))

################
# X11-screen
################

@IF_X11_SCREEN@X11_SCREEN_BUILD_TARGETS = compile-x11-screen
X11_SCREEN_DEPEND_TARGETS = compile-x11-screen

.PHONY: compile-x11-screen
compile-x11-screen: $(PLUGINS_TOOLCHAIN)
compile-x11-screen: $(EDWIN_DEPEND_TARGETS)
compile-x11-screen: $(X11_DEPEND_TARGETS)
	+(cd x11-screen && $(MAKE))

#####################
### Main targets
#####################

# all
#
#	Build the whole system, with the host's tools, an intermediate
#	cross-toolchain if cross-compiling, and the newly built target
#	tools.  Same as cross-host and then cross-target.
#
.PHONY: all
all: cross-host
	$(MAKE) cross-target

# cross-host
#
#	Do the host part of a cross-build: build a cross-toolchain if
#	cross-compiling, compile everything that can be cross-compiled
#	with it, and leave a stamp of approval.
#
.PHONY: cross-host
cross-host: $(COMPILER_HOST_TARGETS)
cross-host: $(CREF_HOST_TARGETS)
cross-host: $(FFI_HOST_TARGETS)
cross-host: $(RUNTIME_HOST_TARGETS)
cross-host: $(SF_HOST_TARGETS)
cross-host: $(SOS_HOST_TARGETS)
cross-host: $(SSP_HOST_TARGETS)
cross-host: $(STAR_PARSER_HOST_TARGETS)
cross-host: $(XML_HOST_TARGETS)
	echo done > stamp_cross-host

# stamp_cross-finished
#
#	Finish whatever work the cross-compiler left: compiling LIARC
#	bundles with the target's C toolchain, converting moc files to
#	com files.
#
#	THIS MUST DEPEND ONLY ON REAL TARGETS, NOT ON PHONY TARGETS
#	THAT MAY RUN ON THE HOST.
#
stamp_cross-finished: $(COMPILER_LIARC_TARGETS)
stamp_cross-finished: $(CREF_LIARC_TARGETS)
stamp_cross-finished: $(FFI_LIARC_TARGETS)
stamp_cross-finished: $(RUNTIME_LIARC_TARGETS)
stamp_cross-finished: $(SF_LIARC_TARGETS)
stamp_cross-finished: $(SOS_LIARC_TARGETS)
stamp_cross-finished: $(SSP_LIARC_TARGETS)
stamp_cross-finished: $(STAR_PARSER_LIARC_TARGETS)
stamp_cross-finished: $(XML_LIARC_TARGETS)
stamp_cross-finished: stamp_cross-host microcode/scheme
	(echo '$(NO_LIARC)' && \
	 echo '(let ((env (->environment (quote (runtime)))))' && \
	 echo '  (load "../compiler/base/crsend" env)' && \
	 echo '  ((access finish-cross-compilation:files env) "."))') \
	| (cd runtime && ../run-build --batch-mode --fasl make.bin)
	(echo '$(NO_LIARC)' && \
	 echo '(let ((env (->environment (quote (runtime)))))' && \
	 echo '  (load "../compiler/base/crsend" env)' && \
	 echo '  ((access finish-cross-compilation:files env) ".."))') \
	| (cd runtime && ../run-build --batch-mode --fasl make.com)
	(echo '$(NO_LIARC)' && \
	 echo '(let ((env (->environment (quote (runtime)))))' && \
	 echo '  (load "../compiler/base/crsend" env)' && \
	 echo '  ((access finish-cross-compilation:info-files env) ".."))') \
	 | (cd runtime && ../run-build --batch-mode --fasl make.com)
	echo "done" > $@

# cross-target
#
#	Do the target part of a cross-build: all the plugins that are
#	built with the newly built target tools, and the microcode, and
#	the bands.
#
#	This step is necessarily separate for three reasons:
#
#	1. We don't have a reasonable way to cross-compile subsystems
#	   that use macros from other cross-compiled subsystems.
#
#	2. We don't assume the user has a C cross-compiler (although if
#	   they did, they could in principle use it here).
#
#	3. We don't have a static linker for bands that can run as part
#	   of a cross-toolchain.
#
.PHONY: cross-target
cross-target: $(BLOWFISH_BUILD_TARGETS)
cross-target: $(EDWIN_BUILD_TARGETS)
cross-target: $(GDBM_BUILD_TARGETS)
cross-target: $(IMAIL_BUILD_TARGETS)
cross-target: $(PGSQL_BUILD_TARGETS)
cross-target: $(X11_BUILD_TARGETS)
cross-target: $(X11_SCREEN_BUILD_TARGETS)
cross-target: lib/all.com
cross-target: lib/runtime.com
cross-target: microcode/scheme
cross-target: compile-libraries

################
# Microcode
################

@IF_LIARC@@IF_CROSS@microcode/scheme: stamp_cross-host
@IF_LIARC@@IF_NATIVE@microcode/scheme: $(RUNTIME_LIARC_TARGETS)
@IF_SVM@microcode/scheme: microcode/svm1-defns.h
microcode/scheme:
	+(cd microcode && $(MAKE) all)

.PHONY: compile-microcode
compile-microcode: microcode/scheme
@IF_BLOWFISH@compile-microcode: compile-blowfish-c
@IF_GDBM@compile-microcode: compile-gdbm-c
@IF_PGSQL@compile-microcode: compile-pgsql-c
@IF_X11@compile-microcode: compile-x11-c

stamp_install-microcode: compile-microcode
	(cd microcode; $(MAKE) install)
	echo "done" > $@

microcode/svm1-defns.h: compiler/machines/svm/svm1-defns.h
	@$(top_srcdir)/etc/maybe-update-file.sh \
	  compiler/machines/svm/svm1-defns.h \
	  microcode/svm1-defns.h

################
# Bands
################

lib/runtime.com: microcode/scheme
lib/runtime.com: $(RUNTIME_DEPEND_TARGETS)
	(. etc/functions.sh && get_fasl_file && cd runtime \
	  && (echo '(disk-save "../$@")' \
	       | ../run-build --batch-mode --fasl "$${FASL}"))

lib/all.com: microcode/scheme
lib/all.com: lib/runtime.com
lib/all.com: $(COMPILER_DEPEND_TARGETS)
lib/all.com: $(SF_DEPEND_TARGETS)
lib/all.com: $(CREF_DEPEND_TARGETS)
	(echo '(begin' && \
	 echo '  (load-option (quote compiler))' && \
	 echo '  (load-option (quote sf))' && \
	 echo '  (disk-save "$@"))') \
	| ./run-build --batch-mode --band runtime.com

################
# Miscellany
################

.PHONY: check
check:
	./run-build --batch-mode --load ../tests/check.scm --eval '(%exit)'

.PHONY: macosx-app
macosx-app:
	etc/macosx/make-app.sh

.PHONY: mostlyclean clean distclean maintainer-clean c-clean
mostlyclean clean distclean maintainer-clean c-clean:
	$(top_srcdir)/Clean.sh $@ $(SUBDIRS) $(OPTION_SUBDIRS)

.PHONY: clean-boot-root
clean-boot-root:
	rm -rf boot-root
	rm -f stamp_*

.PHONY: tags TAGS
tags TAGS:
	$(top_srcdir)/Tags.sh $(SUBDIRS)

.PHONY: subdir-list
subdir-list:
	@for D in $(SUBDIRS); do echo $$D; done

.PHONY: install
install: install-standard @INSTALL_LIARC_BUNDLES@

.PHONY: install-standard
install-standard: install-auxdir-top
	@+$(MAKE_IN_SUBDIRS) install $(INSTALLED_SUBDIRS)

.PHONY: install-basics
install-basics: install-auxdir-top
	@+$(MAKE_IN_SUBDIRS) install $(BASICS_SUBDIRS)

.PHONY: install-auxdir-top
install-auxdir-top:
	$(mkinstalldirs) $(DESTDIR)$(AUXDIR)
	$(INSTALL_DATA) $(top_srcdir)/etc/optiondb.scm $(DESTDIR)$(AUXDIR)/.
	$(INSTALL_DATA) $(top_srcdir)/etc/plugins.scm $(DESTDIR)$(AUXDIR)/.
	$(INSTALL_DATA) lib/*.com $(DESTDIR)$(AUXDIR)/.

################
# Legacy
################

.PHONY: all-liarc
all-liarc:
	@$(top_srcdir)/etc/c-compile.sh "$(MIT_SCHEME_EXE)" --batch-mode --no-init-file
	$(MAKE) compile-liarc-bundles build-bands

.PHONY: build-bands
build-bands:
	@$(top_srcdir)/etc/build-bands.sh

# **** Make liarc distribution from native ****

.PHONY: liarc-dist
liarc-dist:
	@$(top_srcdir)/etc/compile-boot-compiler.sh "$(MIT_SCHEME_EXE)"
	@$(top_srcdir)/etc/c-prepare.sh "$(MIT_SCHEME_EXE)"
	$(MAKE) distclean

# **** Build liarc from distribution ****

stamp_compile-liarc-boot-bundles: stamp_install-microcode
	@+$(MAKE_IN_SUBDIRS) compile-liarc-bundle $(LIARC_BOOT_BUNDLES)
	echo "done" > $@

stamp_install-liarc-boot-bundles: stamp_compile-liarc-boot-bundles
	@+$(MAKE_IN_SUBDIRS) install-liarc-bundle $(LIARC_BOOT_BUNDLES)
	echo "done" > $@

stamp_build-liarc-boot-compiler: stamp_install-liarc-boot-bundles
	@$(top_srcdir)/etc/build-boot-compiler.sh
	echo "done" > $@

stamp_install-liarc-boot-compiler: stamp_build-liarc-boot-compiler
	$(MAKE) install-auxdir-top
	echo "done" > $@

stamp_liarc-compile-scheme:
	@$(top_srcdir)/etc/c-compile.sh boot-root/bin/mit-scheme-c \
	    --library boot-root/lib/mit-scheme-c --band boot-compiler.com
	echo "done" > $@

stamp_compile-liarc-bundles: stamp_liarc-compile-scheme compile-liarc-bundles
	echo "done" > $@

.PHONY: compile-liarc-bundles
compile-liarc-bundles: compile-microcode
	@+$(MAKE_IN_SUBDIRS) compile-liarc-bundle $(LIARC_BUNDLES)

.PHONY: install-liarc-bundles
install-liarc-bundles:
	@+$(MAKE_IN_SUBDIRS) install-liarc-bundle $(LIARC_BUNDLES)

# **** Build native from liarc ****

stamp_build-native-boot-compiler: stamp_install-microcode
	@$(top_srcdir)/etc/build-boot-compiler.sh
	echo "done" > $@

stamp_install-native-boot-compiler: stamp_build-native-boot-compiler
	$(MAKE) install-auxdir-top
	echo "done" > $@

stamp_native-compile-scheme: compile-microcode
	@$(top_srcdir)/etc/compile.sh boot-root/bin/mit-scheme \
	    --library boot-root/lib/$(AUXDIR_NAME) --band boot-compiler.com
	echo "done" > $@

##########################
### Save/restore utilities
##########################

.PHONY: save
save:
	@echo 'Saving objects...'
	@rm -rf saved-objects && \
	mkdir saved-objects && \
	( \
	  find $(SUBDIRS) -type f \
	    \( \
	      -name '*.bci' -o \
	      -name '*.bin' -o \
	      -name '*.c' -o \
	      -name '*.com' -o \
	      -name '*.crf' -o \
	      -name '*.ext' -o \
	      -name '*.fre' -o \
	      -name '*.moc' -o \
	      -name '*.o' -o \
	      -name '*.pkd' -o \
	      -name '*.so' -o \
	      -false \
	    \) \
	    -print0 \
	  | pax -rw -pe -l -v -d -0 saved-objects/. \
	) || { rm -rf saved-objects; exit 1; }

.PHONY: restore
restore:
	@echo 'Restoring objects...'
	@if ! test -d saved-objects; then exit 1; fi && \
	(cd saved-objects && pax -rw -pe -v . ../../.)
