diff options
Diffstat (limited to 'Makefile')
| -rw-r--r-- | Makefile | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c7ff2ba --- /dev/null +++ b/Makefile @@ -0,0 +1,130 @@ +VERSION := 0.1.0 +SOVERSION := 0 + +CC ?= cc +AR ?= ar +CLANG_TIDY ?= clang-tidy +FORMAT ?= clang-format +PREFIX ?= /usr/local +LIBDIR ?= $(PREFIX)/lib +INCLUDEDIR ?= $(PREFIX)/include +BINDIR ?= $(PREFIX)/bin + +FEATURES := -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -D_DEFAULT_SOURCE +WARNINGS := -Wall -Wextra -Wpedantic -Wshadow -Wstrict-prototypes \ + -Wmissing-prototypes -Wold-style-definition -Wvla \ + -Wpointer-arith -Wcast-qual -Wredundant-decls + +SAN := -fsanitize=address,undefined -fno-omit-frame-pointer \ + -fno-sanitize-recover=all + +CPPFLAGS += -Iinclude -Isrc $(FEATURES) +CFLAGS ?= -O2 -g +CFLAGS += -std=c11 $(WARNINGS) $(EXTRA_CFLAGS) +LDFLAGS += $(EXTRA_LDFLAGS) +LDLIBS += -lcurl -lm + +BUILD := build +LIB_SRC := src/client.c src/model.c src/util.c src/json.c src/csv.c +LIB_OBJ := $(LIB_SRC:%.c=$(BUILD)/%.o) +PIC_OBJ := $(LIB_SRC:%.c=$(BUILD)/%.pic.o) +TEST_SRC := tests/test_cepis.c tests/test_server.c +TEST_OBJ := $(TEST_SRC:%.c=$(BUILD)/%.o) +ALL_SRC := $(LIB_SRC) src/cli.c $(TEST_SRC) +ALL_HDR := include/cepis.h src/internal.h src/json.h src/csv.h \ + tests/test_server.h + +STATIC := $(BUILD)/libcepis.a +SHARED := $(BUILD)/libcepis.so.$(VERSION) +CLI := $(BUILD)/cepis +TESTS := $(BUILD)/test_cepis + +.DEFAULT_GOAL := help +.PHONY: help build test lint format check clean memcheck sanitize install \ + uninstall + +help: + @echo 'Targets:' + @echo ' build static and shared libraries, plus the cepis CLI' + @echo ' test build and run the suite against a local HTTP server' + @echo ' lint clang-format --dry-run + clang-tidy (read-only)' + @echo ' format apply clang-format (writes)' + @echo ' check lint, then test, then build' + @echo ' memcheck run the suite under valgrind' + @echo ' sanitize rebuild and run the suite under ASan + UBSan' + @echo ' install install headers, libraries and the CLI under PREFIX' + @echo ' clean remove $(BUILD)/' + @echo + @echo 'Override the compiler with e.g. make test CC=clang' + +build: $(STATIC) $(SHARED) $(CLI) + +$(BUILD)/%.o: %.c + @mkdir -p $(dir $@) + $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ + +$(BUILD)/%.pic.o: %.c + @mkdir -p $(dir $@) + $(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -c $< -o $@ + +$(STATIC): $(LIB_OBJ) + @mkdir -p $(dir $@) + $(AR) rcs $@ $(LIB_OBJ) + +$(SHARED): $(PIC_OBJ) + @mkdir -p $(dir $@) + $(CC) -shared -Wl,-soname,libcepis.so.$(SOVERSION) $(PIC_OBJ) \ + $(LDFLAGS) $(LDLIBS) -o $@ + ln -sf libcepis.so.$(VERSION) $(BUILD)/libcepis.so.$(SOVERSION) + ln -sf libcepis.so.$(VERSION) $(BUILD)/libcepis.so + +$(CLI): $(BUILD)/src/cli.o $(STATIC) + $(CC) $(BUILD)/src/cli.o $(STATIC) $(LDFLAGS) $(LDLIBS) -o $@ + +$(TESTS): $(TEST_OBJ) $(STATIC) + $(CC) $(TEST_OBJ) $(STATIC) $(LDFLAGS) $(LDLIBS) -lpthread -o $@ + +test: $(TESTS) + $(TESTS) + +# Read-only by design, so it is safe in CI and in a pre-commit hook: it reports +# what `make format` would change without changing anything. +lint: + $(FORMAT) --dry-run --Werror $(ALL_SRC) $(ALL_HDR) + $(CLANG_TIDY) --quiet $(ALL_SRC) -- $(CPPFLAGS) -std=c11 + +format: + $(FORMAT) -i $(ALL_SRC) $(ALL_HDR) + +# The order matters: lint is the fastest to fail, build the slowest, so a +# broken run reports the cheapest problem first. +check: lint test build + +memcheck: $(TESTS) + valgrind --error-exitcode=9 --leak-check=full --show-leak-kinds=definite,indirect \ + --errors-for-leak-kinds=definite,indirect --track-origins=yes $(TESTS) + +# Rebuilt from scratch: the sanitizers change the ABI of the objects, so they +# must not be mixed with objects from an ordinary build. +sanitize: + $(MAKE) clean + $(MAKE) test EXTRA_CFLAGS='$(SAN)' EXTRA_LDFLAGS='$(SAN)' + $(MAKE) clean + +install: build + install -d $(DESTDIR)$(INCLUDEDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(BINDIR) + install -m 644 include/cepis.h $(DESTDIR)$(INCLUDEDIR)/ + install -m 644 $(STATIC) $(DESTDIR)$(LIBDIR)/ + install -m 755 $(SHARED) $(DESTDIR)$(LIBDIR)/ + ln -sf libcepis.so.$(VERSION) $(DESTDIR)$(LIBDIR)/libcepis.so.$(SOVERSION) + ln -sf libcepis.so.$(VERSION) $(DESTDIR)$(LIBDIR)/libcepis.so + install -m 755 $(CLI) $(DESTDIR)$(BINDIR)/ + +uninstall: + rm -f $(DESTDIR)$(INCLUDEDIR)/cepis.h + rm -f $(DESTDIR)$(LIBDIR)/libcepis.a + rm -f $(DESTDIR)$(LIBDIR)/libcepis.so* + rm -f $(DESTDIR)$(BINDIR)/cepis + +clean: + rm -rf $(BUILD) |