ROOT_DIR := $(shell dirname "$(realpath $(lastword $(MAKEFILE_LIST)))")
BUILD    ?= $(ROOT_DIR)/build

DEB_HOST_MULTIARCH ?=$(shell dpkg-architecture -qDEB_HOST_MULTIARCH 2>/dev/null || true)

CC	    ?= cc
CFLAGS ?= -Wall -std=gnu99 -g -fPIC

UBOX_SRCS := avl.c avl-cmp.c blob.c blobmsg.c uloop.c usock.c ustream.c ustream-fd.c \
	vlist.c utils.c safe_list.c runqueue.c md5.c kvlist.c ulog.c base64.c

HEADERS := $(wildcard *.h)

UBOX_OBJ   := $(patsubst %.c,$(BUILD)/%.o,$(UBOX_SRCS))

VERSION := 17.01

VERSION_MAJOR := 1
VERSION_MINOR := 0
VERSION_PATCH := 0

UBOX := libubox.so
UBOX_SO := libubox.so.$(VERSION_MAJOR)
UBOX_LIB := libubox.so.$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)

JSON_SCRIPT     := libjson_script.so
JSON_SCRIPT_SRC := json_script.c
JSON_SCRIPT_OBJ := $(JSON_SCRIPT_SRC:.c=.o)

BLOBMSG_JSON     := libblobmsg_json.so
BLOBMSG_JSON_SRC := blobmsg_json.c
BLOBMSG_JSON_OBJ := $(BLOBMSG_JSON_SRC:.c=.o)

#--------------------------------------------------#
JSHN        := jshn
JSHN_SRC    := jshn.c
JSHN_OBJ := $(patsubst %.c,$(BUILD)/%.o,$(JSHN_SRC))
#--------------------------------------------------#

PREFIX ?= /usr/local
DESTDIR ?= /
INCLUDE_PREFIX ?= $(PREFIX)

LIB   := -L$(BUILD)$(PREFIX)/lib/$(DEB_HOST_MULTIARCH)
LIBINC   := -I$(BUILD) -I$(BUILD)/usr/include -I$(BUILD)/usr/include/libubox -I/usr/include/json-c

BINDIR ?= $(DESTDIR)/$(PREFIX)/bin
LIBDIR ?= $(DESTDIR)$(PREFIX)/lib/$(DEB_HOST_MULTIARCH)
INCLUDE_DIR ?= $(DESTDIR)$(INCLUDE_PREFIX)/include/libubox
PKGCONFIGDIR ?= $(DESTDIR)$(PREFIX)/lib/$(DEB_HOST_MULTIARCH)/pkgconfig

BUILD_UBOX_LIB := $(patsubst %,$(BUILD)$(LIBDIR)/%,$(UBOX_LIB))
INSTALL_UBOX_LIB := $(patsubst $(BUILD)$(LIBDIR)/%,$(LIBDIR)/%,$(BUILD_UBOX_LIB))

BUILD_UBOX_SO := $(patsubst %,$(BUILD)$(LIBDIR)/%,$(UBOX_SO))
INSTALL_UBOX_SO := $(patsubst $(BUILD)$(LIBDIR)/%,$(LIBDIR)/%,$(BUILD_UBOX_SO))

BUILD_UBOX := $(patsubst %,$(BUILD)$(LIBDIR)/%,$(UBOX))
INSTALL_UBOX := $(patsubst $(BUILD)$(LIBDIR)/%,$(LIBDIR)/%,$(BUILD_UBOX))

BUILD_HEADERS := $(patsubst %,$(BUILD)/$(INCLUDE_DIR)/%,$(HEADERS))
INSTALL_HEADERS := $(patsubst $(BUILD)/$(INCLUDE_DIR)/%,$(INCLUDE_DIR)/%,$(BUILD_HEADERS))

BUILD_PC_FILE := $(BUILD)/libubox.pc
INSTALL_PC_FILE := $(PKGCONFIGDIR)/libubox.pc

BUILD_JSON_SCRIPT := $(patsubst %,$(BUILD)$(LIBDIR)/%,$(JSON_SCRIPT))
INSTALL_JSON_SCRIPT := $(patsubst $(BUILD)$(LIBDIR)/%,$(LIBDIR)/%,$(BUILD_JSON_SCRIPT))

BUILD_BLOBMSG_JSON := $(patsubst %,$(BUILD)$(LIBDIR)/%,$(BLOBMSG_JSON))
INSTALL_BLOBMSG_JSON := $(patsubst $(BUILD)$(LIBDIR)/%,$(LIBDIR)/%,$(BUILD_BLOBMSG_JSON))

BUILD_JSHN := $(patsubst %,$(BUILD)/$(BINDIR)/%,$(JSHN))
INSTALL_JSHN := $(patsubst $(BUILD)/$(BINDIR)/%,$(BINDIR)/%,$(BUILD_JSHN))

JSHN_SCRIPT := $(DESTDIR)$(PREFIX)/share/libubox/jshn.sh

#------------#
all: libs \
	tools

tools: $(BUILD_JSHN) libs

libs: $(BUILD_HEADERS) $(BUILD_PC_FILE) $(BUILD_UBOX) $(BUILD_UBOX_SO) $(BUILD_UBOX_LIB) \
	$(BUILD_JSON_SCRIPT) $(BUILD_BLOBMSG_JSON)

$(BUILD_PC_FILE): libubox.pc.in
	@mkdir -p "$(shell dirname "$@")"
	@cat $< | \
		sed -e 's~@prefix@~$(PREFIX)~g;' | \
		sed -e 's~@includedir@~$(INCLUDE_DIR)~g;' | \
		sed -e 's~@version@~$(VERSION)~g; ' | \
		sed -e 's~@libdir@~$(LIBDIR)~g; ' > $@

$(BUILD_UBOX_LIB): $(UBOX_OBJ)
	@mkdir -p "$(shell dirname "$@")"
	$(CC) $(CFLAGS) -shared -Wl,-soname,$(UBOX_SO) -o "$@" $(UBOX_OBJ) $(LIBINC) -ljson-c

$(BUILD_UBOX_SO): $(BUILD_UBOX_LIB)
	@mkdir -p "$(shell dirname "$@")"
	@ln -sf "$(shell basename "$<")" "$@"

$(BUILD_UBOX): $(BUILD_UBOX_SO)
	@mkdir -p "$(shell dirname "$@")"
	@ln -sf "$(shell basename "$<")" "$@"

$(BUILD)/$(INCLUDE_DIR)/%.h: %.h
	@mkdir -p "$(shell dirname "$@")"
	@cp -a "$<" "$@"

$(INSTALL_UBOX): $(BUILD_UBOX)
	@mkdir -p "$(shell dirname "$@")"
	cp -a "$<" "$@"

$(INSTALL_UBOX_SO): $(BUILD_UBOX_SO)
	@mkdir -p "$(shell dirname "$@")"
	cp -a "$<" "$@"

$(INSTALL_UBOX_LIB): $(BUILD_UBOX_LIB)
	@mkdir -p "$(shell dirname "$@")"
	cp -a "$<" "$@"

$(INCLUDE_DIR)/%.h: $(BUILD)/$(INCLUDE_DIR)/%.h
	@mkdir -p "$(shell dirname "$@")"
	cp -a "$<" "$@"

$(INSTALL_PC_FILE): $(BUILD_PC_FILE)
	@mkdir -p "$(shell dirname "$@")"
	cp -a "$<" "$@"
	
$(BUILD_JSON_SCRIPT): $(BUILD)/$(JSON_SCRIPT_OBJ)
	gcc $(CFLAGS) -shared -Wl,-soname,$(JSON_SCRIPT) -o $@ $^ $(LIBINC) $(LIB) -ljson-c

$(INSTALL_JSON_SCRIPT): $(BUILD_JSON_SCRIPT)
	@mkdir -p "$(shell dirname "$@")"
	cp -a "$<" "$@"
	
$(BUILD_BLOBMSG_JSON): $(BUILD)/$(BLOBMSG_JSON_OBJ)
	gcc $(CFLAGS) -shared -Wl,-soname,$(BLOBMSG_JSON) -o $@ $^ $(LIBINC) $(LIB) -ljson-c

$(INSTALL_BLOBMSG_JSON): $(BUILD_BLOBMSG_JSON)
	@mkdir -p "$(shell dirname "$@")"
	cp -a "$<" "$@"
	
#---------------------------  JSHN -------------------------------------#
$(BUILD_JSHN): $(JSHN_OBJ) $(BUILD_BLOBMSG_JSON)
	@mkdir -p "$(shell dirname "$@")"
	$(CC) $(CFLAGS) -o "$@" $(JSHN_OBJ) $(LIBINC) $(LIB) -ljson-c -lubox -lblobmsg_json

$(INSTALL_JSHN): $(BUILD_JSHN)
	@mkdir -p "$(shell dirname "$@")"
	cp -a "$<" "$@"
#----------------------------------------------------------------#

$(JSHN_SCRIPT): sh/jshn.sh
	@mkdir -p "$(shell dirname "$@")"
	cp -a "$<" "$@"

libs-install: $(INSTALL_UBOX) $(INSTALL_UBOX_SO) $(INSTALL_UBOX_LIB) \
	$(INSTALL_PC_FILE) $(INSTALL_JSON_SCRIPT) $(INSTALL_BLOBMSG_JSON)

#------------------------------#
tools-install: $(JSHN_SCRIPT) \
	$(INSTALL_JSHN)

headers-install: $(INSTALL_HEADERS)

install: libs-install headers-install \
	tools-install

$(BUILD)/%.o : %.c
	@mkdir -p "$(shell dirname "$@")"
	$(CC) $(CFLAGS) -o "$@" $(LIBINC) -c "$<"

.PHONY: clean
clean:
	rm -f $(BUILD_HEADERS) $(BUILD_UBOX_LIB) $(BUILD_UBOX_SO) $(BUILD_UBOX) \
		$(BUILD_PC_FILE) $(BUILD_HEADERS) $(UBOX_OBJ) \
		$(BUILD_JSON_SCRIPT) $(BUILD)/$(JSON_SCRIPT_OBJ) \
		$(BUILD_BLOBMSG_JSON) $(BUILD)/$(BLOBMSG_JSON_OBJ) \
		$(BUILD_JSHN) $(JSHN_OBJ)

.PHONY: uninstall 
uninstall:
	rm -f $(INSTALL_HEADERS) $(INSTALL_UBOX_LIB) $(INSTALL_UBOX_SO) $(INSTALL_UBOX) \
		$(INSTALL_PC_FILE) $(INSTALL_JSON_SCRIPT) $(INSTALL_BLOBMSG_JSON) $(JSHN_SCRIPT) \
		$(INSTALL_JSHN)

print-%: ; @echo $*=$($*)
