CXX := g++ CXXFLAGS := -std=c++20 -Wall -Wextra -Wpedantic -O2 CPPFLAGS := LDFLAGS := SRC_DIR := src INC_DIR := include BUILD_DIR := build TARGET := app CLANG_FORMAT ?= clang-format CLANG_TIDY ?= clang-tidy SRCS := $(shell find $(SRC_DIR) -name '*.cpp' 2>/dev/null) OBJS := $(patsubst $(SRC_DIR)/%.cpp,$(BUILD_DIR)/%.o,$(SRCS)) SRC_HDRS := $(shell find $(SRC_DIR) \( -name '*.hpp' -o -name '*.h' \) 2>/dev/null) INCLUDE_HDRS := $(shell [ -d $(INC_DIR) ] && find $(INC_DIR) \( -name '*.hpp' -o -name '*.h' \) 2>/dev/null) FORMAT_SRCS := $(SRCS) $(SRC_HDRS) $(INCLUDE_HDRS) CPPFLAGS += -I$(INC_DIR) $(TARGET): $(OBJS) $(CXX) $(OBJS) $(LDFLAGS) -o $@ $(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp @mkdir -p $(dir $@) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ $(BUILD_DIR): mkdir -p $(BUILD_DIR) .PHONY: clean run format tidy tools install run: $(TARGET) ./$(TARGET) clean: rm -rf $(BUILD_DIR) $(TARGET) format: @command -v $(CLANG_FORMAT) >/dev/null 2>&1 || { \ echo "error: $(CLANG_FORMAT) not found in PATH" >&2; \ exit 1; \ } @if [ -n "$(strip $(FORMAT_SRCS))" ]; then \ $(CLANG_FORMAT) -i $(FORMAT_SRCS); \ echo "formatted: $(FORMAT_SRCS)"; \ else \ echo "warning: no source files found to format"; \ fi tidy: @command -v $(CLANG_TIDY) >/dev/null 2>&1 || { \ echo "error: $(CLANG_TIDY) not found in PATH" >&2; \ exit 1; \ } @if [ -n "$(strip $(SRCS))" ]; then \ for src in $(SRCS); do \ echo "running clang-tidy on $$src"; \ $(CLANG_TIDY) $$src -- $(CPPFLAGS) $(CXXFLAGS); \ done; \ else \ echo "warning: no source files found for clang-tidy"; \ fi tools: @command -v $(CLANG_FORMAT) >/dev/null 2>&1 && echo "found $(CLANG_FORMAT)" || echo "missing $(CLANG_FORMAT)" @command -v $(CLANG_TIDY) >/dev/null 2>&1 && echo "found $(CLANG_TIDY)" || echo "missing $(CLANG_TIDY)" install: @missing=""; \ if ! command -v $(CLANG_FORMAT) >/dev/null 2>&1; then \ missing="$$missing clang-format"; \ fi; \ if ! command -v $(CLANG_TIDY) >/dev/null 2>&1; then \ missing="$$missing clang-tidy"; \ fi; \ if [ -z "$$missing" ]; then \ echo "clang-format and clang-tidy already installed"; \ else \ echo "missing tools:$$missing"; \ if command -v apt-get >/dev/null 2>&1; then \ if command -v sudo >/dev/null 2>&1; then SUDO=sudo; else SUDO=; fi; \ $$SUDO apt-get update; \ $$SUDO apt-get install -y $$missing; \ else \ echo "error: apt-get not available; install manually:$$missing" >&2; \ exit 1; \ fi; \ fi