CC      ?= cc
CFLAGS  ?= -std=c99 -Wall -Wextra -Wpedantic -O2 -g -D_POSIX_C_SOURCE=200809L
INCLUDE := -Iinclude -Isrc
LDLIBS  ?= -lm

SRCS    := src/vtree.c src/manager.c src/decomp.c src/apply.c \
           src/compile.c src/model_count.c src/wmc.c src/vtree_ops.c \
           src/rebuild.c src/minimize.c src/canonical.c
OBJS    := $(SRCS:.c=.o)
LIB     := libmvsdd.a

TOOLS   := tools/mvsdd-compile

TESTS   := tests/test_smoke tests/test_apply tests/test_minimize tests/test_wmc tests/test_gc
TEST_BINS := $(TESTS)

# Sanitizer build of every test, straight from the sources.
ASAN_CFLAGS := -std=c99 -g -O1 -fsanitize=address,undefined -fno-omit-frame-pointer \
               -D_POSIX_C_SOURCE=200809L

.PHONY: all test asan clean tools

all: $(LIB) tools

tools: $(TOOLS)

$(LIB): $(OBJS)
	ar rcs $@ $^

%.o: %.c include/mvsdd.h src/internal.h
	$(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@

tests/%: tests/%.c $(LIB)
	$(CC) $(CFLAGS) $(INCLUDE) $< $(LIB) $(LDLIBS) -o $@

tools/%: tools/%.c $(LIB)
	$(CC) $(CFLAGS) $(INCLUDE) $< $(LIB) $(LDLIBS) -o $@

test: $(TEST_BINS)
	@for t in $(TEST_BINS); do \
		echo "==> $$t"; \
		./$$t || exit 1; \
	done

asan:
	@for t in $(TESTS); do \
		$(CC) $(ASAN_CFLAGS) $(INCLUDE) $$t.c $(SRCS) $(LDLIBS) -o $$t-asan || exit 1; \
		echo "==> $$t (asan)"; \
		./$$t-asan || exit 1; \
	done

clean:
	rm -f $(OBJS) $(LIB) $(TEST_BINS) $(TOOLS) $(addsuffix -asan,$(TEST_BINS))
