# SPDX-License-Identifier: AGPL-3.0-or-later
# Loko Scheme - an R6RS Scheme compiler
# Copyright © 2019-2020 Göran Weinholt

# XXX: This Makefile requires GNU make

DESTDIR =
PREFIX = /usr/local
INSTALL = install
INSTALLINFO = install-info
VERSION = $(shell awk -F'"' '/akku-package/ {print $$4}' Akku.manifest)

DEFAULT_TARGET = pc+linux
GDB_AUTOLOAD_PATH = /usr/share/gdb/auto-load

#DEFAULT_TARGET = netbsd
#GDB_AUTOLOAD_PATH = /usr/pkg/share/gdb/auto-load

# Chez Scheme
BOOTSTRAPSCHEME = scheme
SCHEMESCRIPT = scheme --program

do_subst = sed -e 's,[@]PREFIX[@],$(PREFIX),g' \
               -e 's,[@]VERSION[@],$(VERSION),g' \
               -e 's,[@]DEFAULT_TARGET[@],$(DEFAULT_TARGET),g' \
               -e 's,[@]GDB_AUTOLOAD_PATH[@],$(GDB_AUTOLOAD_PATH),g'

all: loko scheme-script

config.sls: config.sls.in Akku.manifest
	$(do_subst) < config.sls.in > config.sls

.akku/env: config.sls
	akku install

loko: .akku/env
	LOKO_SOURCE=.akku/lib .akku/env $(BOOTSTRAPSCHEME) --program compile-loko.sps
	chmod +x loko.out
	if [ -f loko ]; then mv -f loko loko.old; fi
	mv -f loko.out loko

selfcompile: .akku/env loko
	LOKO_SOURCE=.akku/lib .akku/env ./loko -feval --compile loko.sps --output loko.out
	if [ -f loko ]; then mv -f loko loko.old; fi
	mv -f loko.out loko

munchausen: .akku/env loko
	LOKO_SOURCE=.akku/lib .akku/env ./loko --program compile-loko.sps
	chmod +x loko.out
	if [ -f loko ]; then mv -f loko loko.old; fi
	mv -f loko.out loko

scheme-script: loko
	if [ -f scheme-script ]; then mv -f scheme-script scheme-script.old; fi
	ln loko scheme-script

# Header snarfing (extraction of magic numbers)

linux-snarfer.c: tools/header-snarfer.sps tools/linux.snarf
	cat /lib/modules/$(shell uname -r)/source/include/uapi/asm-generic/errno* | \
	  $(SCHEMESCRIPT) tools/header-snarfer.sps tools/linux.snarf loko arch > $@

netbsd-snarfer.c: tools/header-snarfer.sps tools/netbsd.snarf
	cat /usr/include/sys/errno.h | \
	  $(SCHEMESCRIPT) tools/header-snarfer.sps tools/netbsd.snarf loko arch > $@

linux-snarfer: linux-snarfer.c
netbsd-snarfer: netbsd-snarfer.c

arch/amd64/linux-numbers.sls: linux-snarfer
	./linux-snarfer > $@
arch/amd64/netbsd-numbers.sls: netbsd-snarfer
	./netbsd-snarfer > $@

.INTERMEDIATE: linux-snarfer linux-snarfer.c
.INTERMEDIATE: netbsd-snarfer netbsd-snarfer.c

# Documentation

manual:: Documentation/manual/loko.info Documentation/manual/loko.html Documentation/manual/loko.pdf

Documentation/manual/loko.info: Documentation/manual/*.texi Documentation/manual/version.texi
	cd Documentation/manual && makeinfo loko

Documentation/manual/loko.html: Documentation/manual/*.texi Documentation/manual/version.texi
	cd Documentation/manual && makeinfo --no-split --html loko

Documentation/manual/loko.pdf: Documentation/manual/*.texi Documentation/manual/version.texi
	cd Documentation/manual && texi2pdf loko.texi

Documentation/manual/version.texi: Documentation/manual/mkversion.sps loko Akku.manifest
	cd Documentation/manual && ../../.akku/env ../../loko --program mkversion.sps

samples:: loko
	$(MAKE) -C samples

# XXX: Requires "akku install --dev wak-fmt" first
fonts:
	.akku/env loko --program tools/bdf2sls.sps lib/font/8x13.bdf '(loko font font-8x13)' > lib/font/font-8x13.sls
	.akku/env loko --program tools/bdf2sls.sps lib/font/6x13.bdf '(loko font font-6x13)' > lib/font/font-6x13.sls

clean:
	rm -f loko loko.out loko.old
	rm -f scheme-script scheme-script.old
	rm -f config.sls
	rm -f Documentation/manual/version.texi Documentation/manual/loko*.info Documentation/manual/loko.pdf
	rm -f Documentation/manual/loko.aux Documentation/manual/loko.cp Documentation/manual/loko.cps Documentation/manual/loko.html Documentation/manual/loko.log Documentation/manual/loko.toc Documentation/manual/loko.vr Documentation/manual/loko.vrs
	$(MAKE) -C samples clean

install: all
	$(INSTALL) -m 0755 -d   $(DESTDIR)$(PREFIX)/bin
	$(INSTALL) -m 0755 loko $(DESTDIR)$(PREFIX)/bin
# Libraries for users
	$(INSTALL) -m 0755 -d                             $(DESTDIR)$(PREFIX)/share/r6rs/loko/arch/amd64
	$(INSTALL) -m 0644 arch/amd64/linux-numbers.sls   $(DESTDIR)$(PREFIX)/share/r6rs/loko/arch/amd64
	$(INSTALL) -m 0644 arch/amd64/linux-syscalls.sls  $(DESTDIR)$(PREFIX)/share/r6rs/loko/arch/amd64
	$(INSTALL) -m 0644 arch/amd64/netbsd-numbers.sls  $(DESTDIR)$(PREFIX)/share/r6rs/loko/arch/amd64
	$(INSTALL) -m 0644 arch/amd64/netbsd-syscalls.sls $(DESTDIR)$(PREFIX)/share/r6rs/loko/arch/amd64

	$(INSTALL) -m 0755 -d                            $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers
	$(INSTALL) -m 0644 drivers/keyboard.sls          $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers
	$(INSTALL) -m 0644 drivers/keymaps.sls           $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers
	$(INSTALL) -m 0644 drivers/mouse.sls             $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers
	$(INSTALL) -m 0644 drivers/net.sls               $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers
	$(INSTALL) -m 0644 drivers/storage.sls           $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers
	$(INSTALL) -m 0644 drivers/utils.sls             $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers
	$(INSTALL) -m 0644 drivers/virtio.sls            $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers

	$(INSTALL) -m 0644 drivers/pci.sls               $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers
	$(INSTALL) -m 0755 -d                            $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/pci
	$(INSTALL) -m 0644 drivers/pci/roms.sls          $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/pci

	$(INSTALL) -m 0755 -d                            $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/ata
	$(INSTALL) -m 0644 drivers/ata/atapi.sls         $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/ata
	$(INSTALL) -m 0644 drivers/ata/core.sls          $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/ata
	$(INSTALL) -m 0644 drivers/ata/drive.sls         $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/ata
	$(INSTALL) -m 0644 drivers/ata/ide.sls           $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/ata
	$(INSTALL) -m 0644 drivers/ata/identify.sls      $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/ata

	$(INSTALL) -m 0755 -d                            $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/net
	$(INSTALL) -m 0644 drivers/net/eepro100.sls      $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/net
	$(INSTALL) -m 0644 drivers/net/rtl8139.sls       $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/net
	$(INSTALL) -m 0644 drivers/net/tun.sls           $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/net
	$(INSTALL) -m 0644 drivers/net/virtio.sls        $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/net

	$(INSTALL) -m 0755 -d                            $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/scsi
	$(INSTALL) -m 0644 drivers/scsi/core.sls         $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/scsi
	$(INSTALL) -m 0644 drivers/scsi/block.sls        $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/scsi

	$(INSTALL) -m 0755 -d                            $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/video
	$(INSTALL) -m 0644 drivers/video/bga.sls         $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/video
	$(INSTALL) -m 0644 drivers/video/vbe.sls         $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/video

	$(INSTALL) -m 0755 -d                            $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/usb
	$(INSTALL) -m 0644 drivers/usb/core.sls          $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/usb
	$(INSTALL) -m 0644 drivers/usb/hid-numbers.sls   $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/usb
	$(INSTALL) -m 0644 drivers/usb/hub.sls           $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/usb
	$(INSTALL) -m 0644 drivers/usb/uhci.sls          $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/usb

	$(INSTALL) -m 0755 -d                            $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/ps2
	$(INSTALL) -m 0644 drivers/ps2/core.sls          $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/ps2
	$(INSTALL) -m 0644 drivers/ps2/i8042.sls         $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/ps2
	$(INSTALL) -m 0644 drivers/ps2/keyboard.sls      $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/ps2
	$(INSTALL) -m 0644 drivers/ps2/mouse.sls         $(DESTDIR)$(PREFIX)/share/r6rs/loko/drivers/ps2

	$(INSTALL) -m 0644 lib/match.sls                 $(DESTDIR)$(PREFIX)/share/r6rs/loko
	$(INSTALL) -m 0755 -d                            $(DESTDIR)$(PREFIX)/share/r6rs/loko/font
	$(INSTALL) -m 0644 lib/font/font-6x13.sls        $(DESTDIR)$(PREFIX)/share/r6rs/loko/font
	$(INSTALL) -m 0644 lib/font/font-8x13.sls        $(DESTDIR)$(PREFIX)/share/r6rs/loko/font

	$(INSTALL) -m 0755 -d                            $(DESTDIR)$(PREFIX)/share/r6rs/srfi
	$(INSTALL) -m 0644 srfi/170.loko.sls             $(DESTDIR)$(PREFIX)/share/r6rs/srfi/%3a170.loko.sls
	$(INSTALL) -m 0755 -d                            $(DESTDIR)$(PREFIX)/share/r6rs/srfi/%3a170
	$(INSTALL) -m 0644 srfi/170/posix.loko.sls       $(DESTDIR)$(PREFIX)/share/r6rs/srfi/%3a170
	$(INSTALL) -m 0644 srfi/170/linux.loko.sls       $(DESTDIR)$(PREFIX)/share/r6rs/srfi/%3a170/compat.loko.sls

	$(INSTALL) -m 0755 -d                            $(DESTDIR)$(PREFIX)/share/r6rs/srfi
	$(INSTALL) -m 0644 srfi/38.loko.sls              $(DESTDIR)$(PREFIX)/share/r6rs/srfi/%3a38.loko.sls
	$(INSTALL) -m 0755 -d                            $(DESTDIR)$(PREFIX)/share/r6rs/srfi/%3a38
	$(INSTALL) -m 0644 srfi/38/with-shared-structure.loko.sls \
	                                                 $(DESTDIR)$(PREFIX)/share/r6rs/srfi/%3a38

	$(INSTALL) -m 0755 -d                            $(DESTDIR)$(PREFIX)/share/r6rs/pre-srfi
	$(INSTALL) -m 0644 srfi/pre-srfi/processes.loko.sls \
	                                                 $(DESTDIR)$(PREFIX)/share/r6rs/pre-srfi/processes.loko.sls
	$(INSTALL) -m 0755 -d                            $(DESTDIR)$(PREFIX)/share/r6rs/pre-srfi/processes
	$(INSTALL) -m 0644 srfi/pre-srfi/processes/processlib.scm \
	                                                 $(DESTDIR)$(PREFIX)/share/r6rs/pre-srfi/processes
	$(INSTALL) -m 0644 srfi/pre-srfi/processes/linux.loko.sls \
	                                                 $(DESTDIR)$(PREFIX)/share/r6rs/pre-srfi/processes/compat.loko.sls

# Libraries needed when compiling programs
	(cd .akku/lib; find * -type d | \
	  while read fn; do \
	    $(INSTALL) -m 0755 -d $(DESTDIR)$(PREFIX)/lib/loko/$$fn; \
	  done)
# FIXME: Install only those libraries used by (loko compiler static).
	(cd .akku/lib; find * ! -type d -a \
            ! \( -name '*.chezscheme.sls' -o -name '*.ikarus.sls' \) | \
	  while read fn; do \
	    $(INSTALL) -m 0644 $$fn $(DESTDIR)$(PREFIX)/lib/loko/$$fn; \
	  done)
# GDB scripts for debugging Loko and compiled applications
	$(INSTALL) -m 0755 -d $(DESTDIR)$(GDB_AUTOLOAD_PATH)
	$(INSTALL) -m 0644 arch/amd64/loko-gdb.py \
	    $(DESTDIR)$(GDB_AUTOLOAD_PATH)/loko-amd64-$(VERSION)-gdb.py

install-info: Documentation/manual/loko.info
	mkdir -p $(DESTDIR)$(PREFIX)/share/info
	$(INSTALL) -m 0644 Documentation/manual/loko.info* \
	  $(DESTDIR)$(PREFIX)/share/info
	$(INSTALLINFO) --info-dir='$(DESTDIR)$(PREFIX)/share/info' \
	  '$(DESTDIR)$(PREFIX)/share/info/loko.info'

install-all: install install-info
	ln -f $(DESTDIR)$(PREFIX)/bin/loko $(DESTDIR)$(PREFIX)/bin/scheme-script

uninstall:
	rm -f $(DESTDIR)$(PREFIX)/bin/loko
	rm -rf $(DESTDIR)$(PREFIX)/share/loko
	rm -rf $(DESTDIR)$(PREFIX)/lib/loko
	$(INSTALLINFO) --info-dir='$(DESTDIR)$(PREFIX)/share/info' \
	  --delete '$(DESTDIR)$(PREFIX)/share/info/loko.info' || true
	rm -f $(DESTDIR)$(PREFIX)/share/info/loko.info*
