# NOTE: only tested in GNU/Linux. ## Binary dependencies. CC = gcc AR = ar VALGRIND_DUMP = /tmp/lsr_valgrind.log ## Paths. PREFIX ?= /usr/local bindir = $(PREFIX)/bin libdir = $(PREFIX)/lib includedir = $(PREFIX)/include/lsup outdir = bin INCLUDE = -I. -Iinclude -I$(includedir) # Link all ext libraries statically. CFLAGS += -std=gnu11 -Wall -fPIC -MMD $(INCLUDE) DBG_CFLAGS = -Itest -O0 -g3 -DDEBUG LDFLAGS = -L. -L$(outdir) -L$(libdir) -llsuprdf DBG_LDFLAGS = -L. -L$(outdir) -L$(libdir) -llsuprdf_dbg SRC = $(wildcard src/*.c) OBJ = $(SRC:.c=.o) DBG_OBJ = $(SRC:.c=_dbg.o) TEST_SRC = $(wildcard test/*.c) test.c STATIC_LIB = $(outdir)/liblsuprepo.a DYN_LIB = $(outdir)/liblsuprepo.so STATIC_DBG_LIB = $(outdir)/liblsuprepo_dbg.a DYN_DBG_LIB = $(outdir)/liblsuprepo_dbg.so LIBS = $(STATIC_LIB) $(DYN_LIB) DBG_LIBS = $(STATIC_DBG_LIB) $(DYN_DBG_LIB) ## Environment. export LD_LIBRARY_PATH = $(outdir):$(libdir) ## Rules. .DEFAULT_GOAL := lib # Extract all rule comment into a help message. .PHONY: help help: @echo "Command overview:"; echo; \ grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) \ | sed -n 's/^\(.*\): \(.*\)##\(.*\)/\1::\3/p' \ | column -t -s '::' lib: $(LIBS) debug: $(DBG_LIBS) $(STATIC_LIB): $(OBJ) $(AR) rs $@ $^ $(DYN_LIB): $(OBJ) $(CC) -shared $(LDFLAGS) -o $@ $^ $(STATIC_DBG_LIB): $(DBG_OBJ) $(AR) rs $@ $^ $(DYN_DBG_LIB): $(DBG_OBJ) $(CC) -shared $(LDFLAGS) -o $@ $^ # Debug objects. %_dbg.o: %.c $(CC) $(CFLAGS) $(DBG_CFLAGS) $(DBG_LDFLAGS) -c $^ -o $@ install: lib ## Install default libraries to $PREFIX. May require sudo. mkdir -p $(DESTDIR)$(libdir) mkdir -p $(DESTDIR)$(includedir) cp $(LIBS) $(DESTDIR)$(libdir) && \ cp include/*.h $(EXT_H) $(DESTDIR)$(includedir) debug_install: install debug ## Install default and debug libraries. cp $(DBG_LIBS) $(DESTDIR)$(libdir) .PHONY: clean clean: rm -rf ./*.[aod] src/*.[aod] rm -f $(LIBS) bin/test* .PHONY: uninstall uninstall: rm -f $(DESTDIR)$(libdir)/liblsuprepo.* rm -rf $(DESTDIR)$(includedir) # For testing, use debug symbols. bin/test: debug $(TEST_SRC) $(CC) $(CFLAGS) $(DBG_CFLAGS) -Itest $(DBG_LDFLAGS) -llsuprepo_dbg \ test.c -o bin/test .PHONY: test test: bin/test ## Run a test suite. exec bin/test .PHONY: gdb_test gdb_test: bin/test ## Run a test suite within gdb. exec gdb bin/test .PHONY: memcheck memcheck: valgrind \ --leak-check=full --show-leak-kinds=all --track-origins=yes \ --log-file=$(VALGRIND_DUMP) \ ./bin/test @echo "Memcheck complete. Valgrind log is at $(VALGRIND_DUMP)" memtest: bin/test memcheck ## Run a test suite using Valgrind. Output to separate file. bin/profile: debug profile.c $(CC) $(CFLAGS) -g -DTESTING profile.c $(DBG_LDFLAGS) \ -llsuprepo_dbg -o bin/profile .PHONY: profile profile: bin/profile exec valgrind --tool=callgrind --callgrind-out-file="$(CALLGRIND_DUMP)" \ bin/profile 10000 @echo "Profile dump written at $(CALLGRIND_DUMP)" .PHONY: pytest py_test: pip3 install --user . python3 test/cpython_test.py