# ******************************
# *       S E T T I N G S      *
# ******************************


# PUMA root
PUMA ?= ../Puma

# default target
TARGET  ?= linux-release

#AspectC++ source directory
AcSrcDir := ../AspectC++

# include the PUMA configuration variables
# => set _TARGET, RELEASE, CFLAGS, CXXFLAGS, CPPFLAGS, etc.
include $(PUMA)/vars.mk

PLATFORM := $(shell echo $(_TARGET) | cut -d _ -f1)

# determine which Puma library to use: libMiniPuma is preferred
PumaLibs := $(notdir $(wildcard $(PUMA)/lib/$(TARGET)/lib*Puma.a))
ifneq ($(filter libMiniPuma.a, $(PumaLibs)),)
	PUMA_LIB := MiniPuma
else
	PUMA_LIB := Puma
endif

#CXX  := /usr/bin/g++-3.3
#CXX := ag++  -p. -p../aspects --Xcompiler
#CXX := ag++ -v3 -p. --Xcompiler

# check whether we compile for Windows: TARGET-Variable starts with 'win'
ifneq ($(filter win%,$(TARGET)),)
	WIN := yes
endif

# compiler settings

ifeq ($(WIN),yes)
	BinExt := .exe
	RES := windres
	RCFILES := win-ag++.rc
endif

CXXFLAGS += $(CPPFLAGS) -I$(PUMA)/extern -I$(PUMA)/include -std=gnu++17

ifneq ($(PLATFORM),macos)
	ifeq ($(SHARED),)
		LDFLAGS += -static
	endif

LDFLAGS += -Wl,-Bstatic -L$(PUMA)/lib/$(TARGET) -l$(PUMA_LIB)

ifneq ($(SHARED),)
	LDFLAGS += -Wl,-Bdynamic
endif

else
	LDFLAGS += -L$(PUMA)/lib/$(TARGET) -l$(PUMA_LIB)
endif

ifneq ($(PROFILING),)
	LDFLAGS += -lc_p -lm_p 
	CXXFLAGS += -pg
endif


SourceFiles := $(wildcard *.cc) 

BuildDir ?= build/$(TARGET)

ObjDir := $(BuildDir)/obj
ObjectFiles := $(addprefix $(ObjDir)/,$(SourceFiles:%.cc=%.o))

DepDir := $(BuildDir)/dep
DepFiles := $(addprefix $(DepDir)/,$(SourceFiles:%.cc=%.d))

BinDir := $(BuildDir)/bin
BinName := ag++$(BinExt)
BinFile := $(BinDir)/$(BinName)


ifeq ($(WIN),yes)
ObjectFiles += $(addprefix $(ObjDir)/,$(RCFILES:%.rc=%.o))
DepFiles += $(addprefix $(DepDir)/,$(RCFILES:%.rc=%.d))
endif




# ******************************
# *     T A R G E T S          *
# ******************************

all: showtarget $(AcSrcDir)/bin/$(TARGET)/$(BinName)

strip: $(AcSrcDir)/bin/$(TARGET)/$(BinName)
	@$(STRIP) $<

showtarget:
	@echo "Build commands for TARGET=$(TARGET)"
	@echo "  Compiler = $(CXX) $(CXXFLAGS)"
	@echo "  Linker   = $(CXX) $(CXXFLAGS) <objects> $(LDFLAGS)"
	@echo 

help:
	@echo "  help:          show this help"
	@echo "  all (default): compile, link and copy"
	@echo "  copy:          copy executable into AspectC++ bin folder"
	@echo "  test :         run tests"
	@echo "  test_<XX>:     run test number <XX>"
	@echo "  doc:           build documentation"
	@echo "  showtarget:    show compiler options for selected target"
	@echo "  clean:         remove intermediate files of current TARGET"
	@echo "  distclean:     clean all generated files and directories"


clean: 
	@echo -n "CLEAN    "
	rm -rf $(BuildDir) core core.* 
	@make -C doc clean

distclean: clean
 

test:	all
	@export TARGET=$(TARGET);export EXT=$(EXT);cd tests;./run_tests.sh

test_%: all
	@export TARGET=$(TARGET);export EXT=$(EXT);cd tests; ./run_tests.sh $@

doc:
	@make -C doc


.PHONY: all clean distclean showtarget doc

# ******************************
# *       R U L E S            *
# ******************************

$(BinFile): $(ObjectFiles)
	@echo "LD        $@"
	@mkdir -p $(BinDir)
	@$(CXX) -o $@ $(CXXFLAGS) $^ $(LDFLAGS)

$(AcSrcDir)/bin/$(TARGET)/$(BinName): $(BinFile)
	@echo "COPY      $< to $@"
	@mkdir -p $(@D)
	@cp $< $@

$(ObjDir)/%.o : %.cc
	@echo "CC        $<"
	@mkdir -p $(DepDir)
	@mkdir -p $(ObjDir)
	@$(CXX) $(CXXFLAGS) -MMD -MP -MT $@ -MT $(DepDir)/$(<:%.cc=%.d) -MF $(DepDir)/$(<:%.cc=%.d) -c -o $@ $< 
# @echo "CC        $@"
#	@mkdir -p $(ObjDir)
#	@$(CXX) $(CXXFLAGS) -c -o $@ $<

ifeq ($(WIN),yes)
$(ObjDir)/%.o : %.rc
	@echo "DEP       $@."
	@mkdir -p $(DepDir)
	@$(CXX) $(CXXFLAGS) -MM -MP -MT $@ -MT $(DepDir)/$(<:%.cc=%.d) -MF $(DepDir)/$(<:%.cc=%.d) -xc++ $< 
	@echo "RES       $@"
	@mkdir -p $(ObjDir)
	@$(RES) $(filter -D%,$(CXXFLAGS)) $< $@
endif

ifeq (,$(findstring clean,$(MAKECMDGOALS)))
ifeq (,$(findstring help,$(MAKECMDGOALS)))
-include $(DepFiles)
endif
endif

.SUFFIXES: .cc .o .h .rc .mk $(SUFFIXES)
