#
# Makefile for racket
#

srcdir = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
libdir = @libdir@
includepltdir = @includepltdir@
libpltdir = @libpltdir@
collectsdir = @collectsdir@
builddir = @builddir@

# for version.mak:
mainsrcdir = @srcdir@/..
@INCLUDEDEP@ @srcdir@/version.mak

NOOP = :

CC = @CC@
CPP = @CPP@

NICEAR = $(mainsrcdir)/utils/nicear
AR = @AR@
ARFLAGS = @ARFLAGS@
RANLIB = @RANLIB@

STRIP_DEBUG = @STRIP_DEBUG@

ARLIBFLAGS = @LDFLAGS@ @LIBS@

RACKET = racket

# See ../../Makefile about RUN_RACKET_<X>, which 
# typically redirects to RUN_THIS_RACKET_<X>:
RUN_THIS_RACKET_CGC = ./racket@CGC@
RUN_THIS_RACKET_MMM = ./racket@MMM@

MZSRC = $(srcdir)/src

FOREIGN_DIR = ../foreign
FOREIGN_OBJ = $(FOREIGN_DIR)/foreign.@LTO@
LIBFFI_OBJ_ON = $(FOREIGN_DIR)/libffi/src/*.@LTO@ $(FOREIGN_DIR)/libffi/src/*/*.@LTO@
LIBFFI_OBJ_OFF = 
FOREIGN_OBJS = $(FOREIGN_OBJ) $(LIBFFI_OBJ_@OWN_LIBFFI@)
LIBFFI_LIB_ON = ../foreign/libffi/libffi@FOREIGN_CONVENIENCE@.la
LIBFFI_LIB_OFF = 
FOREIGN_LIB = $(FOREIGN_OBJ) $(LIBFFI_LIB_@OWN_LIBFFI@)
FOREIGN_STUB_LIB = $(FOREIGN_OBJ)
FOREIGN_OBJSLIB = @FOREIGN_OBJSLIB@
# Dependency always uses FOREIGN_LIB, but linker uses FOREIGN_OBJSLIB. The
#  FOREIGN_OBJSLIB expansion has too many "*"s to be a valid make target,
#  while FOREIGN_LIB is not always acceptable to the linker.
# The foreign build always uses libtool, so that's why we use .la instead of @LTA@
#  in FOREIGN_LIB.

# About EXE_SUFFIX:
#  Cygwin offers the illusion that binaries have no ".exe" suffix by
#  having the file-open syscall open an ".exe" file for reading when
#  (1) the given filename has no suffix, and (2) there's not a suffixless
#  file present. However, Cygwin doesn't do that when opening a file for
#  output, even when the output mode is 'update. So we need to explcitly
#  add EXE_SUFFIX in a few places.

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

bin: 
	$(MAKE) @MZBINTARGET@

normal-bin:
	$(MAKE) @MAIN_VARIANT@

common:
	$(MAKE) g-c
	$(MAKE) @FOREIGNTARGET@

cgc:
	$(MAKE) common
	$(MAKE) dynlib
	$(MAKE) mzlibrary
	$(MAKE) racket@CGC@ 

3m:
	$(MAKE) @CGC_IF_NEEDED_FOR_MMM@
	cd gc2; $(MAKE) all
	cd dynsrc; $(MAKE) dynlib3m
	cd gc2; $(MAKE) ../racket@MMM@

both:
	$(MAKE) cgc
	$(MAKE) 3m

oskit: 
	$(MAKE) common
	$(MAKE) mzlibrary
	$(MAKE) racket.multiboot

racketlib: 
	$(MAKE) g-c 
	$(MAKE) @FOREIGNTARGET@
	$(MAKE) mzlibrary 

dynlib:
	cd dynsrc; $(MAKE) dynlib 

dynexample:
	$(MAKE) dynlib
	cd dynsrc; $(MAKE) dynexample 

oe:
	$(MAKE) dynlib
	cd dynsrc; $(MAKE) oe

g-c:
	cd @GCDIR@; $(MAKE) ../libmzgc.@LIBSFX@ 

exports:
	cd src; $(MAKE) mzheaders

sproc-extra-lib:
	cd @GCDIR@; $(MAKE) sproc.@LTO@
	$(MAKE) sproc.@LTO@

gc.@LIBSFX@: 
	$(NICEAR) $(AR) $(ARFLAGS) @GCDIR@/gc.@LIBSFX@ @GCDIR@/*.@LTO@

# Compilation of the foreign libraries (this compiles all of them)
foreign-stuff:
	cd $(FOREIGN_DIR); $(MAKE) all

foreign-stub:
	cd $(FOREIGN_DIR); $(MAKE) stub

mzlibrary:
	cd src; $(MAKE) all 
	$(MAKE) libracket.@LIBSFX@

# For no-cgc-needed, we don't need to build the gc or link racketcgc, 
# but gc2 depends on src objects; if building 3m without cgc becomes
# more common, we could improve things to perform even less cgc-build work
no-cgc-needed:
	cd src; $(MAKE) all
	$(MAKE) @FOREIGNTARGET@
	$(MAKE) main.@LTO@
	cd dynsrc; $(MAKE) ../starter

FOREIGN_USED_LIB = $(FOREIGN_OBJ) $(FOREIGN_LIB)
FOREIGN_USED_OBJSLIB = $(FOREIGN_OBJSLIB)
FOREIGN_NOT_USED_LIB = $(FOREIGN_OBJ)
FOREIGN_NOT_USED_OBJSLIB = $(FOREIGN_OBJ)

libracket.@LIBSFX@: src/*.@LTO@ $(@FOREIGN_IF_USED@_LIB)
	$(NICEAR) $(AR) $(ARFLAGS) libracket.@LIBSFX@ src/*.@LTO@ $(@FOREIGN_IF_USED@_OBJSLIB) @LIBRACKET_DEP@
	$(RANLIB) libracket.@LIBSFX@

# Irix sproc, only
sproc.@LTO@: @GCDIR@/sproc.@LTO@
	cp @GCDIR@/sproc.@LTO@ sproc.@LTO@

# Unix ----------------------------------------

racket@CGC@@NOT_OSX@: libracket.@LIBSFX@ libmzgc.@LIBSFX@ main.@LTO@ $(SPECIALIZINGOBJECTS)
	@MZLINKER@ -o racket@CGC@ main.@LTO@ $(SPECIALIZINGOBJECTS) libracket.@LIBSFX@ libmzgc.@LIBSFX@ @LDFLAGS@ @LIBS@

# Mac OS ----------------------------------------

MZFW = Racket.framework/Versions/$(FWVERSION)/Racket

$(MZFW): libracket.@LIBSFX@ libmzgc.@LIBSFX@ $(SPECIALIZINGOBJECTS)
	mkdir -p  Racket.framework/Versions/$(FWVERSION)
	@MZLINKER@ -o $(MZFW) @LDFLAGS@ -framework CoreFoundation -dynamiclib -all_load $(SPECIALIZINGOBJECTS) libracket.@LIBSFX@ libmzgc.@LIBSFX@ @LIBS@
	rm -f Racket.framework/Racket
	ln -s Versions/$(FWVERSION)/Racket Racket.framework/Racket

racket@CGC@@OSX@: $(MZFW) main.@LTO@
	@MZLINKER@ -o racket@CGC@ @PROFFLAGS@ @LDFLAGS@ main.@LTO@ -Wl,-headerpad_max_install_names -F. -framework Racket @LIBS@
	/usr/bin/install_name_tool -change "Racket.framework/Versions/$(FWVERSION)/Racket" "@executable_path/Racket.framework/Versions/$(FWVERSION)/Racket" "racket@CGC@"

# OSKit ----------------------------------------

racket.multiboot : libracket.@LIBSFX@ libmzgc.@LIBSFX@ main.@LTO@
	$(LD) -Ttext 100000 $(LDFLAGS) @OSKHOME@/lib/oskit/multiboot.@LTO@ \
		-o racket.multiboot main.@LTO@ -L. -lracket -lgc \
                -L@OSKHOME@/lib -loskit_kern -loskit_clientos @EXTRA_OSK_LIBS@ \
                -loskit_freebsd_c -loskit_c -loskit_lmm \
                -loskit_freebsd_m -loskit_memfs -loskit_fsnamespace  \
                -loskit_dev -loskit_com \
                -loskit_kern -loskit_freebsd_c -loskit_c \
		@OSKHOME@/lib/oskit/crtn.@LTO@

# ----------------------------------------

DEF_COLLECTS_DIR = -DINITIAL_COLLECTS_DIRECTORY='"'"`cd $(srcdir)/../../collects; pwd`"'"'

main.@LTO@: $(srcdir)/main.c $(srcdir)/include/scheme.h $(srcdir)/sconfig.h $(srcdir)/src/stypes.h $(srcdir)/cmdline.inc $(srcdir)/oskglue.inc
	$(CC) -I$(builddir) -I$(srcdir)/include @CFLAGS@ @COMPFLAGS@ @PREFLAGS@ @PROFFLAGS@ @OPTIONS@ @MZOPTIONS@ $(DEF_COLLECTS_DIR) -c $(srcdir)/main.c -o main.@LTO@

main_ee.@LTO@: main.@LTO@
	$(CC) -I$(builddir) -I$(srcdir)/include @CFLAGS@ @COMPFLAGS@ @PREFLAGS@ @PROFFLAGS@ @OPTIONS@ @MZOPTIONS@ $(DEF_COLLECTS_DIR) -DSTANDALONE_WITH_EMBEDDED_EXTENSION -c $(srcdir)/main.c -o main_ee.@LTO@

ee-main:
	$(MAKE) main_ee.@LTO@

ee-app: $(RACKET) main_ee.@LTO@
	if [ "$(EEAPP)" = '' ] ; then echo "ERROR: You must specify EEAPP" ; else $(CC) $(MAIN_CFLAGS_NODBG) -o $(EEAPP) main_ee.@LTO@ $(EEOBJECTS) $(SPECIALIZINGOBJECTS) libracket.@LIBSFX@ libmzgc.@LIBSFX@ @LIBS@ ; fi

mzstart.exe: $(srcdir)/dynsrc/start.c
	$(CC) @CFLAGS@ -o mzstart.exe $(srcdir)/dynsrc/start.c

starter: mzstart.exe

exn:
	$(MAKE) $(srcdir)/src/schexn.h
	$(MAKE) $(collectsdir)/racket/private/kernstruct.rkt

STARTUPDEST = startup.inc
CSTARTUPDEST = cstartup.inc

startup:
	$(MAKE) $(srcdir)/src/$(STARTUPDEST)
cstartup:
	$(MAKE) $(srcdir)/src/$(CSTARTUPDEST)

total_startup:
	awk '{ if (match($$0, "#define USE_COMPILED_STARTUP 1")) print "#define USE_COMPILED_STARTUP 0"; else print }' src/schminc.h > src/schminc.newh
	mv src/schminc.newh src/schminc.h
	$(MAKE) cgc
	rm -rf $(srcdir)/src/$(CSTARTUPDEST)
	$(MAKE) $(srcdir)/src/$(CSTARTUPDEST)
	awk '{ if (match($$0, "#define USE_COMPILED_STARTUP 0")) print "#define USE_COMPILED_STARTUP 1"; else print }' src/schminc.h > src/schminc.newh
	mv src/schminc.newh src/schminc.h
	$(MAKE) cgc

headers:
	@RUN_RACKET_CGC@ -cqu $(srcdir)/mkincludes.rkt "$(DESTDIR)$(includepltdir)" "$(srcdir)" .

$(srcdir)/src/schexn.h: $(srcdir)/src/makeexn
	$(RACKET) -um $(srcdir)/src/makeexn > $(srcdir)/src/schexn.h
$(collectsdir)/racket/private/kernstruct.rkt: $(srcdir)/src/makeexn
	$(RACKET) -um $(srcdir)/src/makeexn kernstruct $(collectsdir)/racket/private/kernstruct.rkt

$(srcdir)/src/$(STARTUPDEST): $(srcdir)/src/startup.rktl $(srcdir)/src/sstoinct.rkt
	$(RACKET) -cu $(srcdir)/src/sstoinct.rkt < $(srcdir)/src/startup.rktl > $(srcdir)/src/$(STARTUPDEST) 
$(srcdir)/src/$(CSTARTUPDEST): $(srcdir)/src/startup.rktl $(srcdir)/src/schvers.h $(srcdir)/src/schminc.h
	$(RUN_THIS_RACKET_CGC) -cu $(srcdir)/src/sstoinc.rkt $(CSTARTUPEXTRA) $(srcdir)/src/$(CSTARTUPDEST) < $(srcdir)/src/startup.rktl 

mark:
	racket -cu $(srcdir)/src/mkmark.rkt $(srcdir)/src < $(srcdir)/src/mzmarksrc.c

cstartup.zo:
	$(MAKE) startup CSTARTUPEXTRA='zo' CSTARTUPDEST="../cstartup.zo"

clean@NOT_OSX@:
	/bin/rm -rf tmp[123456789] tests/tmp[123456789] tests/sub[123]
	/bin/rm -f tests/*~
	/bin/rm -f *.@LTO@ core
	/bin/rm -f mzdyn.o libmzgc.@LIBSFX@ libracket.@LIBSFX@ libracket3m.@LIBSFX@ libdl.a racket racket.multiboot
	/bin/rm -f include/macosxpre
	/bin/rm -f include/macosxpre.p
	cd gc; $(MAKE) clean
	cd gc2; $(MAKE) clean
	cd sgc; $(MAKE) clean
	cd src; $(MAKE) clean
	cd dynsrc; $(MAKE) clean
	if [ -d ../foreign ] ; then cd ../foreign ; $(MAKE) clean ; fi

clean@OSX@:
	rm -rf Racket.framework
	$(MAKE) clean@NOT_OSX@

BUILDINFO=$(DESTDIR)$(libpltdir)/buildinfo
ICP=@ICP@

install:
	$(MAKE) install-@MAIN_VARIANT@

install-3m:
	$(MAKE) headers
	$(MAKE) @MZINSTALLTARGET@
	$(MAKE) @MZINSTALLTARGET@-3m
	$(MAKE) @MZINSTALLTARGET@-3m-final

install-cgc:
	$(MAKE) headers
	$(MAKE) @MZINSTALLTARGET@
	$(MAKE) @MZINSTALLTARGET@-cgc
	$(MAKE) @MZINSTALLTARGET@-cgc-final

install-both:
	$(MAKE) headers
	$(MAKE) @MZINSTALLTARGET@
	$(MAKE) @MZINSTALLTARGET@-3m
	$(MAKE) @MZINSTALLTARGET@-cgc
	$(MAKE) @MZINSTALLTARGET@-@MAIN_VARIANT@-final

# Unix install ----------------------------------------

# Prefix might be relative to srcdir, or it might be absolute, so we
# have to go up and install things from there.

unix-install:	
	cd ..; rm -f "$(DESTDIR)$(bindir)/racket@CGC_INSTALLED@"
	cd ..; rm -f "$(DESTDIR)$(bindir)/racket@MMM_INSTALLED@"
	cd ..; cp racket/starter "$(DESTDIR)$(libpltdir)/starter"
	cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libpltdir)/starter"
	@RUN_RACKET_CGC@ -cu "$(srcdir)/collects-path.rkt" "$(DESTDIR)$(libpltdir)/starter" @COLLECTS_PATH@
	cd ..; echo 'CC=@CC@' > "$(BUILDINFO)"
	cd ..; echo 'CFLAGS=@CFLAGS@ @PREFLAGS@ @COMPFLAGS@' >> "$(BUILDINFO)"
	cd ..; echo 'OPTIONS=@OPTIONS@' >> "$(BUILDINFO)"
	cd ..; echo 'MZOPTIONS=@MZOPTIONS@' >> "$(BUILDINFO)"
	cd ..; echo "LDFLAGS=@LDFLAGS@" >> "$(BUILDINFO)"
	cd ..; echo 'LIBS=@LIBS@' >> "$(BUILDINFO)"

unix-install-cgc:
	cd ..; $(ICP) racket/libmzgc.@LIBSFX@ "$(DESTDIR)$(libdir)/libmzgc.@LIBSFX@"
	cd ..; $(ICP) racket/libracket.@LIBSFX@ "$(DESTDIR)$(libdir)/libracket.@LIBSFX@"
	cd ..; $(ICP) racket/racket@CGC@ "$(DESTDIR)$(bindir)/racket@CGC_INSTALLED@"
	cd ..; cp racket/mzdyn.o "$(DESTDIR)$(libpltdir)/mzdyn.o"
	@RUN_RACKET_CGC@ -cu "$(srcdir)/collects-path.rkt" "$(DESTDIR)$(bindir)/racket@CGC_INSTALLED@@EXE_SUFFIX@" @COLLECTS_PATH@

unix-install-cgc-final:
	$(NOOP)

unix-install-3m:
	cd ..; $(ICP) racket/racket@MMM@ "$(DESTDIR)$(bindir)/racket@MMM_INSTALLED@"
	cd ..; $(ICP) racket/libracket3m.@LIBSFX@ "$(DESTDIR)$(libdir)/libracket3m.@LIBSFX@"
	cd ..; $(ICP) racket/mzdyn3m.o "$(DESTDIR)$(libpltdir)/mzdyn3m.o"
	@RUN_RACKET_MMM@ -cu "$(srcdir)/collects-path.rkt" "$(DESTDIR)$(bindir)/racket@MMM_INSTALLED@@EXE_SUFFIX@" @COLLECTS_PATH@

unix-install-3m-final:
	$(NOOP)

# OS X install ----------------------------------------

MZFWDIR = @FRAMEWORK_INSTALL_DIR@/Racket.framework
MZFWMMM = Racket.framework/Versions/$(FWVERSION)_3m/Racket
FRAMEWORK_REL_PREFIX = "@executable_path/../lib/"

osx-install:
	$(MAKE) unix-install
	rm -f $(MZFWDIR)/Racket
	rm -rf $(MZFWDIR)/Versions/$(FWVERSION)
	rm -rf $(MZFWDIR)/Versions/$(FWVERSION)_3m
	if [ @FRAMEWORK_REL_INSTALL@ = yes ] ; then rm -rf $(MZFWDIR) ; fi
	mkdir -p @FRAMEWORK_INSTALL_DIR@

osx-install-cgc:
	$(MAKE) unix-install-cgc
	mkdir -p "$(MZFWDIR)/Versions/$(FWVERSION)"
	cp $(MZFW) $(MZFWDIR)/Versions/$(FWVERSION)/
	/usr/bin/install_name_tool -change "@executable_path/Racket.framework/Versions/$(FWVERSION)/Racket" "@FRAMEWORK_PREFIX@Racket.framework/Versions/$(FWVERSION)/Racket" "$(bindir)/racket@CGC_INSTALLED@"
	$(STRIP_DEBUG) "$(bindir)/racket@CGC_INSTALLED@"

osx-install-cgc-final:
	$(MAKE) unix-install-cgc-final
	ln -s Versions/$(FWVERSION)/Racket $(MZFWDIR)/

osx-install-3m:
	$(MAKE) unix-install-3m
	mkdir -p "$(MZFWDIR)/Versions/$(FWVERSION)_3m"
	cp $(MZFWMMM) $(MZFWDIR)/Versions/$(FWVERSION)_3m/
	/usr/bin/install_name_tool -change "@executable_path/Racket.framework/Versions/$(FWVERSION)_3m/Racket" "@FRAMEWORK_PREFIX@Racket.framework/Versions/$(FWVERSION)_3m/Racket" "$(bindir)/racket@MMM_INSTALLED@"
	$(STRIP_DEBUG) "$(bindir)/racket@MMM_INSTALLED@"

osx-install-3m-final:
	$(MAKE) unix-install-3m-final
	ln -s Versions/$(FWVERSION)_3m/Racket $(MZFWDIR)/


# Cygwin install ----------------------------------------

unix-cygwin-install:
	$(MAKE) unix-install
	cd dynsrc; $(MAKE) cygwin-install-core

unix-cygwin-install-cgc:
	$(MAKE) unix-install-cgc
	cd dynsrc; $(MAKE) cygwin-install-cgc

unix-cygwin-install-cgc-final:
	$(MAKE) unix-install-cgc-final

unix-cygwin-install-3m:
	$(MAKE) unix-install-3m
	cd dynsrc; $(MAKE) cygwin-install-3m

unix-cygwin-install-3m-final:
	$(MAKE) unix-install-3m-final

# Generate plt-gdbinit ----------------------------------------

mz-gdbinit: $(srcdir)/mk-gdbinit.rkt $(srcdir)/src/stypes.h
	$(RACKET) $(srcdir)/mk-gdbinit.rkt
