CC = gcc
CFLAGS = -O2 -Wall -Wextra -Werror -fPIC -march=native -I include
LDFLAGS = -lnuma -lpthread

SRCDIR = src
INCDIR = include
OBJDIR = obj

SRCS = $(wildcard $(SRCDIR)/*.c)
OBJS = $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SRCS))
LIB_OBJS = $(filter-out $(OBJDIR)/main.o,$(OBJS))

TARGET = icepick
LIBRARY = libicepick.a
SHARED = libicepick.so

PREFIX ?= /usr/local
BINDIR = $(PREFIX)/bin
LIBDIR = $(PREFIX)/lib
INCLUDEDIR = $(PREFIX)/include

.PHONY: all clean install uninstall

all: $(TARGET) $(LIBRARY) $(SHARED)

$(OBJDIR):
	mkdir -p $(OBJDIR)

$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR)
	$(CC) $(CFLAGS) -c $< -o $@

$(LIBRARY): $(LIB_OBJS)
	ar rcs $@ $^

$(SHARED): $(LIB_OBJS)
	$(CC) -shared -o $@ $^ $(LDFLAGS)

$(TARGET): $(OBJDIR)/main.o $(LIBRARY)
	$(CC) $(CFLAGS) $< -L. -licepick $(LDFLAGS) -o $@

install: $(TARGET) $(LIBRARY) $(SHARED)
	install -d $(BINDIR) $(LIBDIR) $(INCLUDEDIR)
	install -m 755 $(TARGET) $(BINDIR)/
	install -m 644 $(LIBRARY) $(LIBDIR)/
	install -m 755 $(SHARED) $(LIBDIR)/
	install -m 644 $(INCDIR)/icepick.h $(INCLUDEDIR)/

uninstall:
	rm -f $(BINDIR)/$(TARGET)
	rm -f $(LIBDIR)/$(LIBRARY)
	rm -f $(LIBDIR)/$(SHARED)
	rm -f $(INCLUDEDIR)/icepick.h

clean:
	rm -rf $(OBJDIR) $(TARGET) $(LIBRARY) $(SHARED)

$(OBJDIR)/msr.o: $(SRCDIR)/msr.c $(SRCDIR)/internal.h $(INCDIR)/icepick.h
$(OBJDIR)/topology.o: $(SRCDIR)/topology.c $(SRCDIR)/internal.h $(INCDIR)/icepick.h
$(OBJDIR)/clos.o: $(SRCDIR)/clos.c $(SRCDIR)/internal.h $(INCDIR)/icepick.h
$(OBJDIR)/region.o: $(SRCDIR)/region.c $(SRCDIR)/internal.h $(INCDIR)/icepick.h
$(OBJDIR)/lock.o: $(SRCDIR)/lock.c $(SRCDIR)/internal.h $(INCDIR)/icepick.h
$(OBJDIR)/verify.o: $(SRCDIR)/verify.c $(SRCDIR)/internal.h $(INCDIR)/icepick.h
$(OBJDIR)/bench.o: $(SRCDIR)/bench.c $(SRCDIR)/internal.h $(INCDIR)/icepick.h
$(OBJDIR)/monitor.o: $(SRCDIR)/monitor.c $(SRCDIR)/internal.h $(INCDIR)/icepick.h
$(OBJDIR)/main.o: $(SRCDIR)/main.c $(SRCDIR)/internal.h $(INCDIR)/icepick.h
