Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
255 lines (216 loc) · 10 KB
/
Copy pathMakefile
File metadata and controls
255 lines (216 loc) · 10 KB
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# Makefile for the PACT runtime.
CC = gcc
CFLAGS = -Wall -Wextra -O3 -g -D_GNU_SOURCE -I. -MMD -MP
LDFLAGS = -lm -lnuma -lpthread
TARGET = pact
# All sources except logging.c, which is an optional build (its symbols are
# no-ops via logging.h unless PACT_ENABLE_LOGGING is set; see `make logging`).
SOURCES = $(filter-out logging.c,$(wildcard *.c))
OBJECTS = $(SOURCES:.c=.o)
DEPS = $(OBJECTS:.o=.d)
.PHONY: all clean logging format check-format check-style FORCE
all: $(TARGET)
# usage.c prints the version string from the generated build-info.h.
# Checked every run; the file (and usage.o) only refresh when the git
# version actually changes, so incremental builds stay incremental.
build-info.h: FORCE
@GIT=$$(git describe --always --dirty --tags 2>/dev/null || echo unknown); \
if ! grep -qsF "\"$$GIT\"" $@; then \
printf '#define PACT_GIT_VERSION "%s"\n#define PACT_BUILD_DATE "%s"\n' \
"$$GIT" "$$(date -u +%Y-%m-%dT%H:%M:%SZ)" > $@; \
fi
FORCE:
usage.o: build-info.h
$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -o $(TARGET) $(LDFLAGS)
# Rebuild everything when CFLAGS change (e.g. after `make logging`, whose
# -DPACT_ENABLE_LOGGING objects must not be reused by a plain build).
.buildflags: FORCE
@echo '$(CFLAGS)' | cmp -s - $@ 2>/dev/null || echo '$(CFLAGS)' > $@
%.o: %.c .buildflags
$(CC) $(CFLAGS) -c $< -o $@
-include $(DEPS)
# Optional build with file logging enabled.
logging:
$(MAKE) clean
$(MAKE) CFLAGS="$(CFLAGS) -DPACT_ENABLE_LOGGING" SOURCES="$(wildcard *.c)"
clean:
rm -f *.o *.d $(TARGET) build-info.h .buildflags
# Style checks (see CODING_STYLE.md).
# check-style: grep-based brace-style check, no dependencies.
# check-format: full clang-format check. Prefer clang-format-18 (the
# version CI pins, so local and CI agree), fall back to the unversioned
# binary, or override with CLANG_FORMAT=<binary>.
CLANG_FORMAT ?= $(shell command -v clang-format-18 || command -v clang-format)
CLANG_FORMAT_VER = $(shell $(CLANG_FORMAT) --version 2>/dev/null | grep -oE '[0-9]+' | head -1)
FMT_SRCS = $(filter-out khashl.h minicoro.h build-info.h,$(wildcard *.c *.h))
# .clang-format uses InsertBraces (clang-format >= 15); the style is pinned to
# 16+. Ubuntu 22.04's unversioned clang-format is 14 and would spew "unknown
# key" errors for every file, so fail early with a clear message instead.
define require_clang_format
@test -n "$(CLANG_FORMAT)" || { \
echo "clang-format not found; install clang-format-18 or set CLANG_FORMAT=<binary>"; exit 1; }
@test "$(CLANG_FORMAT_VER)" -ge 16 2>/dev/null || { \
echo "clang-format >= 16 required (found: $(CLANG_FORMAT_VER)); install clang-format-18"; exit 1; }
endef
check-style:
bash check-style.sh
format:
$(require_clang_format)
$(CLANG_FORMAT) -i $(FMT_SRCS)
check-format:
$(require_clang_format)
$(CLANG_FORMAT) --dry-run -Werror $(FMT_SRCS)
.PHONY: test-event-loop-startup
test-event-loop-startup:
CC="$(CC)" python3 ../tests/test-event-loop-startup.py
.PHONY: test-pebs-startup
test-pebs-startup:
@set -e; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -Wall -Wextra -O1 -g -D_GNU_SOURCE -I. \
-fsanitize=address,undefined -ffunction-sections -fdata-sections \
../tests/test-pebs-startup.c error.c -Wl,--gc-sections -lm -o "$$test_bin"; \
"$$test_bin"
.PHONY: test-log-levels
test-log-levels: all
CC="$(CC)" python3 ../tests/test-log-levels.py
.PHONY: test-sampling-window
test-sampling-window:
@set -e; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -Wall -Wextra -O2 -D_GNU_SOURCE -I. -ffunction-sections -fdata-sections \
../tests/test-sampling-window.c error.c -Wl,--gc-sections -lm -o "$$test_bin"; \
"$$test_bin"
.PHONY: test-thread-coverage
test-thread-coverage:
@set -e; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -Wall -Wextra -O1 -g -D_GNU_SOURCE -I. -pthread \
-fsanitize=address,undefined -ffunction-sections -fdata-sections \
../tests/test-thread-coverage.c perf.c error.c -Wl,--gc-sections -lm -o "$$test_bin"; \
"$$test_bin"
.PHONY: test-workload-exit
test-workload-exit:
@set -e; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -Wall -Wextra -O2 -D_GNU_SOURCE -I. -ffunction-sections -fdata-sections \
../tests/test-workload-exit.c utils.c error.c -Wl,--gc-sections -lm -o "$$test_bin"; \
"$$test_bin"
.PHONY: test-pebs-quality
test-pebs-quality:
@set -e; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -Wall -Wextra -O1 -g -D_GNU_SOURCE -I. \
-fsanitize=address,undefined -ffunction-sections -fdata-sections \
../tests/test-pebs-quality.c error.c -Wl,--gc-sections -lm -o "$$test_bin"; \
"$$test_bin"
.PHONY: test-cha-freshness
test-cha-freshness:
@set -e; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -Wall -Wextra -O1 -g -D_GNU_SOURCE -I. \
-fsanitize=address,undefined -ffunction-sections -fdata-sections \
../tests/test-cha-freshness.c error.c -Wl,--gc-sections -lm -o "$$test_bin"; \
"$$test_bin"
.PHONY: test-pmu-control
test-pmu-control:
@set -e; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -Wall -Wextra -O1 -g -D_GNU_SOURCE -I. \
-fsanitize=address,undefined -ffunction-sections -fdata-sections \
../tests/test-pmu-control.c error.c -Wl,--gc-sections -lm -o "$$test_bin"; \
"$$test_bin"
.PHONY: test-bin-index
test-bin-index:
@set -e; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -Wall -Wextra -O1 -g -D_GNU_SOURCE -I. \
-fsanitize=address,undefined,float-cast-overflow -fno-sanitize-recover=all \
-ffunction-sections -fdata-sections \
../tests/test-bin-index.c cooling.c obj-pool.c error.c -Wl,--gc-sections -lm -o "$$test_bin"; \
"$$test_bin"
.PHONY: test-binning
test-binning:
@set -eu; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -D_GNU_SOURCE -I. -O1 -g -fsanitize=address,undefined \
-ffunction-sections -fdata-sections ../tests/test-binning.c binning.c \
-Wl,--gc-sections -lm -o "$$test_bin"; "$$test_bin"
.PHONY: test-pac-stats
test-pac-stats:
@set -e; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -Wall -Wextra -O1 -g -D_GNU_SOURCE -I. \
-fsanitize=address,undefined,float-cast-overflow -ffunction-sections -fdata-sections \
../tests/test-pac-stats.c error.c -Wl,--gc-sections -lm -o "$$test_bin"; \
"$$test_bin"
.PHONY: test-pac-threshold
test-pac-threshold:
@set -e; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -Wall -Wextra -O1 -g -D_GNU_SOURCE -I. \
-fsanitize=address,undefined,float-cast-overflow -fno-sanitize-recover=all \
-ffunction-sections -fdata-sections \
../tests/test-pac-threshold.c cooling.c obj-pool.c error.c -Wl,--gc-sections -lm -o "$$test_bin"; \
"$$test_bin"
.PHONY: test-quiet-stats
test-quiet-stats:
@set -e; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -Wall -Wextra -O1 -g -D_GNU_SOURCE -I. \
-fsanitize=undefined -fno-sanitize-recover=all \
-ffunction-sections -fdata-sections \
../tests/test-quiet-stats.c error.c -Wl,--gc-sections -lm -o "$$test_bin"; \
"$$test_bin"
.PHONY: test-startup-alloc
test-startup-alloc:
@set -eu; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -D_GNU_SOURCE -I. -O1 -g -ffunction-sections -fdata-sections \
-fsanitize=undefined -fno-sanitize-recover=all \
../tests/test-startup-alloc.c config.c error.c obj-pool.c \
-Wl,--gc-sections -Wl,--wrap=calloc -Wl,--wrap=free \
-Wl,--wrap=sched_getaffinity -lm -o "$$test_bin"; \
python3 ../tests/test-startup-alloc.py "$$test_bin"
.PHONY: test-pool-limit
test-pool-limit:
@set -eu; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -D_GNU_SOURCE -I. -O1 -g -ffunction-sections -fdata-sections \
-fsanitize=undefined -fno-sanitize-recover=all \
../tests/test-pool-limit.c cli.c config.c error.c obj-pool.c \
-Wl,--gc-sections -lm -o "$$test_bin"; \
"$$test_bin"
.PHONY: test-pool-fallback
test-pool-fallback:
@set -eu; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -D_GNU_SOURCE -I. -O1 -g -ffunction-sections -fdata-sections \
-fsanitize=undefined -fno-sanitize-recover=all \
../tests/test-pool-fallback.c error.c obj-pool.c \
-Wl,--gc-sections -Wl,--wrap=pool_create -lm -o "$$test_bin"; \
"$$test_bin"
.PHONY: test-migration-wait-stress
test-migration-wait-stress:
@set -e; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -Wall -Wextra -O1 -g -D_GNU_SOURCE -I. \
-fsanitize=address,undefined -ffunction-sections -fdata-sections \
../tests/test-migration-wait-stress.c error.c -Wl,--gc-sections \
-Wl,--wrap=poll -Wl,--wrap=__poll_chk -lm -lpthread -o "$$test_bin"; \
"$$test_bin"
.PHONY: test-migration-wakeup
test-migration-wakeup:
@set -e; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -Wall -Wextra -O1 -g -D_GNU_SOURCE -I. \
-fsanitize=address,undefined -ffunction-sections -fdata-sections \
../tests/test-migration-wakeup.c error.c -Wl,--gc-sections \
-Wl,--wrap=read -Wl,--wrap=__read_chk -Wl,--wrap=write -lm -lpthread -o "$$test_bin"; \
"$$test_bin"
.PHONY: test-migration-stop
test-migration-stop:
@set -e; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -Wall -Wextra -O1 -g -D_GNU_SOURCE -I. \
-fsanitize=address,undefined -ffunction-sections -fdata-sections \
../tests/test-migration-stop.c error.c -Wl,--gc-sections -lm -lpthread -o "$$test_bin"; \
"$$test_bin"
.PHONY: test-task-scan-error
test-task-scan-error:
@set -eu; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -Wall -Wextra -Werror -std=gnu11 -O1 -g -I. \
-fsanitize=address,undefined -ffunction-sections -fdata-sections \
../tests/test-task-scan-error.c error.c perf.c \
-Wl,--gc-sections -lm -lnuma -lpthread -o "$$test_bin"; \
"$$test_bin" 1; "$$test_bin" 0
.PHONY: test-migration-recovery
test-migration-recovery:
@set -e; test_bin=$$(mktemp); trap 'rm -f "$$test_bin"' EXIT; \
$(CC) -Wall -Wextra -O1 -g -D_GNU_SOURCE -I. \
-fsanitize=address,undefined -ffunction-sections -fdata-sections \
../tests/test-migration-recovery.c error.c -Wl,--gc-sections -lm -o "$$test_bin"; \
"$$test_bin"