Files
2026-09-19 13:16:00 +02:00

105 lines
3.1 KiB
Makefile

COMPILER = gcc
# COMPILER FLAGS
C_FLAG_STD_C99 = -std=c99 # Use the C99 language standard
C_FLAG_DEBUG_INFO = -g # Include debug information
#C_FLAG_HEADERS = -H # Prints paths of all headers
C_FLAG_ALL_WARNINGS = -Wall # Enable most common warning
C_FLAG_PEDANTIC = -Wpedantic # Enforce ISO C standard strictly
C_FLAG_SHADOW = -Wshadow # Warn if a local variable shadows another
C_FLAG_STRICT_PROTOS = -Wstrict-prototypes # Warn if function declarations are missing parameter types
C_FLAG_NO_UNKNOWN_PRAGMAS = -Wno-unknown-pragmas # Suppress warnings about unknown pragmas
C_FLAG_DEPS = -MMD -MP # Emit per-file header dependency files for incremental rebuilds
C_FLAGS = \
$(C_FLAG_STD_C99) \
$(C_FLAG_DEBUG_INFO) \
$(C_FLAG_HEADERS) \
$(C_FLAG_ALL_WARNINGS) \
$(C_FLAG_PEDANTIC) \
$(C_FLAG_SHADOW) \
$(C_FLAG_STRICT_PROTOS) \
$(C_FLAG_NO_UNKNOWN_PRAGMAS) \
$(C_FLAG_DEPS)
# BUILD-MODE FLAGS
RELEASE_FLAGS = -O2
DEBUG_FLAGS = -O0 -DDEBUG -fsanitize=address,undefined -fno-omit-frame-pointer
# INCLUDE FLGAS
INCLUDE_FLAGS = \
-Iinclude \
$(EXTERNAL_FLAGS) \
$(RAYLIB_CFLAGS)
# EXTERNAL FLAGS
EXTERNAL_RAYGUI = -Iexternal/raygui
EXTERNAL_RINI = -Iexternal/rini
EXTERNAL_FLAGS = \
$(EXTERNAL_RINI) \
$(EXTERNAL_RAYGUI)
# CROSS PLATTFORM
ifeq ($(OS), Windows_NT)
SRC = $(wildcard src\*.c)
BIN_DIR = bin\win
RAYLIB_CFLAGS = -I%RAYLIB%
RAYLIB_LIBS = -L%RAYLIB% -lraylib -lopengl32 -lgdi32 -lwinmm
EXE_EXT = .exe
else
SRC = $(wildcard src/*.c)
BIN_DIR = bin/unix
RAYLIB_CFLAGS = $(shell pkg-config --cflags raylib)
RAYLIB_LIBS = $(shell pkg-config --libs raylib) -lm
EXE_EXT =
endif
TARGET_RELEASE = $(BIN_DIR)/game$(EXE_EXT)
TARGET_DEBUG = $(BIN_DIR)/game-debug$(EXE_EXT)
# PER-FILE OBJECTS (one .o per .c, only stale ones get rebuilt)
OBJ_DIR_RELEASE = build/release
OBJ_DIR_DEBUG = build/debug
OBJS_RELEASE = $(patsubst src/%.c,$(OBJ_DIR_RELEASE)/%.o,$(SRC))
OBJS_DEBUG = $(patsubst src/%.c,$(OBJ_DIR_DEBUG)/%.o,$(SRC))
DEPS_RELEASE = $(OBJS_RELEASE:.o=.d)
DEPS_DEBUG = $(OBJS_DEBUG:.o=.d)
# COMMANDS
build: $(TARGET_RELEASE)
debug: $(TARGET_DEBUG)
$(TARGET_RELEASE): $(OBJS_RELEASE) | $(BIN_DIR)
$(COMPILER) $(OBJS_RELEASE) -o $(TARGET_RELEASE) $(RAYLIB_LIBS)
$(TARGET_DEBUG): $(OBJS_DEBUG) | $(BIN_DIR)
$(COMPILER) $(DEBUG_FLAGS) $(OBJS_DEBUG) -o $(TARGET_DEBUG) $(RAYLIB_LIBS)
$(OBJ_DIR_RELEASE)/%.o: src/%.c | $(OBJ_DIR_RELEASE)
$(COMPILER) $(C_FLAGS) $(RELEASE_FLAGS) $(INCLUDE_FLAGS) -c $< -o $@
$(OBJ_DIR_DEBUG)/%.o: src/%.c | $(OBJ_DIR_DEBUG)
$(COMPILER) $(C_FLAGS) $(DEBUG_FLAGS) $(INCLUDE_FLAGS) -c $< -o $@
# DIRECTORIES ARE ORDER-ONLY PREREQUISITES SO `clean` CAN REMOVE THEM WITHOUT
# RACING A CHAINED `build`/`debug` IN THE SAME INVOCATION (e.g. `make clean build`)
$(OBJ_DIR_RELEASE) $(OBJ_DIR_DEBUG) $(BIN_DIR):
mkdir -p $@
-include $(DEPS_RELEASE)
-include $(DEPS_DEBUG)
clean:
rm -rf bin build
run: build
./$(TARGET_RELEASE)
run-debug: debug
./$(TARGET_DEBUG)
.PHONY: build debug clean run run-debug