main
1# This requires GNU Make
2.SUFFIXES: # disable built-in rules
3
4BUILD_DIR ?= ./build
5CC ?= gcc
6LD ?= ld
7RM ?= rm
8MAKE ?= make
9
10KC_USE_PLATFORM_LIBC ?= TRUE
11KC_MEMORY_ZEROING ?= LOOSE
12PROGNAME ?= main
13LDFLAGS ?=
14CFLAGS += -std=c99
15CFLAGS += -I$(KC_DIR)/include
16
17ifndef PROJ_SRC_DIR
18 $(error PROJ_SRC_DIR is not defined. Where should source files be taken from?)
19endif
20
21ifndef KC_DIR
22 $(error KC_DIR is not defined. The library can not be found without it.)
23endif
24
25OBJS := $(wildcard $(PROJ_SRC_DIR)/*.c)
26OBJS := $(OBJS:$(PROJ_SRC_DIR)/%.c=$(BUILD_DIR)/%.o)
27$(info $(OBJS))
28HEADER_DEPS := $(OBJS:.o=.d)
29
30ifeq ( $(CC), cc )
31 $(warning If you actually want to do anything besides compilation, please set CC to your actual compiler's name (like gcc or clang).)
32endif
33
34$(info )
35$(info ** Identifying system configuration **)
36$(info Compiler: $(CC))
37
38ifeq ($(CC), gcc)
39 ANALYZE_FLAGS += -fanalyzer -Wanalyzer-symbol-too-complex -Wanalyzer-too-complex
40 DEBUG_FLAGS += -Og -g -Wall -Wextra -pedantic -Wpedantic
41 SANITIZE_FLAGS += -fsanitize=address,pointer-compare
42 PROFILE_FLAGS +=
43else ifeq ( $(CC), clang )
44 ANALYZE_FLAGS += -Xanalyze
45 DEBUG_FLAGS += -Og -g -Wall -Wextra -pedantic -Wpedantic
46 SANITIZE_FLAGS +=
47 PROFILE_FLAGS +=
48else
49 $(warning Current compiler is not supported for analysis.)
50endif
51
52
53# Cross-platform mess
54ifdef OS
55 $(info OS: windows)
56
57 MAIN_TARGET=$(BUILD_DIR)/$(PROGNAME).exe
58 TEST_TARGET=$(BUILD_DIR)/test_runner.exe
59 CP=cp
60else ifeq ($(shell uname),Linux)
61 $(info OS: linux)
62
63 MAIN_TARGET=$(BUILD_DIR)/$(PROGNAME)
64 TEST_TARGET=$(BUILD_DIR)/test_runner
65 CP=cp
66else
67 $(error The current platform is unsupported)
68endif
69
70$(info )
71$(info ** Outputs ** )
72
73$(info name $(PROGNAME) )
74$(info main $(MAIN_TARGET) )
75$(info test $(TEST_TARGET) )
76
77$(info )
78$(info ** Identifying library options **)
79
80ifeq ($(KC_MEMORY_ZEROING), LOOSE)
81 CFLAGS += -DKC_ZERO_MEMORY_LOOSE
82 $(info Memory zeroing: LOOSE)
83
84else ifeq ($(KC_MEMORY_ZEROING), STRICT)
85 CFLAGS += -DKC_ZERO_MEMORY_STRICT
86 $(info Memory zeroing: STRICT)
87else
88 $(error Invalid value '$(KC_MEMORY_ZEROING)' passed for KC_MEMORY_ZEROING option. Allowed are: LOOSE, STRICT)
89endif
90
91ifeq ($(KC_USE_PLATFORM_LIBC), TRUE)
92 $(info Platform libc ON)
93 CFLAGS += -DKC_USE_PLATFORM_LIBC
94 BUILD_COMMAND := $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $(MAIN_TARGET)
95else
96 CFLAGS += 0 -nostdlib -nolibc -nodefaultlibs
97 $(info Platform libc OFF)
98 BUILD_COMMAND := $(LD) $(LDFLAGS) $(OBJS) -o $(MAIN_TARGET)
99endif
100
101-include $(HEADER_DEPS)
102
103.PHONY:
104help:
105 $(info )
106 $(info ** Possible Targets **)
107 $(info -- release - release buikd)
108 $(info -- debug - debug build)
109 $(info -- test - build and run tests)
110 $(info -- analyze - debug build with static analyzer)
111 $(info )
112
113.PHONY: release
114release: $(MAIN_TARGET)
115
116.PHONY: debug
117debug: CFLAGS += $(DEBUG_FLAGS) $(SANITIZE_FLAGS)
118debug: $(MAIN_TARGET)
119 @echo Building debug
120 @echo $(DEBUG_FLAGS)
121
122.PHONY: test
123test: $(TEST_TARGET)
124 $(TEST_TARGET)
125
126$(MAIN_TARGET): $(OBJS)
127 $(BUILD_COMMAND)
128
129$(TEST_TARGET): $(BUILD_DIR)/test_runner.c $(OBJS) $(BUILD_DIR)/testfunction_list.h
130
131
132$(KC_DIR)/test_runner.c: $(KC_DIR)/src/test_runner.c
133 $(CP) $< $@
134
135$(BUILD_DIR)/testfunction_list.h: $(OBJS)
136
137
138$(BUILD_DIR)/%.o : $(PROJ_SRC_DIR)/%.c
139 @mkdir -p $(@D)
140 $(CC) $(CFLAGS) -MMD $< -c -o $@
141
142.PHONY: clean
143clean:
144 $(RM) -rf ./build/
145