CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
AR := $(CROSS_COMPILE)ar
RANLIB := $(CROSS_COMPILE)ranlib
YACC := bison
LEX := flex

APPL := $(addprefix ${IPROUTE2_APPS_BLDDIR}/bin/,${IPROUTE2_APPS_LIST})

# full-set
# EXT_FUNC := 802_3 nat arp arpreply ip ip6 standard log redirect 
# EXT_FUNC += vlan mark_m mark pkttype stp among limit ulog nflog
# EXT_FUNC += ftos time wmm_mark
TC_QDISC := fifo htb prio
TC_QDISC += $(IPROUTE2_TC_APPS_QDISCS)
TC_QDISC_UC := $(shell echo $(TC_QDISC) | tr a-z A-Z)
TC_FILTER := fw u32
TC_FILTER += $(IPROUTE2_TC_APPS_FILTERS)
TC_FILTER_UC := $(shell echo $(TC_FILTER) | tr a-z A-Z)
TC_ACTION := mirred
TC_ACTION += $(IPROUTE2_TC_APPS_ACTIONS)
TC_ACTION_UC := $(shell echo $(TC_ACTION) | tr a-z A-Z)
SO_LOBJS := utils.o rt_names.o ll_types.o ll_proto.o 
SO_LOBJS += ll_addr.o inet_proto.o ll_map.o libnetlink.o
SO_LOBJS := $(addprefix lib/, ${SO_LOBJS})
SO_BOBJS := $(addprefix ${IPROUTE2_APPS_BLDDIR}/,${SO_LOBJS})
SO_LIB := $(IPROUTE2_APPS_BLDDIR)/$(IPROUTE2_APPS_LIB)
STATIC_LIB := $(basename $(SO_LIB))_pic.a

IP_LOBJS := ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o
IP_LOBJS += rtm_map.o iptunnel.o ip6tunnel.o tunnel.o ipneigh.o
IP_LOBJS += ipntable.o iplink.o ipmaddr.o ipmonitor.o ipmroute.o
IP_LOBJS += ipprefix.o ipxfrm.o xfrm_state.o xfrm_policy.o xfrm_monitor.o
IP_LOBJS += iplink_vlan.o link_veth.o link_gre.o iplink_can.o iplink_macvlan.o
IP_LOBJS := $(addprefix ip/, ${IP_LOBJS})
IP_BOBJS := $(addprefix ${IPROUTE2_APPS_BLDDIR}/,${IP_LOBJS})

RTMON_LOBJS := rtmon.o
RTMON_LOBJS := $(addprefix ip/, ${RTMON_LOBJS})
RTMON_BOBJS := $(addprefix ${IPROUTE2_APPS_BLDDIR}/,${RTMON_LOBJS})

TC_LOBJS := tc_core.o tc_red.o tc_cbq.o tc_estimator.o tc_stab.o
TC_LOBJS += tc.o tc_qdisc.o tc_class.o tc_filter.o tc_util.o
TC_LOBJS += tc_monitor.o m_action.o m_estimator.o m_police.o
TC_LOBJS += $(foreach T,$(TC_QDISC), q_$(T).o)
TC_LOBJS += $(foreach T,$(TC_FILTER), f_$(T).o)
TC_LOBJS += $(foreach T,$(TC_ACTION), m_$(T).o)
TC_LOBJS := $(addprefix tc/, ${TC_LOBJS})
TC_BOBJS := $(addprefix ${IPROUTE2_APPS_BLDDIR}/,${TC_LOBJS})

LOBJS := $(SO_LOBJS)
BOBJS := $(SO_BOBJS)
ifneq (,$(findstring ip,$(IPROUTE2_APPS_LIST)))
LOBJS += $(IP_LOBJS)
BOBJS += $(IP_BOBJS)
endif
ifneq (,$(findstring rtmon,$(IPROUTE2_APPS_LIST)))
LOBJS += $(RTMON_LOBJS)
BOBJS += $(RTMON_BOBJS)
endif
ifneq (,$(findstring tctrl,$(IPROUTE2_APPS_LIST)))
LOBJS += $(TC_LOBJS)
BOBJS += $(TC_BOBJS)
endif

CFLAGS := -fpic -g -Os -Wall -Wstrict-prototypes
CFLAGS += -I$(IPROUTE2_APPS_DIR) -I$(IPROUTE2_APPS_DIR)/include
CFLAGS += -I$(IPROUTE2_APPS_DIR)/tc
CFLAGS += -D_GNU_SOURCE -DCONFIG_GACT -DCONFIG_GACT_PROB
CFLAGS += $(foreach T,$(TC_QDISC_UC), -DTC_Q_$(T))
CFLAGS += $(foreach T,$(TC_FILTER_UC), -DTC_F_$(T))
CFLAGS += $(foreach T,$(TC_ACTION_UC), -DTC_A_$(T))
CFLAGS += $(IPROUTE2_APPS_CFLAGS)
YACCFLAGS = -d -t -v
SO_LDFLAGS := -shared -Wl,-soname,$(IPROUTE2_APPS_LIB)
APPL_LDFLAGS := -lm -ldl -L$(IPROUTE2_APPS_BLDDIR) -l$(subst .so,,$(subst lib,,$(IPROUTE2_APPS_LIB))) -Wl,-rpath-link -Wl,--allow-shlib-undefined

all: $(BOBJS) $(STATIC_LIB) $(SO_LIB) $(APPL)

$(STATIC_LIB): $(SO_BOBJS)
	@$(AR) rcs $@ $^
	@$(RANLIB) $@

$(SO_LIB): $(SO_BOBJS)
	@$(CC) $(SO_LDFLAGS) $(CFLAGS) -o $@ $^
	
$(IPROUTE2_APPS_BLDDIR)/bin/ip: $(SO_LIB) $(IP_BOBJS)
	-@if [ ! -d $(@D)  ]; then mkdir -p $(@D); fi
	@$(CC) -o $@ $(IP_BOBJS) $(APPL_LDFLAGS)

$(IPROUTE2_APPS_BLDDIR)/bin/rtmon: $(SO_LIB) $(RTMON_BOBJS)
	-@if [ ! -d $(@D)  ]; then mkdir -p $(@D); fi
	@$(CC) -o $@ $(RTMON_BOBJS) $(APPL_LDFLAGS)
	
$(IPROUTE2_APPS_BLDDIR)/bin/tctrl: $(SO_LIB) $(TC_BOBJS)
	-@if [ ! -d $(@D)  ]; then mkdir -p $(@D); fi
	@$(CC) -o $@ $(TC_BOBJS) $(APPL_LDFLAGS)
	
%.yacc.c: %.y
	@$(YACC) $(YACCFLAGS) -o $@ $<

%.lex.c: %.l
	@$(LEX) -o$@ $<

$(IPROUTE2_APPS_BLDDIR)/%.o: %.c
	@echo "Compiling $<"
	@$(CC) $(CFLAGS) -c $< -o $@
	
clean:
	@rm -rf $(IPROUTE2_APPS_BLDDIR)/*
	@rm -f tc/emp_ematch.yacc.h tc/emp_ematch.yacc.output
	@rm -f tc/emp_ematch.lex.c tc/emp_ematch.yacc.c

ifeq (,$(findstring clean,$(MAKECMDGOALS)))
-include $(addprefix ${IPROUTE2_APPS_BLDDIR}/,$(addsuffix .d,$(basename $(LOBJS))))

$(IPROUTE2_APPS_BLDDIR)/%.d: %.c
	-@if [ ! -d $(@D)  ]; then mkdir -p $(@D); fi
	@echo "Generating dependency file for $<"; \
	$(CC) -M $(CFLAGS) $< >$@.tmp; \
	echo "$@ \\" > $@; \
	sed 's,\($*\)\.o[ :]*,$$(IPROUTE2_APPS_BLDDIR)\/\1.o: ,g' < $@.tmp >> $@; \
	rm -f $@.tmp
endif
