sinclude Makefile.local
sinclude Makefile.type_system
sinclude Makefile.local$(TYPE_SYSTEM)
include Makefile.build_env

#-----------------------------------------------------------------------------
# The following are the steps for adding a new kernel and userland
# configuration.  First define the $(TARGET) name by which the new
# kernel and userland configuration are to be known.  "make" targets,
# with the exception of $(DEFAULTTARGET) are added as follows.
#--------
# Please assume the target name to be added is the symbol $(TARGET).
# (For example replace $(TARGET) with mycompany.)
#--------
# Abbreviation of detailed steps (six lines below):
#	1) Create uClinux/linux/arch/mipsnommu/defconfig-brecis.$(TARGET)
#	2) Create uClinux/romdisk/etc.$(TARGET) and other needed files.
#	3) Edit this file to add new $(TARGET) -- please read below!
#	   Alternatively put into Makefile.local -- perhaps start this way.
#	4) Create uClinux/uC-src/defconfig.$(TARGET)
#--------
# Detailed steps explained below here.
# 1) Create the .config file used by the uClinux kernel under the name
#    $(KERNELDIR)/arch/mipsnommu/defconfig-brecis.$(TARGET)
#    The following steps may be used to create this file:
#    a) select one of the $(KERNELDIR)/arch/mipsnommu/defconfig-brecis*
#       files which most closely matches the kernel one wishes to build.
#    b) Copy this file to $(KERNELDIR)/.config
#    c) In the $(KERNELDIR) directory,
#       use one of the following to edit the .config file
#       make config -or- make menuconfig -or- make xconfig
#    d) Copy the newly created .config file to $(KERNELDIR)/arch/mipsnommu
#       with the filename defconfig-brecis.$(TARGET)
#    -- or one can copy the close one to defconfig-brecis.$(TARGET), and
#    -- edit with a text editor.
# 2) Create the appropriate files and/or directories in the $(ROMDISKDIR)
#    directory.  Files and directories include:
#    a) BOOT.FILES.$(TARGET)
#    b) BOOT.FILES.$(TARGET).EXCLUDE
#    c) etc.$(TARGET)
#    d) and others, please examine $(ROMDISKDIR)/Makefile
# 3) In this Makefile (the one you are reading), please do the following:
#    a) Add the new target to the appropriate target list if necessary:
#       1) NFSTARGETS if $(TARGET) requires NFS=NFS.
#          Alternatively, place LOCALNFSTARGETS := $(TARGET) in
#          Makefile.local.
#       2) or add a new list of targets if the make for the $(TARGET)
#          requires additional parameters.  
#          Please look at $(NFSTARGETS) below.
#          Please add the new list of targets to $(OTHERTARGETS).
# 4) In $(UCSRCDIR), define defconfig.$(TARGET) which will be used
#    to create the $(UCSRCDIR)/.config file.  $(UCSRCDIR)/.config
#    controls which programs in userland get built.  
#    If $(UCSRCDIR)/defconfig.$(TARGET) does not exist, 
#    $(UCSRCDIR)/defconfig is used to create $(UCSRCDIR)/.config.
#    The following steps may be used to create this file:
#    a) Select one of the $(UCSRCDIR)/defconfig*
#       files which most closely matches the userland one wishes to build.
#    b) Copy this file to $(UCSRCDIR)/.config
#    c) In the $(UCSRCDIR) directory, 
#       use one of the following to edit the .config file
#       make config -or- make menuconfig -or- make xconfig
#    d) Copy the newly created .config file to $(UCSCRDIR)
#       with the filename defconfig.$(TARGET)
#    -- Or one can copy the close one to defconfig.$(TARGET), and
#    -- edit with a text editor.
#--------
# Note: $(DEFAULTTARGET) is special.
#  1) $(DEFAULTTARGET) uses $(KERNELDIR)/arch/mipsnommu/defconfig-brecis
#     to create the kernel .config file.
#  2) $(DEFAULTTARGET) assumes the $(DEFAULTGZIPELF)
#  3) $(DEFAULTTARGET) assumes $(UCSRCDIR)/defconfig will be used
#     to create the userland .config file.
#
#-----------------------------------------------------------------------------
# To add a new build/clean step, please do as follows:
# 1) Define a Directory variable for the location to do the step: $(CWD)/xxx
#    Please see UCLIBCDIR or UCSRCDIR as examples
# 2) Place the Directory in the appropriate list: ULIBDIRS, ULANDDIRS, ...
#    or create a new list
# 3) If a new list is created, place the new list in the appropriate place
#    in the Build method lists: NORMALDIRS, SUDIRS, or specifically define the
#    way to build/clean the new Directory; see _build_$(KERNELDIR) and
#    _clean_$(KERNELDIR) for example
# 4) If the Directory was not added to an existing list found in the
#    DIRECTORYORDER variable, add the Directory to the DIRECTORY variable
#    at the appropriate place
#-----------------------------------------------------------------------------

DO_GZIPELF	:= gzip
DEFAULTGZIPELF	:= $(DO_GZIPELF)
LAST_GZIPELF	?= $(DEFAULTGZIPELF)
GZIPELF		?= $(LAST_GZIPELF)

DEFAULTTARGET	:= default
LAST_TYPE_SYSTEM?= unknown
ifeq ($(LAST_TYPE_SYSTEM),unknown)
  TYPE_SYSTEM ?=
else
  TYPE_SYSTEM	?= $(LAST_TYPE_SYSTEM)
endif

export TYPE_SYSTEM GZIPELF

KERNELDIR	:= $(CWD)/linux

BRECISDIR	:= $(CWD)/brecis
GENROMFSDIR	:= $(CWD)/genromfs
GMPDIR		:= $(CWD)/gmp
GUNZIPDIR	:= $(CWD)/brecis/gunzip
GZIPELFDIR	:= $(CWD)/brecis/holes/gzipelf
INITDIR		:= $(CWD)/brecis/init
ROMDISKDIR	:= $(CWD)/romdisk
TFTPDIR		:= /tftpboot/$(USER)
UCLIBCDIR	:= $(CWD)/uclibc
UCSRCDIR	:= $(CWD)/uC-src

# Directory lists

ULIBDIRS	:= $(UCLIBCDIR) $(GMPDIR)

DEMODIRS	:= $(BRECISDIR)/demo $(BRECISDIR)/adventure 
DEMODIRS	+= $(BRECISDIR)/ve-api

ULANDDIRS	:= $(GENROMFSDIR) $(DEMODIRS) $(UCSRCDIR)

APPDIRS		:= $(INITDIR) $(ULANDDIRS)

# Build/clean method lists

NORMALDIRS	:= $(GUNZIPDIR) $(GZIPELFDIR) $(ULIBDIRS) $(APPDIRS)

SUDIRS		:= $(ROMDISKDIR)

# Targets

NFSTARGETS	:= nfs 
NFSTARGETS	+= $(LOCALNFSTARGETS)

# If one defines a new target list, be certain to add it to $(OTHERTARGETS)

OTHERTARGETS	:= $(NFSTARGETS)

# Dynamically determine NORMAL $(NORMALTARGETS)

KERNELCFGBASE	:= $(KERNELDIR)/arch/mipsnommu/defconfig-brecis
KERNELCONFIGS	:= $(wildcard $(KERNELCFGBASE).*)
DEFCONFIGS	:= $(patsubst $(KERNELCFGBASE).%,%,$(KERNELCONFIGS))
NORMALTARGETS	:= $(filter-out $(OTHERTARGETS), $(DEFCONFIGS))

ALLTARGETS	:= $(DEFAULTTARGET) $(NFSTARGETS) $(NORMALTARGETS)

DIRECTORYORDER	:= $(ULIBDIRS)
DIRECTORYORDER	+= $(GZIPELFDIR)
DIRECTORYORDER	+= $(APPDIRS) INSTALLAPPS

# Optional ZSP (VE/PE) firmware directory, process only
# if present.
ZSPDIR		:= $(BRECISDIR)/zsp-ldr
ifneq ($(wildcard $(ZSPDIR)/Makefile),)
	DIRECTORYORDER	+= ZSPDIR
endif

DIRECTORYORDER	+= MODULES $(ROMDISKDIR) 
DIRECTORYORDER	+= $(GUNZIPDIR) $(KERNELDIR) $(TFTPDIR)

DIRECTORIESTODO	?= $(DIRECTORYORDER)

ifneq ($(GZIPELF),$(DO_GZIPELF))
NOGZIPELF	:= .nogzipelf
else
NOGZIPELF	:=
endif

usage USAGE help HELP ::
	@ echo ' '
	@ echo 'These do less as you go down the list.'
	@ echo ' '
	@ echo '"make everything" - does LINUXALL, demo, adventure'
	@ echo '"make linuxall" - to recompile all of userland, romdisk, and kernel.'
	@ echo '"make uclibc" - to recompile all of uclibc (libc.a), UCSRC, then ROMDISK'
	@ echo '"make libc" - make user library libc.a (no make clean), then UCSRC & ROMDISK '
	@ echo '"make ucsrc" - to recompile user programs in uC-src, then ROMDISK.'
	@ echo '"make src" - to make user programs (uC-src) (no make clean), then ROMDISK'
	@ echo '"make linux" - to make kernel modules, linux kernel, re-use userland.'
	@ echo '"make romdisk" - to regenerate romdisk image (then does "make linux").'
	@ echo '"make image.bin" - to make linux kernel, re-use romdisk image.'
	@ echo ' '
	@ echo 'Others of interest:'
	@ echo '"make CLEAN" - to clean up kernel, userland, romdisk, etc.'
	@ echo '"make distclean" - to remove all config info, followed by make CLEAN'
	@ echo '"make demo" - to recompile user program "demo".'
	@ echo '"make adventure" - to recompile user program "adventure".'
	@ echo ' '
	@ echo 'Special kernel and/or userland setups:'
	@ for i in $(sort $(ALLTARGETS)) ; \
		do \
			if [ "$${i}" != "$(DEFAULTTARGET)" ] ; then \
				CFG_FILE=$(KERNELCFGBASE).$${i} ; \
			else \
				CFG_FILE=$(KERNELCFGBASE) ; \
			fi ; \
			HELP_USAGE=`grep CONFIG_HELP_USAGE= $${CFG_FILE} | \
				sed -e 's/^CONFIG_HELP_USAGE="//' \
					-e 's/"$$//' ` ; \
			echo "\"make $${i}\" - $${HELP_USAGE}" ; \
		done
	@ echo ' '
#	@ echo '"make setup" - to setup linux kernel, library symbolic links, etc.'

all ALL doall DOALL :: $(ALLTARGETS)

#---------------
LINUXALL linuxall ::
	$(MAKE) CLEAN
	$(MAKE) SETUP
	$(MAKE) BUILD

#---------------
LINUX linux kernel KERNEL :: 
ifeq ($(wildcard Makefile.type_system),)
	$(MAKE) LINUXALL
else
ifeq ($(wildcard $(KERNELDIR)/.config),)
	$(MAKE) LINUXALL
else
ifneq ($(LAST_GZIPELF),$(GZIPELF))
	$(MAKE) LINUXALL
else
ifneq ($(TYPE_SYSTEM),$(LAST_TYPE_SYSTEM))
	$(MAKE) CLEAN DIRECTORIESTODO="$(ULANDDIRS) $(KERNELDIR)"
	$(MAKE) SETUP
	$(MAKE) SRC
else
	$(MAKE) BUILD \
		DIRECTORIESTODO="`echo $(DIRECTORYORDER) \
			 | sed -e 's$\%.* MODULES % MODULES %'`" 
endif
endif
endif
endif

#---------------
redokernel REDOKERNEL redo REDO ::
	$(MAKE) CLEAN DIRECTORIESTODO="$(KERNELDIR)"
	$(MAKE) SETUP
	$(MAKE) LINUX

#---------------
image.bin IMAGE.BIN ::
	$(MAKE) BUILD \
		DIRECTORIESTODO="`echo $(DIRECTORYORDER) \
			 | sed -e 's$\%.* $(KERNELDIR) % $(KERNELDIR) %'`" 
#---------------
ROMDISK romdisk amit.rom ::
	$(MAKE) BUILD \
		DIRECTORIESTODO="`echo $(DIRECTORYORDER) \
			 | sed -e 's$\%.* $(ROMDISKDIR) % $(ROMDISKDIR) %'`" 

#---------------
UCLIBC uclibc ::
	$(MAKE) CLEAN \
		DIRECTORIESTODO="$(ULIBDIRS) $(APPDIRS)"
	$(MAKE) BUILD \
		DIRECTORIESTODO="`echo $(DIRECTORYORDER) \
			 | sed -e 's$\%.* $(ULIBDIRS) % $(ULIBDIRS) %'`" 

#---------------
libc LIBC ::
	$(MAKE) BUILD \
		DIRECTORIESTODO="`echo $(DIRECTORYORDER) \
			 | sed -e 's$\%.* $(ULIBDIRS) % $(ULIBDIRS) %'`" 

#---------------
UCSRC ucsrc UC-SRC uc-src uC-src :: 
	$(MAKE) CLEAN DIRECTORIESTODO="$(ULANDDIRS)"
	$(MAKE) BUILD \
		DIRECTORIESTODO="`echo $(DIRECTORYORDER) \
			 | sed -e 's$\%.* $(ULANDDIRS) % $(ULANDDIRS) %'`" 

#---------------
src SRC :: 
	$(MAKE) BUILD \
		DIRECTORIESTODO="`echo $(DIRECTORYORDER) \
			 | sed -e 's$\%.* $(ULANDDIRS) % $(ULANDDIRS) %'`" 
	@echo "Built directories in order $(DIRECTORIESTODO)"

#---------------
demo DEMO :: 
	$(MAKE) CLEAN BUILD DIRECTORIESTODO="$(BRECISDIR)/demo"

#---------------
adventure ADVENTURE :: 
	$(MAKE) CLEAN BUILD DIRECTORIESTODO="$(BRECISDIR)/adventure"

#---------------
gmp GMP ::
	$(MAKE) CLEAN BUILD DIRECTORIESTODO="$(GMPDIR)"

#---------------
everything EVERYTHING :: LINUXALL DEMO ADVENTURE

nfsrename NFSRENAME ::
	$(CD) $(ROMDISKDIR) && $(SU) "rm -rf $(NFSDIR)"
	$(CD) $(ROMDISKDIR) && $(SU) "mv nfs $(NFSDIR)"

#--------------- build rules

#---------- build dependencies - must be before build commands

build BUILD :: STARTBUILD $(patsubst %, _build_%, $(DIRECTORIESTODO)) DONEBUILD
	@ls -al /tftpboot/${USER}/image.flash${TYPE_SYSTEM}

STARTBUILD :: SHOWTOOLSVERSION
	@echo "Building with TYPE_SYSTEM=$(TYPE_SYSTEM), GZIPELF=$(GZIPELF)"
	@echo "Building directories in order $(DIRECTORIESTODO)"

DONEBUILD ::
	@echo "Built with TYPE_SYSTEM=$(TYPE_SYSTEM), GZIPELF=$(GZIPELF)"
	@echo "Built directories in order $(DIRECTORIESTODO)"

#---------- build commands

$(DEFAULTTARGET) :: 
	$(MAKE) LINUX TYPE_SYSTEM= GZIPELF=$(DEFAULTGZIPELF)

$(NFSTARGETS) ::
	$(MAKE) LINUX TYPE_SYSTEM=.$@ NFS=NFS

$(NORMALTARGETS) :: 
	$(MAKE) LINUX TYPE_SYSTEM=.$@

setup SETUP :: USERLANDBUILDCONFIG
	echo "LAST_TYPE_SYSTEM ?= $(TYPE_SYSTEM)" > Makefile.type_system
	echo ""LAST_GZIPELF ?= $(GZIPELF) >> Makefile.type_system
	$(CD) $(KERNELDIR) && \
	$(CP) $(KERNELCFGBASE)$(TYPE_SYSTEM) .config && \
	rm -f .config.old && \
	$(MAKE) include/linux/version.h && \
	$(MAKE) oldconfig && \
	$(MAKE) dep && \
	ln -sf $(ROMDISKDIR)/romdisk.img romdisk.img

INSTALL_TOOLS ::
	if test ! -x ../tools/mipsisa32-brecis-uclinux/bin/mips-gcc; then \
		if test ! -e ../tools/mipsisa32-brecis-uclinux.$(TOOLHOSTTYPE).*.tar.gz; then \
			echo "Get the file brecis/tools/mipsisa32-brecis-uclinux.$(TOOLHOSTTYPE).*.tar.gz"; \
			exit 1; \
		fi; \
		($(CD) ../tools; \
		tar xzf mipsisa32-brecis-uclinux.$(TOOLHOSTTYPE).*.tar.gz) || exit 1; \
		echo Tools installed; \
	fi

$(patsubst %, _build_%, $(NORMALDIRS)) ::
	$(CD) $(patsubst _build_%, %, $@) && $(MAKE)

_build_$(ROMDISKDIR) ::
	$(CD) $(patsubst _build_%, %, $@) && $(SU) "$(MAKE) clean romdisk.img"

_build_$(KERNELDIR) ::
	rm -f $(TFTPDIR)/image.{bin,flash}
	$(CD) $(KERNELDIR) && $(MAKE) image.bin && \
		gzip -9 -c image.bin > image.bin.gz && \
		cat $(GUNZIPDIR)/gunzip image.bin.gz > image.flash && \
		$(CP) -f image.flash $(TFTPDIR)/image.flash

ifneq ($(TYPE_SYSTEM),)
_build_$(TFTPDIR) ::
	mv -f $(TFTPDIR)/image.bin{,$(TYPE_SYSTEM)$(NOGZIPELF)}
	ln -s $(TFTPDIR)/image.bin{$(TYPE_SYSTEM)$(NOGZIPELF),}
	mv -f $(TFTPDIR)/image.flash{,$(TYPE_SYSTEM)$(NOGZIPELF)}
	ln -s $(TFTPDIR)/image.flash{$(TYPE_SYSTEM)$(NOGZIPELF),}
else
_build_$(TFTPDIR) ::
	mv -f $(TFTPDIR)/image.bin{,.$(DEFAULTTARGET)$(NOGZIPELF)}
	ln -s $(TFTPDIR)/image.bin{.$(DEFAULTTARGET)$(NOGZIPELF),}
	mv -f $(TFTPDIR)/image.flash{,.$(DEFAULTTARGET)$(NOGZIPELF)}
	ln -s $(TFTPDIR)/image.flash{.$(DEFAULTTARGET)$(NOGZIPELF),}
endif

_build_MODULES ::
	$(CD) $(KERNELDIR) && \
		if [ "`grep CONFIG_MODULES=y .config`" != "" ] ; then \
			$(MAKE) INSTALL_MOD_PATH=$(ROMDISKDIR)/root modules ; \
		else echo "MODULES not built" ; fi

_build_INSTALLAPPS ::
	$(CD) $(UCSRCDIR) && $(MAKE) install

_build_ZSPDIR ::
	$(CD) $(ZSPDIR) && $(MAKE) install

$(patsubst %, _build_%, $(DIRECTORIESTODO)) ::

#--------------- clean rules
distclean::
	$(MAKE) clean
	$(CD) $(UCSRCDIR) && $(MAKE) distclean

clean CLEAN :: INSTALL_TOOLS STARTCLEAN $(patsubst %, _clean_%, $(DIRECTORIESTODO)) DONECLEAN
	rm -f Makefile.type_system

STARTCLEAN :: SHOWTOOLSVERSION USERLANDCLEANCONFIG
	@echo "Cleaning with TYPE_SYSTEM=$(TYPE_SYSTEM), GZIPELF=$(GZIPELF)"
	@echo "Cleaning directories in order $(DIRECTORIESTODO)"

DONECLEAN ::
	@echo "Cleaned with TYPE_SYSTEM=$(TYPE_SYSTEM), GZIPELF=$(GZIPELF)"
	@echo "Cleaned directories in order $(DIRECTORIESTODO)"
	@echo "$(PATH)"

$(patsubst %, _clean_%, $(NORMALDIRS)) ::
	$(CD) $(patsubst _clean_%, %, $@) && \
		$(MAKE) clean TYPE_SYSTEM=$(LAST_TYPE_SYSTEM)

$(patsubst %, _clean_%, $(SUDIRS)) ::
	$(CD) $(patsubst _clean_%, %, $@) && \
		$(SU) "$(MAKE) clean TYPE_SYSTEM=$(LAST_TYPE_SYSTEM)"

_clean_$(KERNELDIR) ::
	$(CD) $(KERNELDIR) && $(MAKE) mrproper TYPE_SYSTEM=$(LAST_TYPE_SYSTEM)
	$(CD) $(KERNELDIR) && rm -f scripts/split-include image.{bin,elf,flash}
	$(CD) $(KERNELDIR) && rm -f image.bin.gz romdisk.img

$(patsubst %, _clean_%, $(DIRECTORIESTODO)) ::

_clean_ZSPDIR ::
	$(CD) $(ZSPDIR) && $(MAKE) clean

#--------------- other rules

SHOWTOOLSVERSION::
	@echo "##### Cross Compiler $(CROSSCOMPILER) version #####"
	$(CROSSCOMPILER) -v
	@echo "##### PATH variable <$(PATH)> #####"

USERLANDBUILDCONFIG ::
ifeq ($(wildcard $(UCSRCDIR)/.config),)
ifneq ($(wildcard $(UCSRCDIR)/defconfig$(TYPE_SYSTEM)),)
	$(CP) $(UCSRCDIR)/{defconfig$(TYPE_SYSTEM),.config}
endif
	$(CD) $(UCSRCDIR) && $(MAKE) oldconfig
endif

USERLANDCLEANCONFIG ::
ifneq ($(TYPE_SYSTEM),$(LAST_TYPE_SYSTEM))
	$(CD) $(UCSRCDIR) && $(MAKE) distclean
endif

