-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathMakefile
More file actions
249 lines (217 loc) · 10.5 KB
/
Copy pathMakefile
File metadata and controls
249 lines (217 loc) · 10.5 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
# Copyright (C) 2026 Intel Corporation
# SPDX-License-Identifier: PostgreSQL
EXTENSION = svs
EXTVERSION = 0.1.0
MODULE_big = svs
DATA = sql/$(EXTENSION)--$(EXTVERSION).sql
OBJS = src/svs.o \
src/vamana.o \
src/svs_cpu_budget.o \
src/svs_memory.o \
src/svs_index_residency.o \
src/svs_slot_naming.o \
src/vamanalauncher.o \
src/vamana_replication.o \
src/vamana_checkpoint.o \
src/vamana_undo.o \
src/vamana_subxid_pending_array.o \
src/vamana_subxact_guard.o \
src/svs_vector_buffer.o \
src/vamanabuild.o \
src/svs_parallel_build.o \
src/svs_build_thread_grant.o \
src/svs_build_request_protocol.o \
src/svs_cpu_slots.o \
src/vamanacache.o \
src/vamanaio.o \
src/vamanainsert.o \
src/vamanascan.o \
src/vamanautils.o \
src/vamanavacuum.o \
src/vamanaworker.o \
src/vamanaworkerstats.o \
src/vamanaworkershmem.o \
src/vamanaworkerindex.o \
src/vamanaworkersearch.o \
src/vamanaworkerwrite.o \
src/svs_wrapper.o \
src/svs_capacity_search.o \
src/vamana_databases.o \
src/vamana_teardown.o \
src/vamana_warmup.o
HEADERS = src/vamana.h src/svs_wrapper.h src/vamana_databases.h src/vamanalauncher.h src/svs_cpu_budget.h src/svs_memory.h src/svs_index_residency.h src/svs_slot_naming.h src/svs_cpu_slots.h src/svs_capacity_search.h src/svs_vector_buffer.h
# halfvec_compression/vector_compression build real LeanVec and LVQ indexes,
# which require hardware most CI runners lack. Excluded from TESTS/REGRESS so
# plain 'make installcheck' never attempts them; run via 'make installcheck-hw'.
HW_TESTS = halfvec_compression vector_compression
TESTS = $(filter-out $(addprefix test/sql/,$(addsuffix .sql,$(HW_TESTS))),$(wildcard test/sql/*.sql))
# Same hardware limitation, TAP side: these files build real LeanVec/LVQ
# indexes. Excluded from the default 'prove_installcheck' file list so it
# never attempts them; run via 'make prove_installcheck-hw'.
HW_TAP_TESTS = test/t/39_persistence_compression.pl test/t/44_build_memory_calibration_compression.pl
REGRESS = $(patsubst test/sql/%.sql,%,$(TESTS))
# Load pgvector first (for vector/halfvec types), then this extension
REGRESS_OPTS = --inputdir=test --load-extension=vector --load-extension=$(EXTENSION)
# To compile for portability, run: make OPTFLAGS=""
OPTFLAGS = -march=native
# Mac ARM doesn't always support -march=native
ifeq ($(shell uname -s), Darwin)
ifeq ($(shell uname -p), arm)
OPTFLAGS =
endif
endif
# PowerPC doesn't support -march=native
ifneq ($(filter ppc64%, $(shell uname -m)), )
OPTFLAGS =
endif
# RISC-V64 doesn't support -march=native
ifeq ($(shell uname -m), riscv64)
OPTFLAGS =
endif
# Hardening flags. -Wall, -Wformat, -Wformat-security, -Wimplicit-fallthrough,
# and -fPIC already come from pg_config; they are restated here for clarity.
# New protections added by this Makefile: -Werror=format-security,
# -fstack-protector-strong, -fstack-clash-protection, _FORTIFY_SOURCE uplift,
# and -Wl,-z,now (see HARDENING_LDFLAGS).
# -Werror is opt-in via WERROR=1 (e.g. in CI): a shipped -Werror is not safe
# across future compiler and PostgreSQL releases. -Werror=format-security is
# unconditional as it guards a specific, narrow class of bug.
# -Wconversion/-Wextra omitted: trigger errors in PostgreSQL system headers.
# -U_FORTIFY_SOURCE before -D avoids a redefinition diagnostic on distros that
# predefine it. Level 3 requires GCC 12+; GCC 11 gets 2.
FORTIFY_LEVEL := $(shell [ "$$(${CC:-gcc} -dumpversion 2>/dev/null | cut -d. -f1)" -ge 12 ] 2>/dev/null && echo 3 || echo 2)
HARDENING_CFLAGS = -Wall -Wimplicit-fallthrough \
-Wformat -Wformat-security -Werror=format-security \
-fstack-protector-strong -fstack-clash-protection \
-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=$(FORTIFY_LEVEL) -fPIC
ifeq ($(WERROR),1)
HARDENING_CFLAGS += -Werror
endif
# Linker hardening flags. -z,noexecstack and -z,relro are distro defaults;
# -z,now is the load-bearing addition (full RELRO; not a default for shared libs).
# -z,nodlopen omitted: PostgreSQL loads extensions via dlopen.
HARDENING_LDFLAGS = -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now
PG_CFLAGS += $(OPTFLAGS) -ftree-vectorize -fassociative-math -fno-signed-zeros -fno-trapping-math $(HARDENING_CFLAGS)
# Coverage instrumentation, opt-in via 'make COVERAGE=1'. Kept out of default
# builds because --coverage slows the binary and writes .gcda files at runtime.
ifeq ($(COVERAGE),1)
PG_CFLAGS += --coverage
SHLIB_LINK += --coverage
endif
# SVS library paths
SVS_INSTALL ?= svs_install_public
# Validate SVS library exists
ifeq (,$(wildcard $(SVS_INSTALL)/lib/libsvs_c_api.so))
$(error SVS library not found at $(SVS_INSTALL)/lib/libsvs_c_api.so. Run build_svs_public.sh first or set SVS_INSTALL correctly)
endif
# -isystem, not -I, for the SVS C API headers: they are a third-party
# dependency this project does not control, and svs_c.h trips
# -Wdeclaration-after-statement (part of pg_config's own --cflags). -isystem
# suppresses warnings from headers found through it, so WERROR=1 in CI is not
# tripped by someone else's header.
PG_CPPFLAGS += -isystem $(SVS_INSTALL)/include -I$(shell $(PG_CONFIG) --includedir-server)/extension/vector
SHLIB_LINK += -L$(SVS_INSTALL)/lib -lsvs_c_api -Wl,-rpath,$(SVS_INSTALL)/lib $(HARDENING_LDFLAGS)
PG_CONFIG ?= pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
# Remove GCC coverage artefacts on 'make clean'
EXTRA_CLEAN = $(wildcard src/*.gcda) $(wildcard src/*.gcno)
include $(PGXS)
# Expose the build's injection-point setting to TAP tests (fault-path tests
# skip themselves when it is not 'yes').
export enable_injection_points
# for Mac
ifeq ($(PROVE),)
PROVE = prove
endif
# for Postgres < 15
PROVE_FLAGS += -I ./test/perl
# ---------------------------------------------------------------------------
# Stale-install guard
#
# 'installcheck' and 'prove_installcheck' run against whatever is already
# installed in pkglibdir, not against what was just built: neither target
# depends on 'install'. That means a tree that fails to build, or one whose
# source changed since the last 'make install', can still report a full test
# pass, because the tests never look at the tree. This guard closes that gap
# by refusing to run either target when the built and installed shlib differ.
#
# It deliberately does not add 'install' as a prerequisite: testing an
# already-installed build is a normal developer workflow, and an implicit
# install would write into a system directory without being asked.
# ---------------------------------------------------------------------------
.PHONY: guard-fresh-install
guard-fresh-install:
@if [ ! -f '$(DESTDIR)$(pkglibdir)/$(shlib)' ]; then \
echo "error: $(shlib) is not installed at $(DESTDIR)$(pkglibdir)/$(shlib)."; \
echo " Run 'make install' first."; \
exit 1; \
fi
@if ! cmp -s '$(CURDIR)/$(shlib)' '$(DESTDIR)$(pkglibdir)/$(shlib)'; then \
echo "error: built $(CURDIR)/$(shlib) differs from installed $(DESTDIR)$(pkglibdir)/$(shlib)."; \
echo " Run 'make install' to test what was just built."; \
exit 1; \
fi
installcheck: guard-fresh-install
# ---------------------------------------------------------------------------
# Hardware-dependent regression tests
#
# halfvec_compression.sql and vector_compression.sql build real LeanVec and
# LVQ compressed indexes via SVS, which require hardware most CI runners
# lack. Run this target explicitly on hardware that supports it; it is not
# part of plain 'installcheck'.
# ---------------------------------------------------------------------------
.PHONY: installcheck-hw
installcheck-hw: guard-fresh-install
$(MAKE) installcheck REGRESS="$(HW_TESTS)"
# ---------------------------------------------------------------------------
# Hardening verification (SDL429 evidence)
#
# Confirms the protections in HARDENING_CFLAGS/HARDENING_LDFLAGS actually took
# effect in the built svs.so, using only readelf and nm from binutils, which
# the build already requires. Checks svs.so only: the SVS C API library it
# links against is a dependency this project does not build or release.
# ---------------------------------------------------------------------------
.PHONY: hardening-check
SVS_SO ?= $(CURDIR)/$(shlib)
hardening-check:
@sh $(CURDIR)/ci/hardening_check.sh '$(SVS_SO)'
prove_installcheck: guard-fresh-install
rm -rf $(CURDIR)/tmp_check
cd $(srcdir) && TESTDIR='$(CURDIR)' PATH="$(bindir):$$PATH" LD_LIBRARY_PATH="$(shell $(PG_CONFIG) --libdir):$$LD_LIBRARY_PATH" PGPORT='6$(DEF_PGPORT)' PG_REGRESS='$(top_builddir)/src/test/regress/pg_regress' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),$(filter-out $(HW_TAP_TESTS),$(wildcard test/t/*.pl)))
# ---------------------------------------------------------------------------
# Hardware-dependent TAP tests
#
# 39_persistence_compression.pl and 44_build_memory_calibration_compression.pl
# build real LeanVec and LVQ compressed indexes via SVS, which require
# hardware most CI runners lack. Run this target explicitly on hardware that
# supports it; it is not part of plain 'prove_installcheck'.
# ---------------------------------------------------------------------------
.PHONY: prove_installcheck-hw
prove_installcheck-hw: guard-fresh-install
$(MAKE) prove_installcheck PROVE_TESTS="$(HW_TAP_TESTS)"
# ---------------------------------------------------------------------------
# Coverage report targets
#
# Workflow:
# 1. make COVERAGE=1 (builds with instrumentation)
# 2. make install && make prove_installcheck (accumulates .gcda counters)
# 3. make coverage (generates all three report formats)
#
# To start a clean measurement run:
# make coverage-clean && make prove_installcheck && make coverage
# ---------------------------------------------------------------------------
GCOVR ?= gcovr
COVERAGE_FILTER = --filter src/
# coverage: generate text summary, AI-consumable JSON, and interactive HTML
coverage:
mkdir -p coverage_reports
$(GCOVR) $(COVERAGE_FILTER) --txt coverage_reports/coverage.txt
$(GCOVR) $(COVERAGE_FILTER) --json-pretty --output coverage_reports/coverage.json
$(GCOVR) $(COVERAGE_FILTER) --html-details coverage_reports/index.html
@echo "Coverage reports written to coverage_reports/"
# coverage-clean: zero .gcda counters so the next test run starts fresh.
# Does NOT remove .gcno files (those require a recompile to regenerate).
coverage-clean:
find $(CURDIR)/src -name '*.gcda' -delete
@echo "Coverage counters reset (*.gcda removed)"
.PHONY: coverage coverage-clean