-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMakefile
105 lines (87 loc) · 2.54 KB
/
Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# Detect operating system
UNAME_S := $(shell uname -s)
# Check for Homebrew LLVM on macOS, fallback to system clang
ifeq ($(UNAME_S),Darwin)
HOMEBREW_LLVM := $(shell test -x /opt/homebrew/opt/llvm/bin/clang && echo "yes")
ifeq ($(HOMEBREW_LLVM),yes)
CC = /opt/homebrew/opt/llvm/bin/clang
else
CC = clang
$(warning On macOS, Homebrew LLVM is recommended for leak detection. Install with: brew install llvm)
endif
else
CC = clang
endif
# Compiler flags
WARNING_FLAGS = -Wall -Werror -Wextra
STD_FLAGS = -std=c11 -pedantic -D_POSIX_C_SOURCE=200809L -D_GNU_SOURCE
INCLUDE_FLAGS = -I./src
CFLAGS = $(WARNING_FLAGS) $(STD_FLAGS) $(INCLUDE_FLAGS)
# Linker flags
LDFLAGS =
# Directory structure
SRC_DIR = src
OBJ_DIR = obj
BIN_DIR = bin
SCRIPT_DIR = tests
# Find all source files
SOURCES = $(wildcard $(SRC_DIR)/*.c)
OBJECTS = $(SOURCES:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
EXECUTABLE = $(BIN_DIR)/colette
# Build targets
.PHONY: all memcheck debug test release clean rebuild directories install
# Main target
all: release
# Debug target
debug: DEBUG = 1
debug: CFLAGS += -DDBUG -g -O0
debug: directories $(EXECUTABLE)
# Memcheck flags based on compiler
ifeq ($(HOMEBREW_LLVM),yes)
MEMCHECK_SANITIZE = -fsanitize=address,leak
else
MEMCHECK_SANITIZE = -fsanitize=address
endif
# Memcheck target
# Allows program to continue after finding issues
MEMCHECK_SANITIZE += -fsanitize-recover=address,leak
# Still halt on undefined behavior
MEMCHECK_SANITIZE += -fno-sanitize-recover=undefined
# Better stack traces
MEMCHECK_SANITIZE += -fno-omit-frame-pointer
MEMCHECK_SANITIZE += -fno-optimize-sibling-calls
memcheck: DEBUG = 1
memcheck: CFLAGS += $(MEMCHECK_SANITIZE) -DDBUG -g -O0 -fno-inline
memcheck: LDFLAGS += $(MEMCHECK_SANITIZE)
memcheck: directories $(EXECUTABLE)
$(SCRIPT_DIR)/run_memcheck.sh
# Test target
test: debug
$(SCRIPT_DIR)/run_tests.sh
# Release target
release: DEBUG = 0
release: CFLAGS += -O2
release: directories $(EXECUTABLE)
# Create necessary directories
directories:
mkdir -p $(OBJ_DIR)
mkdir -p $(BIN_DIR)
# Link object files into executable
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
# Compile source files into object files
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
# Clean build files
clean:
rm -rf $(OBJ_DIR)
rm -rf $(BIN_DIR)
rebuild: clean all
rebuild-debug: clean debug
rebuild-memcheck: clean memcheck
rebuild-test: clean test
rebuild-release: clean release
install: all
echo $(shell gcc --version | grep ^gcc | sed 's/^.* //g')
mkdir -p ~/bin
cp $(EXECUTABLE) ~/bin/