# build environment
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)

OS ?= LINUX
BUILD_BINDIR := $(BUILD)/bin
BUILD_SBINDIR := $(BUILD)/sbin
BUILD_LIBDIR := $(BUILD)/lib/$(DEB_HOST_MULTIARCH)
BUILD_USRBIN := $(BUILD)/usr/bin
BUILD_USRSHARE := $(BUILD)/usr/share
BUILD_USRSBIN := $(BUILD)/usr/sbin
BUILD_INCLUDEDIR := $(BUILD)/include/vdev
BUILD_ETCDIR := $(BUILD)/etc
BUILD_PKGCONFIG := $(BUILD)/lib/$(DEB_HOST_MULTIARCH)/pkgconfig

# install environment
PREFIX         ?= /usr/local
INCLUDE_PREFIX ?= $(PREFIX)
BINDIR         ?= $(PREFIX)/bin
SBINDIR        ?= $(PREFIX)/sbin
LIBDIR         ?= $(PREFIX)/lib/$(DEB_HOST_MULTIARCH)
INCLUDEDIR     ?= $(INCLUDE_PREFIX)/include/vdev
ETCDIR         ?= $(PREFIX)/etc
ETCDIR_VDEV    ?= $(ETCDIR)/vdev
SHAREDIR       ?= $(PREFIX)/share
PKGCONFIG      ?= $(INCLUDE_PREFIX)/lib/$(DEB_HOST_MULTIARCH)/pkgconfig
RUNDIR         ?= $(PREFIX)/run
RUNDIR_VDEV    ?= $(RUNDIR)/vdev
##LOGDIR         ?= $(PREFIX)/var/log
LOGDIR         ?= $(PREFIX)/run
LOGDIR_VDEV    ?= $(LOGDIR)/vdev

# uni-json (static JSON library); vendored under third-party/uni-json
UNIJSON_ROOT ?= $(ROOT_DIR)/third-party/uni-json
# dmidecode-builtin: vendored util/types under third-party/dmidecode-builtin/vendor/.
UNIJSON_INC  := -I$(UNIJSON_ROOT)/include
UNIJSON_LIB  := $(UNIJSON_ROOT)/bin/libuni-json.a

# libvdev (NOTE: not an installable target; just common code)
LIBVDEV_ROOT := $(ROOT_DIR)/libvdev 
BUILD_LIBVDEV := $(BUILD_LIBDIR)
BUILD_LIBVDEV_HEADERS := $(BUILD_INCLUDEDIR)
BUILD_LIBVDEV_DIRS := $(BUILD_LIBVDEV) $(BUILD_LIBVDEV_HEADERS)
INSTALL_LIBVDEV := $(DESTDIR)$(LIBDIR)
INSTALL_LIBVDEV_HEADERS := $(DESTDIR)$(INCLUDEDIR)

# libudev-compat 
BUILD_LIBUDEV_COMPAT := $(BUILD)/libudev-compat
BUILD_LIBUDEV_COMPAT_HEADERS := $(BUILD_INCLUDEDIR)
BUILD_LIBUDEV_COMPAT_DIRS := $(BUILD_LIBUDEV_COMPAT) $(BUILD_LIBUDEV_COMPAT_HEADERS)
INSTALL_LIBUDEV_COMPAT := $(DESTDIR)$(LIBDIR)
INSTALL_LIBUDEV_COMPAT_HEADERS := $(DESTDIR)$(INCLUDEDIR)
LIBUDEV_VERSION := 219

# vdevd 
BUILD_VDEVD := $(BUILD_SBINDIR)
BUILD_VDEVD_HELPERS := $(BUILD)/lib/vdev
BUILD_VDEVD_DIRS := $(BUILD_VDEVD) $(BUILD_VDEVD_HELPERS)
INSTALL_VDEVD := $(DESTDIR)$(SBINDIR)
INSTALL_VDEVD_HELPERS := $(DESTDIR)$(PREFIX)/lib/vdev

# vdevfs 
BUILD_VDEVFS := $(BUILD_USRSBIN)
BUILD_VDEVFS_DIRS := $(BUILD_VDEVFS)
INSTALL_VDEVFS := $(DESTDIR)$(SBINDIR)

# config
BUILD_VDEV_CONFIG := $(BUILD_ETCDIR)/vdev
BUILD_VDEV_INITSCRIPT := $(BUILD_ETCDIR)/init.d
BUILD_VDEV_INITRAMFS := $(BUILD_USRSHARE)/initramfs-tools
BUILD_VDEV_CONFIG_DIRS := $(BUILD_VDEV_CONFIG)
INSTALL_VDEV_CONFIG := $(DESTDIR)$(ETCDIR)/vdev
INSTALL_VDEV_INITSCRIPT := $(DESTDIR)$(ETCDIR)/init.d
INSTALL_VDEV_INITRAMFS := $(DESTDIR)$(SHAREDIR)/initramfs-tools

# hwdb 
BUILD_HWDB := $(BUILD)/lib/vdev/hwdb
BUILD_HWDB_DIRS := $(BUILD_HWDB)
INSTALL_HWDB := $(DESTDIR)$(PREFIX)/lib/vdev/hwdb

# compiler
# We switch to -std=gnu11 or gnu23 to enable __VA_OPT__ and modern extensions
# We add -D_FORTIFY_SOURCE=2 for runtime overflow detection
# We add -Wl,-z,relro -Wl,-z,now to harden the binary against memory exploits (Hardening)
CFLAGS     := -Wall -Wextra -std=gnu11 -g -O2 -fPIC \
              -fstack-protector-strong -D_FORTIFY_SOURCE=2 \
              -pthread -Wno-unused-variable -Wno-unused-but-set-variable

LDFLAGS    := -lpstat -Wl,-z,relro -Wl,-z,now

# Memory / overflow debugging: build with `make clean all SANITIZE=1`
# (AddressSanitizer includes LeakSanitizer on typical GCC/Clang builds).
# _FORTIFY_SOURCE and -O2 are dropped here because they interact poorly with ASan.
ifeq ($(SANITIZE),1)
CFLAGS := $(filter-out -O2 -D_FORTIFY_SOURCE=2,$(CFLAGS))
CFLAGS += -O1 -fsanitize=address -fno-omit-frame-pointer
LDFLAGS += -fsanitize=address
endif

INC      := -I. -I$(ROOT_DIR) -I$(BUILD_INCLUDEDIR) $(UNIJSON_INC)
DEFS     := -D_THREAD_SAFE -D__STDC_FORMAT_MACROS -D_VDEV_OS_$(OS) -D_XOPEN_SOURCE=700
LIBINC   := 
CC       ?= cc

# build setup
BUILD_DIRS   := $(sort $(BUILD_VDEVD_DIRS) \
                $(BUILD_VDEVFS_DIRS) \
				$(BUILD_LIBUDEV_COMPAT_DIRS) \
				$(BUILD_LIBVDEV_DIRS) \
				$(BUILD_HWDB))

all:

build_setup: $(BUILD_DIRS)

$(BUILD_DIRS):
	@mkdir -p "$@"

$(UNIJSON_LIB):
ifeq ($(SANITIZE),1)
	$(MAKE) -C $(UNIJSON_ROOT) DEV=1 \
		EXTRA_CFLAGS="-O1 -fsanitize=address -fno-omit-frame-pointer" \
		EXTRA_LDFLAGS="-fsanitize=address"
else
	$(MAKE) -C $(UNIJSON_ROOT)
endif

# rule to make an archive member from an object file
(%.o): %.o ;    $(AR) cr $@ $*.o

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