|
| 1 | +# are we using clang? |
| 2 | +ISCLANG := $(shell if $(CC) --version | grep -e 'LLVM\|clang' >/dev/null; then echo 1; fi) |
| 3 | +ISLINUX := $(if $(wildcard /usr/include/linux/*.h),1,) |
| 4 | + |
| 5 | +CFLAGS := -std=gnu11 -W -Wall -Wshadow -Wno-unused-command-line-argument -g $(DEFS) $(CFLAGS) |
| 6 | +CXXFLAGS := -std=gnu++1z -W -Wall -Wshadow -Wno-unused-command-line-argument -g $(DEFS) $(CXXFLAGS) |
| 7 | +O ?= -O3 |
| 8 | +ifeq ($(filter 0 1 2 3 s,$(O)$(NOOVERRIDEO)),$(strip $(O))) |
| 9 | +override O := -O$(O) |
| 10 | +endif |
| 11 | +LDFLAGS := -no-pie |
| 12 | + |
| 13 | +# sanitizer arguments |
| 14 | +ifndef SAN |
| 15 | +SAN := $(SANITIZE) |
| 16 | +endif |
| 17 | +ifndef TSAN |
| 18 | + ifeq ($(WANT_TSAN),1) |
| 19 | +TSAN := $(SAN) |
| 20 | + endif |
| 21 | +endif |
| 22 | + |
| 23 | +check_for_sanitizer = $(if $(strip $(shell $(CC) -fsanitize=$(1) -x c -E /dev/null 2>&1 | grep sanitize=)),$(info ** WARNING: The `$(CC)` compiler does not support `-fsanitize=$(1)`.),1) |
| 24 | +ifeq ($(TSAN),1) |
| 25 | + ifeq ($(or $(ISCLANG),$(filter-out 3.% 4.% 5.% 6.%,$(shell $(CC) -dumpversion)),$(filter-out Linux%,$(shell uname))),) |
| 26 | +$(info ** WARNING: If ThreadSanitizer fails, try `make SAN=1 CC=clang`.) |
| 27 | + endif |
| 28 | + ifeq ($(call check_for_sanitizer,thread),1) |
| 29 | +CFLAGS += -fsanitize=thread |
| 30 | +CXXFLAGS += -fsanitize=thread |
| 31 | + endif |
| 32 | +else |
| 33 | + ifeq ($(or $(ASAN),$(SAN)),1) |
| 34 | + ifeq ($(call check_for_sanitizer,address),1) |
| 35 | +CFLAGS += -fsanitize=address |
| 36 | +CXXFLAGS += -fsanitize=address |
| 37 | + endif |
| 38 | + endif |
| 39 | + ifeq ($(or $(LSAN),$(LEAKSAN)),1) |
| 40 | + ifeq ($(call check_for_sanitizer,leak),1) |
| 41 | +CFLAGS += -fsanitize=leak |
| 42 | +CXXFLAGS += -fsanitize=leak |
| 43 | + endif |
| 44 | + endif |
| 45 | +endif |
| 46 | +ifeq ($(or $(UBSAN),$(SAN)),1) |
| 47 | + ifeq ($(call check_for_sanitizer,undefined),1) |
| 48 | +CFLAGS += -fsanitize=undefined |
| 49 | +CXXFLAGS += -fsanitize=undefined |
| 50 | + endif |
| 51 | +endif |
| 52 | + |
| 53 | +# profiling |
| 54 | +ifeq ($(or $(PROFILE),$(PG)),1) |
| 55 | +CFLAGS += -pg |
| 56 | +CXXFLAGS += -pg |
| 57 | +endif |
| 58 | + |
| 59 | +# these rules ensure dependencies are created |
| 60 | +DEPCFLAGS = -MD -MF $(DEPSDIR)/$*.d -MP |
| 61 | +DEPSDIR := .deps |
| 62 | +BUILDSTAMP := $(DEPSDIR)/rebuildstamp |
| 63 | +DEPFILES := $(wildcard $(DEPSDIR)/*.d) |
| 64 | +ifneq ($(DEPFILES),) |
| 65 | +include $(DEPFILES) |
| 66 | +endif |
| 67 | + |
| 68 | +# when the C compiler or optimization flags change, rebuild all objects |
| 69 | +ifneq ($(strip $(DEP_CC)),$(strip $(CC) $(CPPFLAGS) $(CFLAGS) $(O))) |
| 70 | +DEP_CC := $(shell mkdir -p $(DEPSDIR); echo >$(BUILDSTAMP); echo "DEP_CC:=$(CC) $(CPPFLAGS) $(CFLAGS) $(O)" >$(DEPSDIR)/_cc.d) |
| 71 | +endif |
| 72 | +ifneq ($(strip $(DEP_CXX)),$(strip $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(O))) |
| 73 | +DEP_CXX := $(shell mkdir -p $(DEPSDIR); echo >$(BUILDSTAMP); echo "DEP_CXX:=$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(O)" >$(DEPSDIR)/_cxx.d) |
| 74 | +endif |
| 75 | + |
| 76 | + |
| 77 | +V = 0 |
| 78 | +ifeq ($(V),1) |
| 79 | +run = $(1) $(3) |
| 80 | +xrun = /bin/echo "$(1) $(3)" && $(1) $(3) |
| 81 | +else |
| 82 | +run = @$(if $(2),/bin/echo " $(2) $(3)" &&,) $(1) $(3) |
| 83 | +xrun = $(if $(2),/bin/echo " $(2) $(3)" &&,) $(1) $(3) |
| 84 | +endif |
| 85 | +runquiet = @$(1) $(3) |
| 86 | + |
| 87 | +# cancel implicit rules we don't want |
| 88 | +%: %.c |
| 89 | +%.o: %.c |
| 90 | +%: %.cc |
| 91 | +%.o: %.cc |
| 92 | +%: %.o |
| 93 | + |
| 94 | +$(BUILDSTAMP): |
| 95 | + @mkdir -p $(@D) |
| 96 | + @echo >$@ |
| 97 | + |
| 98 | +always: |
| 99 | + @: |
| 100 | + |
| 101 | +clean-hook: |
| 102 | + @: |
| 103 | + |
| 104 | +.PHONY: always clean-hook |
| 105 | +.PRECIOUS: %.o |
0 commit comments