# This makefile is used to a limited degree with nmake, but it mostly
# intended for use as a GNU makefile.

RACKET = ../../bin/racket
SCHEME = scheme

# Controls whether Racket layers are built as unsafe:
UNSAFE_COMP = --unsafe

# Controls whether compiled code is compressed:
COMPRESS_COMP = # --compress

# Controls whether Racket layers are built with expression-level debugging:
DEBUG_COMP = # --debug

# Controls whether Rumble is built as unsafe:
RUMBLE_UNSAFE_COMP = --unsafe

COMPILE_FILE = $(SCHEME) --script compile-file.ss $(UNSAFE_COMP) $(COMPRESS_COMP) $(DEBUG_COMP) --dest "$(BUILDDIR)"
COMPILE_FILE_DEPS = compile-file.ss include.ss place-register.ss 

RACKET_SETUP_ARGS = ../../bin/racket ../collects ../etc 0 false

PRIMITIVES_TABLES = primitive/kernel.ss primitive/unsafe.ss primitive/flfxnum.ss \
                    primitive/paramz.ss primitive/extfl.ss primitive/network.ss \
                    primitive/futures.ss primitive/foreign.ss primitive/place.ss \
                    primitive/linklet.ss primitive/internal.ss

# Set by the makefile in the "c" directory when driving this one
BUILDDIR = 

# List all targets ".scm" that use "convert.rkt" so we can generate a
# dependency rule for all of them:
CONVERTED = $(BUILDDIR)compiled/thread.scm $(BUILDDIR)compiled/io.scm \
            $(BUILDDIR)compiled/regexp.scm $(BUILDDIR)compiled/expander.scm \
            $(BUILDDIR)compiled/schemify.scm $(BUILDDIR)compiled/known.scm

# Additional dependencies for those ".scm" files generated by "convert.rkt":
CONVERT_DEPS = $(PRIMITIVES_TABLES)

CONVERT_RACKET = $(RACKET) -l- setup --chain ../setup-go.rkt $(BUILDDIR)compiled
CONVERT = $(CONVERT_RACKET) '(CONVERTED)' $(BUILDDIR)compiled/convert.d convert.rkt $(UNSAFE_COMP)

# Depenency chain for ".so" files:
RUMBLE_DEPS = $(BUILDDIR)chezpart.so
THREAD_DEPS = $(RUMBLE_DEPS) $(BUILDDIR)rumble.so
IO_DEPS = $(THREAD_DEPS) $(BUILDDIR)thread.so
REGEXP_DEPS = $(IO_DEPS) $(BUILDDIR)io.so
SCHEMIFY_DEPS = $(REGEXP_DEPS) $(BUILDDIR)regexp.so
LINKLET_DEPS = $(SCHEMIFY_DEPS) $(BUILDDIR)schemify.so
EXPANDER_DEPS = $(LINKLET_DEPS) $(BUILDDIR)linklet.so
MAIN_DEPS = $(EXPANDER_DEPS) $(BUILDDIR)expander.so

all:
	$(MAKE) rktio
	$(MAKE) rktl
	$(MAKE) $(BUILDDIR)racket.so

expander-demo: $(BUILDDIR)expander.so demo/expander.ss ../../bin/racket
	$(SCHEME) $(EXPANDER_DEPS) $(BUILDDIR)expander.so demo/expander.ss

run: $(BUILDDIR)main.so ../../bin/racket
	$(SCHEME) --script $(BUILDDIR)main.so $(RACKET_SETUP_ARGS) $(ARGS)

setup:
	$(MAKE) run ARGS="-l- setup $(ARGS)"

setup-v:
	$(MAKE) run ARGS="-W 'info@compiler/cm info@linklet debug@GC:major error' -l- setup -j 1 $(ARGS)"

run-wpo: $(BUILDDIR)racket.so ../../bin/racket
	$(SCHEME) --script $(BUILDDIR)racket.so $(RACKET_SETUP_ARGS) $(ARGS)

$(BUILDDIR)racket.so: $(BUILDDIR)main.so $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) --whole-program $(BUILDDIR)racket.so $(BUILDDIR)main.wpo

$(BUILDDIR)main.so: $(MAIN_DEPS) main.sps $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) main.sps $(MAIN_DEPS)

strip:
	$(SCHEME) --script strip.ss $(MAIN_DEPS) $(BUILDDIR)racket.so

rktl:
	$(MAKE) thread-rktl
	$(MAKE) io-rktl
	$(MAKE) regexp-rktl
	$(MAKE) schemify-rktl
	$(MAKE) known-rktl
	$(MAKE) expander-rktl

# For running without an enclosing build of the traditional Racket VM:
../../bin/racket:
	mkdir -p ../../bin
	touch ../../bin/racket

$(BUILDDIR)expander.so: expander.sls $(BUILDDIR)compiled/expander.scm $(PRIMITIVES_TABLES) $(EXPANDER_DEPS) $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) expander.sls $(EXPANDER_DEPS)

$(BUILDDIR)compiled/expander.scm: $(BUILDDIR)compiled/expander.rktl $(CONVERT_DEPS)
	$(CONVERT) $(BUILDDIR)compiled/expander.rktl $(BUILDDIR)compiled/expander.scm

$(BUILDDIR)compiled/expander.rktl:
	$(MAKE) expander-rktl

expander-rktl:
	$(MAKE) bounce BOUNCE_DIR=../expander BOUNCE_TARGET=expander-src BUILDDIR="../cs/"

linklet-demo: $(BUILDDIR)linklet.so
	$(SCHEME) $(LINKLET_DEPS) $(BUILDDIR)linklet.so demo/linklet.ss

LINKLET_SRCS = linklet/read.ss \
               linklet/write.ss \
               linklet/performance.ss \
               linklet/annotation.ss \
               linklet/compress.ss \
               linklet/db.ss

$(BUILDDIR)linklet.so: linklet.sls $(LINKLET_SRCS) $(LINKLET_DEPS) $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) linklet.sls $(LINKLET_DEPS)


$(BUILDDIR)schemify.so: schemify.sls $(BUILDDIR)compiled/schemify.scm $(BUILDDIR)compiled/known.scm $(SCHEMIFY_DEPS) $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) schemify.sls $(SCHEMIFY_DEPS)

$(BUILDDIR)compiled/schemify.scm: $(BUILDDIR)compiled/schemify.rktl $(CONVERT_DEPS)
	$(CONVERT) --skip-export $(BUILDDIR)compiled/schemify.rktl $(BUILDDIR)compiled/schemify.scm

$(BUILDDIR)compiled/schemify.rktl:
	$(MAKE) schemify-rktl

schemify-rktl:
	$(MAKE) bounce BOUNCE_DIR=../schemify BOUNCE_TARGET=schemify-src BUILDDIR="../cs/"


# Used by schemify.sls at compile time
$(BUILDDIR)compiled/known.scm: $(BUILDDIR)compiled/known.rktl $(CONVERT_DEPS)
	$(CONVERT) --skip-export $(BUILDDIR)compiled/known.rktl $(BUILDDIR)compiled/known.scm

$(BUILDDIR)compiled/known.rktl:
	$(MAKE) known-rktl

known-rktl:
	$(MAKE) bounce BOUNCE_DIR=../schemify BOUNCE_TARGET=known-src BUILDDIR="../cs/"


regexp-demo: $(BUILDDIR)regexp.so
	$(SCHEME) $(REGEXP_DEPS) $(BUILDDIR)regexp.so demo/regexp.ss

$(BUILDDIR)regexp.so: $(BUILDDIR)compiled/regexp.scm regexp.sls $(REGEXP_DEPS) $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) regexp.sls $(REGEXP_DEPS)

$(BUILDDIR)compiled/regexp.scm: $(BUILDDIR)compiled/regexp.rktl $(CONVERT_DEPS)
	$(CONVERT) $(BUILDDIR)compiled/regexp.rktl $(BUILDDIR)compiled/regexp.scm

$(BUILDDIR)compiled/regexp.rktl:
	$(MAKE) regexp-rktl

regexp-rktl:
	$(MAKE) bounce BOUNCE_DIR=../regexp BOUNCE_TARGET=regexp-src BUILDDIR="../cs/"


io-demo: $(BUILDDIR)io.so
	$(SCHEME) $(IO_DEPS) $(BUILDDIR)io.so demo/io.ss

$(BUILDDIR)io.so: $(BUILDDIR)compiled/io.scm io.sls $(IO_DEPS) ../rktio/rktio.rktl $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) io.sls $(IO_DEPS)

$(BUILDDIR)compiled/io.scm: $(BUILDDIR)compiled/io.rktl $(CONVERT_DEPS)
	$(CONVERT) $(BUILDDIR)compiled/io.rktl $(BUILDDIR)compiled/io.scm

$(BUILDDIR)compiled/io.rktl:
	$(MAKE) io-rktl

io-rktl:
	$(MAKE) bounce BOUNCE_DIR=../io BOUNCE_TARGET=io-src BUILDDIR="../cs/"

rktio:
	$(MAKE) bounce BOUNCE_DIR=../io BOUNCE_TARGET=rktio


thread-demo: $(BUILDDIR)thread.so
	$(SCHEME) $(THREAD_DEPS) $(BUILDDIR)thread.so demo/thread.ss

$(BUILDDIR)thread.so: $(BUILDDIR)compiled/thread.scm thread.sls $(THREAD_DEPS) $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) thread.sls $(THREAD_DEPS)

$(BUILDDIR)compiled/thread.scm: $(BUILDDIR)compiled/thread.rktl $(CONVERT_DEPS)
	$(CONVERT) $(BUILDDIR)compiled/thread.rktl $(BUILDDIR)compiled/thread.scm

$(BUILDDIR)compiled/thread.rktl:
	$(MAKE) thread-rktl

thread-rktl:
	$(MAKE) bounce BOUNCE_DIR=../thread BOUNCE_TARGET=thread-src BUILDDIR="../cs/"


bounce:
	$(MAKE) bounce-go RACKET="`$(RACKET) absify.rkt --exec $(RACKET)`"

bounce-go:
	cd $(BOUNCE_DIR); $(MAKE) RACO="$(RACKET) -N raco -l- raco" $(BOUNCE_TARGET)


chaperone-demo: $(BUILDDIR)rumble.so
	$(SCHEME) $(BUILDDIR)chezpart.so $(BUILDDIR)rumble.so demo/chaperone.ss

hash-demo: $(BUILDDIR)rumble.so
	$(SCHEME) $(BUILDDIR)chezpart.so $(BUILDDIR)rumble.so demo/hash.ss

struct-demo: $(BUILDDIR)rumble.so
	$(SCHEME) $(BUILDDIR)chezpart.so $(BUILDDIR)rumble.so demo/struct.ss

control-demo: $(BUILDDIR)rumble.so
	$(SCHEME) $(BUILDDIR)chezpart.so $(BUILDDIR)rumble.so demo/control.ss

foreign-demo: $(BUILDDIR)rumble.so
	$(SCHEME) $(BUILDDIR)chezpart.so $(BUILDDIR)rumble.so demo/foreign.ss

will-demo: $(BUILDDIR)rumble.so
	$(SCHEME) $(BUILDDIR)chezpart.so $(BUILDDIR)rumble.so demo/will.ss

future-demo: $(BUILDDIR)rumble.so
	$(SCHEME) $(BUILDDIR)chezpart.so $(BUILDDIR)rumble.so demo/future.ss

future2-demo: $(BUILDDIR)rumble.so
	$(SCHEME) $(BUILDDIR)chezpart.so $(BUILDDIR)rumble.so demo/future2.ss

RUMBLE_SRCS = rumble/define.ss \
              rumble/virtual-register.ss \
              rumble/check.ss \
	      rumble/syntax-rule.ss \
              rumble/constant.ss \
              rumble/hash-code.ss \
              rumble/struct.ss \
              rumble/prefab.ss \
              rumble/procedure.ss \
              rumble/impersonator.ss \
              rumble/equal.ss \
              rumble/object-name.ss \
              rumble/arity.ss \
              rumble/intmap.ss \
              rumble/hash.ss \
              rumble/datum.ss \
	      rumble/lock.ss \
	      rumble/thread-local.ss \
              rumble/thread-cell.ss \
              rumble/parameter.ss \
              rumble/begin0.ss \
              rumble/pthread.ss \
              rumble/control.ss \
              rumble/interrupt.ss \
              rumble/engine.ss \
              rumble/source.ss \
              rumble/error.ss \
              rumble/srcloc.ss \
              rumble/boolean.ss \
              rumble/bytes.ss \
              rumble/string.ss \
              rumble/char.ss \
              rumble/symbol.ss \
              rumble/list.ss \
              rumble/vector.ss \
              rumble/box.ss \
              rumble/immutable.ss \
              rumble/keyword.ss \
              rumble/mpair.ss \
              rumble/number.ss \
              rumble/random.ss \
              rumble/flvector.ss \
              rumble/correlated.ss \
              rumble/graph.ss \
              rumble/time.ss \
              rumble/memory.ss \
              rumble/ephemeron.ss \
              rumble/will-executor.ss \
              rumble/system.ss \
              rumble/unsafe.ss \
              rumble/extfl.ss \
              rumble/place.ss \
              rumble/foreign.ss \
              rumble/future.ss \
              rumble/version.ss \
              rumble/inline.ss \
              ../racket/src/schvers.h

$(BUILDDIR)rumble.so: $(RUMBLE_DEPS) rumble.sls $(RUMBLE_SRCS) $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) $(RUMBLE_UNSAFE_COMP) rumble.sls $(RUMBLE_DEPS)

$(BUILDDIR)chezpart.so: chezpart.sls $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) chezpart.sls

clean:
	rm -f chezpart.so rumble.so regexp.so io.so linklet.so expander.so schemify.so
	rm -f chezpart.wpo rumble.wpo regexp.wpo io.wpo linklet.wpo expander.wpo schemify.wpo
	rm -f thread.so thread.wpo main.wpo main.so
	rm -rf compiled


# The following included dependency files are generated by when
# creating compiler/expander.rktl, etc. The `-inclide` statements are
# wrapped in a pattern that causes them to be ignored by `nmake`,
# while the `nmake` directives are ignored by GNU `make`.

# \
!if 0

# These dependencies are used only for direct use of the makefile
-include compiled/expander.d
-include compiled/thread.d
-include compiled/io.d
-include compiled/regexp.d
-include compiled/schemify.d
-include compiled/known.d

# These dependencies are needed when "cs/c" drives the makefile
-include $(BUILDDIR)compiled/convert.d

#\
!endif

# \
!include $(BUILDDIR)compiled/convert.d
