
.PHONY: install install-chicken install-gambit install-gauche install-guile \
	install-sisc install-core install-tools all core tools \
	chicken gambit gauche guile sisc clean dist test check doc

VERSION=0.3.1

COPY=cp
MOVE=mv
DELETE=rm
MKDIR=mkdir
TYPE=type
ECHO=echo
CAT=cat
FIND=find
REDIR2NULL=>/dev/null 2>&1

TEX2PAGE=tex2page

BINDIR=/usr/local/bin/

ALL_MODULES=combinators env file io pathname process regex string-cursor tcp

########################################################################

all: core

core:
	@$(TYPE) chicken $(REDIR2NULL) && make chicken || true
	@$(TYPE) gsi $(REDIR2NULL) && make gambit || true
	@$(TYPE) sisc $(REDIR2NULL) && make sisc || true

install-core: core
	@$(TYPE) chicken $(REDIR2NULL) && make install-chicken || true
	@$(TYPE) gsi $(REDIR2NULL) && make install-gambit || true
	@$(TYPE) gauche-config $(REDIR2NULL) && make install-gauche || true
	@$(TYPE) guile $(REDIR2NULL) && make install-guile || true
	@$(TYPE) sisc $(REDIR2NULL) && make install-sisc || true

tools: tools/common-scheme

install-tools: tools
	@$(COPY) tools/common-scheme $(BINDIR)

install: install-core

uninstall:
	@$(TYPE) chicken $(REDIR2NULL) && make uninstall-chicken || true
	@$(TYPE) gsi $(REDIR2NULL) && make uninstall-gambit || true
	@$(TYPE) gauche-config $(REDIR2NULL) && make uninstall-gauche || true
	@$(TYPE) guile $(REDIR2NULL) && make uninstall-guile || true
	@$(TYPE) sisc $(REDIR2NULL) && make uninstall-sisc || true
	$(DELETE) -f $(BINDIR)/common-scheme

########################################################################

CSC=csc
CHICKEN_OPTS=-O2
CHICKEN_MODULE_NAMES=$(ALL_MODULES)
CHICKEN_MODULES=$(CHICKEN_MODULE_NAMES:%=chicken/common/%.so)

chicken/common/%.so: chicken/common/%.scm
	$(CSC) $(CHICKEN_OPTS) -s $<

chicken: $(CHICKEN_MODULES)

install-chicken: chicken
	cd chicken && chicken-setup srfi-10000
	$(MKDIR) -p `chicken-setup -repository`/common
	$(COPY) chicken/common/*.so `chicken-setup -repository`/common/

uninstall-chicken:
	$(DELETE) -f `chicken-setup -repository`/srfi-10000.*
	for f in $(CHICKEN_MODULE_NAMES); do \
	  $(DELETE) -f `chicken-setup -repository`/common/$$f.so; \
	done

########################################################################

GAMBIT_HOME=/usr/local/Gambit-C
GSC=$(GAMBIT_HOME)/bin/gsc
GAMBIT_OPTS=
GAMBIT_LIBS=-lgambc -lm -ldl -lutil
GAMBIT_MODULE_NAMES=combinators env file io pathname process string-cursor tcp
GAMBIT_MODULES=$(GAMBIT_MODULE_NAMES:%=gambit/common/%.o1)

gambit/common/%.o1: gambit/common/%.scm
	$(DELETE) -f $@
	$(GSC) $(GAMBIT_OPTS) -dynamic -prelude '(include "../srfi-10000.scm")' $<
	$(DELETE) -f $(@:gambit/common/%.o1=%.c)
	$(MOVE) $(@:gambit/common/%=%) gambit/common/

gambit/require.o1: gambit/require.scm
	$(GSC) -dynamic $<
	$(MOVE) require.o1 gambit/
	$(DELETE) require.c

gambit: $(GAMBIT_MODULES) gambit/require.o1

install-gambit: gambit
	$(MKDIR) -p $(GAMBIT_HOME)/modules/common/
	$(COPY) gambit/srfi-10000.scm $(GAMBIT_HOME)
	$(COPY) gambit/require.o1 $(GAMBIT_HOME)
	$(COPY) gambit/common/*.o1 $(GAMBIT_HOME)/modules/common/

uninstall-gambit:
	$(DELETE) -f $(GAMBIT_HOME)/srfi-10000.scm $(GAMBIT_HOME)/require.o1
	for f in $(GAMBIT_MODULE_NAMES); do \
	  $(DELETE) -f $(GAMBIT_MODULE_NAMES)/modules/common/$$f.o1; \
	done

########################################################################

gauche:

install-gauche: gauche
	$(COPY) gauche/srfi-10000.scm `gauche-config --sitelibdir`
	$(MKDIR) -p `gauche-config --sitelibdir`/common/
	$(COPY) gauche/common/*.scm `gauche-config --sitelibdir`/common/
# add srfi-10000 to hard-coded srfi list
	grep -q '(srfi-10000 srfi-10000)' `gauche-config --syslibdir`/srfi-0.scm || patch `gauche-config --syslibdir`/srfi-0.scm gauche/srfi-0.scm.diff

uninstall-gauche:
	$(DELETE) -f `gauche-config --sitelibdir`/srfi-10000.scm
	for f in $(ALL_MODULES); do \
	  $(DELETE) -f `gauche-config --sitelibdir`/common/$$f.scm; \
	done

########################################################################

guile:

install-guile: guile
	$(MKDIR) -p `guile-config info pkgdatadir`/site/common/
	$(MKDIR) -p `guile-config info pkgdatadir`/site/srfi/
	$(COPY) guile/srfi-10000.scm `guile-config info pkgdatadir`/site/srfi/
	$(COPY) guile/common/*.scm `guile-config info pkgdatadir`/site/common/

uninstall-guile:
	$(DELETE) -f `guile-config info pkgdatadir`/site/srfi/srfi-10000.scm
	for f in $(ALL_MODULES); do \
	  $(DELETE) -f `guile-config info pkgdatadir`/site/common/$$f.scm; \
	done

########################################################################

SISC_HOME=/usr/local/lib/sisc
SISC_INSTALL_DIR=$(SISC_HOME)

SISC=sisc
SISC_SRFI_DIR=sisc/sisc/libs/srfi
SISC_COMMON_MODULE_NAMES=combinators env file io pathname process string-cursor
SISC_COMMON_MODULES=$(SISC_COMMON_MODULE_NAMES:%=sisc/common/%.scc)

%.scc: %.scm
	$(SISC) -x -e '(compile-file "$<" "$@")'

common-scheme.jar: $(SISC_SRFI_DIR)/srfi-10000.scc $(SISC_COMMON_MODULES)
	cd sisc && jar cf ../common-scheme.jar `find . -name \*.scc`

sisc: common-scheme.jar

install-sisc: sisc
	$(COPY) common-scheme.jar $(SISC_INSTALL_DIR)

uninstall-sisc:
	$(DELETE) -f $(SISC_INSTALL_DIR)/common-scheme.jar

########################################################################

CS_EGG_FILES=srfi-10000.scm srfi-10000.setup common

common-scheme.egg: $(CS_EGG_FILES)
	cd chicken && tar czvf ../$@ $<

########################################################################

doc: common-scheme.html

common-scheme.html: common-scheme.tex
	$(TEX2PAGE) $<

########################################################################

tools/common-scheme: tools/common-scheme.scm
	@if $(TYPE) chicken $(REDIR2NULL); then \
	  echo "creating common-scheme as chicken executable"; \
	  $(CSC) $(CHICKEN_OPTS) $<; \
	elif $(TYPE) gsi $(REDIR2NULL); then \
	  echo "creating common-scheme as gambit executable"; \
	  $(GSC) $(GAMBIT_OPTS) -prelude '(include "gambit/srfi-10000.scm")' $<; \
	  $(CC) -O2 -I$(GAMBIT_HOME)/include -L$(GAMBIT_HOME)/lib $@.c $@_.c $(GAMBIT_LIBS) -o $@; \
	  $(DELETE) -f $@.c $@_.c; \
	elif $(TYPE) gosh $(REDIR2NULL); then \
	  echo "creating common-scheme as gauche script"; \
	  $(ECHO) '#!'`which gosh` > $@; \
	  $(CAT) $< >> $@; \
	  $(CHMOD) 755 $@; \
	elif $(TYPE) guile $(REDIR2NULL); then \
	  echo "creating common-scheme as guile script"; \
	  $(ECHO) '#!'`which guile` > $@; \
	  $(ECHO) '!#' >> $@; \
	  $(CAT) $< >> $@; \
	  $(CHMOD) 755 $@; \
	else \
	  echo "no implementation found"; \
	fi

########################################################################

clean:
	$(FIND) . \( -name \*~ -o -name \*.so -o -name \*.o1 -o -name \*.scc \) -exec rm -f '{}' \;
	$(DELETE) -f tools/common-scheme

dist: clean
	cd .. && mv common-scheme common-scheme-$(VERSION) && tar czvf common-scheme-$(VERSION).tar.gz common-scheme-$(VERSION) --exclude \*.tar.bz2 --exclude \*.tar.gz --exclude CVS && mv common-scheme-$(VERSION) common-scheme && mv common-scheme-$(VERSION).tar.gz common-scheme

check: test

test:
	cd tests && make test
