#############################################################################
#	Copyright (c) 2009, Bendor Research Pty. Ltd. All rights reserved.		#
#	This software is released under the GNU General Public License, version	#
#	3, with the exemptions that 1) the header files installed by this 	 	#
#	package can be included in closed-source code and 2) the libraries		#
#	built by this package can be statically linked into a closed-source 	#
#	binary. See the file LICENSE for the details.							#
#	This software is provided "AS IS", without any warranty or guarantee.	#
#	By using this software you acknowledge that neither Bendor Research nor	#
#	any of its personnel or affiliates can be held liable for any damages,	#
#	including, but not limited to, loss of business, loss of money, loss of #
#	life, loss of reputation, arising out of this software being faulty or	#
#	not performing as advertised, even if Bendor Research was aware of such	#
#	faults in the software. You use this software at your own risk, any and #
#	all liabilities that arise out of your using this software are strictly	#
#	yours.																	#
#############################################################################

ifeq "$(SUBMAKE)" ""

#############################################################################
#				This is executed only in the top level make					#
#############################################################################

#	Get the configuration
#	~~~~~~~~~~~~~~~~~~~~~

ifeq "$(ARMLIB_CONFIG)" ""
ARMLIB_CONFIG = Makefile.conf
endif

include $(ARMLIB_CONFIG)

#	Compiler flags
#	~~~~~~~~~~~~~~

CFLAGS	= $(VERSFLG) -g -std=gnu99 -pipe -MMD -c -ffreestanding \
		  -I $(PWD)/include -I $(PWD)/internals -mcpu=$(CPU) -fno-common \
		  -fno-delete-null-pointer-checks -fno-trapping-math \
		  -fno-math-errno -W -Werror -Wall -Wundef -Wmissing-declarations \
		  -Wwrite-strings -Wmissing-field-initializers \
		  -Wshadow

#	Optimisation dependent C flags
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

COSIZE	= -Os -fno-unroll-loops
COSPEED	= -O2

#	Assembler flags
#	~~~~~~~~~~~~~~~

AFLAGS	= $(VERSFLG) -g -pipe -MMD -c -mcpu=$(CPU) \
		  -I $(PWD)/include -I $(PWD)/internals \
		  -Wa,--fatal-warnings -W -Werror -Wall -Wundef

#	Linker flags
#	~~~~~~~~~~~~

LFLAGS	= $(VERSFLG) -g -nostartfiles -nodefaultlibs -nostdlib \
		  -static -static-libgcc -mcpu=$(CPU) \
		  -Werror -Wl,--warn-common,--fatal-warnings

#	Macros generated from the config parameters
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

ifeq "$(USE_GCC)" ""
GCC_VER := $(shell $(CC) --version | head -1 | awk '{print $$3}')
VERSFLG :=
else
GCC_VER := $(USE_GCC)
VERSFLG := -V $(GCC_VER)
endif

ifeq "$(strip $(OBJDIR))" ""
OBJDIR	:= $(PWD)/objs
endif

#	Other macros
#	~~~~~~~~~~~~

PWD		:= $(shell pwd)
SUBMAKE	:= yes
TODAY	:= $(shell date "+%F")
RELSTEM	:= armlib
RELNAME	:= $(RELSTEM).$(TODAY)

#	Exports to submakes
#	~~~~~~~~~~~~~~~~~~~

export	CC AS LD AR OC OD SUBMAKE OBJDIR VERSIONS
export	PWD CFLAGS AFLAGS LFLAGS GCC_VER VERSFLG
export	COSIZE COSPEED

#	Top level targets
#	~~~~~~~~~~~~~~~~~

all:	build_library
	@true

install:	all
	@echo "Installing   libraries"
	@for f in $(LIBC_NAME) $(EXEC_NAME) $(LIBM_NAME) $(COOP_NAME) \
			  $(CRYP_NAME) $(GCCS_NAME) $(FIXP_NAME) ; do \
	  for x in $(VERSIONS) ; do \
	  	if ! install -D $(OBJDIR)/lib/lib$$f-$$x.a \
			 $(INSTALL)/lib/lib$$f-$$x.a 2> install.err ; \
		  then exit 1 ; \
	    fi ; \
	  done \
	 done
	@echo "Installing   headers"
	@for f in `find include -name chips -prune -o -type d -print` ; do \
		install -D -d $(INSTALL)/$$f ; done
	@for f in `find include -name chips -prune -o -type f -print` ; do \
	  (	cat $$f | \
		grep -v "^[[:space:]]*$$" | \
		grep -v "^[[:space:]]*//" | \
		grep -v "^[[:space:]]*/\*" | \
		grep -v "^[[:space:]]*\*$$" | \
		grep -v "^[[:space:]]*\*/" | \
		grep -v "^[[:space:]]*\*[[:space:]]\+" | \
		sed -e 's\//.*\\' > $(INSTALL)/$$f \
	  ) 2> install.err ; \
	 done
	@cp -r include/chips $(INSTALL)/include 2> install.err
	@echo "Installing   utilities"
	@install -d $(INSTALL)/bin 2> install.err
	@cp -r $(OBJDIR)/bin/* $(INSTALL)/bin 2> install.err
	@echo "Installing   documentation"
	@install -d $(INSTALL)/docs 2> install.err
	@cp -r docs/html $(INSTALL)/docs 2> install.err
	@rm install.err

clean:
	@echo "Cleaning up " $(OBJDIR)
	@rm -rf $(OBJDIR)/* *.err

veryclean:
	@echo "Cleaning up " $(OBJDIR)
	@rm -rf $(OBJDIR)/* *.err
	@echo "Cleaning up " $(PWD)/docs
	@rm -rf docs/html
	@echo "Cleaning up " backup files
	@find . -name "*~" -exec rm {} \;

docs:
	@echo "Generating   documentation"
	@rm -rf docs/html
	@doxygen docs/doxygen/doxyfile > /dev/null 2> docs.err
	@if grep '\([Ww]arning\|[Eerror]\)' docs.err > /dev/null; then false; fi
	@rm docs.err

release: all
	@echo "Creating    " /tmp/$(RELNAME)
	@rm -rf /tmp/$(RELNAME)
	@mkdir /tmp/$(RELNAME)
	@cp -a * /tmp/$(RELNAME)
	@echo "Test build  " /tmp/$(RELNAME)
	@sh -c "cd /tmp/$(RELNAME) ; unset SUBMAKE ; make -s -r clean" > /dev/null
	@sh -c "cd /tmp/$(RELNAME) ; unset SUBMAKE ; make -s -r all" > /dev/null
	@sh -c "cd /tmp/$(RELNAME) ; unset SUBMAKE ; make -s -r veryclean"
	@sh -c "cd /tmp/$(RELNAME) ; unset SUBMAKE ; make -s -r docs"
	@echo "Archiving   " /tmp/$(RELNAME).tgz
	@sh -c "cd /tmp ; \
			tar cfz $(RELNAME).tgz --exclude $(RELNAME)/temp \
					--exclude $(RELNAME)/junk $(RELNAME)"
	@echo "Removing    " /tmp/$(RELNAME)
	@rm -rf /tmp/$(RELNAME)

#	Main make subordinate targets
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

build_library:
	@if [[ ! -d $(OBJDIR) ]] ; then \
		echo "Creating    " $(OBJDIR) && \
		mkdir $(OBJDIR) && \
		chmod 777 $(OBJDIR) ; \
	 fi
	@$(foreach lt,ais ans tis tns aif anf tif tnf na lib bin tool, \
		if [[ ! -d $(OBJDIR)/$(lt) ]] ; then \
	   		mkdir $(OBJDIR)/$(lt) ; \
		fi ; \
	  )
	@make -s -C tool -r -R
	@make -s -C gccs TARGET=$(PWD)/$(GCCS_NAME) $(PWD)/$(GCCS_NAME)
	@make -s -C libc TARGET=$(PWD)/$(LIBC_NAME) $(PWD)/$(LIBC_NAME)
	@make -s -C libm TARGET=$(PWD)/$(LIBM_NAME) $(PWD)/$(LIBM_NAME)
	@make -s -C fixp TARGET=$(PWD)/$(FIXP_NAME) $(PWD)/$(FIXP_NAME)
	@make -s -C cryp TARGET=$(PWD)/$(CRYP_NAME) $(PWD)/$(CRYP_NAME)
	@make -s -C exec TARGET=$(PWD)/$(EXEC_NAME) $(PWD)/$(EXEC_NAME)
	@make -s -C coop TARGET=$(PWD)/$(COOP_NAME) $(PWD)/$(COOP_NAME)

#	Make the toplevel targets immune to files
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.PHONY:	build_library docs clean veryclean

else

#############################################################################
#				This is executed only in the submakes						#
#############################################################################

#	Submake derived macros
#	~~~~~~~~~~~~~~~~~~~~~~

HERE	= $(patsubst $(PWD)/%,%,$(shell pwd))
OBJECTS	= $(foreach lt,$(VERSIONS), \
			   $(patsubst %,$(OBJDIR)/$(lt)/%.o,$(basename $(FILES))))

#	Library section prefix
#	~~~~~~~~~~~~~~~~~~~~~~

ifneq "$(SECTPFX)" ""
ifeq "$(SECTPFX)" "YES"
RENAME = .$(notdir $(basename $(TARGET)))
else
RENAME = $(SECTPFX)
endif
else
RENAME =
endif

#	Define a rule to build a library
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

define	build-lib
$(TARGET): $(OBJDIR)/lib/lib$(notdir $(TARGET))-$(1).a
$(OBJDIR)/lib/lib$(notdir $(TARGET))-$(1).a: \
$(foreach fn,$(basename $(FILES)),$(OBJDIR)/$(1)/$(fn).o)
	@echo "Building    " $$(patsubst $$(OBJDIR)/lib/%,%,$$@)
	@rm -f $$@
	@$(AR) -q $$@ $$^ 2> $$(PWD)/$$(basename $$(notdir $$@)).err
	@$(OC) `for x in \`$(OD) -h $$@ | grep '^ \+[0-9]' | awk '{print $$$$2}' \
			| sort -u | grep -v "\(debug\|attribute\|comment\)"\` ; \
			do echo --rename-section $$$$x=$$(RENAME)$$$$x ; done` $$@ $$@ \
			2> $$(PWD)/$$(basename $$(notdir $$@)).err
	@$(AR) -s $$@ 2> $$(PWD)/$$(basename $$(notdir $$@)).err
	@rm $$(PWD)/$$(basename $$(notdir $$@)).err
endef

#	Create all the rules to build the libraries
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

$(foreach lt,$(VERSIONS),$(eval $(call build-lib,$(lt))))

#	How to create all 8 versions from the source
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

test = $(if $(findstring $(1),$(VERSIONS)),trans,noop)

define	noop
endef

define	trans
$($(1)) $($(2)) $(5) -m$(3)thumb -m$(4)thumb-interwork \
	-MF $(OBJDIR)/$(6)/$*.d -o $(OBJDIR)/$(6)/$*.o $< 2> $(PWD)/$*.err
rm -f $(PWD)/$*.err
endef

define	translate
$(call $(call test,ais),$(1),$(2),no-,,$(COSIZE),ais)
$(call $(call test,ans),$(1),$(2),no-,no-,$(COSIZE),ans)
$(call $(call test,tis),$(1),$(2),,,$(COSIZE),tis)
$(call $(call test,tns),$(1),$(2),,no-,$(COSIZE),tns)
$(call $(call test,aif),$(1),$(2),no-,,$(COSPEED),aif)
$(call $(call test,anf),$(1),$(2),no-,no-,$(COSPEED),anf)
$(call $(call test,tif),$(1),$(2),,,$(COSPEED),tif)
$(call $(call test,tnf),$(1),$(2),,no-,$(COSPEED),tnf)
endef

#	C source stem rule
#	~~~~~~~~~~~~~~~~~~

$(foreach lt,$(VERSIONS),$(OBJDIR)/$(lt)/%.o): %.c
	@echo "Compiling   " $(HERE)/$<
	@$(call translate,CC,CFLAGS)

#	Assembly source stem rule
#	~~~~~~~~~~~~~~~~~~~~~~~~~

$(foreach lt,$(VERSIONS),$(OBJDIR)/$(lt)/%.o): %.S
	@echo "Assembling  " $(HERE)/$<
	@$(call translate,AS,AFLAGS)

#	Dependencies
#	~~~~~~~~~~~~

-include $(foreach lt,$(VERSIONS),\
		   $(patsubst %,$(OBJDIR)/$(lt)/%.d,$(basename $(FILES))))
endif

