summaryrefslogtreecommitdiff
path: root/Makefile
diff options
context:
space:
mode:
authorDoan Luu Duc Tai <doan@luuduct.ai>2026-09-08 14:46:47 -0500
committerDoan Luu Duc Tai <doan@luuduct.ai>2026-09-08 14:46:47 -0500
commitf34fb5042d40c186583f9e3009d8a1dd71d07d43 (patch)
tree3f494f3723ebe9f173d0702a97509794f0ef85a5 /Makefile
Initial commitmain
Diffstat (limited to 'Makefile')
-rw-r--r--Makefile226
1 files changed, 226 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..9df0c19
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,226 @@
+TARGET := vfetch
+MAIN_SRC := main.c
+LIB_SRC := lib/miniaudio.c lib/pl_mpeg.c
+APP_SRCS := $(wildcard src/*.c)
+OBJS := $(MAIN_SRC:.c=.o) $(LIB_SRC:.c=.o) $(APP_SRCS:.c=.o)
+DEPS := $(OBJS:.o=.d)
+PROJECT_SRCS := $(MAIN_SRC) $(APP_SRCS) $(wildcard src/*.h)
+
+PKGS := chafa glib-2.0
+
+INSTALL_PATH := /usr/local/bin
+
+CC := $(firstword $(shell command -v clang gcc))
+ifeq ($(CC),)
+ $(error No compatible C compiler found.)
+endif
+
+PKG_CONFIG := $(shell command -v pkg-config)
+ifeq ($(PKG_CONFIG),)
+ $(error 'pkg-config' not found.)
+endif
+
+PKG_CFLAGS := $(shell pkg-config --cflags $(PKGS) | sed 's/-I/-isystem /g')
+PKG_LDFLAGS := $(shell pkg-config --libs $(PKGS))
+
+DEPFLAGS := -MMD -MP
+
+CORE_CFLAGS := \
+ -D_XOPEN_SOURCE=700 \
+ -std=c11 \
+ -isystem $(CURDIR)/lib \
+ $(PKG_CFLAGS)
+
+STRICT_CFLAGS := \
+ -pedantic-errors \
+ -Wall \
+ -Wextra \
+ -Wpedantic \
+ -Werror \
+ -Wformat=2 \
+ -Wformat-security \
+ -Wformat-nonliteral \
+ -Wformat-signedness \
+ -Wstack-protector \
+ -Wvla \
+ -Wodr \
+ -Wstrict-prototypes \
+ -Wmissing-prototypes \
+ -Wmissing-declarations \
+ -Wmissing-include-dirs \
+ -Wmissing-field-initializers \
+ -Wredundant-decls \
+ -Wpointer-arith \
+ -Wpointer-sign \
+ -Wabsolute-value \
+ -Wconversion \
+ -Wsign-conversion \
+ -Wundef \
+ -Winline \
+ -Wcast-qual \
+ -Wfloat-equal \
+ -Wold-style-definition \
+ -Woverlength-strings \
+ -Wwrite-strings \
+ -Wlogical-not-parentheses \
+ -Wpacked \
+ -Winit-self \
+ -Wstrict-overflow=5 \
+ -Wunused-macros \
+ -Wunreachable-code \
+ -Wdate-time \
+ -Wbad-function-cast \
+ -Wnested-externs \
+ -Wswitch-default \
+ -Wswitch-enum \
+ -Wuninitialized \
+ -Wdouble-promotion \
+ -Wcast-function-type \
+ -Wnull-dereference \
+ -Wdisabled-optimization \
+ -Wno-padded
+
+CLANG_SPECIFIC_STRICT_FLAGS := \
+ -Wcomma \
+ -Wshadow \
+ -Wcast-align \
+ -Wdocumentation \
+ -Wstrict-aliasing \
+ -Wpadded-bitfield \
+ -Wformat-overflow \
+ -Wformat-truncation \
+ -Wimplicit-fallthrough
+
+GCC_SPECIFIC_STRICT_FLAGS := \
+ -Walloc-zero \
+ -Wsuggest-attribute=const \
+ -Wsuggest-attribute=format \
+ -Wshadow=local \
+ -Wcast-align=strict \
+ -Wimplicit-fallthrough=5 \
+ -Wstrict-aliasing=2 \
+ -Wformat-overflow=2 \
+ -Wformat-truncation=2 \
+ -Wjump-misses-init \
+ -Wlogical-op \
+ -Wuseless-cast \
+ -Wduplicated-cond \
+ -Wduplicated-branches \
+ -Wswitch-unreachable \
+ -Wpacked-bitfield-compat \
+ -Wunsafe-loop-optimizations \
+ -Wtrampolines
+
+ALL_STRICT_FLAGS := $(STRICT_CFLAGS) $(CLANG_SPECIFIC_STRICT_FLAGS) $(GCC_SPECIFIC_STRICT_FLAGS)
+
+RELEASE_CFLAGS := \
+ -O3 \
+ -flto=auto \
+ -fno-semantic-interposition \
+ -fstack-protector-strong \
+ -fstack-clash-protection \
+ -fPIE \
+ -D_FORTIFY_SOURCE=2 \
+ -ffunction-sections \
+ -fdata-sections \
+ -fcf-protection \
+ -march=native
+
+DEBUG_CFLAGS_COMMON := -g -Og -fno-omit-frame-pointer -fno-common -flto=auto
+ANALYZER_FLAGS_GCC := -fanalyzer
+SANITIZER_ASAN_FLAGS := -fsanitize=address,undefined,leak
+SANITIZER_TSAN_FLAGS := -fsanitize=thread
+
+COMMON_LDFLAGS := -pthread $(PKG_LDFLAGS) -lm -latomic
+RELEASE_LDFLAGS := -flto=auto -Wl,--gc-sections -Wl,--build-id=none -s -pie
+
+.PHONY: all fallback debug debug-threaded check clean install uninstall tidy iwyu format format-check
+.DELETE_ON_ERROR:
+
+CFLAGS := $(CORE_CFLAGS)
+LDFLAGS := $(COMMON_LDFLAGS)
+
+all: CFLAGS += $(RELEASE_CFLAGS)
+all: LDFLAGS += $(RELEASE_LDFLAGS)
+all: $(TARGET)
+
+fallback: $(TARGET)
+
+debug: CC := $(CC)
+debug: CFLAGS += $(STRICT_CFLAGS) $(DEBUG_CFLAGS_COMMON) $(SANITIZER_ASAN_FLAGS)
+debug: CFLAGS += $(if $(findstring clang,$(notdir $(CC))),$(CLANG_SPECIFIC_STRICT_FLAGS))
+debug: CFLAGS += $(if $(findstring gcc,$(notdir $(CC))),$(GCC_SPECIFIC_STRICT_FLAGS) $(ANALYZER_FLAGS_GCC))
+debug: LDFLAGS += $(SANITIZER_ASAN_FLAGS)
+debug: LDFLAGS += -flto=auto
+debug: $(TARGET)
+
+debug-threaded: CC := $(CC)
+debug-threaded: CFLAGS += $(STRICT_CFLAGS) $(DEBUG_CFLAGS_COMMON) $(SANITIZER_TSAN_FLAGS)
+debug-threaded: CFLAGS += $(if $(findstring clang,$(notdir $(CC))),$(CLANG_SPECIFIC_STRICT_FLAGS))
+debug-threaded: CFLAGS += $(if $(findstring gcc,$(notdir $(CC))),$(GCC_SPECIFIC_STRICT_FLAGS) $(ANALYZER_FLAGS_GCC))
+debug-threaded: LDFLAGS += $(SANITIZER_TSAN_FLAGS)
+debug-threaded: LDFLAGS += -flto=auto
+debug-threaded: $(TARGET)
+
+-include $(DEPS)
+
+$(MAIN_SRC:.c=.o): $(MAIN_SRC)
+ @echo " CC (Strict) $<"
+ $(CC) $(DEPFLAGS) $(CFLAGS) -c $< -o $@
+
+src/%.o: src/%.c
+ @echo " CC (Strict) $<"
+ $(CC) $(DEPFLAGS) $(CFLAGS) -c $< -o $@
+
+lib/%.o: lib/%.c
+ @echo " CC (Lax) $<"
+ $(CC) $(DEPFLAGS) $(filter-out $(ALL_STRICT_FLAGS),$(CFLAGS)) -c $< -o $@
+
+IWYU := $(shell command -v include-what-you-use 2>/dev/null)
+
+$(TARGET): $(OBJS)
+ @echo " CCLD $@"
+ $(CC) $(OBJS) -o $@ $(LDFLAGS)
+ @echo "Build complete. Executable '$(TARGET)' created."
+
+check: debug tidy iwyu format-check
+
+clean:
+ @echo "Cleaning up..."
+ rm -f $(TARGET) $(OBJS) $(DEPS)
+ @echo "Clean complete."
+
+install: all
+ @echo "Installing $(TARGET) to $(INSTALL_PATH)..."
+ install -Dm755 "$(TARGET)" "$(INSTALL_PATH)/$(TARGET)"
+ @echo "Installation complete."
+
+uninstall:
+ @echo "Uninstalling $(TARGET)..."
+ rm -f "$(INSTALL_PATH)/$(TARGET)"
+ $(MAKE) clean
+ @echo "Uninstall complete."
+
+tidy:
+ @echo " TIDY Running clang-tidy..."
+ clang-tidy $(MAIN_SRC) $(APP_SRCS) -- $(CORE_CFLAGS) $(STRICT_CFLAGS) $(CLANG_SPECIFIC_STRICT_FLAGS)
+
+iwyu:
+ @if [ -z "$(IWYU)" ]; then \
+ echo " SKIP include-what-you-use not found on this system."; \
+ else \
+ for file in $(MAIN_SRC) $(APP_SRCS); do \
+ echo " IWYU $$file"; \
+ $(IWYU) -Xiwyu --error \
+ -Xiwyu --check_also="src/*.h" \
+ $(CORE_CFLAGS) $(STRICT_CFLAGS) $$file || exit 1; \
+ done; \
+ fi
+
+format:
+ @echo " FORMAT Applying source code formatting..."
+ clang-format -i $(PROJECT_SRCS)
+
+format-check:
+ @echo " FORMAT Checking source code formatting..."
+ clang-format --dry-run -Werror $(PROJECT_SRCS)