# Make sure the default target is 'all' by listing it first
all:

###################################################
##             ENVIRONMENT SETUP                 ##
###################################################


###########  ENVIRONMENT VARIABLES  ###############
# If you need to modify these, you should set them as environment
# variables instead of changing them here - that way other tools (such
# as mntmem and crashDebug) can use these as well.

# Directory the Tekkotsu framework is stored
TEKKOTSU_ROOT ?= /usr/local/Tekkotsu

# Location where the memstick will be mounted
MEMSTICK_ROOT ?= /mnt/memstick

# Directory where the OPEN-R SDK was installed
# See http://www.tekkotsu.org/SDKInstall.html
# or the OPEN-R website: http://openr.aibo.com/
OPENRSDK_ROOT ?= /usr/local/OPEN_R_SDK

# in case your memory stick drivers use uppercase, you'll need to
# set 'FILENAME_CASE' to 'upper'
FILENAME_CASE ?= lower

# this will delete files from the memory stick that aren't also in
# your build image - except files at the root level of the memstick,
# like memstick.ind
# default: OFF (empty string) - any non-empty string is ON
STRICT_MEMSTICK_IMAGE ?=

# What model are you targeting?  This will look at the
# $TEKKOTSU_ROOT/TARGET_MODEL file to find out.  If the file is not
# found, it is created with the default setting TGT_ERS2xx.  change
# the target model, make will automatically recompile everything for
# you.
# Legal values: TGT_ERS210 TGT_ERS220 TGT_ERS2xx TGT_ERS7
TEKKOTSU_TARGET_MODEL ?= TGT_ERS7

# What OS is this going to be running under?
# Right now, the only choice is Aperios, but in the future we may
# support running under linux systems, either as simulation for
# AIBOs, or direct support for linux-based robots.
TEKKOTSU_TARGET_PLATFORM ?= PLATFORM_APERIOS

# This can be nice if you want to use more to page through errors
# if they occur.  Otherwise, try using cat instead.
TEKKOTSU_LOGVIEW ?= $(if $(findstring Darwin,$(shell uname)),cat,more)

# These control the location that the temporary object files will
# be stored.
TEKKOTSU_BUILDDIR ?= $(TEKKOTSU_ROOT)/build
PROJECT_BUILDDIR ?= build
# or perhaps you would like something like this better:
#TEKKOTSU_BUILDDIR ?= /tmp/tekkotsu_build_$(USER)
#PROJECT_BUILDDIR ?= /tmp/project_build_$(USER)



#############  MAKEFILE VARIABLES  ################
# Change these right here in the Makefile

# Want any other libraries passed to the compiler?  Put them here.
LIBS=-lObjectComm -lOPENR -lInternet -lantMCOOP -lERA201D1

# Would you like some more compiler flags?  We like lots of warnings.
# There are some files with exceptions to these flags - MMCombo*.cc
# need to have optimizations turned off, and several TinyFTPD sources
# have -Weffc++ and -DOPENR_DEBUG turned off.  If you want to modify
# these exceptions, look in the middle of the 'Makefile Machinery'
# section. (grep/search for the file name)
CXXFLAGS= \
	-g -pipe -fno-inline \
  -O2 -frename-registers -fomit-frame-pointer -ffast-math -fno-common \
	-Wall -W -Wshadow -Wlarger-than-8192 -Wpointer-arith -Wcast-qual \
	-Woverloaded-virtual -Weffc++ -Wdeprecated -Wnon-virtual-dtor \
	-I"`pwd`" -I$(TEKKOTSU_ROOT) -I$(TEKKOTSU_ROOT)/Motion/roboop -I$(TEKKOTSU_ROOT)/Shared/newmat \
	-isystem $(TEKKOTSU_ROOT)/Shared/jpeg-6b \
	-isystem $(OPENRSDK_ROOT)/OPEN_R/include/MCOOP \
	-isystem $(OPENRSDK_ROOT)/OPEN_R/include/R4000 \
	-isystem $(OPENRSDK_ROOT)/OPEN_R/include \
	-D$(TEKKOTSU_TARGET_PLATFORM) -DDEBUG -DOPENR_DEBUG -D$(TEKKOTSU_TARGET_MODEL) $(GLOBAL_MAP) \

#These will be the actual build directories used for the current target
TGT_BD:=$(TEKKOTSU_TARGET_PLATFORM)_$(TEKKOTSU_TARGET_MODEL)
TK_BD:=$(TEKKOTSU_BUILDDIR)/$(TGT_BD)
PROJ_BD:=$(PROJECT_BUILDDIR)/$(TGT_BD)
$(shell mkdir -p $(TK_BD))
$(shell mkdir -p $(PROJ_BD))


###################################################
##              SOURCE CODE LIST                 ##
###################################################

# Find all of the source files: (except temp files in build directory)
# You shouldn't need to change anything here unless you want to add
# external libraries
SRCSUFFIX=.cc
PROJ_SRCS:=$(patsubst ./%,%,$(shell find . -name "*$(SRCSUFFIX)" -or -name "$(PROJECT_BUILDDIR)" \! -prune -or -name "templates" \! -prune))

# We're assuming all of the source files we found are to be linked
# into MMCombo.
MAIN_SRCS:=$(PROJ_SRCS)

# We can also link in third-party libraries
USERLIBS:= $(TEKKOTSU_ROOT)/Shared/jpeg-6b/libjpeg.a \
           $(TEKKOTSU_ROOT)/Motion/roboop/libroboop.a \
           $(TEKKOTSU_ROOT)/Shared/newmat/libnewmat.a \


###################################################
##               PROCESS SETUP                   ##
###################################################
# This part will set up the four processes:
# MMCombo is forked into Main and Motion
# TinyFTPD is the FTP server
# SoundPlay handles sound output

# It should be pretty easy to add a new process here if
# you're inclined to do so.

# These all are relative to TEKKOTSU_ROOT
PROCESS_OBJS=MMCombo TinyFTPD SoundPlay
MMCombo_COMP=MMCombo MMCombo/MMComboStub.o Behaviors Events Motion Shared SoundPlay/SoundManager.o SoundPlay/WAV.o Vision Wireless
TinyFTPD_COMP=TinyFTPD TinyFTPD/TinyFTPDStub.o
SoundPlay_COMP=SoundPlay SoundPlay/SoundPlayStub.o Shared/Config.o Shared/ProcessID.o Events/EventRouter.o Events/EventTranslator.o Events/EventBase.o Events/LocomotionEvent.o Events/TextMsgEvent.o Events/VisionObjectEvent.o Shared/LoadSave.o Shared/get_time.o
STUB_FILES:=$(addprefix $(TEKKOTSU_ROOT)/,$(addsuffix /stub.cfg,$(PROCESS_OBJS)))
STUB_CHECK_FILES:=$(addprefix $(TK_BD)/,$(subst /,-,$(STUB_FILES)))

# It's important that the process names and variables are the same
# case as your memory stick reader - memsticks don't store case, and
# some drivers may convert all file names to uppercase, others to
# lower case.  Ours is lower case.  I think this only really matters
# if you want to update a stick instead of recopying it (make update
# vs. make install)

ifeq ($(FILENAME_CASE),lower)

PROCESSES=mmcombo tinyftpd sndplay
mmcombo_OBJS:=$(addprefix $(PROJ_BD)/,$(MAIN_SRCS:$(SRCSUFFIX)=.o)) $(TK_BD)/MMCombo.o
mmcombo_OCF:=$(TEKKOTSU_ROOT)/MMCombo/MMCombo.ocf
tinyftpd_OBJS:=$(TK_BD)/TinyFTPD.o
tinyftpd_OCF:=$(TEKKOTSU_ROOT)/TinyFTPD/TinyFTPD.ocf
sndplay_OBJS:=$(TK_BD)/SoundPlay.o
sndplay_OCF:=$(TEKKOTSU_ROOT)/SoundPlay/SoundPlay.ocf
CONVERTCASE=$(TEKKOTSU_ROOT)/tools/makelowercase

BINSUFFIX=.bin
MSIMGDIR=ms
INSTALLDIR=$(MSIMGDIR)/open-r/mw/objs
MMCOMBOBIN=mmcombo.bin
MAINFORK=mainobj.bin
MOTOFORK=motoobj.bin

else

PROCESSES=MMCOMBO TINYFTPD SNDPLAY
MMCOMBO_OBJS:=$(addprefix $(PROJ_BD)/,$(MAIN_SRCS:$(SRCSUFFIX)=.o)) $(TK_BD)/MMCombo.o
MMCOMBO_OCF:=$(TEKKOTSU_ROOT)/MMCombo/MMCombo.ocf
TINYFTPD_OBJS:=$(TK_BD)/TinyFTPD.o
TINYFTPD_OCF:=$(TEKKOTSU_ROOT)/TinyFTPD/TinyFTPD.ocf
SNDPLAY_OBJS:=$(TK_BD)/SoundPlay.o
SNDPLAY_OCF:=$(TEKKOTSU_ROOT)/SoundPlay/SoundPlay.ocf
CONVERTCASE=$(TEKKOTSU_ROOT)/tools/makeuppercase

BINSUFFIX=.BIN
MSIMGDIR=MS
INSTALLDIR=$(MSIMGDIR)/OPEN-R/MW/OBJS
MMCOMBOBIN=MMCOMBO.BIN
MAINFORK=MAINOBJ.BIN
MOTOFORK=MOTOOBJ.BIN

endif

# creates process build target names: MMCombo -> build/MMCombo.o
BUILDS:=$(foreach proc,$(PROCESS_OBJS),$(TK_BD)/$(proc).o)

# Each process build target depends on the component object files that
# should be linked together.  These live in the $TK_BD directory and
# should be fairly static unless you're editing the framework itself.
# The automatic way of creating these dependancies automatically is
# too messy, just add a rule for each process by hand: (skip lines!)
$(word 1,$(BUILDS)): $(foreach comp,$($(word 1,$(PROCESS_OBJS))_COMP), $(if $(suffix $(comp)),$(TK_BD)/$(comp),$(patsubst $(TEKKOTSU_ROOT)%.cc,$(TK_BD)%.o,$(shell find $(TEKKOTSU_ROOT)/$(comp) -name "*.cc") )))

$(word 2,$(BUILDS)): $(foreach comp,$($(word 2,$(PROCESS_OBJS))_COMP), $(if $(suffix $(comp)),$(TK_BD)/$(comp),$(patsubst $(TEKKOTSU_ROOT)%.cc,$(TK_BD)%.o,$(shell find $(TEKKOTSU_ROOT)/$(comp) -name "*.cc") )))

$(word 3,$(BUILDS)): $(foreach comp,$($(word 3,$(PROCESS_OBJS))_COMP), $(if $(suffix $(comp)),$(TK_BD)/$(comp),$(patsubst $(TEKKOTSU_ROOT)%.cc,$(TK_BD)%.o,$(shell find $(TEKKOTSU_ROOT)/$(comp) -name "*.cc") )))

# Each of the executable binaries depends on the corresponding
# framework build target(s) plus any project files which were
# specified above. (by default, all project files are linked into
# MMCombo) These live in the project directory's build dir and will
# need to be recompiled any time you change source that's part of that
# process (but not otherwise ;)
# Again, the automatic way of creating these dependancies
# automatically is too messy, just add a rule for each process by
# hand: (skip lines!)
PROC_BINS:=$(addprefix $(PROJ_BD)/,$(addsuffix $(BINSUFFIX),$(PROCESSES)))

$(word 1,$(PROC_BINS)): $($(word 1,$(PROCESSES))_OBJS) $($(word 1,$(PROCESSES))_OCF)

$(word 2,$(PROC_BINS)): $($(word 2,$(PROCESSES))_OBJS) $($(word 2,$(PROCESSES))_OCF)

$(word 3,$(PROC_BINS)): $($(word 3,$(PROCESSES))_OBJS) $($(word 3,$(PROCESSES))_OCF)


###################################################
##             MAKEFILE MACHINERY                ##
###################################################
# Hopefully, you shouldn't have to change anything down here,
# except one or two little things ;)

# Location of Aperios (the Aibo's OS) binary executables
SYSTEM_BINARIES:=$(OPENRSDK_ROOT)/OPEN_R/MS_$(if $(findstring $(TEKKOTSU_TARGET_MODEL),TGT_ERS7),ERS7,ERS200)/WCONSOLE/nomemprot

# List of all components for all processes, sorted to
# remove duplicates.
COMPONENTS:=$(sort $(foreach proc,$(PROCESS_OBJS),$($(proc)_COMP)))

# list of all source files of all components, sorted to remove
# duplicates.  This gives us all the source files which we care about,
# all in one place.
TK_SRCS:=$(sort $(foreach comp,$(COMPONENTS), $(if $(suffix $(filter-out %.a,$(comp))),$(TEKKOTSU_ROOT)/$(basename $(comp)).cc,$(shell find $(TEKKOTSU_ROOT)/$(comp) -name "*.cc") )))
TK_DEPENDS:=$(subst $(TEKKOTSU_ROOT),$(TK_BD),$(TK_SRCS:$(SRCSUFFIX)=.d))
PROJ_DEPENDS:=$(addprefix $(PROJ_BD)/,$(PROJ_SRCS:$(SRCSUFFIX)=.d))
DEPENDS:=$(sort $(PROJ_DEPENDS) $(TK_DEPENDS))

# These are the file names of the final executable binaries, in the
# memstick image directory
INSTALL_BINS:=$(addprefix $(INSTALLDIR)/,$(MAINFORK) $(MOTOFORK) $(addsuffix $(BINSUFFIX),$(filter-out mmcombo MMCOMBO,$(PROCESSES))))

CXX=$(OPENRSDK_ROOT)/bin/mipsel-linux-g++
LD=$(OPENRSDK_ROOT)/bin/mipsel-linux-ld
STRIP=$(OPENRSDK_ROOT)/bin/mipsel-linux-strip
MKBIN=$(OPENRSDK_ROOT)/OPEN_R/bin/mkbin
STUBGEN=$(OPENRSDK_ROOT)/OPEN_R/bin/stubgen2
COLORFILT=$(TEKKOTSU_ROOT)/tools/colorfilt
FILTERSYSWARN=$(TEKKOTSU_ROOT)/tools/filtersyswarn/filtersyswarn $(OPENRSDK_ROOT)
MKBINFLAGS=-p $(OPENRSDK_ROOT)

.PHONY: all compile install clean cleanDeps cleanProj cleanTemps Tekkotsu reportTarget newstick update docs dox doc cleandoc updateTools checkInstalledTimestamp

all: compile
	@echo "Build successful."
	@echo "Type: '$(MAKE) install' to copy all files to the memory stick"
	@echo "  or: '$(MAKE) update' to copy only changed files"
	@echo "  or: '$(TEKKOTSU_ROOT)/tools/{ftpinstall,ftpupdate} <ipaddr> ms' might also be useful"

reportTarget:
	@echo " ** Targeting $(TEKKOTSU_TARGET_MODEL) for build ** ";

updateTools:
	cd $(TEKKOTSU_ROOT)/tools && $(MAKE);

updateLibs:
	@echo "Updating libraries..."
	@$(foreach x,$(USERLIBS),make -C $(dir $(x)) $(notdir $(x)) && ) true

#the touch at the end is because memsticks seem to round time to even seconds, which screws up updates.  Grr.
compile: reportTarget cleanTemps updateTools updateLibs checkInstalledTimestamp $(PROJ_BD)/installed.timestamp
	@image="$(PROJ_BD)/$(notdir $(MEMSTICK_ROOT))" ; \
	if [ "$(TEKKOTSU_ROOT)/TARGET_MODEL" -nt "$$image" ] ; then \
		echo "Deleting old cached OPEN-R binaries"; \
		rm -rf "$$image" ; \
	fi; \
	if [ \! -d "$$image" ] ; then \
		if [ \! -d "$(SYSTEM_BINARIES)" ] ; then \
v			echo "Could not find OPEN-R system binaries" ; \
			exit 1 ; \
		fi ; \
		echo "Copying system files..." ; \
		cp -r "$(SYSTEM_BINARIES)" "$$image" ; \
		chmod -R u+w "$$image" ; \
		cur=`pwd`; \
		cd "$$image"; \
		$(CONVERTCASE) -r *; \
		cd "$$cur"; \
		rm -f "$$image/open-r/mw/conf/connect.cfg" "$$image/open-r/mw/conf/object.cfg" "$$image/open-r/system/conf/wlandflt.txt" ; \
		curt=`date +%Y%m%d%H%M`; \
		find "$$image" -exec touch -ft $$curt \{\} \; ; \
	fi;

checkInstalledTimestamp:
	@for x in $(INSTALL_BINS) ; do \
		if [ "$$x" -nt "$(PROJ_BD)/installed.timestamp" ] ; then \
			printf "Target switch detected, cleaning binaries..." ; \
			rm -f $(INSTALL_BINS) ; \
			printf "done.\n" ; \
		fi; \
	done;

ifeq ($(findstring clean,$(MAKECMDGOALS)),)
ifeq ($(findstring docs,$(MAKECMDGOALS)),)
-include $(DEPENDS)
endif
endif

$(STUB_CHECK_FILES):
	@thedir=`echo $@ | sed 's/.*-\(.*\)-.*/\1/g'`; \
	cd $(TEKKOTSU_ROOT)/$$thedir ; \
	$(STUBGEN) stub.cfg ; \
	mkdir -p $(dir $@) ; \
	touch $@ ;

%.d : $(STUB_CHECK_FILES)
	@mkdir -p $(dir $@)
	@src=$(patsubst %.d,%.cc,$(if $(findstring $(TK_BD),$@),$(patsubst $(TK_BD)%,$(TEKKOTSU_ROOT)%,$@),$(patsubst $(PROJ_BD)/%,%,$@))); \
	echo "$@..." | sed 's@.*$(TGT_BD)/@Generating @'; \
	$(CXX) $(CXXFLAGS) -MP -MG -MT "$@" -MT "$(@:.d=.o)" -MM "$$src" > $@

%/def.h %/entry.h: %/stub.cfg
	@echo "Doing $@"
	cd $* && $(STUBGEN) stub.cfg
	@echo "Done with $@"

#%/entry.h: %/stub.cfg
#	cd $(TEKKOTSU_ROOT)/$* && $(STUBGEN) stub.cfg

%Stub.h %Stub.cc: 
	@echo "Doing $@"
	cd $(dir $@) && $(STUBGEN) stub.cfg
	@echo "Done with $@"

#%Stub.cc:
#	cd $(dir $@) && $(STUBGEN) stub.cfg
#	@echo "Done with $@"

%.h :
	@if [ "$(notdir $@)" = "def.h" -o "$(notdir $@)" = "entry.h" ] ; then \
		echo "WARNING: You shouldn't be seeing this message.  Report that you did." ; \
		echo "         Try a clean recompile." ; \
	fi;
	@echo "ERROR: Seems to be a missing header file '$@'...";
	@echo "       Someone probably forgot to check a file into CVS.";
	@echo "       I'll try to find where it's being included from:";
	@find . -name "*.h" -exec grep -H "$(notdir $@)" \{\} \; ;
	@find . -name "*.cc" -exec grep -H "$(notdir $@)" \{\} \; ;
	@find $(TEKKOTSU_ROOT) -name "*.h" -exec grep -H "$(notdir $@)" \{\} \; ;
	@find $(TEKKOTSU_ROOT) -name "*.cc" -exec grep -H "$(notdir $@)" \{\} \; ;
	@echo "";
	@echo "You might need to rebuild the dependancy files ('make cleanDeps') to get rid of this error.";
	@exit 1

#The "fork" we do of MMCombo into MainObj and MotoObj crashes with optimization... not a big loss, just turn it off for these files
$(TK_BD)/MMCombo/MMCombo.o $(TK_BD)/MMCombo/MMComboStub.o: %.o:
	@mkdir -p $(dir $@)
	@src=$(patsubst %.o,%$(SRCSUFFIX),$(if $(findstring $(TK_BD),$@),$(patsubst $(TK_BD)%,$(TEKKOTSU_ROOT)%,$@),$(patsubst $(PROJ_BD)/%,%,$@))); \
	if [ -r dist_hosts.txt ] ; then \
		echo "Adding $@ to job list"; \
		echo "$(CXX) $(filter-out -O2,$(CXXFLAGS)) -o $@ -c $$src > $*.log 2>&1; retval=\$$?; cat $*.log | $(FILTERSYSWARN) | $(COLORFILT); test \$$retval -eq 0;" >> $(PROJ_BD)/joblist.txt ; \
		touch $@; \
		echo "$@" >> $(PROJ_BD)/touched.txt ; \
	else \
		echo "Compiling $$src... (no -O2)"; \
		$(CXX) $(filter-out -O2,$(CXXFLAGS)) -o $@ -c $$src > $*.log 2>&1; \
		retval=$$?; \
		cat $*.log | $(FILTERSYSWARN) | $(COLORFILT) | $(TEKKOTSU_LOGVIEW); \
		test $$retval -eq 0; \
	fi;

$(TK_BD)/TinyFTPD/TinyFTPD.o $(TK_BD)/TinyFTPD/FtpMethod.o $(TK_BD)/TinyFTPD/FtpRequest.o $(TK_BD)/TinyFTPD/FtpDTP.o $(TK_BD)/TinyFTPD/FtpPI.o: %.o:
	@mkdir -p $(dir $@)
	@src=$(patsubst %.o,%$(SRCSUFFIX),$(if $(findstring $(TK_BD),$@),$(patsubst $(TK_BD)%,$(TEKKOTSU_ROOT)%,$@),$(patsubst $(PROJ_BD)/%,%,$@))); \
	if [ -r dist_hosts.txt ] ; then \
		echo "Adding $@ to job list"; \
		echo "$(CXX) $(filter-out -DOPENR_DEBUG,$(filter-out -Weffc++,$(CXXFLAGS))) -o $@ -c $$src > $*.log 2>&1; retval=\$$?; cat $*.log | $(FILTERSYSWARN) | $(COLORFILT); test \$$retval -eq 0;" >> $(PROJ_BD)/joblist.txt ; \
		touch $@; \
		echo "$@" >> $(PROJ_BD)/touched.txt ; \
	else \
		echo "Compiling $$src... (reduced warnings, no OPENR_DEBUG)"; \
		$(CXX) $(filter-out -DOPENR_DEBUG,$(filter-out -Weffc++,$(CXXFLAGS))) -o $@ -c $$src > $*.log 2>&1; \
		retval=$$?; \
		cat $*.log | $(FILTERSYSWARN) | $(COLORFILT) | $(TEKKOTSU_LOGVIEW); \
		test $$retval -eq 0; \
	fi;

$(TK_BD)/SoundPlay/WAV.o: %.o: $(FILTERSYSWARN)
	@mkdir -p $(dir $@)
	@src=$(patsubst %.o,%$(SRCSUFFIX),$(if $(findstring $(TK_BD),$@),$(patsubst $(TK_BD)%,$(TEKKOTSU_ROOT)%,$@),$(patsubst $(PROJ_BD)/%,%,$@))); \
	if [ -r dist_hosts.txt ] ; then \
		echo "Adding $@ to job list"; \
		echo "$(CXX) $(filter-out -Weffc++,$(CXXFLAGS)) -o $@ -c $$src > $*.log 2>&1; retval=\$$?; cat $*.log | $(FILTERSYSWARN) | $(COLORFILT); test \$$retval -eq 0;" >> $(PROJ_BD)/joblist.txt ; \
		touch $@; \
		echo "$@" >> $(PROJ_BD)/touched.txt ; \
	else \
		echo "Compiling $$src... (reduced warnings)"; \
		$(CXX) $(filter-out -Weffc++,$(CXXFLAGS)) -o $@ -c $$src > $*.log 2>&1; \
		retval=$$?; \
		cat $*.log | $(FILTERSYSWARN) | $(COLORFILT) | $(TEKKOTSU_LOGVIEW); \
		test $$retval -eq 0; \
	fi;

%.o:
	@mkdir -p $(dir $@)
	@src=$(patsubst %.o,%$(SRCSUFFIX),$(if $(findstring $(TK_BD),$@),$(patsubst $(TK_BD)%,$(TEKKOTSU_ROOT)%,$@),$(patsubst $(PROJ_BD)/%,%,$@))); \
	if [ -r dist_hosts.txt ] ; then \
		echo "Adding $@ to job list"; \
		echo "$(CXX) $(CXXFLAGS) -o $@ -c $$src > $*.log 2>&1; retval=\$$?; cat $*.log | $(FILTERSYSWARN) | $(COLORFILT); test \$$retval -eq 0;" >> $(PROJ_BD)/joblist.txt ; \
		touch $@; \
		echo "$@" >> $(PROJ_BD)/touched.txt ; \
	else \
		echo "Compiling $$src..."; \
		$(CXX) $(CXXFLAGS) -o $@ -c $$src > $*.log 2>&1; \
		retval=$$?; \
		cat $*.log | $(FILTERSYSWARN) | $(COLORFILT) | $(TEKKOTSU_LOGVIEW); \
		test $$retval -eq 0; \
	fi;

#This is for external libraries which we are including, such as libjpeg
%.a:
	export OPENRSDK_ROOT=$(OPENRSDK_ROOT) ;\
	export TEKKOTSU_ROOT=$(TEKKOTSU_ROOT) ;\
	$(MAKE) -C $(dir $@) $(notdir $@)

#BUILDS:   (framework object files, one per process - resides in framework)
$(BUILDS):
	@if [ -r dist_hosts.txt -a -r $(PROJ_BD)/joblist.txt ] ; then \
		echo "Distributing compiles..."; \
		../tools/pm.pl dist_hosts.txt $(PROJ_BD)/joblist.txt ; \
	fi
	@rm -f $(PROJ_BD)/joblist.txt; #this is so we don't rebuild multiple times
	@echo "Linking component object files..."
	@if [ $(words $(foreach comp,$(addprefix $(TK_BD)/,$($(basename $(notdir $@))_COMP)),$(if $(suffix $(comp)),$(comp),$(patsubst %.cc,%.o,$(shell find $(comp) -name "*.o"))))) -gt 20 ] ; then \
		echo "$@ <- [...]"; \
	else \
		echo "$@ <- $(sort $(foreach comp,$(addprefix $(TK_BD)/,$(filter-out %.a,$($(basename $(notdir $@))_COMP))), $(if $(suffix $(comp)),$(comp),$(shell find $(comp) -name "*.o") )))" | sed 's@$(TK_BD)/@@g'; \
	fi;
	@$(LD) -i     $(sort $(foreach comp,$(addprefix $(TK_BD)/,$(filter-out %.a,$($(basename $(notdir $@))_COMP))), $(if $(suffix $(comp)),$(comp),$(shell find $(comp) -name "*.o") ))) -o $@ ; \
		if [ $$? -ne 0 ] ; then exit 1; fi;

#PROC_BINS:    (executable binaries, uncompressed)
# we have to do a couple extra steps to cd into the builddir because
# mkbin doesn't support -o target in a different directory... drops an
# intermediate file in . and then complains (as of 1.1.3 anyway)
$(PROJ_BD)/%$(BINSUFFIX): $(USERLIBS)
	@if [ -r dist_hosts.txt -a -r $(PROJ_BD)/joblist.txt ] ; then \
		echo "Distributing compiles..."; \
		../tools/pm.pl dist_hosts.txt $(PROJ_BD)/joblist.txt ; \
	fi
	@rm -f $(PROJ_BD)/joblist.txt; #this is so we don't rebuild multiple times
	@echo "Creating executable binary..."
	@echo "$@ <- $($(basename $(notdir $@))_OBJS), $($(basename $(notdir $@))_OCF), $(LIBS) $(USERLIBS)" | sed 's@ $(PROJ_BD)/@ @g';
	@#we'll need to do some filtering on USERLIBS below because now we'll be in builddir below
	@$(LD) -i $($(basename $(notdir $@))_OBJS) -o $(PROJ_BD)/tmp.o
	@cp $($(basename $(notdir $@))_OCF) $(PROJ_BD)/tmp.ocf
	@pt=`pwd`;\
	cd $(PROJ_BD) ; \
	$(MKBIN) $(MKBINFLAGS) -o $(notdir $@) tmp.o -m tmp.ocf $(LIBS) $(filter /%,$(USERLIBS)) $(addsuffix \",$(addprefix \"$$pt/,$(filter-out /%,$(USERLIBS)))) ; \
	if [ $$? -gt 0 ] ; then \
		echo "Build failed."; \
		exit 1; \
	fi; \
	$(STRIP) $(notdir $@) ; \
	rm tmp.o tmp.ocf;


#INSTALL_BINS:     (compressed executables, in proper location in image directory)
$(INSTALLDIR)/%$(BINSUFFIX): $(PROJ_BD)/%$(BINSUFFIX)
	@if [ \! -d "$(INSTALLDIR)" ] ; then \
		echo "I can't find $(INSTALLDIR).  Hmmm."; \
		exit 1; \
	fi;
	@echo "Compressing $< -> $@"
	@gzip -c $< > $@;

$(INSTALLDIR)/$(MAINFORK): $(PROJ_BD)/$(MMCOMBOBIN) $(TEKKOTSU_ROOT)/tools/binstrswap/binstrswap
	@if [ \! -d "$(INSTALLDIR)" ] ; then \
		echo "I can't find $(INSTALLDIR).  Hmmm."; \
		exit 1; \
	fi;
	@echo "Compressing $< ~> $@"
	@$(TEKKOTSU_ROOT)/tools/binstrswap/binstrswap $< MMCombo MainObj | gzip -c > $@
#	@sed 's/MMCombo/MainObj/g;s/mmcombo/mainobj/g' $< | gzip -c > $@

$(INSTALLDIR)/$(MOTOFORK): $(PROJ_BD)/$(MMCOMBOBIN) $(TEKKOTSU_ROOT)/tools/binstrswap/binstrswap
	@if [ \! -d "$(INSTALLDIR)" ] ; then \
		echo "I can't find $(INSTALLDIR).  Hmmm."; \
		exit 1; \
	fi;
	@echo "Compressing $< ~> $@"
	@$(TEKKOTSU_ROOT)/tools/binstrswap/binstrswap $< MMCombo MotoObj | gzip -c > $@
#	@sed 's/MMCombo/MotoObj/g;s/mmcombo/motoobj/g' $< | gzip -c > $@

$(PROJ_BD)/installed.timestamp: $(INSTALL_BINS)
	@touch $@

install: compile
	@echo "Installing files to memory stick at $(MEMSTICK_ROOT)"
	@$(TEKKOTSU_ROOT)/tools/cpymem --all --img $(MSIMGDIR) --tgt $(MEMSTICK_ROOT) --tools $(TEKKOTSU_ROOT)/tools

update: compile $(TEKKOTSU_ROOT)/tools/evenmodtime/evenmodtime
	@echo "Syncing $(MSIMGDIR) and $(MEMSTICK_ROOT)"
	@$(TEKKOTSU_ROOT)/tools/evenmodtime/evenmodtime `find $(MSIMGDIR)` $(PROJ_BD)/installed.timestamp
	@$(TEKKOTSU_ROOT)/tools/mntmem $(MEMSTICK_ROOT)
	@if [ $(STRICT_MEMSTICK_IMAGE) ] ; then \
		echo "Strict image copy is on." ; \
		rsync -rLtWCv --delete $(MSIMGDIR)/* $(PROJ_BD)/$(notdir $(MEMSTICK_ROOT))/* $(MEMSTICK_ROOT) ; \
	else \
		rsync -rLtWCv $(MSIMGDIR)/* $(PROJ_BD)/$(notdir $(MEMSTICK_ROOT))/* $(MEMSTICK_ROOT) ; \
	fi;
	@$(TEKKOTSU_ROOT)/tools/umntmem $(MEMSTICK_ROOT)

newstick:
	$(TEKKOTSU_ROOT)/tools/mntmem $(MEMSTICK_ROOT)
	rm -rf $(MEMSTICK_ROOT)/*
	cp -r $(SYSTEM_BINARIES)/* $(MEMSTICK_ROOT)
	$(TEKKOTSU_ROOT)/tools/umntmem $(MEMSTICK_ROOT)

$(FILTERSYSWARN):
	(cd $(TEKKOTSU_ROOT)/tools && $(MAKE));

cleanTemps:
	rm -f $(PROJ_BD)/joblist.txt $(PROJ_BD)/touched.txt

clean: cleanProj
	@printf "Cleaning all ~ files corresponding to .cc files..."
	@rm -f $(addsuffix ~,$(TK_SRCS)) $(TK_SRCS:$(SRCSUFFIX)=.h~)
	@printf "done.\n"
	rm -f $(foreach proc,$(PROCESS_OBJS),$(TEKKOTSU_ROOT)/$(proc)/$(proc)Stub.cc $(TEKKOTSU_ROOT)/$(proc)/$(proc)Stub.h $(TEKKOTSU_ROOT)/$(proc)/def.h $(TEKKOTSU_ROOT)/$(proc)/entry.h)
	rm -rf $(TEKKOTSU_BUILDDIR)
	cd $(TEKKOTSU_ROOT)/tools ; $(MAKE) clean
	$(foreach lib,$(USERLIBS),$(MAKE) -C $(dir $(lib)) clean ;)

cleanDeps:
	@printf "Cleaning all .d files corresponding to .cc files..."
	@rm -f $(DEPENDS)
	@printf "done.\n"

cleanProj:
	@printf "Cleaning all ~ files corresponding to project .cc files..."
	@rm -f $(addsuffix ~,$(PROJ_SRCS)) $(PROJ_SRCS:$(SRCSUFFIX)=.h~)
	@printf "done.\n"
	rm -rf $(PROJECT_BUILDDIR)
	rm -f $(INSTALL_BINS)

dox doc docs:
	cd $(TEKKOTSU_ROOT) && $(MAKE) $@

cleandoc:
	docs/builddocs --clean



