Files
libvec/Makefile
T

130 lines
4.8 KiB
Makefile

# ==============================================================================
# Toolchain & Executables
# ==============================================================================
LLVM_DIR ?= /opt/homebrew/opt/llvm/bin
CC := $(LLVM_DIR)/clang
LLVM_PROFDATA := $(LLVM_DIR)/llvm-profdata
LLVM_COV := $(LLVM_DIR)/llvm-cov
CPPCHECK := cppcheck
# ==============================================================================
# Flags & Directories
# ==============================================================================
CFLAGS := -std=c23 -Wall -Wextra -Wpedantic -Wshadow \
-Wconversion -Wsign-conversion \
-g -O1 -fno-omit-frame-pointer
SAN_FLAGS := -fsanitize=address,undefined
INCLUDES := -Iinclude -Isrc/lib -Isrc/lib/char -Isrc/lib/utils
ASAN_ENV := ASAN_OPTIONS="allocator_may_return_null=1:detect_stack_use_after_return=1" \
UBSAN_OPTIONS="halt_on_error=1:print_stacktrace=1"
CPPCHECK_FLAGS := --enable=all \
--inconclusive \
--error-exitcode=1 \
--check-level=exhaustive \
--suppress=missingIncludeSystem \
--suppress=unmatchedSuppression \
--suppress=unusedFunction \
--suppress=staticFunction \
--inline-suppr \
$(INCLUDES)
# Sources & Build Directories
SRCS := src/lib/char/char.c src/lib/utils/utils.c
TEST_SRC := tests/test_learn.c
FUZZ_SRC := tests/fuzz_char.c
BIN_DIR := tests/bin
CACHE_DIR := tests/cache
TEST_BIN := $(BIN_DIR)/test_learn_runner
TSAN_BIN := $(BIN_DIR)/test_tsan_runner
FUZZ_BIN := $(BIN_DIR)/fuzz_char_runner
COV_BIN := $(BIN_DIR)/test_cov_runner
# ==============================================================================
# Targets & Workflow Rules
# ==============================================================================
.PHONY: all test sanitize check check-sources analyze cppcheck fuzz cov-build cov clean
all: test
$(BIN_DIR) $(CACHE_DIR):
@mkdir -p $@
# --- Compilation Targets ---
$(TEST_BIN): $(SRCS) $(TEST_SRC) | $(BIN_DIR)
$(CC) $(CFLAGS) $(SAN_FLAGS) $(INCLUDES) $^ -o $@
$(TSAN_BIN): $(SRCS) $(TEST_SRC) | $(BIN_DIR)
$(CC) $(CFLAGS) -fsanitize=thread $(INCLUDES) $^ -o $@
$(FUZZ_BIN): $(SRCS) $(FUZZ_SRC) | $(BIN_DIR)
$(CC) $(CFLAGS) -fsanitize=fuzzer,address,undefined $(INCLUDES) $^ -o $@
# --- Testing & Sanitizer Suites ---
test: $(TEST_BIN)
@echo "=== Running Unit Tests (ASan + UBSan) ==="
@$(ASAN_ENV) ./$(TEST_BIN)
sanitize: $(TEST_BIN) $(TSAN_BIN)
@echo "\n=== [1/2] Running Address + UndefinedBehavior Sanitizers ==="
@$(ASAN_ENV) ./$(TEST_BIN)
@echo "\n=== [2/2] Running ThreadSanitizer ==="
@./$(TSAN_BIN)
@echo "\n>>> Sanitizers passed with zero defects."
# Unified master check: runtime sanitizers, static analyzer, and cppcheck
check: sanitize analyze cppcheck
@echo "\n=============================================="
@echo " ALL TESTS, SANITIZERS & STATIC CHECKS PASSED "
@echo "=============================================="
fuzz: $(FUZZ_BIN)
@echo "=== Starting Fuzzer (Press Ctrl+C to stop) ==="
@$(ASAN_ENV) ./$(FUZZ_BIN) -max_total_time=60
# --- Coverage Profiling ---
cov-build: $(SRCS) $(TEST_SRC) | $(BIN_DIR)
$(CC) $(CFLAGS) $(SAN_FLAGS) -fprofile-instr-generate -fcoverage-mapping $(INCLUDES) $^ -o $(COV_BIN)
cov: cov-build | $(CACHE_DIR)
@echo "=== Recording Coverage Profile Data ==="
@$(ASAN_ENV) LLVM_PROFILE_FILE="$(CACHE_DIR)/test_char.profdata_raw" ./$(COV_BIN)
@$(LLVM_PROFDATA) merge -sparse $(CACHE_DIR)/test_char.profdata_raw -o $(CACHE_DIR)/test_char.profdata
@echo "\n=== Line & Branch Coverage Report: src/lib/char/char.c ==="
@$(LLVM_COV) report $(COV_BIN) -instr-profile=$(CACHE_DIR)/test_char.profdata src/lib/char/char.c
@$(LLVM_COV) show $(COV_BIN) -instr-profile=$(CACHE_DIR)/test_char.profdata src/lib/char/char.c --format=html > coverage.html
@echo "\nDetailed HTML report written to coverage.html."
# --- Static Analysis & Object Checking ---
check-sources: | $(BIN_DIR)
@echo "=== Compiling Sources to Object Files (ASan + UBSan) ==="
$(CC) $(CFLAGS) $(SAN_FLAGS) $(INCLUDES) -c src/lib/char/char.c -o $(BIN_DIR)/char.o
$(CC) $(CFLAGS) $(SAN_FLAGS) $(INCLUDES) -c src/lib/utils/utils.c -o $(BIN_DIR)/utils.o
@echo "Library sources compiled cleanly."
analyze:
@echo "=== Running Clang Static Analyzer ==="
@$(CC) $(CFLAGS) $(INCLUDES) \
--analyze \
-Xanalyzer -analyzer-output=text \
-Xanalyzer -analyzer-checker=core,unix,deadcode,security \
$(SRCS)
@echo "Clang Static Analyzer complete: zero defects."
cppcheck:
@echo "=== Running Cppcheck Static Analysis ==="
@$(CPPCHECK) $(CPPCHECK_FLAGS) include/ src/
@echo "Cppcheck passed with zero defects."
# --- Housekeeping ---
clean:
rm -rf $(BIN_DIR)/* $(CACHE_DIR)/* coverage.html