# NOTE: only tested in GNU/Linux. ## Binary dependencies. CC = gcc AR = ar LEXER = re2c PARSER = lemon ## Paths. PREFIX = /usr/local bindir = $(PREFIX)/bin libdir = $(PREFIX)/lib includedir = $(PREFIX)/include/lsup_rdf CALLGRIND_DUMP = /tmp/lsup_callgrind.%p.out INCLUDE_BASE = . -Iinclude -Iext/xxHash -Iext/openldap/libraries/liblmdb \ -Iext/tpl/src -Iext/uthash/src -Iext/log/src INCLUDE = -I$(INCLUDE_BASE) CFLAGS += -Wall -fPIC -MMD -DLOG_USE_COLOR $(INCLUDE) TEST_CFLAGS = -Itest -O0 -g3 -DDEBUG # NOTE: -luuid is a Linux system library. Other OS's might need a different # link or a non-system library built. LDFLAGS = -Lext/openldap/libraries/liblmdb -Lext/xxHash \ -llmdb -lxxhash -luuid CODEC_DIR = src/codec #CODEC_SRC = $(wildcard src/codec/*_parser.c) CODEC_SRC = $(wildcard src/codec/*_grammar.c) \ $(wildcard src/codec/*_parser.c) CODEC_OBJ = $(CODEC_SRC:.c=.o) # External sources compiled in core object. EXT_SRC = $(wildcard ext/log/src/*.c) \ $(wildcard ext/tpl/src/*.c) # External headers of libraries compiled in core. EXT_H = $(wildcard ext/log/src/*.h) \ $(wildcard ext/tpl/src/*.h) \ $(wildcard ext/uthash/src/*.h) SRC = $(EXT_SRC) $(wildcard src/*.c) #CODEC_OBJ = $(wildcard src/codec/*.o) OBJ = $(SRC:.c=.o) $(CODEC_OBJ) TEST_SRC = $(wildcard test/*.c) test.c #TEST_OBJ = $(TEST_SRC:.c=.o) DEPLIBS = libxxhash liblmdb LIBS = liblsuprdf.a liblsuprdf.so # For visual dep graph. DEPS := $(shell echo "${INCLUDE_BASE}" | sed -e 's/ -I/,/g') DOCS = docs ## Rules. all: $(DEPLIBS) $(LIBS) liblsuprdf.a: $(OBJ) $(AR) rs $@ $^ liblsuprdf.so: $(OBJ) $(CC) -shared $(LDFLAGS) -o $@ $^ $(CODEC_OBJ): $(CODEC_SRC) %_parser.c: %_lexer.re %_grammar.c $(LEXER) $< -o $@ -T --case-ranges %_grammar.c: %_grammar.y $(PARSER) $< -q -m -T$(CODEC_DIR)/lempar.c -d$(CODEC_DIR) # Build all external dependencies in core object. core.o: core.c $(EXT_SRC) $(EXT_H) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ # Ext libraries compiled as shared objects. .PHONY: libxxhash libxxhash: $(MAKE) -C ext/xxHash .PHONY: liblmdb liblmdb: $(MAKE) -C ext/openldap/libraries/liblmdb install: all mkdir -p $(DESTDIR)$(libdir) mkdir -p $(DESTDIR)$(includedir) cp liblsuprdf.* $(DESTDIR)$(libdir) && \ cp include/*.h $(EXT_H) $(DESTDIR)$(includedir) .PHONY: clean clean: rm -rf src/*.[aod] ./*[aod] src/codec/*[aod] .PHONY: uninstall uninstall: rm -f $(DESTDIR)$(libdir)/liblsuprdf.* rm -rf $(DESTDIR)$(includedir) bin/test: $(OBJ) $(TEST_SRC) $(DEPLIBS) $(CC) \ $(CFLAGS) $(TEST_CFLAGS) $(SRC) $(CODEC_SRC) test.c -L. $(LDFLAGS) \ -o bin/test .PHONY: debug debug: bin/test exec gdb bin/test .PHONY: test test: bin/test exec bin/test lint: splint \ $(INCLUDE) -Itest \ -DUINT_MAX=0xFFFFFFFFUL \ -nullpass \ -posix-lib \ test.c .PHONY: memcheck memcheck: valgrind \ --leak-check=full --show-leak-kinds=all --track-origins=yes \ --log-file=/tmp/lsup_valgrind.log \ ./bin/test echo "Memcheck complete. Valgrind log is at /tmp/lsup_valgrind.log" memtest: test memcheck bin/profile: $(OBJ) $(DEPLIBS) $(CC) \ $(CFLAGS) -g -DTESTING $(SRC) $(CODEC_SRC) profile.c -L. $(LDFLAGS) \ -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 # Build a visual dependency graph. # Requires cinclude2dot (https://www.flourish.org/cinclude2dot) and Graphviz. depgraph: src/* include/* cinclude2dot --merge=module --include=$(DEPS) \ --exclude='test|ext' >| $(DOCS)/dev/deps.dot dot $(DOCS)/dev/deps.dot -Tpdf >| $(DOCS)/dev/deps.pdf