#
#	Makefile for the Clean Standard Environment
#

#
#		make (= make stdenv):
#			compiles all modules
#
#		make install:
#			compiles all modules
#			copies files to install directory
#
#		make cleanup:
#			removes all files in this directory that can be recreated
#

CLEAN_MODULES = \
	StdArray StdCharList StdClass StdDebug StdFunc StdList \
	StdOrdList StdOverloaded StdTuple _SystemEnum StdEnum _SystemArray StdEnv \
	_SystemStrictLists _SystemEnumStrict StdStrictLists StdOverloadedList

SYSTEM_MODULES = \
	StdBool StdChar StdFile StdInt StdMisc StdReal StdString

ABC_MODULES = \
	_system

OBJECT_MODULES = \
	_startup

SYSTEM_OBJECT_MODULES = \
	_reals crt crti crtn

CLEAN_MODULES_ABC = $(CLEAN_MODULES:%=CleanSystemFiles/%.abc)

SYSTEM_MODULES_ABC = $(SYSTEM_MODULES:%=CleanSystemFiles/%.abc)

SYSTEM_MODULES_ICL = $(SYSTEM_MODULES:%=%.icl)

ABC_MODULES_ABC = $(ABC_MODULES:%=CleanSystemFiles/%.abc)

CLEAN_MODULES_O = $(CLEAN_MODULES:%=CleanSystemFiles/%.o)

SYSTEM_MODULES_O = $(SYSTEM_MODULES:%=CleanSystemFiles/%.o)

ABC_MODULES_O = $(ABC_MODULES:%=CleanSystemFiles/%.o)

OBJECT_MODULES_O = $(OBJECT_MODULES:%=CleanSystemFiles/%.o)

SYSTEM_OBJECT_MODULES_O = $(SYSTEM_OBJECT_MODULES:%=CleanSystemFiles/%.o)

STDENV_FILES = \
	$(CLEAN_MODULES:%=%.icl) \
	$(CLEAN_MODULES:%=%.dcl) \
	$(SYSTEM_MODULES:%=%.dcl) \
	$(SYSTEM_MODULES_ABC) \
	$(CLEAN_MODULES_ABC) \
	$(ABC_MODULES_ABC) \
	wait1 \
	$(SYSTEM_MODULES_O) \
	$(CLEAN_MODULES_O) \
	$(ABC_MODULES_O) \
	$(OBJECT_MODULES_O) \
	$(SYSTEM_OBJECT_MODULES_O)

wait1:
	sleep 1

#
# Compile
#

stdenv: $(STDENV_FILES)

#
# Install
#
# the order here is important, because the files will be
# installed in the order given below.

INSTALL_STDENV_FILES = \
	$(CLEAN_MODULES:%=$(INSTALL_STDENV_DIR)/%.icl) \
	$(CLEAN_MODULES:%=$(INSTALL_STDENV_DIR)/%.dcl) \
	$(SYSTEM_MODULES:%=$(INSTALL_STDENV_DIR)/%.dcl) \
	$(ABC_MODULES:%=$(INSTALL_STDENV_DIR)/%.dcl) \
	$(OBJECT_MODULES:%=$(INSTALL_STDENV_DIR)/%.dcl) \
	$(SYSTEM_MODULES:%=$(INSTALL_STDENV_DIR)/CleanSystemFiles/%.abc) \
	$(CLEAN_MODULES:%=$(INSTALL_STDENV_DIR)/CleanSystemFiles/%.abc) \
	$(ABC_MODULES:%=$(INSTALL_STDENV_DIR)/CleanSystemFiles/%.abc) \
	wait2 \
	$(SYSTEM_MODULES:%=$(INSTALL_STDENV_DIR)/CleanSystemFiles/%.o) \
	$(CLEAN_MODULES:%=$(INSTALL_STDENV_DIR)/CleanSystemFiles/%.o) \
	$(ABC_MODULES:%=$(INSTALL_STDENV_DIR)/CleanSystemFiles/%.o) \
	$(OBJECT_MODULES:%=$(INSTALL_STDENV_DIR)/CleanSystemFiles/%.o) \
	$(SYSTEM_OBJECT_MODULES:%=$(INSTALL_STDENV_DIR)/CleanSystemFiles/%.o) \
	$(INSTALL_STDENV_DIR)/CleanSystemFiles/libCleanxv.a

install: stdenv $(INSTALL_STDENV_DIR) $(INSTALL_STDENV_DIR)/CleanSystemFiles $(INSTALL_STDENV_FILES)

wait2:
	sleep 1

$(INSTALL_STDENV_DIR) : 
	mkdir -p "$@"

$(INSTALL_STDENV_DIR)/CleanSystemFiles : 
	mkdir -p $(INSTALL_STDENV_DIR)/"Clean System Files" 
	ln -s $(INSTALL_STDENV_DIR)/"Clean System Files" $(INSTALL_STDENV_DIR)/"CleanSystemFiles" 

$(INSTALL_STDENV_DIR)/% : %
	cp "$<" "$@"
	chmod 644 "$@"

$(INSTALL_STDENV_DIR)/CleanSystemFiles/libCleanxv.a :
	$(RM) $(INSTALL_STDENV_DIR)/CleanSystemFiles/libCleanxv.a; \
	if test -f ../../iolib/libCleanvx.a; \
 	then ln -fs ../../iolib/libCleanxv.a $(INSTALL_STDENV_DIR)/CleanSystemFiles/libCleanxv.a; \
	else touch ../../libCleanxv.a; ln -fs ../../iolib/libCleanxv.a $(INSTALL_STDENV_DIR)/CleanSystemFiles/libCleanxv.a; rm ../../libCleanxv.a; \
	fi

#
# Cleanup
#

cleanup:
	$(RM) $(CLEAN_MODULES_ABC) \
	$(RM) $(CLEAN_MODULES_O) \
	$(RM) $(SYSTEM_MODULES_O) \
	$(RM) $(ABC_MODULES_O)

#
# Commands
#

CLM = clm -P .
CLMFLAGS =

.SUFFIXES: .abc .dcl .icl .o

.icl.abc:
	$(CLM) $(CLMFLAGS) -ABC $*

.icl.o:
	$(CLM) $(CLMFLAGS) -O `basename "$*" .icl`

.abc.o:
	$(CLM) $(CLMFLAGS) -O `basename "$*" .icl`


CleanSystemFiles/StdArray.o : StdArray.icl StdArray.dcl
	$(CLM) -O StdArray

CleanSystemFiles/StdArray.abc : StdArray.icl StdArray.dcl
	$(CLM) -ABC StdArray

CleanSystemFiles/StdCharList.o : StdCharList.icl StdCharList.dcl
	$(CLM) -O StdCharList

CleanSystemFiles/StdCharList.abc : StdCharList.icl StdCharList.dcl
	$(CLM) -ABC StdCharList

CleanSystemFiles/StdClass.o : StdClass.icl StdClass.dcl
	$(CLM) -O StdClass

CleanSystemFiles/StdClass.abc : StdClass.icl StdClass.dcl
	$(CLM) -ABC StdClass

CleanSystemFiles/StdDebug.o : StdDebug.icl StdDebug.dcl
	$(CLM) -O StdDebug

CleanSystemFiles/StdDebug.abc : StdDebug.icl StdDebug.dcl
	$(CLM) -ABC StdDebug

CleanSystemFiles/StdEnum.o : StdEnum.icl StdEnum.dcl
	$(CLM) -O StdEnum

CleanSystemFiles/StdEnum.abc : StdEnum.icl StdEnum.dcl
	$(CLM) -ABC StdEnum

CleanSystemFiles/StdEnv.o : StdEnv.icl StdEnv.dcl
	$(CLM) -O StdEnv

CleanSystemFiles/StdEnv.abc : StdEnv.icl StdEnv.dcl
	$(CLM) -ABC StdEnv
	
CleanSystemFiles/_SystemEnumStrict.o : _SystemEnumStrict.icl _SystemEnumStrict.dcl
	$(CLM) -O _SystemEnumStrict

CleanSystemFiles/_SystemEnumStrict.abc : _SystemEnumStrict.icl _SystemEnumStrict.dcl
	$(CLM) -ABC _SystemEnumStrict

CleanSystemFiles/_SystemStrictLists.o : _SystemStrictLists.icl _SystemStrictLists.dcl
	$(CLM) -O _SystemStrictLists

CleanSystemFiles/_SystemStrictLists.abc : _SystemStrictLists.icl _SystemStrictLists.dcl
	$(CLM) -ABC _SystemStrictLists

CleanSystemFiles/StdStrictLists.o : StdStrictLists.icl StdStrictLists.dcl
	$(CLM) -O StdStrictLists

CleanSystemFiles/StdStrictLists.abc : StdStrictLists.icl StdStrictLists.dcl
	$(CLM) -ABC StdStrictLists

CleanSystemFiles/StdOverloadedList.o : StdOverloadedList.icl StdOverloadedList.dcl
	$(CLM) -O StdOverloadedList

CleanSystemFiles/StdOverloadedList.abc : StdOverloadedList.icl StdOverloadedList.dcl
	$(CLM) -ABC StdOverloadedList

CleanSystemFiles/StdFunc.o : StdFunc.icl StdFunc.dcl
	$(CLM) -O StdFunc

CleanSystemFiles/StdFunc.abc : StdFunc.icl StdFunc.dcl
	$(CLM) -ABC StdFunc

CleanSystemFiles/StdList.o : StdList.icl StdList.dcl
	$(CLM) -O StdList

CleanSystemFiles/StdList.abc : StdList.icl StdList.dcl
	$(CLM) -ABC StdList

CleanSystemFiles/StdOrdList.o : StdOrdList.icl StdOrdList.dcl
	$(CLM) -O StdOrdList

CleanSystemFiles/StdOrdList.abc : StdOrdList.icl StdOrdList.dcl
	$(CLM) -ABC StdOrdList

CleanSystemFiles/StdOverloaded.o : StdOverloaded.icl StdOverloaded.dcl
	$(CLM) -O StdOverloaded

CleanSystemFiles/StdOverloaded.abc : StdOverloaded.icl StdOverloaded.dcl
	$(CLM) -ABC StdOverloaded

CleanSystemFiles/StdTuple.o : StdTuple.icl StdTuple.dcl
	$(CLM) -O StdTuple

CleanSystemFiles/StdTuple.abc : StdTuple.icl StdTuple.dcl
	$(CLM) -ABC StdTuple

CleanSystemFiles/_SystemEnum.o : _SystemEnum.icl _SystemEnum.dcl
	$(CLM) -O _SystemEnum

CleanSystemFiles/_SystemEnum.abc : _SystemEnum.icl _SystemEnum.dcl
	$(CLM) -ABC _SystemEnum

CleanSystemFiles/StdBool.o : StdBool.dcl CleanSystemFiles/StdBool.abc
	$(CLM) -O StdBool

CleanSystemFiles/StdBool.abc : StdBool.icl StdBool.dcl
	$(CLM) -ABC StdBool

CleanSystemFiles/StdChar.o : StdChar.dcl CleanSystemFiles/StdChar.abc
	$(CLM) -O StdChar

CleanSystemFiles/StdChar.abc : StdChar.icl StdChar.dcl
	$(CLM) -ABC StdChar

CleanSystemFiles/StdFile.o : StdFile.dcl CleanSystemFiles/StdFile.abc
	$(CLM) -O StdFile

CleanSystemFiles/StdFile.abc : StdFile.icl StdFile.dcl
	$(CLM) -ABC StdFile

CleanSystemFiles/StdInt.o : StdInt.dcl CleanSystemFiles/StdInt.abc
	$(CLM) -O StdInt

CleanSystemFiles/StdInt.abc : StdInt.icl StdInt.dcl
	$(CLM) -ABC StdInt

CleanSystemFiles/StdMisc.o : StdMisc.dcl CleanSystemFiles/StdMisc.abc
	$(CLM) -O StdMisc

CleanSystemFiles/StdMisc.abc : StdMisc.icl StdMisc.dcl
	$(CLM) -ABC StdMisc

CleanSystemFiles/StdReal.o : StdReal.dcl CleanSystemFiles/StdReal.abc
	$(CLM) -O StdReal

CleanSystemFiles/StdReal.abc : StdReal.icl StdReal.dcl
	$(CLM) -ABC StdReal

CleanSystemFiles/StdString.o : StdString.dcl CleanSystemFiles/StdString.abc
	$(CLM) -O StdString

CleanSystemFiles/StdString.abc : StdString.icl StdString.dcl
	$(CLM) -ABC StdString

CleanSystemFiles/_SystemArray.o : _SystemArray.dcl CleanSystemFiles/_SystemArray.abc
	$(CLM) -O _SystemArray

CleanSystemFiles/_SystemArray.abc : _SystemArray.icl _SystemArray.dcl
	$(CLM) -ABC _SystemArray

CleanSystemFiles/_system.o : CleanSystemFiles/_system.abc
	$(CLM) -O _system

# compile system modules twice, to make sure all inlining is done
system_abc: $(SYSTEM_MODULES_ABC) system_abc_touch

system_abc_touch:
	touch $(SYSTEM_MODULES_ICL)
	$(MAKE) system_abc_again

system_abc_again: $(SYSTEM_MODULES_ABC)
