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