-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
141 lines (111 loc) · 5.05 KB
/
Copy pathMakefile
File metadata and controls
141 lines (111 loc) · 5.05 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
VM ?= ebpf
PROJECT_DIR := $(CURDIR)
BUILD ?= $(CURDIR)/build
ARCH := $(shell uname -m | sed 's/x86_64/x86/; s/aarch64/arm64/')
CLANG ?= clang
BPFTOOL ?= bpftool
SRC := src
VMLINUX := $(BUILD)/vmlinux.h
# The per-version BTF blobs are EXPENSIVE to regenerate (gen_btf.sh downloads and
# compiles every SQLite release — minutes of work), so the canonical cache lives
# OUTSIDE $(BUILD) and `clean` never touches it. $(BTF_DIR) is the consumer-facing
# path (loader default, run_tests.sh's $B/btf): it's a symlink into the cache,
# recreated cheaply on build. Override BTF_CACHE to relocate the persistent store.
BTF_CACHE ?= $(CURDIR)/.btf-cache
BTF_DIR := $(BUILD)/btf
DETECT := $(BUILD)/detect_version
MERGE := $(BUILD)/merge_btf
SQL_BPF_OBJ := $(BUILD)/sqlite_trace.bpf.o
SQL_SKEL := $(BUILD)/sqlite_trace.skel.h
SQL_TRACE := $(BUILD)/sqlite_trace
# SQLite has two number encodings: the amalgamation DOWNLOAD number used in
# sqlite.org URLs/paths (e.g. 3400000), and the runtime VERSION number returned
# by sqlite3_libversion_number (e.g. 3040000). BTF blobs are named by the
# version number (what the loader detects); libs/sources use the download number.
SQLITE_SRC := /tmp/sqlite-btf-build
SQLITE_DEFS := -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_RTREE
LIB_VERSIONS := 3400000 3460100
CFLAGS := -g -O2 -Wall
BPF_CFLAGS := -g -O2 -target bpf -D__TARGET_ARCH_$(ARCH) -I$(BUILD) -I$(SRC)
# Mirror DEFAULT_BTF_DIR in src/sqlite_trace.c — where the loader looks for
# sqlite-<ver>.btf blobs when neither --btf-dir nor $SQLITE_TRACE_BTF_DIR is set.
INSTALL_BTF_DIR ?= /usr/share/sqlite-trace/btf
.PHONY: all detect resolve trace merge btf install-btf libs test test-prereqs \
clean vm-create vm-start vm-stop vm-delete vm-shell vm-test
all: $(SQL_TRACE)
detect: $(DETECT)
trace: $(SQL_TRACE)
merge: $(MERGE)
# Generate into the persistent cache (idempotent: skips versions already built),
# then refresh the in-build symlink that consumers read through.
btf: | $(BTF_CACHE)
OUT_DIR=$(BTF_CACHE) ./gen_btf.sh
$(MAKE) $(BTF_DIR)
$(BUILD):
mkdir -p $(BUILD)
$(BTF_CACHE):
mkdir -p $(BTF_CACHE)
$(VMLINUX): | $(BUILD)
$(BPFTOOL) btf dump file /sys/kernel/btf/vmlinux format c > $@
# $(BTF_DIR) (build/btf) is a symlink to the persistent $(BTF_CACHE); clean wipes
# build/ but the cache and this rule rebuild the link for free. The cache is
# populated on first build via gen_btf.sh (idempotent — skips existing blobs);
# run `make btf` to re-poll for newly-released SQLite versions. The link is
# PHONY-rebuilt each time so a deleted build/ always gets it back, but the costly
# blob generation only runs when the cache itself is empty.
$(BTF_DIR): gen_btf.sh | $(BUILD) $(BTF_CACHE)
@if [ -z "$$(ls -A $(BTF_CACHE) 2>/dev/null)" ]; then \
OUT_DIR=$(BTF_CACHE) ./gen_btf.sh; \
fi
rm -rf $(BTF_DIR)
ln -sfn $(BTF_CACHE) $(BTF_DIR)
# Copy the built blobs to the loader's compiled-in default dir so the tracer
# resolves them without --btf-dir / $SQLITE_TRACE_BTF_DIR. Run inside the VM.
install-btf: $(BTF_DIR)
mkdir -p $(INSTALL_BTF_DIR)
cp $(BTF_DIR)/sqlite-*.btf $(INSTALL_BTF_DIR)/
@echo "installed $$(ls $(BTF_DIR)/sqlite-*.btf | wc -l) blobs to $(INSTALL_BTF_DIR)"
$(DETECT): $(SRC)/detect_version.c $(SRC)/resolve_step.c | $(BUILD)
$(CC) $(CFLAGS) -DDETECT_MAIN $(SRC)/detect_version.c $(SRC)/resolve_step.c -lelf -o $@
RESOLVE := $(BUILD)/resolve_step
$(RESOLVE): $(SRC)/resolve_step.c | $(BUILD)
$(CC) $(CFLAGS) -DRESOLVE_MAIN $(SRC)/resolve_step.c -lelf -o $@
resolve: $(RESOLVE)
$(MERGE): $(SRC)/merge_btf.c | $(BUILD)
$(CC) $(CFLAGS) $< -lbpf -lelf -lz -o $@
$(SQL_BPF_OBJ): $(SRC)/sqlite_trace.bpf.c $(SRC)/sqlite_trace.h $(VMLINUX)
$(CLANG) $(BPF_CFLAGS) -c $< -o $@
$(SQL_SKEL): $(SQL_BPF_OBJ)
$(BPFTOOL) gen skeleton $< > $@
TRACE_HELPERS := $(SRC)/detect_version.c $(SRC)/resolve_step.c $(SRC)/target_resolve.c \
$(SRC)/btf_merge.c $(SRC)/app_context.c
$(SQL_TRACE): $(SRC)/sqlite_trace.c $(SRC)/sqlite_trace.h $(TRACE_HELPERS) $(SQL_SKEL)
$(CC) $(CFLAGS) -I$(BUILD) -I$(SRC) $(SRC)/sqlite_trace.c $(TRACE_HELPERS) \
-lbpf -lelf -lz -o $@
# Real per-version shared lib + a demo linked against it, so tests can attach to
# a process actually running that SQLite version.
libs: $(foreach v,$(LIB_VERSIONS),$(BUILD)/libsqlite3-$(v).so $(BUILD)/sqlite_demo_$(v))
$(BUILD)/libsqlite3-%.so: | $(BUILD) $(BTF_DIR)
$(CC) -O2 -fPIC -shared $(SQLITE_SRC)/sqlite-amalgamation-$*/sqlite3.c \
-o $@ $(SQLITE_DEFS) -lpthread -ldl -lm
$(BUILD)/sqlite_demo_%: $(SRC)/sqlite_demo.c $(BUILD)/libsqlite3-%.so
$(CC) $(CFLAGS) $(SRC)/sqlite_demo.c -I$(SQLITE_SRC)/sqlite-amalgamation-$* \
-L$(BUILD) -l:libsqlite3-$*.so -Wl,-rpath,$(BUILD) -o $@
test-prereqs: $(SQL_TRACE) $(DETECT) $(BTF_DIR) libs
test: test-prereqs run_tests.sh
BUILD=$(BUILD) ./run_tests.sh
clean:
rm -rf $(BUILD)
# --- VM lifecycle (run from the macOS host) ---
vm-create:
limactl start --name $(VM) $(PROJECT_DIR)/ebpf.yaml
vm-start:
limactl start $(VM)
vm-stop:
limactl stop $(VM)
vm-delete:
limactl delete $(VM)
vm-shell:
limactl shell --workdir $(PROJECT_DIR) $(VM)
vm-test:
limactl shell --workdir $(PROJECT_DIR) $(VM) -- make test