Created
April 19, 2025 22:37
-
-
Save wonbyte/eef605c5cd23b4042e96c204a27f60c3 to your computer and use it in GitHub Desktop.
C Makefile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Debugging and tracing flags | |
TRACEFLAGS := -g -fno-omit-frame-pointer -funwind-tables | |
# Compiler and basic settings | |
CC := clang | |
VERSION := 1.0.0 | |
DEVFLAGS := -Wall -Wextra -Wunused-parameter | |
INCLUDES := -I include | |
CFLAGS := $(DEVFLAGS) $(TRACEFLAGS) $(INCLUDES) | |
# Directories | |
SRC_DIR := src | |
HDR_DIR := include | |
OBJDIR := build | |
BINDIR := bin | |
# Targets | |
TARGET := $(BINDIR)/nugget | |
RELEASE_TARGET := $(BINDIR)/nugget-release | |
ASAN_TARGET := $(BINDIR)/nugget-asan | |
# Optimization flags for release builds | |
RELEASE_FLAGS := -O3 -DNDEBUG | |
# AddressSanitizer flags | |
ASAN_FLAGS := -fsanitize=address,leak $(TRACEFLAGS) | |
# Sources, objects, dependencies | |
SRCS := $(wildcard $(SRC_DIR)/*.c) | |
HDRS := $(wildcard $(HDR_DIR)/*.h) | |
OBJS := $(SRCS:$(SRC_DIR)/%.c=$(OBJDIR)/%.o) | |
DEPS := $(OBJS:.o=.d) | |
# Clang-tidy | |
CLANG_TIDY := clang-tidy | |
# Colors | |
COLOR_RESET := \033[0m | |
COLOR_GREEN := \033[32m | |
COLOR_YELLOW := \033[33m | |
# Core build and run | |
.PHONY: all run clean pristine | |
all: compile_commands $(TARGET) | |
run: $(TARGET) | |
@./$(TARGET) | |
clean: | |
@rm -rf $(OBJDIR) $(BINDIR) compile_commands.json \ | |
$(HDR_DIR)/version.h .cache | |
pristine: clean | |
@echo "$(COLOR_YELLOW)[Running pristine clean]$(COLOR_RESET)" | |
@find . -name '.DS_Store' -delete | |
@find . -name '*~' -delete | |
@find . -name '*.swp' -delete | |
@if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then \ | |
echo "$(COLOR_YELLOW)[Git clean]$(COLOR_RESET)"; \ | |
git clean -xfd; \ | |
else \ | |
echo "$(COLOR_YELLOW)[Not a git repo, skipping git clean]$(COLOR_RESET)"; \ | |
fi | |
# Build final normal binary | |
$(TARGET): $(OBJS) | $(BINDIR) | |
@echo "$(COLOR_YELLOW)[Linking]$(COLOR_RESET) $@" | |
@$(CC) $(CFLAGS) $^ -o $@ | |
# Build object files (depends on version_header and build/) | |
$(OBJDIR)/%.o: $(SRC_DIR)/%.c version_header | $(OBJDIR) | |
@echo "$(COLOR_GREEN)[Compiling]$(COLOR_RESET) $<" | |
@$(CC) $(CFLAGS) -MMD -c $< -o $@ | |
# Create build and bin folders if needed | |
$(OBJDIR) $(BINDIR): | |
@mkdir -p $@ | |
# Development tools | |
.PHONY: format tidy compile_commands | |
format: | |
@clang-format -i $(SRCS) $(HDRS) | |
tidy: | |
@$(CLANG_TIDY) $(SRCS) $(HDRS) \ | |
--header-filter='^src/|^include/' \ | |
--system-headers=false -- $(CFLAGS) | |
compile_commands: | |
@echo "$(COLOR_YELLOW)[Checking for compile_commands updates]$(COLOR_RESET)" | |
@if [ ! -f compile_commands.json ]; then \ | |
echo "$(COLOR_GREEN)[Generating fresh compile_commands.json]$(COLOR_RESET)"; \ | |
bear -- make clean all; \ | |
else \ | |
if find $(SRC_DIR) $(HDR_DIR) -type f \( -name '*.c' -o -name '*.h' \) \ | |
-newer compile_commands.json | grep . >/dev/null; then \ | |
echo "$(COLOR_GREEN)[Sources changed. Regenerating compile_commands.json]$(COLOR_RESET)"; \ | |
bear -- make clean all; \ | |
else \ | |
echo "$(COLOR_GREEN)[Sources unchanged. Skipping regenerate]$(COLOR_RESET)"; \ | |
fi \ | |
fi | |
# Advanced builds | |
.PHONY: release asan | |
release: CFLAGS := $(DEVFLAGS) $(RELEASE_FLAGS) $(INCLUDES) | |
release: clean version_header $(RELEASE_TARGET) | |
@echo "$(COLOR_YELLOW)[Release build complete]$(COLOR_RESET)" | |
$(RELEASE_TARGET): $(OBJS) | $(BINDIR) | |
@echo "$(COLOR_YELLOW)[Linking Release]$(COLOR_RESET) $@" | |
@$(CC) $(CFLAGS) $^ -o $@ | |
asan: CFLAGS += $(ASAN_FLAGS) | |
asan: clean $(ASAN_TARGET) | |
@echo "$(COLOR_YELLOW)[Running ASan Binary]$(COLOR_RESET)" | |
@./$(ASAN_TARGET) | |
$(ASAN_TARGET): $(OBJS) | $(BINDIR) | |
@echo "$(COLOR_YELLOW)[Linking ASan]$(COLOR_RESET) $@" | |
@$(CC) $(CFLAGS) $^ -o $@ | |
# Version header generation | |
version_header: | |
@echo "$(COLOR_GREEN)[Generating version.h]$(COLOR_RESET)" | |
@mkdir -p $(HDR_DIR) | |
@echo '#pragma once' > $(HDR_DIR)/version.h | |
@echo '#define PROJECT_VERSION "$(VERSION)"' >> $(HDR_DIR)/version.h | |
# Help | |
.PHONY: help | |
help: | |
@echo "Usage: make [target]" | |
@echo "" | |
@echo "Available targets:" | |
@grep -E '^[a-zA-Z_-]+:.*' Makefile | grep -v '\.o:' | \ | |
sed 's/:.*//' | sort | uniq | |
# Automatically include dependency files | |
-include $(DEPS) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment