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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
# $@: name of the target file (one before colon)
# $<: name of first prerequisite file (first one after colon)
# $^: names of all prerequisite files (space separated)
# $*: stem (bit which matches the % wildcard in rule definition)
#
# VAR = val: Normal setting - values within are recursively expand when var used.
# VAR := val: Setting of var with simple expansion of values inside - values are expanded at decl time.
# VAR ?= val: Set var only if it doesn't have a value.
# VAR += val: Append val to existing value (or set if var didn't exist).
# To use static analyzer:
# http://clang-analyzer.llvm.org/scan-build.html
# Ie:
# scan-build -k -V --use-analyzer ~/bin/clang make
NAME = inotify-info
CFG ?= release
ifeq ($(CFG), debug)
ASAN ?= 1
endif
PREFIX ?= /usr/local
BINDIR := $(PREFIX)/bin
LD = $(CC)
RM = rm -f
MKDIR = mkdir -p
VERBOSE ?= 0
INOTIFYINFO_VERSION ?= $(shell git describe --tags --dirty 2>/dev/null || echo unknown)
COMPILER = $(shell $(CC) -v 2>&1 | grep -q "clang version" && echo clang || echo gcc)
WARNINGS = -Wall -Wextra -Wpedantic -Wmissing-include-dirs -Wformat=2 -Wshadow
ifneq ($(COMPILER),clang)
# https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
WARNINGS += -Wsuggest-attribute=format -Wall
endif
DEFINES = -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64
DEFINES += -DINOTIFYINFO_VERSION=\"$(INOTIFYINFO_VERSION)\"
CFLAGS += $(WARNINGS) $(DEFINES)
CFLAGS += -std=gnu99 -fno-exceptions
CXXFLAGS += $(WARNINGS) $(DEFINES)
CXXFLAGS += -std=c++11 -fno-exceptions -fno-rtti -Woverloaded-virtual
LIBS = -Wl,--no-as-needed -lm -ldl -lpthread -lstdc++
CFILES = \
inotify-info.cpp \
lfqueue/lfqueue.c
# Useful GCC address sanitizer checks not enabled by default
# https://kristerw.blogspot.com/2018/06/useful-gcc-address-sanitizer-checks-not.html
ifeq ($(ASAN), 1)
# https://gcc.gnu.org/gcc-5/changes.html
# -fsanitize=float-cast-overflow: check that the result of floating-point type to integer conversions do not overflow;
# -fsanitize=vptr: enable checking of C++ member function calls, member accesses and some conversions between pointers to base and derived classes, detect if the referenced object does not have the correct dynamic type.
ASAN_FLAGS = -fno-omit-frame-pointer -fno-optimize-sibling-calls
ASAN_FLAGS += -fsanitize=address # fast memory error detector (heap, stack, global buffer overflow, and use-after free)
ASAN_FLAGS += -fsanitize=leak # detect leaks
ASAN_FLAGS += -fsanitize=undefined # fast undefined behavior detector
ASAN_FLAGS += -fsanitize=float-divide-by-zero # detect floating-point division by zero;
ASAN_FLAGS += -fsanitize=bounds # enable instrumentation of array bounds and detect out-of-bounds accesses;
ASAN_FLAGS += -fsanitize=object-size # enable object size checking, detect various out-of-bounds accesses.
ASAN_FLAGS += -fsanitize=alignment # enable alignment checking, detect various misaligned objects;
CFLAGS += $(ASAN_FLAGS)
CXXFLAGS += $(ASAN_FLAGS)
LDFLAGS += $(ASAN_FLAGS)
endif
ifeq ($(CFG), debug)
ODIR=_debug
CFLAGS += -O0 -DDEBUG
CFLAGS += -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_GLIBCXX_SANITIZE_VECTOR -D_LIBCPP_DEBUG=1 -D_LIBCPP_ENABLE_DEBUG_MODE=1
else
ODIR=_release
CFLAGS += -O2 -DNDEBUG
endif
PROJ = $(ODIR)/$(NAME)
ifeq ($(VERBOSE), 1)
VERBOSE_PREFIX=
else
VERBOSE_PREFIX=@
endif
C_OBJS = ${CFILES:%.c=${ODIR}/%.o}
OBJS = ${C_OBJS:%.cpp=${ODIR}/%.o}
all: $(PROJ)
$(ODIR)/$(NAME): $(OBJS)
@echo "Linking $@...";
$(VERBOSE_PREFIX)$(LD) $(LDFLAGS) $^ $(LIBS) -o $@
-include $(OBJS:.o=.d)
$(ODIR)/%.o: %.c Makefile
$(VERBOSE_PREFIX)echo "---- $< ----";
@$(MKDIR) $(dir $@)
$(VERBOSE_PREFIX)$(CC) -MMD -MP $(CFLAGS) -o $@ -c $<
$(ODIR)/%.o: %.cpp Makefile
$(VERBOSE_PREFIX)echo "---- $< ----";
@$(MKDIR) $(dir $@)
$(VERBOSE_PREFIX)$(CXX) -MMD -MP $(CXXFLAGS) -o $@ -c $<
.PHONY: lint
lint:
find . -name '*.h' -o -name '*.c' -o -name '*.cpp' | xargs clang-format -i --style=webkit
.PHONY: clean
clean:
@echo Cleaning...
$(VERBOSE_PREFIX)$(RM) $(PROJ)
$(VERBOSE_PREFIX)$(RM) $(OBJS)
$(VERBOSE_PREFIX)$(RM) $(OBJS:.o=.d)
$(VERBOSE_PREFIX)$(RM) $(OBJS:.o=.dwo)
.PHONY: install
install: all
install -D $(PROJ) $(BINDIR)/$(NAME)
.PHONY: uninstall
uninstall:
$(RM) $(BINDIR)/$(NAME)
define RELEASE_RULES
inotify-info-$(TAG).tar.gz:
git archive --prefix=inotify-info-$(TAG)/ v$(TAG) | gzip -n > $$@
endef
$(foreach TAG,$(shell git tag 2>/dev/null | sed -n '/^v/ s/^v//p'),$(eval $(RELEASE_RULES)))
|