CC := clang
AR := ar

CFLAGS_BASE := -std=c11 -D_POSIX_C_SOURCE=200809L -Wall -Wextra -Wpedantic -Werror -O2 -g
CFLAGS := $(CFLAGS_BASE)
LDFLAGS :=

ifeq ($(SANITIZE),1)
CFLAGS += -fsanitize=address,undefined -fno-omit-frame-pointer
LDFLAGS += -fsanitize=address,undefined
endif

INCLUDES := -Icommon
COMMON_OBJS := common/wire.o common/message.o common/framing.o common/socket_utils.o
COMMON_LIB := common/libcommon.a

ALL_BINS := client/client db/db server_sync/server server_threaded/server server_select/server server_event/server

.PHONY: all clean demo

all: $(ALL_BINS)

$(COMMON_LIB): $(COMMON_OBJS)
	$(AR) rcs $@ $^

common/%.o: common/%.c
	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

client/client: client/client.o $(COMMON_LIB)
	$(CC) $(CFLAGS) $< $(COMMON_LIB) $(LDFLAGS) -o $@

client/client.o: client/client.c
	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

db/db: db/db.o $(COMMON_LIB)
	$(CC) $(CFLAGS) $< $(COMMON_LIB) $(LDFLAGS) -o $@

db/db.o: db/db.c
	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

server_sync/server: server_sync/server.o $(COMMON_LIB)
	$(CC) $(CFLAGS) $< $(COMMON_LIB) $(LDFLAGS) -o $@

server_sync/server.o: server_sync/server.c
	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

server_threaded/server: server_threaded/server.o $(COMMON_LIB)
	$(CC) $(CFLAGS) $< $(COMMON_LIB) $(LDFLAGS) -pthread -o $@

server_threaded/server.o: server_threaded/server.c
	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

server_select/server: server_select/server.o $(COMMON_LIB)
	$(CC) $(CFLAGS) $< $(COMMON_LIB) $(LDFLAGS) -o $@

server_select/server.o: server_select/server.c
	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

server_event/server: server_event/server.o $(COMMON_LIB)
	$(CC) $(CFLAGS) $< $(COMMON_LIB) $(LDFLAGS) -o $@

server_event/server.o: server_event/server.c
	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

clean:
	rm -f common/*.o client/*.o db/*.o server_sync/*.o server_threaded/*.o server_select/*.o server_event/*.o
	rm -f $(COMMON_LIB) $(ALL_BINS)

demo: all
	./scripts/demo_servers.sh
