# $Id: Makefile 995 2009-08-11 14:26:31Z mike $

# defaults for ARCHS (architectures to build for) 
# and CASES (plain names without path/extension from the $(SRC_DIR) directory)
ARCHS ?= tricore i386
CASES ?= %
ARCH =


# input and output paths
SRC_DIR ?= src
OUT_DIR ?= out

# general flags (ARCH-specific flags below) 
CXXFLAGS 		?= -O3 -finline-limit=1200 -fno-rtti -fno-exceptions
AGXXFLAGS 		?= --weave_only --c_compiler $(CXX) --keep_acc --no_line --keywords
OBJDUMPFLAGS 	?= -d --demangle --reloc

# ARCH-specific tools and flags (set only if different from generic version)
i386_CXX			:= g++ 
i386_PATH			:=
i386_OBJDUMP		:= objdump
	
i386_CXXFLAGS 		?= -fomit-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-jumps -fno-align-loops -fno-align-labels -fno-reorder-blocks -fno-prefetch-loop-arrays
tricore_CXXFLAGS 	?= -mcpu=tc1796 -mnocallerrors -DTRIBOARD_TC1796

# generic version of ARCH-specific tools and flags
$(ARCH)_CXX		?= $(ARCH)-g++
$(ARCH)_OBJDUMP	?= $(ARCH)-objdump
$(ARCH)_PATH 	?= $(dir $(shell which $($(ARCH)_CXX)))

# tools
AGXX	= $(shell which ag++ 2> /dev/null)
CXX 	= $($(ARCH)_PATH)$($(ARCH)_CXX)
OBJDUMP	= $($(ARCH)_PATH)$($(ARCH)_OBJDUMP)

# path overrides (assuming tools under /proj/i4ciao/tools) 
ifeq ($(tricore_PATH),)
	override tricore_PATH	:= /proj/i4ciao/tools/trigcc/bin/
endif
ifeq ($(AGXX),)	
	override  AGXX			:= /proj/i4ciao/tools/bin/ag++
endif	

# for convenience, ARCHS and CASES may have been given as comma-separated lists
override ARCHS := $(shell echo $(ARCHS) | sed s/,/\ /)
override CASES := $(shell echo $(CASES) | sed s/,/\ /)

# sources are taken from $(SRC_DIR), but filtered by $(CASES)
SRC_FILES 		:= $(shell find $(SRC_DIR) -follow -name '*.cpp')
SRC_NAMES 		:= $(patsubst $(SRC_DIR)/%.cpp,%,$(SRC_FILES))
override CASES 	:= $(filter $(CASES),$(SRC_NAMES))
SRC 			?= $(patsubst %,$(SRC_DIR)/%.cpp,$(CASES))

# generated files
ACC  	:= $(patsubst $(SRC_DIR)/%.cpp,$(OUT_DIR)/$(ARCH)/%.acc, $(SRC)) 
OBJ  	:= $(patsubst %.acc, %.o, $(ACC)) 
DUMP	:= $(patsubst %.o, %.dump, $(OBJ))

all: do_all

# clean everything
clean: 
	@-if [ -d $(OUT_DIR) ]; then rm -r $(OUT_DIR); fi
	@-rm -f puma.config ALL.report

report: $(SRC)
	@$(foreach FILE, $(SRC), \
		find $(OUT_DIR) -name "$(notdir $(FILE:.cpp=.dump))" | xargs cat >$(OUT_DIR)/$(notdir $(FILE:.cpp=.report)) ;\
	)
	@cat $(OUT_DIR)/*.report >ALL.report	

### ---> if $(ARCH) has not been specified...
ifeq ($(ARCH),)

# ...just reinvoke make for every architecture in $(ARCHS)
%:
	@$(foreach ARCH, $(ARCHS), \
		echo ">>>>> invoking for $(ARCH)" ;\
		$(MAKE) --no-print-directory $(MAKECMDGOALS) ARCH=$(ARCH) ;\
		echo "<<<<< finished $(ARCH)" ;\
	)

### <---
else
### ---> otherwise we have real goals

do_all: weave compile dump

weave: $(ACC)
compile: $(OBJ)
dump: $(DUMP)

endif
### <---


# Weave a C++ File in the '$(SRC_DIR)' directory
$(OUT_DIR)/$(ARCH)/%.acc: $(SRC_DIR)/%.cpp
	@echo "AGXX  $< --> $@"
	@if [ ! -e $(@D) ];then mkdir -p $(@D);fi
	@$(AGXX) $(AGXXFLAGS) $< -o $@ 


# Compile a woven C++ File in the '$(OUT_DIR)' directory
%.o: %.acc
	@echo "CXX   $< --> $@"
	@$(CXX) -xc++ -c $< -o $@ $(CXXFLAGS) $($(ARCH)_CXXFLAGS) 

# Create a dump-File
%.dump: %.o
	@echo "DUMP  $< --> $@"
	@$(OBJDUMP) $(OBJDUMPFLAGS) $< >$@ 
	@cat $@ >> $(OUT_DIR)/$(@F)

# Print out important subtitutions
debug:

	@echo CASES=$(CASES)
	@echo ARCHS=$(ARCHS)
	@echo AGXX=$(AGXX)
	@echo CXX=$(CXX)
	@echo OBJ=$(OBJ)
	@echo SRC=$(SRC)
	@echo PLAIN=$(PLAIN)
	@echo ACC=$(ACC)

.PRECIOUS: $(OUT_DIR)/$(ARCH)/%.o $(OUT_DIR)/$(ARCH)/%.acc


.PHONY: all clean debug $(ARCHS)


	
