## Native and VM-obfuscated build for Polyphonia

# Tools
CC := clang-19
CXX := clang++-19
OPT := opt-19
LLC := llc-19
LLVM_CONFIG := llvm-config-19

# Dirs
SRC_DIR := src
OUT := dist
OBJ := $(OUT)/obj
BIN := $(OUT)/bin

# Obfuscator
OBF_DIR := ../obfuscator
PASS_SO := $(OBF_DIR)/build/libVMObfuscatorPass.so
LLVM_DIR ?= /usr/lib/llvm-19/lib/cmake/llvm
RUNTIME_OBJ := $(OBJ)/vm_runtime.o

# Flags
VM_TRACE ?= 0
CFLAGS := -Wall -O2 -pthread -I$(OBF_DIR)/include -DVM_ENABLE_TRACE=$(VM_TRACE) -DPG_ENABLED -I/usr/include/postgresql
LDFLAGS := -lpthread -no-pie -lpq
IR_CFLAGS ?= -O0 -fno-vectorize -fno-slp-vectorize
SOURCES := $(SRC_DIR)/polyphonia_pg.c $(SRC_DIR)/tone_library.c

TARGET := $(BIN)/polyphonia

.PHONY: all vm native clean run pass runtime dirs

all: vm

dirs:
	@mkdir -p $(OBJ) $(BIN)

# Build obfuscator pass if needed
pass:
	cmake -S $(OBF_DIR) -B $(OBF_DIR)/build -DLLVM_DIR=$(LLVM_DIR)
	cmake --build $(OBF_DIR)/build

# Build runtime object in-place
runtime: $(RUNTIME_OBJ)

$(RUNTIME_OBJ): $(OBF_DIR)/src/runtime/vm_runtime.c $(OBF_DIR)/include/vm_defs.h | dirs
	$(CC) -I$(OBF_DIR)/include -Wall -O2 -DVM_ENABLE_TRACE=$(VM_TRACE) -c -o $@ $<

# VM-obfuscated build: compile all to bitcode, link, obfuscate once
BC_OBJS := $(patsubst $(SRC_DIR)/%.c,$(OBJ)/%.bc,$(SOURCES))

$(OBJ)/%.bc: $(SRC_DIR)/%.c | dirs
	$(CC) $(CFLAGS) $(IR_CFLAGS) -emit-llvm -c $< -o $@

$(OBJ)/program.bc: $(BC_OBJS) | dirs
	llvm-link-19 $^ -o $@

$(OBJ)/program_scalar.bc: $(OBJ)/program.bc | pass
	$(OPT) -passes="scalarizer" $< -o $@

$(OBJ)/program_obf.ll: $(OBJ)/program_scalar.bc $(PASS_SO) | pass
	$(OPT) -load-pass-plugin=$(PASS_SO) -passes="vm-obfuscate" $< -o $@ -S

$(OBJ)/program_obf.s: $(OBJ)/program_obf.ll
	$(LLC) $< -o $@

vm: dirs pass runtime $(OBJ)/program_obf.s
	$(CC) $(OBJ)/program_obf.s $(RUNTIME_OBJ) -o $(TARGET) $(LDFLAGS)
	@echo "Built VM-obfuscated server: $(TARGET)"

# Native build (without obfuscation)
native: dirs
	$(CC) $(CFLAGS) $(SOURCES) -o $(TARGET) $(LDFLAGS)
	@echo "Built native server: $(TARGET)"

run: vm
	@$(TARGET)

clean:
	rm -rf $(OUT)
	@echo "Cleaned polyphonia build artifacts"
