# Define kernel versions and corresponding object files
#KERNEL_VERSIONS = 512 506 420 416
KERNEL_VERSIONS = 512
#KERNEL_VERSIONS = 416

# Define compiler and options
CC = /usr/bin/clang
LLC = /usr/bin/llc
LLVM_STRIP = /usr/bin/llvm-strip

# Define source and output directories
SRC = ./ebpf/ebpf.c

ifeq ($(debug),1)
DEBUG_MODE=-D_DEBUG_MODE
endif

ifdef kernel
	KERNEL_VERSIONS= ${kernel}
ifeq ($(kernel),all)
	KERNEL_VERSIONS = 512 506 420 416
endif
endif

ARCH ?= $(shell uname -m | sed -e s/x86_64/x86_64/ \
				  -e s/aarch64.\*/arm64/)
MACHINE_ARCH := $(ARCH)
GO_ARCH := $(MACHINE_ARCH)

ARCH_TAG=-D__TARGET_ARCH_x86 -D__x86_64__

ifeq ($(MACHINE_ARCH),x86_64)
        MACHINE_ARCH := amd64
		GO_ARCH := amd64
endif
ifeq ($(MACHINE_ARCH),amd64)
        MACHINE_ARCH := amd64
		GO_ARCH := amd64
endif

ifeq ($(MACHINE_ARCH),aarch64)
        MACHINE_ARCH := arm64
		GO_ARCH := arm64
		ARCH_TAG=-D__TARGET_ARCH_arm64 -D__aarch64__ -D__AARCH64EB__

endif

ifeq ($(MACHINE_ARCH),arm64)
        MACHINE_ARCH := arm64
		GO_ARCH := arm64
		ARCH_TAG=-D__TARGET_ARCH_arm64 -D__aarch64__ -D__AARCH64EB__
endif

OBJ_DIR = ebpf/bin/$(MACHINE_ARCH)

# Define flags
CFLAGS = -I. -Ivmlinux -Iinclude -Iebpf/include -Iebpf/utrace/go/include -Iebpf/utrace/java/include -Iebpf/utrace/netcore/include \
	-D__BPF_TRACING__ -D GROUP_LEADER_OFFSET_OVERRIDE=0 -DSTART_BOOTTIME_OFFSET_OVERRIDE=0 \
	-DSTART_BOOTTIME_VARNAME=real_start_time -std=gnu99 -Wimplicit-function-declaration \
	-ffreestanding -fno-builtin -Wall -Wno-deprecated-declarations \
	-Wno-gnu-variable-sized-type-not-at-end -Wno-pragma-once-outside-header \
	-Wno-address-of-packed-member -Wno-unknown-warning-option \
	-fno-color-diagnostics -fno-unwind-tables -fno-stack-protector \
	-Wno-unused-variable \
	$(ARCH_TAG) \
	$(DEBUG_MODE) \
	-fno-asynchronous-unwind-tables -g -O2 -emit-llvm

define MAP_VERSION
$(if $(filter $1,$(VERSION_512)),v5.12,$(if $(filter $1,$(VERSION_506)),v5.6,$(if $(filter $1,$(VERSION_420)),v4.20,$(if $(filter $1,$(VERSION_416)),v4.16,unknown))))
endef

# Define version kv
VERSION_512 = 512
VERSION_506 = 506
VERSION_420 = 420
VERSION_416 = 416

# Create necessary directories
$(OBJ_DIR):
	mkdir -p $(OBJ_DIR)

# Set logs
$(info  -- Compiling target kernel ${KERNEL_VERSIONS})
$(info  -- Compiling for ${ARCH})
$(info  -- Compiling for ${ARCH_TAG} $(DEBUG_MODE))
$(info  -- Compiling use ${CC})
$(info  -- Compiling use ${LLC})
$(info  -- Compiling use ${LLVM_STRIP})
$(info  -- Compiling use ${SRC})

all: $(KERNEL_VERSIONS:%=$(OBJ_DIR)/%_$(MACHINE_ARCH).o)
# Rule to compile and process eBPF for each kernel version
$(OBJ_DIR)/%_$(MACHINE_ARCH).o: $(OBJ_DIR)/%_$(MACHINE_ARCH).ll
	$(LLC) -march=bpf -filetype=obj -mcpu=v2 -o $(OBJ_DIR)/$(call MAP_VERSION,$*)_$(MACHINE_ARCH).o $<
	$(LLVM_STRIP) -g $(OBJ_DIR)/$(call MAP_VERSION,$*)_$(MACHINE_ARCH).o
	@echo "Release $(call MAP_VERSION,$*)_$(MACHINE_ARCH) Build complete."

# Rule to generate LLVM IR from eBPF source
$(OBJ_DIR)/%_$(MACHINE_ARCH).ll: $(SRC) | $(OBJ_DIR)
	$(CC) $(CFLAGS) -D__KERNEL_FROM=$* -o $@ -c $(SRC)

clean:
	rm -f $(OBJ_DIR)/*_$(MACHINE_ARCH).ll $(OBJ_DIR)/*_$(MACHINE_ARCH).o

.PHONY: all clean
