# Development tasks. Plain g++/clang++ rules, no generator step: the library is # five translation units and one external dependency. # # make list the targets # make test build and run the suite # make lint clang-format --dry-run + clang-tidy, no files touched # make build libcepis.a and the example CLI into build/ # # Override the compiler or the standard with e.g. `make CXX=clang++ STD=c++20`. CXX ?= g++ AR ?= ar STD ?= c++17 BUILD_DIR ?= build CURL_CFLAGS := $(shell pkg-config --cflags libcurl 2>/dev/null) CURL_LIBS := $(shell pkg-config --libs libcurl 2>/dev/null || echo -lcurl) WARNINGS := -Wall -Wextra CXXFLAGS ?= -O2 -g ALL_CXXFLAGS := -std=$(STD) $(WARNINGS) $(CXXFLAGS) -Iinclude -Isrc $(CURL_CFLAGS) LDLIBS := $(CURL_LIBS) -lpthread LIB_SOURCES := src/client.cpp src/csv.cpp src/http.cpp src/json.cpp src/models.cpp TEST_SOURCES := tests/test_cepis.cpp tests/test_main.cpp tests/test_server.cpp EXAMPLE_SOURCES := examples/cepis_lookup.cpp LIB_OBJECTS := $(LIB_SOURCES:%.cpp=$(BUILD_DIR)/%.o) TEST_OBJECTS := $(TEST_SOURCES:%.cpp=$(BUILD_DIR)/%.o) EXAMPLE_OBJECTS := $(EXAMPLE_SOURCES:%.cpp=$(BUILD_DIR)/%.o) LIBRARY := $(BUILD_DIR)/libcepis.a TEST_BINARY := $(BUILD_DIR)/cepis-tests EXAMPLE_BINARY := $(BUILD_DIR)/cepis-lookup SOURCES := $(LIB_SOURCES) $(TEST_SOURCES) $(EXAMPLE_SOURCES) HEADERS := $(wildcard include/cepis/*.hpp) $(wildcard src/*.hpp) $(wildcard tests/*.hpp) .DEFAULT_GOAL := help .PHONY: help test lint format build check clean help: @echo 'Targets:' @echo ' test build and run the test suite' @echo ' lint clang-format --dry-run + clang-tidy (read-only)' @echo ' format apply clang-format (writes)' @echo ' build libcepis.a and the example CLI into $(BUILD_DIR)/' @echo ' check lint + test + build, in that order' @echo ' clean remove $(BUILD_DIR)/' @echo @echo 'Override the compiler or standard with e.g. make test CXX=clang++ STD=c++20' $(BUILD_DIR)/%.o: %.cpp $(HEADERS) @mkdir -p $(dir $@) $(CXX) $(ALL_CXXFLAGS) -c $< -o $@ $(LIBRARY): $(LIB_OBJECTS) @mkdir -p $(dir $@) $(AR) rcs $@ $^ $(TEST_BINARY): $(TEST_OBJECTS) $(LIBRARY) $(CXX) $(ALL_CXXFLAGS) $(TEST_OBJECTS) $(LIBRARY) $(LDLIBS) -o $@ $(EXAMPLE_BINARY): $(EXAMPLE_OBJECTS) $(LIBRARY) $(CXX) $(ALL_CXXFLAGS) $(EXAMPLE_OBJECTS) $(LIBRARY) $(LDLIBS) -o $@ build: $(LIBRARY) $(EXAMPLE_BINARY) test: $(TEST_BINARY) $(TEST_BINARY) # 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: clang-format --dry-run --Werror $(SOURCES) $(HEADERS) clang-tidy --quiet $(SOURCES) -- $(ALL_CXXFLAGS) format: clang-format -i $(SOURCES) $(HEADERS) # 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 clean: rm -rf $(BUILD_DIR)