-include Makefile.local
CFLAGS = -std=c99 -Wall -Wextra -pedantic -O3 -D_POSIX_C_SOURCE=199309L -D_GNU_SOURCE -march=native
# warnings
# CFLAGS += -Wno-unused-function
# LTO
CFLAGS += -flto
LDFLAGS += $(CFLAGS)
# asserts, etc.
CFLAGS += -DNDEBUG
# libs
LDLIBS = -lm -lrt
# OpenMP
CFLAGS += -fopenmp
LDFLAGS += -fopenmp
# debug symbols
CFLAGS += -ggdb
LDFLAGS += -ggdb
# pthreads due to debugging
CFLAGS += -pthread
LDLIBS += -lpthread
LDFLAGS += -pthread
# profiling
# CFLAGS += -pg
# LDFLAGS += -pg
# gcov
# CFLAGS += -fprofile-arcs -ftest-coverage
# LDFLAGS += -fprofile-arcs
# binaries
BIN = bin/allocated-demo
EXECUTABLES = \
	bin/allocated-random \
	bin/allocated-demo \
	bin/allocated-images \
	bin/allocated-plot \
	bin/allocated-annotate \
	bin/streaming-demo \
	bin/streaming-images \
	bin/streaming-plot
# other variables
DATE = $(shell date -I)
# backtrace
LDFLAGS += -rdynamic
# 32-bit build
# CFLAGS += -m32
# LDFLAGS += -m32
OBJ = imageptr.o vec2.o range2.o codeblock.o transform.o core8x8.o system.o plot.o threads.o
# due to the files in ./bin directory
CFLAGS += -I.
LDFLAGS += -L.
# PIC
CFLAGS += -fPIC
# library
MAJOR = 0
MINOR = 0.0
LIBNAME = libsl
STATIC = $(LIBNAME).a
SHARED = $(LIBNAME).so
SONAME = $(SHARED).$(MAJOR)
RANLIB ?= ranlib

.PHONY: all
all: binary static shared

$(EXECUTABLES): %: %.o $(OBJ)

Makefile.uptodate: Makefile Makefile.local
	$(MAKE) distclean
	touch $@

Makefile.local:
	touch $@

.PHONY: binary
binary: Makefile.uptodate $(EXECUTABLES)

.PHONY: static
static: Makefile.uptodate $(STATIC)

$(STATIC): $(OBJ)
	$(AR) ru $@ $^
	$(RANLIB) $@

.PHONY: shared
shared: Makefile.uptodate $(SHARED)

# gcc        => libsl.so.0.0.0 (soname libsl.so.0)
# libsl.so.0 -> libsl.so.0.0.0
# libsl.so   -> libsl.so.0.0.0
$(SHARED): $(OBJ)
	$(CC) -shared -Wl,-soname,$(SONAME) $(CFLAGS) -o $@.$(MAJOR).$(MINOR) $^ $(LDFLAGS) $(LDLIBS)
	-ln -f -s $@.$(MAJOR).$(MINOR) $(SONAME)
	-ln -f -s $@.$(MAJOR).$(MINOR) $@

core8x8.o: core8x8.c core8x8.h core8x8fpu.c core8x8sse.c core8x8avx.c

.PHONY: distclean
distclean: clean
	$(RM) -- ./{,codeblocks/}*.pgm *.zip *.gcno *.gcda *.gcov
	$(RM) -r -- doc

.PHONY: clean
clean:
	$(RM) -- *.o bin/*.o $(EXECUTABLES) $(STATIC) $(SHARED) $(SHARED).$(MAJOR) $(SHARED).$(MAJOR).$(MINOR) gmon.out

.PHONY: dist
dist: distclean
	zip -r9 dwt-$(DATE).zip Makefile *.{h,c} *.supp ./codeblocks

.PHONY: memcheck
memcheck: binary
	valgrind --tool=memcheck --leak-check=full --show-reachable=yes --read-var-info=yes --suppressions=openmp.supp ./$(BIN)

.PHONY: valgrind
valgrind: memcheck

.PHONY: helgrind
helgrind: binary
	valgrind --tool=helgrind --read-var-info=yes --suppressions=openmp.supp ./$(BIN)

.PHONY: run
run: binary
	./$(BIN)

.PHONY: date
date:
	@echo $(DATE)

.PHONY: time
time: binary
	\time -v ./$(BIN)

.PHONY: perf
perf: binary
	perf stat -e dTLB-load-misses ./$(BIN)

.PHONY: doc
doc:
	doxygen
