# https://spin.atomicobject.com/2016/08/26/makefile-c-projects/ was a great # base for this Makefile -include config.mk export CFLAGS export LDFLAGS BIN := $(BUILD_DIR)/$(BIN_FILENAME) SRCS != find '$(SRC_DIR)' -iname '*.c' SRCS_TEST != find '$(TEST_DIR)' -iname '*.c' SRCS_H != find include -iname '*.h' SRCS_H_INTERNAL != find $(SRC_DIR) -iname '*.h' OBJS := $(SRCS:%=$(BUILD_DIR)/%.o) OBJS_TEST := $(SRCS_TEST:%=$(BUILD_DIR)/%.o) DEPS := $(SRCS:%=$(BUILD_DIR)/%.d) $(SRCS_TEST:%=$(BUILD_DIR)/%.d) BINS_TEST := $(OBJS_TEST:%.c.o=%) TARGETS_TEST := $(BINS_TEST:%=test-%) TARGETS_MEM_TEST := $(BINS_TEST:%=test-mem-%) _CFLAGS := $(addprefix -I,$(INC_DIRS)) $(CFLAGS) -Wall -Wextra -DLANDER_VERSION=\"$(VERSION)\" _LDFLAGS := $(addprefix -L,$(LIB_DIRS)) $(addprefix -l,$(LIBS)) $(LDFLAGS) .PHONY: all all: $(BIN) # =====COMPILATION===== # Utility used by the CI to lint .PHONY: objs objs: $(OBJS) .PHONY: liblsm liblsm: $(MAKE) -C lsm .PHONY: liblnm liblnm: $(MAKE) -C lnm .PHONY: libltm libltm: $(MAKE) -C ltm $(BIN): liblsm liblnm libltm $(OBJS) $(CC) -o $@ $(OBJS) $(_LDFLAGS) $(BUILD_DIR)/$(SRC_DIR)/%.c.o: $(SRC_DIR)/%.c mkdir -p $(dir $@) $(CC) $(_CFLAGS) -c $< -o $@ .PHONY: bin-docker bin-docker: docker build -t lander . docker container create --name lander-temp lander docker cp -q lander-temp:/bin/lander $(BUILD_DIR)/lander-docker docker container rm lander-temp # =====TESTING===== .PHONY: run run: $(BIN) LANDER_API_KEY=test \ LANDER_DATA_DIR=data \ '$(BUILD_DIR)/$(BIN_FILENAME)' .PHONY: valgrind valgrind: $(BIN) LANDER_API_KEY=test \ LANDER_DATA_DIR=data \ valgrind --track-origins=yes --leak-check=full '$(BUILD_DIR)/$(BIN_FILENAME)' .PHONY: test test: $(TARGETS_TEST) .PHONY: test-mem test-mem: $(TARGETS_MEM_TEST) .PHONY: $(TARGETS_TEST) $(TARGETS_TEST): test-%: % ./$^ .PHONY: $(TARGETS_MEM_TEST) $(TARGETS_MEM_TEST): test-mem-%: % valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes --leak-check=full ./$^ .PHONY: build-test build-test: $(BINS_TEST) $(BINS_TEST): %: %.c.o $(CC) \ $^ -o $@ # Along with the include directory, each test includes $(TEST_DIR) (which # contains the acutest.h header file), and the src directory of the module it's # testing. This allows tests to access internal methods, which aren't publicly # exposed. $(BUILD_DIR)/$(TEST_DIR)/%.c.o: $(TEST_DIR)/%.c mkdir -p $(dir $@) $(CC) $(_CFLAGS) -I$(TEST_DIR) \ -I$(dir $(@:$(BUILD_DIR)/$(TEST_DIR)/%=$(SRC_DIR)/%)) \ -c $< -o $@ # =====MAINTENANCE===== .PHONY: lint lint: clang-format -n --Werror $(SRCS) $(SRCS_H) $(SRCS_H_INTERNAL) make -C lsm lint make -C landerctl lint .PHONY: fmt fmt: clang-format -i $(SRCS) $(SRCS_H) $(SRCS_H_INTERNAL) make -C lsm fmt make -C landerctl fmt .PHONY: check check: mkdir -p $(BUILD_DIR)/cppcheck cppcheck \ $(addprefix -I,$(INC_DIRS)) \ --cppcheck-build-dir=$(BUILD_DIR)/cppcheck \ --error-exitcode=1 \ --enable=warning,style \ --inline-suppr \ --check-level=exhaustive \ --quiet \ -j$(shell nproc) \ $(SRCS) make -C lsm check make -C landerctl check .PHONY: clean clean: rm -rf $(BUILD_DIR) $(MAKE) -C lsm clean $(MAKE) -C lnm clean $(MAKE) -C landerctl clean .PHONY: bear bear: clean bear -- make bear --append -- make build-test # Make make aware of the .d files -include $(DEPS)