################################################################################
#  Makefile
#
#  This makefile will work for libraries (.a or .so) and applications.
#  If the target application has a suffix of .both, then both shared(.so)
#  and static (.a) libraries will be built.
#
#  objects to be made and required libraries are are defined in objects.mk
#
#  This makefile is based on the general directory structure as follows:
#   Level   Name                  Description
#     0     "src"                 root of source code
#     1 -   "lib"                 directory containing all libs
#     2 --    libary              one of many library files 
#     3 ---     "inc"             include files
#     3 ---     "Release"         temporary build folder
#     3 ---     "Static"
#     4 ----      "Release"         temporary build folder
#     3 ---     "src"             source code files
#     1 -   product               a product which may have multiple applications
#     2 --    application         one of many applications on the product
#     3 ---     "src"             source code & include files for the product
#     3 ---     "Release"         temp folder used for non debug version of build
#     3 ---     "Debug"           temp folder used for debug version of build
#     1 -   sysbase               system level utilities, shared among products
#     2 --    system application  one of several system applications
#     1 --  "inc"                 shared includes, EDS for example
#
################################################################################

#SHELL = /bin/sh


# clear implicit rules
.SUFFIXES :

#.SECONDARYEXPANSION :
.LOW_RESOLUTION_TIME :
.DELETE_ON_ERROR :
#.SECONDARY :
.NOTPARALLEL :


RM := rm -rf
MD := mkdir -p
CP := cp -f

ifeq ($(MVI_LIB_FOLDER_NAME),)
MVI_LIB_FOLDER_NAME=mvi56e-ldm
endif

MVI_LIB_FOLDER=../$(MVI_LIB_FOLDER_NAME)

ifeq ($(TW_SAMPLE_APP_FLAGS),)
TW_SAMPLE_APP_FLAGS=-I../${MVI_LIB_FOLDER_NAME}/src/inc -I../${MVI_LIB_FOLDER_NAME}/src/lib/ocx/inc
endif

#######################################################
# All of the sources & libraries participating in the build are defined here
-include objects.mk


############################################
# define Link Libraries based on build target  
# if we are building another lib, then the other libs are at the same level in the directory tree
#     which is to say, we are already in the lib directory
# if we are building an application, then the libs are up a level
ifneq ($(findstring .both,$(TARGETAPP)),)
#building both so and a
LIBSRCHBASE = ./..
else
ifneq ($(findstring .so,$(TARGETAPP)),)
#building shared library
LIBSRCHBASE = ./..
else
ifneq ($(findstring .a,$(TARGETAPP)),)
#building static library
LIBSRCHBASE = ./..
else
#building an application
# Location where MVI56E dependency libraries are stored, relative to the folder tw-ldm-sample-app-mvi56e:
LIBSRCHBASE = $(MVI_LIB_FOLDER)/src/lib
endif
endif
endif


ifeq ($(MAKECMDGOALS),debug)
#everything should be debug
CDEBUG 	= -g3 -DDEBUG
TARGETDIR := Debug
LINKLIBDIRS = $(patsubst %, -L$(LIBSRCHBASE)/%/$(TARGETDIR), $(LIBDIRS))
LIBS2BUILD := $(patsubst %, $(LIBSRCHBASE)/%, $(LIBDIRS))

else
ifeq ($(MAKECMDGOALS),mixdebug)
#only the current target is debug, all libs are whatever was last built
CDEBUG 	=
LINKLIBDIRS = $(patsubst %, -L$(LIBSRCHBASE)/%, $(LIBDIRS))
LIBS2BUILD := $(patsubst %, $(LIBSRCHBASE)/%, $(LIBDIRS))
TARGETDIR := Debug

else
ifeq ($(MAKECMDGOALS),mixrel)
#only the current target is debug, all libs are whatever was last built
CDEBUG 	=
LINKLIBDIRS = $(patsubst %, -L$(LIBSRCHBASE)/%, $(LIBDIRS))
LIBS2BUILD := $(patsubst %, $(LIBSRCHBASE)/%, $(LIBDIRS))
TARGETDIR := Release

else
#Everything should be built release
CDEBUG 	=
TARGETDIR := Release
LINKLIBDIRS = $(patsubst %, -L$(LIBSRCHBASE)/%/$(TARGETDIR), $(LIBDIRS))
LIBS2BUILD := $(patsubst %, $(LIBSRCHBASE)/%, $(LIBDIRS))
endif
endif
endif




ifneq ($(findstring .both,$(TARGETAPP)),)	
TARGETSHAREDLIB  = $(subst .both,.so,$(TARGETAPP))
TARGETARCHIVELIB = $(subst .both,.a,$(TARGETAPP))
else
ifneq ($(findstring .so,$(TARGETAPP)),)
TARGETSHAREDLIB  =  $(TARGETAPP)
else
ifneq 	($(findstring .a,$(TARGETAPP)),)
TARGETARCHIVELIB = $(TARGETAPP)
endif
endif
endif


############################################################
# 1. if the target is lib, then tell linker to create shared lib 
# 2.  library include files that for compile params
#  path is slightly different if building a library
#  product/src/appdir  vs.  product/src/lib/libdir
#  build occurs from the appdir or libdir
INCLIBDIRS = $(subst /Static,, $(LIBDIRS))

ifneq ($(findstring .a,$(TARGETAPP)),)
CINCLUDE = $(patsubst %, -I../%/inc, $(INCLIBDIRS))
ARCH := ar
ARCHFLAGS := -r
ARCHIVETARGETDIR = Static/$(TARGETDIR)
TARGETS=$(ARCHIVETARGETDIR)/$(TARGETARCHIVELIB)
else
LINK = ~/datm3/toolchain/bin/armv5l-timesys-linux-gnueabi-g++
ifneq ($(findstring .so,$(TARGETAPP)),)
CINCLUDE = $(patsubst %, -I../%/inc, $(INCLIBDIRS))
LDFLAGS := -shared -o
TARGETS=$(TARGETDIR)/$(TARGETSHAREDLIB)
else
ifneq ($(findstring .both,$(TARGETAPP)),)
CINCLUDE = $(patsubst %, -I../%/inc, $(INCLIBDIRS))

LDFLAGS := -shared -o
ARCH := ar
ARCHFLAGS := -r
ARCHIVETARGETDIR = Static/$(TARGETDIR)
TARGETS=$(TARGETDIR)/$(TARGETSHAREDLIB) $(ARCHIVETARGETDIR)/$(TARGETARCHIVELIB)
else
#building an application
CINCLUDE = $(patsubst %, -I./../../lib/%/inc, $(INCLIBDIRS))
LDFLAGS := -o
TARGETS=$(TARGETDIR)/$(TARGETAPP)
endif
endif
endif


#not needed
# create list of source files with path.
#C_SRCS += $(patsubst %, src/%, $(SRCS_C))

#create list of object files with path.
OBJS += $(patsubst %.c, $(TARGETDIR)/%.o, $(SRCS_C))

#create list of dependency files with path.
C_DEPS += $(patsubst %.c, $(TARGETDIR)/%.d, $(SRCS_C))


CC = ~/datm3/toolchain/bin/armv5l-timesys-linux-gnueabi-gcc

#CFLAGS	+= $(CINCLUDE) -I./inc $(CDEBUG) -O0 -Wall -Wstrict-prototypes -fmessage-length=0 -MMD -MF"$(@:%.o=%.d)" -MP -MT"$(@:%.o=%.d)" -o"$(@:%.d=%.o)" 
#TODO: Compiling with debug symbols, without optimization:
CFLAGS	+= $(TW_SAMPLE_APP_FLAGS) $(CINCLUDE) -I./inc $(CDEBUG) -g -Wall -Wstrict-prototypes -fmessage-length=0 -MMD -MF"$(@:%.o=%.d)" -MP -MT"$(@:%.o=%.d)" -o"$(@:%.d=%.o)" 

COMPILE_C = $(CC) $(CPPFLAGS) $(CFLAGS) -c "$<"


LIB2LINKIN = $(patsubst %, -l%, $(LIBS))
LIB2LINKIN += $(patsubst %, -l%, $(SYSLIBS))

################################################
# define nonexistent (phony) targets

.PHONY : debug mixdebug mixrel sublibs clean test $(LIBS2BUILD)



#######################################
# Rules and Recipits
#######################################

ifeq ($(MAKECMDGOALS),mixrel)
mixrel : test $(TARGETS)
	@echo 'Mixed Release build'
endif

ifeq ($(MAKECMDGOALS),mixdebug)
mixdebug : $(TARGETS)
	@echo 'Mixed Debug build'
endif

	
# if the application is being built define the rules for building 

ifneq ($(MAKECMDGOALS),test)
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),sublibs)


# Application link rule
$(TARGETS) :  $(OBJS) 
	@echo 'Linking target: $@'
	
ifneq ($(findstring .both,$(TARGETAPP)),)	
	@echo 'Building BOTH shared and static libraries'
	@echo 'Invoking: Cygwin C++ Linker'
	$(LINK) $(LDFLAGS) $(TARGETSHAREDLIB) $(OBJS) $(LIB2LINKIN) $(LINKLIBDIRS)

	@echo 'Copy shared lib to target directory'
	-$(CP) 	$(TARGETSHAREDLIB)  $(TARGETDIR)	
		
	@echo 'Invoking: GCC Archiver'
	$(ARCH) $(ARCHFLAGS) $(TARGETARCHIVELIB) $(OBJS)
	
	@echo 'Copy archive to target directory'
	-$(MD) $(ARCHIVETARGETDIR)
	-$(CP) $(TARGETARCHIVELIB)  $(ARCHIVETARGETDIR)
else
ifneq ($(findstring .so,$(TARGETAPP)),)	
	@echo 'Linking shared library::Invoking: Cygwin C++ Linker'
	$(LINK) $(LDFLAGS) $(TARGETAPP) $(OBJS) $(LIB2LINKIN) $(LINKLIBDIRS)

	 @echo 'Copy target to target directory'
	-$(CP) 	$(TARGETAPP)  $(TARGETDIR)
else
ifneq ($(findstring .a,$(TARGETAPP)),)	
	@echo 'Linking static library::Invoking: GCC Archiver'
		
	$(ARCH) $(ARCHFLAGS) $(TARGETARCHIVELIB) $(OBJS)
	
	@echo 'Copy target to target directory'
	-$(MD) $(ARCHIVETARGETDIR)
	-$(CP) $(TARGETARCHIVELIB)  $(ARCHIVETARGETDIR)
else
	@echo 'Linking application::Invoking: Cygwin C++ Linker'
	$(LINK) $(LDFLAGS) $(TARGETAPP) $(OBJS) $(LIB2LINKIN) $(LINKLIBDIRS)

	@echo 'Copy target to target directory'
	-$(CP) 	$(TARGETAPP)  $(TARGETDIR)
endif
endif	
endif
	@echo 'Finished building target: $@'
	@echo ' '


# define rule to utilize dependency files to make objects.
$(TARGETDIR)/%.o : $(TARGETDIR)/%.d
	@echo 'Compiling file: $<'
	$(COMPILE_C)
	@echo 'Finished Compiling: $<'
	@echo ' '


# this acts a the default way to make the dependency 
$(TARGETDIR)/%.d : src/%.c
	@echo 'Preprocessing file: $<'
	-$(MD) $(TARGETDIR)
	$(COMPILE_C)	
	@echo 'Finished preprocessing: $<'
	@echo ' '
	
	
#include any existing dependency files 	
-include $(C_DEPS)	

# this causes a dependency file to be recreated when a required .h is missing.
%.h :
	-@echo ' '
	-@echo 'Include file $@ can not be found.'
	-@echo ' '

endif
endif
endif


ifneq ($(MAKECMDGOALS),clean)

# define a rules for making libraries as needed.

sublibs : $(LIBS2BUILD)
#	for dir in $(LIBS2BUILD); do \
#		$(MAKE) -C $$dir/Release ; \
#	done
	
#rule for making libraries
#%.so :
$(LIBS2BUILD) :
	-@echo 'MAKING libary : $@'
	@$(MAKE) -C $@/Release

endif


ifeq ($(MAKECMDGOALS),clean)

# Action phony Targets
# this version will not work correctly until the libs2build are converted to this type of make script.
#    so for now it is commented out
#clean:   $(LIBS2BUILD)
clean:       
	-@echo 'Removing intermediate and target files'
	-$(RM) Release/*.o Release/*.d Release/$(TARGETAPP) 
	-$(RM) Debug/*.o Debug/*.d Debug/$(TARGETAPP)
#	-$(MD) Release
#	-$(MD) Debug
	-@echo ' '
	
$(LIBS2BUILD) :
	-@echo 'MAKING libary : $@'
	@$(MAKE) -C $@/Release clean

endif


test :
	-@echo 'TARGETS = $(TARGETS)'
	-@echo 'TARGETAPP = $(TARGETAPP)'
	-@echo 'TARGETSHAREDLIB = $(TARGETSHAREDLIB)'
	-@echo 'TARGETARCHIVELIB = $(TARGETARCHIVELIB)'	
	-@echo 'LIBS2BUILD = $(LIBS2BUILD)'
#	-@echo 'CDEBUG = $(CDEBUG)'
	-@echo 'C_DEPS = $(C_DEPS)'
	-@echo 'OBJS = $(OBJS)'
	-@echo 'TARGETDIR = $(TARGETDIR)'	
	-@echo 'CINCLUDE = $(CINCLUDE)'
	-@echo 'INCLIBDIRS = $(INCLIBDIRS)'
	-@echo 'LINKLIBDIRS = $(LINKLIBDIRS)'
	-@echo 'LIB2LINKIN = $(LIB2LINKIN)'
	