CC ?= cc
CFLAGS ?= -O2 -g -std=c11 -Wall -Wextra -Werror
CPPFLAGS += -Iinclude
BUILD := ../build/platform
CORE := core/core.c core/wire.c
HEADERS := $(wildcard include/*.h)
.PHONY: all test core-test linux-test clean freertos-test sanitize benchmark feature-test libraries public-test
all: $(BUILD)/core-vectors $(BUILD)/device-sim $(BUILD)/sdk-demo $(BUILD)/runtime-test
$(BUILD):
	mkdir -p $@
$(BUILD)/core-vectors: $(CORE) tests/core_vectors.c include/sdk.h include/sdk_core.h include/sdk_wire.h | $(BUILD)
	$(CC) $(CPPFLAGS) $(CFLAGS) $(CORE) tests/core_vectors.c -o $@
$(BUILD)/device-sim: core/wire.c backends/simulator.c include/sdk_wire.h | $(BUILD)
	$(CC) $(CPPFLAGS) $(CFLAGS) core/wire.c backends/simulator.c -o $@
$(BUILD)/sdk-demo: $(CORE) runtime/linux/runtime.c examples/demo.c $(HEADERS) | $(BUILD)
	$(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) -pthread -o $@
$(BUILD)/runtime-test: $(CORE) runtime/linux/runtime.c tests/runtime_test.c $(HEADERS) | $(BUILD)
	$(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) -pthread -o $@
core-test: $(BUILD)/core-vectors
	$(BUILD)/core-vectors
linux-test: all
	timeout 30 $(BUILD)/runtime-test $(abspath $(BUILD)/device-sim)
test: core-test linux-test
sanitize:
	$(MAKE) BUILD=../build/asan CFLAGS='-O1 -g -std=c11 -Wall -Wextra -Werror -fsanitize=address,undefined -fno-omit-frame-pointer' test
clean:
	rm -rf $(BUILD)

FREERTOS := ../third_party/FreeRTOS-Kernel
PORT := $(FREERTOS)/portable/ThirdParty/GCC/Posix
FREERTOS_SOURCES := $(FREERTOS)/tasks.c $(FREERTOS)/queue.c $(FREERTOS)/list.c $(FREERTOS)/timers.c $(FREERTOS)/event_groups.c $(FREERTOS)/stream_buffer.c $(FREERTOS)/portable/MemMang/heap_4.c $(PORT)/port.c $(PORT)/utils/wait_for_event.c
$(BUILD)/freertos-test: $(CORE) tests/core_vectors.c tests/freertos_test.c runtime/freertos/runtime.c runtime/freertos/FreeRTOSConfig.h $(HEADERS) $(FREERTOS_SOURCES) | $(BUILD)
	$(CC) $(CPPFLAGS) $(CFLAGS) -D_GNU_SOURCE -DCORE_VECTORS_LIBRARY -Iruntime/freertos -I$(FREERTOS)/include -I$(PORT) $(CORE) tests/core_vectors.c tests/freertos_test.c runtime/freertos/runtime.c $(FREERTOS_SOURCES) -pthread -o $@
freertos-test: $(BUILD)/freertos-test
	timeout 30 $(BUILD)/freertos-test

$(BUILD)/benchmark: $(CORE) runtime/linux/runtime.c examples/benchmark.c $(HEADERS) | $(BUILD)
	$(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) -pthread -o $@
benchmark: $(BUILD)/benchmark $(BUILD)/device-sim
	mkdir -p ../build/benchmark
	set -e; for limit in 4 16; do for round in 1 2 3 4 5; do timeout 40 $(BUILD)/benchmark $(abspath $(BUILD)/device-sim) $$limit $$round ../build/benchmark/limit-$$limit-round-$$round.csv; done; done

$(BUILD)/feature-test: $(CORE) runtime/linux/runtime.c tests/feature_test.c $(HEADERS) | $(BUILD)
	$(CC) $(CPPFLAGS) $(CFLAGS) -DSDK_ENABLE_DATA=0 $(filter %.c,$^) -pthread -o $@
feature-test: $(BUILD)/feature-test $(BUILD)/device-sim
	timeout 10 $(BUILD)/feature-test $(abspath $(BUILD)/device-sim)

$(BUILD)/core.o: core/core.c $(wildcard include/*.h) | $(BUILD)
	$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
$(BUILD)/wire.o: core/wire.c $(wildcard include/*.h) | $(BUILD)
	$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
$(BUILD)/linux.o: runtime/linux/runtime.c $(wildcard include/*.h) | $(BUILD)
	$(CC) $(CPPFLAGS) $(CFLAGS) -pthread -c $< -o $@
$(BUILD)/libplatformcore.a: $(BUILD)/core.o $(BUILD)/wire.o
	$(AR) rcs $@ $^
$(BUILD)/libplatformlinux.a: $(BUILD)/linux.o
	$(AR) rcs $@ $^
libraries: $(BUILD)/libplatformcore.a $(BUILD)/libplatformlinux.a

$(BUILD)/public-consumer: examples/public-consumer.c libraries
	$(CC) $(CPPFLAGS) $(CFLAGS) $< -L$(BUILD) -lplatformlinux -lplatformcore -pthread -o $@
public-test: $(BUILD)/public-consumer $(BUILD)/device-sim
	timeout 10 $(BUILD)/public-consumer $(abspath $(BUILD)/device-sim)
