# 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 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 = /bin/bash



srcdir = .
top_srcdir = .

prefix = /usr/local
exec_prefix = ${prefix}

bindir = ${exec_prefix}/bin
sbindir = ${exec_prefix}/sbin
libexecdir = ${exec_prefix}/libexec
datarootdir = ${prefix}/share
datadir = ${datarootdir}
sysconfdir = ${prefix}/etc
sharedstatedir = ${prefix}/com
localstatedir = ${prefix}/var
libdir = ${exec_prefix}/lib
infodir = ${datarootdir}/info
mandir = ${datarootdir}/man
includedir = ${prefix}/include
oldincludedir = /usr/include

DESTDIR =
top_builddir = .

INSTALL = /usr/bin/install -c
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_SCRIPT = ${INSTALL}

LN_S = ln -s
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/microcode/mkinstalldirs

# **** END BOILERPLATE ****

.PHONY: default-target
default-target: all

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

SUBDIRS = $(INSTALLED_SUBDIRS) win32 xdoc
INSTALLED_SUBDIRS = microcode runtime libraries $(OPTION_SUBDIRS) $(LIARC_BUNDLES)
BASICS_SUBDIRS = microcode runtime $(LIARC_BUNDLES)
OPTION_SUBDIRS =  edwin imail x11 x11-screen

MIT_SCHEME_EXE = mit-scheme-aarch64le
AUXDIR_NAME = mit-scheme-aarch64le-11.1
AUXDIR = $(libdir)/mit-scheme-aarch64le-11.1

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

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

TOOL_COMPILER_HEAP =    # XXX rename

#!cross-compiling: TOOL_COMPILER_BAND = --band tools/compiler.com
TOOL_COMPILER_BAND = # default band

#!cross-compiling: TOOL_SYNTAXER_BAND = --band tools/syntaxer.com
TOOL_SYNTAXER_BAND = --band runtime.com

#!cross-compiling: TOOL_RUNTIME_ONLY_BAND = --band tools/runtime.com
TOOL_RUNTIME_ONLY_BAND = --band runtime.com

TOOL_COMPILER_LOAD = # nothing, always from the band
#!cross-compiling: TOOL_SYNTAXER_LOAD = # nothing, included in the band
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)
#!cross-compiling: TOOL_OPTIONS = --no-init-file # host adapter loaded in toolchain
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:aarch64le (cdr (member "--" (command-line)))))' \
  --eval '(%exit 0)' \
  --

#!cross-compiling: CROSS_HOST = $(TOOL_CROSS_HOST)
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).
#!cross-compiling: TOOLCHAIN = stamp_toolchain

#!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)
#!liarc: RUNTIME_HOST_LIARC_TARGETS = runtime/runtime-unx.c
#!liarc: RUNTIME_LIARC_TARGETS = # nothing, statically linked into microcode
RUNTIME_DEPEND_TARGETS = $(RUNTIME_HOST_TARGETS) $(RUNTIME_LIARC_TARGETS)
#!cross-compiling: 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)
#!liarc: SF_HOST_LIARC_TARGETS = sf/sf-unx.c
#!liarc: SF_LIARC_TARGETS = bundle-sf
SF_DEPEND_TARGETS = $(SF_HOST_TARGETS) $(SF_LIARC_TARGETS)
#!cross-compiling: 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)
bundle-sf: $(SF_HOST_TARGETS)
#!cross-compiling: 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)
#!liarc: COMPILER_HOST_LIARC_TARGETS = compiler/compiler-unx.c
#!liarc: COMPILER_LIARC_TARGETS = bundle-compiler
COMPILER_DEPEND_TARGETS = $(COMPILER_HOST_TARGETS) $(COMPILER_LIARC_TARGETS)
#!cross-compiling: COMPILER_DEPEND_TARGETS = stamp_cross-finished

.PHONY: syntax-compiler
syntax-compiler: $(RUNTIME_CREF_TARGETS)
syntax-compiler: $(SF_CREF_TARGETS)
syntax-compiler: $(TOOLCHAIN)
#!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)
bundle-compiler: $(COMPILER_HOST_TARGETS)
#!cross-compiling: 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)
#!liarc: CREF_HOST_LIARC_TARGETS = cref/cref-unx.c
#!liarc: CREF_LIARC_TARGETS = bundle-cref
CREF_DEPEND_TARGETS = $(CREF_HOST_TARGETS) $(CREF_LIARC_TARGETS)
#!cross-compiling: 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)
bundle-cref: $(CREF_HOST_TARGETS)
#!cross-compiling: 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)
#!liarc: STAR_PARSER_HOST_LIARC_TARGETS = star-parser/parser-unx.c
#!liarc: STAR_PARSER_LIARC_TARGETS = bundle-star-parser
STAR_PARSER_DEPEND_TARGETS = $(STAR_PARSER_HOST_TARGETS) $(STAR_PARSER_LIARC_TARGETS)
#!cross-compiling: 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)
bundle-star-parser: $(STAR_PARSER_HOST_TARGETS)
#!cross-compiling: 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)
#!liarc: FFI_HOST_LIARC_TARGETS = ffi/ffi-unx.c
#!liarc: FFI_LIARC_TARGETS = bundle-ffi
FFI_DEPEND_TARGETS = $(FFI_HOST_TARGETS) $(FFI_LIARC_TARGETS)
#!cross-compiling: 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)
bundle-ffi: $(FFI_HOST_TARGETS)
#!cross-compiling: 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)
#!liarc: SOS_HOST_LIARC_TARGETS = sos/sos-unx.c
#!liarc: SOS_LIARC_TARGETS = bundle-sos
SOS_DEPEND_TARGETS = $(SOS_HOST_TARGETS) $(SOS_LIARC_TARGETS)
#!cross-compiling: 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)
bundle-sos: $(SOS_HOST_TARGETS)
#!cross-compiling: bundle-sos: stamp_cross-host
	+(cd sos && $(MAKE) compile-liarc-bundle)
sos/sos-unx.pkd: $(SOS_CREF_TARGETS)

################
# Windows FFI
################

WIN32_CREF_TARGETS = syntax-win32
WIN32_HOST_TARGETS = compile-win32
# no LIARC on Windows
WIN32_DEPEND_TARGETS = $(WIN32_HOST_TARGETS)
#!cross-compiling: WIN32_DEPEND_TARGETS = stamp_cross-finished

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

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

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

XML_CREF_TARGETS = compile-xml # no separate syntax step
XML_HOST_TARGETS = compile-xml $(XML_HOST_LIARC_TARGETS)
#!liarc: XML_HOST_LIARC_TARGETS = xml/xml-unx.c
#!liarc: XML_LIARC_TARGETS = bundle-xml
XML_DEPEND_TARGETS = $(XML_HOST_TARGETS) $(XML_LIARC_TARGETS)
#!cross-compiling: 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)
bundle-xml: $(XML_HOST_TARGETS)
#!cross-compiling: 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)
#!liarc: SSP_HOST_LIARC_TARGETS = ssp/ssp-unx.c
#!liarc: SSP_LIARC_TARGETS = bundle-ssp
SSP_DEPEND_TARGETS = $(SSP_HOST_TARGETS) $(SSP_LIARC_TARGETS)
#!cross-compiling: 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)
bundle-ssp: $(SSP_HOST_TARGETS)
#!cross-compiling: 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
################

#!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
################

#!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))

################
# mcrypt
################

#!mcrypt: MCRYPT_BUILD_TARGETS = compile-mcrypt
MCRYPT_DEPEND_TARGETS = compile-mcrypt

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

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

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

#!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
################

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
################

EDWIN_BUILD_TARGETS = compile-edwin
EDWIN_DEPEND_TARGETS = compile-edwin

.PHONY: compile-edwin
compile-edwin: $(PLUGINS_TOOLCHAIN)
compile-edwin: $(XML_DEPEND_TARGETS)
#!blowfish: compile-edwin: $(BLOWFISH_DEPEND_TARGETS)
#!gdbm: compile-edwin: $(GDBM_DEPEND_TARGETS)
compile-edwin: $(X11_DEPEND_TARGETS)
	+(cd edwin && $(MAKE))

################
# 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
################

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: $(WIN32_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: $(WIN32_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: $(MCRYPT_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
################

#!liarc: #!cross-compiling: microcode/scheme: stamp_cross-host
#!liarc: microcode/scheme: $(RUNTIME_LIARC_TARGETS)
#!svm: microcode/scheme: microcode/svm1-defns.h
microcode/scheme:
	+(cd microcode && $(MAKE) all)

.PHONY: compile-microcode
compile-microcode: microcode/scheme
#!blowfish: compile-microcode: compile-blowfish-c
#!gdbm: compile-microcode: compile-gdbm-c
#!mcrypt: compile-microcode: compile-mcrypt-c
#!pgsql: compile-microcode: compile-pgsql-c
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 

.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 . ../../.)
