1# SPDX-License-Identifier: GPL-2.0 2include ../../../build/Build.include 3include ../../../scripts/Makefile.arch 4include ../../../scripts/Makefile.include 5 6CXX ?= $(CROSS_COMPILE)g++ 7 8CURDIR := $(abspath .) 9TOOLSDIR := $(abspath ../../..) 10LIBDIR := $(TOOLSDIR)/lib 11BPFDIR := $(LIBDIR)/bpf 12TOOLSINCDIR := $(TOOLSDIR)/include 13BPFTOOLDIR := $(TOOLSDIR)/bpf/bpftool 14APIDIR := $(TOOLSINCDIR)/uapi 15ifneq ($(O),) 16GENDIR := $(O)/include/generated 17else 18GENDIR := $(abspath ../../../../include/generated) 19endif 20GENHDR := $(GENDIR)/autoconf.h 21HOSTPKG_CONFIG := pkg-config 22 23ifneq ($(wildcard $(GENHDR)),) 24 GENFLAGS := -DHAVE_GENHDR 25endif 26 27BPF_GCC ?= $(shell command -v bpf-gcc;) 28SAN_CFLAGS ?= 29SAN_LDFLAGS ?= $(SAN_CFLAGS) 30RELEASE ?= 31OPT_FLAGS ?= $(if $(RELEASE),-O2,-O0) 32CFLAGS += -g $(OPT_FLAGS) -rdynamic \ 33 -Wall -Werror \ 34 $(GENFLAGS) $(SAN_CFLAGS) \ 35 -I$(CURDIR) -I$(INCLUDE_DIR) -I$(GENDIR) -I$(LIBDIR) \ 36 -I$(TOOLSINCDIR) -I$(APIDIR) -I$(OUTPUT) 37LDFLAGS += $(SAN_LDFLAGS) 38LDLIBS += -lelf -lz -lrt -lpthread 39 40ifneq ($(LLVM),) 41# Silence some warnings when compiled with clang 42CFLAGS += -Wno-unused-command-line-argument 43endif 44 45# Check whether bpf cpu=v4 is supported or not by clang 46ifneq ($(shell $(CLANG) --target=bpf -mcpu=help 2>&1 | grep 'v4'),) 47CLANG_CPUV4 := 1 48endif 49 50# Order correspond to 'make run_tests' order 51TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \ 52 test_dev_cgroup \ 53 test_sock test_sockmap get_cgroup_id_user \ 54 test_cgroup_storage \ 55 test_tcpnotify_user test_sysctl \ 56 test_progs-no_alu32 57TEST_INST_SUBDIRS := no_alu32 58 59# Also test bpf-gcc, if present 60ifneq ($(BPF_GCC),) 61TEST_GEN_PROGS += test_progs-bpf_gcc 62TEST_INST_SUBDIRS += bpf_gcc 63endif 64 65ifneq ($(CLANG_CPUV4),) 66TEST_GEN_PROGS += test_progs-cpuv4 67TEST_INST_SUBDIRS += cpuv4 68endif 69 70TEST_GEN_FILES = test_lwt_ip_encap.bpf.o test_tc_edt.bpf.o 71TEST_FILES = xsk_prereqs.sh $(wildcard progs/btf_dump_test_case_*.c) 72 73# Order correspond to 'make run_tests' order 74TEST_PROGS := test_kmod.sh \ 75 test_xdp_redirect.sh \ 76 test_xdp_redirect_multi.sh \ 77 test_xdp_meta.sh \ 78 test_xdp_veth.sh \ 79 test_offload.py \ 80 test_sock_addr.sh \ 81 test_tunnel.sh \ 82 test_lwt_seg6local.sh \ 83 test_lirc_mode2.sh \ 84 test_skb_cgroup_id.sh \ 85 test_flow_dissector.sh \ 86 test_xdp_vlan_mode_generic.sh \ 87 test_xdp_vlan_mode_native.sh \ 88 test_lwt_ip_encap.sh \ 89 test_tcp_check_syncookie.sh \ 90 test_tc_tunnel.sh \ 91 test_tc_edt.sh \ 92 test_xdping.sh \ 93 test_bpftool_build.sh \ 94 test_bpftool.sh \ 95 test_bpftool_metadata.sh \ 96 test_doc_build.sh \ 97 test_xsk.sh \ 98 test_xdp_features.sh 99 100TEST_PROGS_EXTENDED := with_addr.sh \ 101 with_tunnels.sh ima_setup.sh verify_sig_setup.sh \ 102 test_xdp_vlan.sh test_bpftool.py 103 104# Compile but not part of 'make run_tests' 105TEST_GEN_PROGS_EXTENDED = test_sock_addr test_skb_cgroup_id_user \ 106 flow_dissector_load test_flow_dissector test_tcp_check_syncookie_user \ 107 test_lirc_mode2_user xdping test_cpp runqslower bench bpf_testmod.ko \ 108 xskxceiver xdp_redirect_multi xdp_synproxy veristat xdp_hw_metadata \ 109 xdp_features 110 111TEST_GEN_FILES += liburandom_read.so urandom_read sign-file uprobe_multi 112 113# Emit succinct information message describing current building step 114# $1 - generic step name (e.g., CC, LINK, etc); 115# $2 - optional "flavor" specifier; if provided, will be emitted as [flavor]; 116# $3 - target (assumed to be file); only file name will be emitted; 117# $4 - optional extra arg, emitted as-is, if provided. 118ifeq ($(V),1) 119Q = 120msg = 121else 122Q = @ 123msg = @printf ' %-8s%s %s%s\n' "$(1)" "$(if $(2), [$(2)])" "$(notdir $(3))" "$(if $(4), $(4))"; 124MAKEFLAGS += --no-print-directory 125submake_extras := feature_display=0 126endif 127 128# override lib.mk's default rules 129OVERRIDE_TARGETS := 1 130override define CLEAN 131 $(call msg,CLEAN) 132 $(Q)$(RM) -r $(TEST_GEN_PROGS) 133 $(Q)$(RM) -r $(TEST_GEN_PROGS_EXTENDED) 134 $(Q)$(RM) -r $(TEST_GEN_FILES) 135 $(Q)$(RM) -r $(EXTRA_CLEAN) 136 $(Q)$(MAKE) -C bpf_testmod clean 137 $(Q)$(MAKE) docs-clean 138endef 139 140include ../lib.mk 141 142SCRATCH_DIR := $(OUTPUT)/tools 143BUILD_DIR := $(SCRATCH_DIR)/build 144INCLUDE_DIR := $(SCRATCH_DIR)/include 145BPFOBJ := $(BUILD_DIR)/libbpf/libbpf.a 146ifneq ($(CROSS_COMPILE),) 147HOST_BUILD_DIR := $(BUILD_DIR)/host 148HOST_SCRATCH_DIR := $(OUTPUT)/host-tools 149HOST_INCLUDE_DIR := $(HOST_SCRATCH_DIR)/include 150else 151HOST_BUILD_DIR := $(BUILD_DIR) 152HOST_SCRATCH_DIR := $(SCRATCH_DIR) 153HOST_INCLUDE_DIR := $(INCLUDE_DIR) 154endif 155HOST_BPFOBJ := $(HOST_BUILD_DIR)/libbpf/libbpf.a 156RESOLVE_BTFIDS := $(HOST_BUILD_DIR)/resolve_btfids/resolve_btfids 157RUNQSLOWER_OUTPUT := $(BUILD_DIR)/runqslower/ 158 159VMLINUX_BTF_PATHS ?= $(if $(O),$(O)/vmlinux) \ 160 $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux) \ 161 ../../../../vmlinux \ 162 /sys/kernel/btf/vmlinux \ 163 /boot/vmlinux-$(shell uname -r) 164VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS)))) 165ifeq ($(VMLINUX_BTF),) 166$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)") 167endif 168 169# Define simple and short `make test_progs`, `make test_sysctl`, etc targets 170# to build individual tests. 171# NOTE: Semicolon at the end is critical to override lib.mk's default static 172# rule for binaries. 173$(notdir $(TEST_GEN_PROGS) \ 174 $(TEST_GEN_PROGS_EXTENDED) \ 175 $(TEST_CUSTOM_PROGS)): %: $(OUTPUT)/% ; 176 177# sort removes libbpf duplicates when not cross-building 178MAKE_DIRS := $(sort $(BUILD_DIR)/libbpf $(HOST_BUILD_DIR)/libbpf \ 179 $(BUILD_DIR)/bpftool $(HOST_BUILD_DIR)/bpftool \ 180 $(HOST_BUILD_DIR)/resolve_btfids \ 181 $(RUNQSLOWER_OUTPUT) $(INCLUDE_DIR)) 182$(MAKE_DIRS): 183 $(call msg,MKDIR,,$@) 184 $(Q)mkdir -p $@ 185 186$(OUTPUT)/%.o: %.c 187 $(call msg,CC,,$@) 188 $(Q)$(CC) $(CFLAGS) -c $(filter %.c,$^) $(LDLIBS) -o $@ 189 190$(OUTPUT)/%:%.c 191 $(call msg,BINARY,,$@) 192 $(Q)$(LINK.c) $^ $(LDLIBS) -o $@ 193 194# LLVM's ld.lld doesn't support all the architectures, so use it only on x86 195ifeq ($(SRCARCH),$(filter $(SRCARCH),x86 riscv)) 196LLD := lld 197else 198LLD := ld 199endif 200 201# Filter out -static for liburandom_read.so and its dependent targets so that static builds 202# do not fail. Static builds leave urandom_read relying on system-wide shared libraries. 203$(OUTPUT)/liburandom_read.so: urandom_read_lib1.c urandom_read_lib2.c liburandom_read.map 204 $(call msg,LIB,,$@) 205 $(Q)$(CLANG) $(CLANG_TARGET_ARCH) \ 206 $(filter-out -static,$(CFLAGS) $(LDFLAGS)) \ 207 $(filter %.c,$^) $(filter-out -static,$(LDLIBS)) \ 208 -fuse-ld=$(LLD) -Wl,-znoseparate-code -Wl,--build-id=sha1 \ 209 -Wl,--version-script=liburandom_read.map \ 210 -fPIC -shared -o $@ 211 212$(OUTPUT)/urandom_read: urandom_read.c urandom_read_aux.c $(OUTPUT)/liburandom_read.so 213 $(call msg,BINARY,,$@) 214 $(Q)$(CLANG) $(CLANG_TARGET_ARCH) \ 215 $(filter-out -static,$(CFLAGS) $(LDFLAGS)) $(filter %.c,$^) \ 216 -lurandom_read $(filter-out -static,$(LDLIBS)) -L$(OUTPUT) \ 217 -fuse-ld=$(LLD) -Wl,-znoseparate-code -Wl,--build-id=sha1 \ 218 -Wl,-rpath=. -o $@ 219 220$(OUTPUT)/sign-file: ../../../../scripts/sign-file.c 221 $(call msg,SIGN-FILE,,$@) 222 $(Q)$(CC) $(shell $(HOSTPKG_CONFIG) --cflags libcrypto 2> /dev/null) \ 223 $< -o $@ \ 224 $(shell $(HOSTPKG_CONFIG) --libs libcrypto 2> /dev/null || echo -lcrypto) 225 226$(OUTPUT)/bpf_testmod.ko: $(VMLINUX_BTF) $(RESOLVE_BTFIDS) $(wildcard bpf_testmod/Makefile bpf_testmod/*.[ch]) 227 $(call msg,MOD,,$@) 228 $(Q)$(RM) bpf_testmod/bpf_testmod.ko # force re-compilation 229 $(Q)$(MAKE) $(submake_extras) RESOLVE_BTFIDS=$(RESOLVE_BTFIDS) -C bpf_testmod 230 $(Q)cp bpf_testmod/bpf_testmod.ko $@ 231 232DEFAULT_BPFTOOL := $(HOST_SCRATCH_DIR)/sbin/bpftool 233ifneq ($(CROSS_COMPILE),) 234CROSS_BPFTOOL := $(SCRATCH_DIR)/sbin/bpftool 235TRUNNER_BPFTOOL := $(CROSS_BPFTOOL) 236USE_BOOTSTRAP := "" 237else 238TRUNNER_BPFTOOL := $(DEFAULT_BPFTOOL) 239USE_BOOTSTRAP := "bootstrap/" 240endif 241 242$(OUTPUT)/runqslower: $(BPFOBJ) | $(DEFAULT_BPFTOOL) $(RUNQSLOWER_OUTPUT) 243 $(Q)$(MAKE) $(submake_extras) -C $(TOOLSDIR)/bpf/runqslower \ 244 OUTPUT=$(RUNQSLOWER_OUTPUT) VMLINUX_BTF=$(VMLINUX_BTF) \ 245 BPFTOOL_OUTPUT=$(HOST_BUILD_DIR)/bpftool/ \ 246 BPFOBJ_OUTPUT=$(BUILD_DIR)/libbpf \ 247 BPFOBJ=$(BPFOBJ) BPF_INCLUDE=$(INCLUDE_DIR) \ 248 EXTRA_CFLAGS='-g $(OPT_FLAGS) $(SAN_CFLAGS)' \ 249 EXTRA_LDFLAGS='$(SAN_LDFLAGS)' && \ 250 cp $(RUNQSLOWER_OUTPUT)runqslower $@ 251 252TEST_GEN_PROGS_EXTENDED += $(TRUNNER_BPFTOOL) 253 254$(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED): $(BPFOBJ) 255 256TESTING_HELPERS := $(OUTPUT)/testing_helpers.o 257CGROUP_HELPERS := $(OUTPUT)/cgroup_helpers.o 258UNPRIV_HELPERS := $(OUTPUT)/unpriv_helpers.o 259TRACE_HELPERS := $(OUTPUT)/trace_helpers.o 260JSON_WRITER := $(OUTPUT)/json_writer.o 261CAP_HELPERS := $(OUTPUT)/cap_helpers.o 262 263$(OUTPUT)/test_dev_cgroup: $(CGROUP_HELPERS) $(TESTING_HELPERS) 264$(OUTPUT)/test_skb_cgroup_id_user: $(CGROUP_HELPERS) $(TESTING_HELPERS) 265$(OUTPUT)/test_sock: $(CGROUP_HELPERS) $(TESTING_HELPERS) 266$(OUTPUT)/test_sock_addr: $(CGROUP_HELPERS) $(TESTING_HELPERS) 267$(OUTPUT)/test_sockmap: $(CGROUP_HELPERS) $(TESTING_HELPERS) 268$(OUTPUT)/test_tcpnotify_user: $(CGROUP_HELPERS) $(TESTING_HELPERS) $(TRACE_HELPERS) 269$(OUTPUT)/get_cgroup_id_user: $(CGROUP_HELPERS) $(TESTING_HELPERS) 270$(OUTPUT)/test_cgroup_storage: $(CGROUP_HELPERS) $(TESTING_HELPERS) 271$(OUTPUT)/test_sock_fields: $(CGROUP_HELPERS) $(TESTING_HELPERS) 272$(OUTPUT)/test_sysctl: $(CGROUP_HELPERS) $(TESTING_HELPERS) 273$(OUTPUT)/test_tag: $(TESTING_HELPERS) 274$(OUTPUT)/test_lirc_mode2_user: $(TESTING_HELPERS) 275$(OUTPUT)/xdping: $(TESTING_HELPERS) 276$(OUTPUT)/flow_dissector_load: $(TESTING_HELPERS) 277$(OUTPUT)/test_maps: $(TESTING_HELPERS) 278$(OUTPUT)/test_verifier: $(TESTING_HELPERS) $(CAP_HELPERS) $(UNPRIV_HELPERS) 279$(OUTPUT)/xsk.o: $(BPFOBJ) 280 281BPFTOOL ?= $(DEFAULT_BPFTOOL) 282$(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) \ 283 $(HOST_BPFOBJ) | $(HOST_BUILD_DIR)/bpftool 284 $(Q)$(MAKE) $(submake_extras) -C $(BPFTOOLDIR) \ 285 ARCH= CROSS_COMPILE= CC="$(HOSTCC)" LD="$(HOSTLD)" \ 286 EXTRA_CFLAGS='-g $(OPT_FLAGS)' \ 287 OUTPUT=$(HOST_BUILD_DIR)/bpftool/ \ 288 LIBBPF_OUTPUT=$(HOST_BUILD_DIR)/libbpf/ \ 289 LIBBPF_DESTDIR=$(HOST_SCRATCH_DIR)/ \ 290 prefix= DESTDIR=$(HOST_SCRATCH_DIR)/ install-bin 291 292ifneq ($(CROSS_COMPILE),) 293$(CROSS_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) \ 294 $(BPFOBJ) | $(BUILD_DIR)/bpftool 295 $(Q)$(MAKE) $(submake_extras) -C $(BPFTOOLDIR) \ 296 ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) \ 297 EXTRA_CFLAGS='-g $(OPT_FLAGS)' \ 298 OUTPUT=$(BUILD_DIR)/bpftool/ \ 299 LIBBPF_OUTPUT=$(BUILD_DIR)/libbpf/ \ 300 LIBBPF_DESTDIR=$(SCRATCH_DIR)/ \ 301 prefix= DESTDIR=$(SCRATCH_DIR)/ install-bin 302endif 303 304all: docs 305 306docs: 307 $(Q)RST2MAN_OPTS="--exit-status=1" $(MAKE) $(submake_extras) \ 308 -f Makefile.docs \ 309 prefix= OUTPUT=$(OUTPUT)/ DESTDIR=$(OUTPUT)/ $@ 310 311docs-clean: 312 $(Q)$(MAKE) $(submake_extras) \ 313 -f Makefile.docs \ 314 prefix= OUTPUT=$(OUTPUT)/ DESTDIR=$(OUTPUT)/ $@ 315 316$(BPFOBJ): $(wildcard $(BPFDIR)/*.[ch] $(BPFDIR)/Makefile) \ 317 $(APIDIR)/linux/bpf.h \ 318 | $(BUILD_DIR)/libbpf 319 $(Q)$(MAKE) $(submake_extras) -C $(BPFDIR) OUTPUT=$(BUILD_DIR)/libbpf/ \ 320 EXTRA_CFLAGS='-g $(OPT_FLAGS) $(SAN_CFLAGS)' \ 321 EXTRA_LDFLAGS='$(SAN_LDFLAGS)' \ 322 DESTDIR=$(SCRATCH_DIR) prefix= all install_headers 323 324ifneq ($(BPFOBJ),$(HOST_BPFOBJ)) 325$(HOST_BPFOBJ): $(wildcard $(BPFDIR)/*.[ch] $(BPFDIR)/Makefile) \ 326 $(APIDIR)/linux/bpf.h \ 327 | $(HOST_BUILD_DIR)/libbpf 328 $(Q)$(MAKE) $(submake_extras) -C $(BPFDIR) \ 329 EXTRA_CFLAGS='-g $(OPT_FLAGS)' ARCH= CROSS_COMPILE= \ 330 OUTPUT=$(HOST_BUILD_DIR)/libbpf/ \ 331 CC="$(HOSTCC)" LD="$(HOSTLD)" \ 332 DESTDIR=$(HOST_SCRATCH_DIR)/ prefix= all install_headers 333endif 334 335$(INCLUDE_DIR)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL) | $(INCLUDE_DIR) 336ifeq ($(VMLINUX_H),) 337 $(call msg,GEN,,$@) 338 $(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@ 339else 340 $(call msg,CP,,$@) 341 $(Q)cp "$(VMLINUX_H)" $@ 342endif 343 344$(RESOLVE_BTFIDS): $(HOST_BPFOBJ) | $(HOST_BUILD_DIR)/resolve_btfids \ 345 $(TOOLSDIR)/bpf/resolve_btfids/main.c \ 346 $(TOOLSDIR)/lib/rbtree.c \ 347 $(TOOLSDIR)/lib/zalloc.c \ 348 $(TOOLSDIR)/lib/string.c \ 349 $(TOOLSDIR)/lib/ctype.c \ 350 $(TOOLSDIR)/lib/str_error_r.c 351 $(Q)$(MAKE) $(submake_extras) -C $(TOOLSDIR)/bpf/resolve_btfids \ 352 CC="$(HOSTCC)" LD="$(HOSTLD)" AR="$(HOSTAR)" \ 353 LIBBPF_INCLUDE=$(HOST_INCLUDE_DIR) \ 354 OUTPUT=$(HOST_BUILD_DIR)/resolve_btfids/ BPFOBJ=$(HOST_BPFOBJ) 355 356# Get Clang's default includes on this system, as opposed to those seen by 357# '--target=bpf'. This fixes "missing" files on some architectures/distros, 358# such as asm/byteorder.h, asm/socket.h, asm/sockios.h, sys/cdefs.h etc. 359# 360# Use '-idirafter': Don't interfere with include mechanics except where the 361# build would have failed anyways. 362define get_sys_includes 363$(shell $(1) $(2) -v -E - </dev/null 2>&1 \ 364 | sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') \ 365$(shell $(1) $(2) -dM -E - </dev/null | grep '__riscv_xlen ' | awk '{printf("-D__riscv_xlen=%d -D__BITS_PER_LONG=%d", $$3, $$3)}') \ 366$(shell $(1) $(2) -dM -E - </dev/null | grep '__loongarch_grlen ' | awk '{printf("-D__BITS_PER_LONG=%d", $$3)}') 367endef 368 369# Determine target endianness. 370IS_LITTLE_ENDIAN = $(shell $(CC) -dM -E - </dev/null | \ 371 grep 'define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__') 372MENDIAN=$(if $(IS_LITTLE_ENDIAN),-mlittle-endian,-mbig-endian) 373 374ifneq ($(CROSS_COMPILE),) 375CLANG_TARGET_ARCH = --target=$(notdir $(CROSS_COMPILE:%-=%)) 376endif 377 378CLANG_SYS_INCLUDES = $(call get_sys_includes,$(CLANG),$(CLANG_TARGET_ARCH)) 379BPF_CFLAGS = -g -Wall -Werror -D__TARGET_ARCH_$(SRCARCH) $(MENDIAN) \ 380 -I$(INCLUDE_DIR) -I$(CURDIR) -I$(APIDIR) \ 381 -I$(abspath $(OUTPUT)/../usr/include) 382 383CLANG_CFLAGS = $(CLANG_SYS_INCLUDES) \ 384 -Wno-compare-distinct-pointer-types 385 386$(OUTPUT)/test_l4lb_noinline.o: BPF_CFLAGS += -fno-inline 387$(OUTPUT)/test_xdp_noinline.o: BPF_CFLAGS += -fno-inline 388 389$(OUTPUT)/flow_dissector_load.o: flow_dissector_load.h 390$(OUTPUT)/cgroup_getset_retval_hooks.o: cgroup_getset_retval_hooks.h 391 392# Build BPF object using Clang 393# $1 - input .c file 394# $2 - output .o file 395# $3 - CFLAGS 396define CLANG_BPF_BUILD_RULE 397 $(call msg,CLNG-BPF,$(TRUNNER_BINARY),$2) 398 $(Q)$(CLANG) $3 -O2 --target=bpf -c $1 -mcpu=v3 -o $2 399endef 400# Similar to CLANG_BPF_BUILD_RULE, but with disabled alu32 401define CLANG_NOALU32_BPF_BUILD_RULE 402 $(call msg,CLNG-BPF,$(TRUNNER_BINARY),$2) 403 $(Q)$(CLANG) $3 -O2 --target=bpf -c $1 -mcpu=v2 -o $2 404endef 405# Similar to CLANG_BPF_BUILD_RULE, but with cpu-v4 406define CLANG_CPUV4_BPF_BUILD_RULE 407 $(call msg,CLNG-BPF,$(TRUNNER_BINARY),$2) 408 $(Q)$(CLANG) $3 -O2 --target=bpf -c $1 -mcpu=v4 -o $2 409endef 410# Build BPF object using GCC 411define GCC_BPF_BUILD_RULE 412 $(call msg,GCC-BPF,$(TRUNNER_BINARY),$2) 413 $(Q)$(BPF_GCC) $3 -O2 -c $1 -o $2 414endef 415 416SKEL_BLACKLIST := btf__% test_pinning_invalid.c test_sk_assign.c 417 418LINKED_SKELS := test_static_linked.skel.h linked_funcs.skel.h \ 419 linked_vars.skel.h linked_maps.skel.h \ 420 test_subskeleton.skel.h test_subskeleton_lib.skel.h \ 421 test_usdt.skel.h 422 423LSKELS := fentry_test.c fexit_test.c fexit_sleep.c atomics.c \ 424 trace_printk.c trace_vprintk.c map_ptr_kern.c \ 425 core_kern.c core_kern_overflow.c test_ringbuf.c \ 426 test_ringbuf_map_key.c 427 428# Generate both light skeleton and libbpf skeleton for these 429LSKELS_EXTRA := test_ksyms_module.c test_ksyms_weak.c kfunc_call_test.c \ 430 kfunc_call_test_subprog.c 431SKEL_BLACKLIST += $$(LSKELS) 432 433test_static_linked.skel.h-deps := test_static_linked1.bpf.o test_static_linked2.bpf.o 434linked_funcs.skel.h-deps := linked_funcs1.bpf.o linked_funcs2.bpf.o 435linked_vars.skel.h-deps := linked_vars1.bpf.o linked_vars2.bpf.o 436linked_maps.skel.h-deps := linked_maps1.bpf.o linked_maps2.bpf.o 437# In the subskeleton case, we want the test_subskeleton_lib.subskel.h file 438# but that's created as a side-effect of the skel.h generation. 439test_subskeleton.skel.h-deps := test_subskeleton_lib2.bpf.o test_subskeleton_lib.bpf.o test_subskeleton.bpf.o 440test_subskeleton_lib.skel.h-deps := test_subskeleton_lib2.bpf.o test_subskeleton_lib.bpf.o 441test_usdt.skel.h-deps := test_usdt.bpf.o test_usdt_multispec.bpf.o 442xsk_xdp_progs.skel.h-deps := xsk_xdp_progs.bpf.o 443xdp_hw_metadata.skel.h-deps := xdp_hw_metadata.bpf.o 444xdp_features.skel.h-deps := xdp_features.bpf.o 445 446LINKED_BPF_SRCS := $(patsubst %.bpf.o,%.c,$(foreach skel,$(LINKED_SKELS),$($(skel)-deps))) 447 448# Set up extra TRUNNER_XXX "temporary" variables in the environment (relies on 449# $eval()) and pass control to DEFINE_TEST_RUNNER_RULES. 450# Parameters: 451# $1 - test runner base binary name (e.g., test_progs) 452# $2 - test runner extra "flavor" (e.g., no_alu32, cpuv4, gcc-bpf, etc) 453define DEFINE_TEST_RUNNER 454 455TRUNNER_OUTPUT := $(OUTPUT)$(if $2,/)$2 456TRUNNER_BINARY := $1$(if $2,-)$2 457TRUNNER_TEST_OBJS := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.test.o, \ 458 $$(notdir $$(wildcard $(TRUNNER_TESTS_DIR)/*.c))) 459TRUNNER_EXTRA_OBJS := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.o, \ 460 $$(filter %.c,$(TRUNNER_EXTRA_SOURCES))) 461TRUNNER_EXTRA_HDRS := $$(filter %.h,$(TRUNNER_EXTRA_SOURCES)) 462TRUNNER_TESTS_HDR := $(TRUNNER_TESTS_DIR)/tests.h 463TRUNNER_BPF_SRCS := $$(notdir $$(wildcard $(TRUNNER_BPF_PROGS_DIR)/*.c)) 464TRUNNER_BPF_OBJS := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.bpf.o, $$(TRUNNER_BPF_SRCS)) 465TRUNNER_BPF_SKELS := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.skel.h, \ 466 $$(filter-out $(SKEL_BLACKLIST) $(LINKED_BPF_SRCS),\ 467 $$(TRUNNER_BPF_SRCS))) 468TRUNNER_BPF_LSKELS := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.lskel.h, $$(LSKELS) $$(LSKELS_EXTRA)) 469TRUNNER_BPF_SKELS_LINKED := $$(addprefix $$(TRUNNER_OUTPUT)/,$(LINKED_SKELS)) 470TEST_GEN_FILES += $$(TRUNNER_BPF_OBJS) 471 472# Evaluate rules now with extra TRUNNER_XXX variables above already defined 473$$(eval $$(call DEFINE_TEST_RUNNER_RULES,$1,$2)) 474 475endef 476 477# Using TRUNNER_XXX variables, provided by callers of DEFINE_TEST_RUNNER and 478# set up by DEFINE_TEST_RUNNER itself, create test runner build rules with: 479# $1 - test runner base binary name (e.g., test_progs) 480# $2 - test runner extra "flavor" (e.g., no_alu32, cpuv4, gcc-bpf, etc) 481define DEFINE_TEST_RUNNER_RULES 482 483ifeq ($($(TRUNNER_OUTPUT)-dir),) 484$(TRUNNER_OUTPUT)-dir := y 485$(TRUNNER_OUTPUT): 486 $$(call msg,MKDIR,,$$@) 487 $(Q)mkdir -p $$@ 488endif 489 490# ensure we set up BPF objects generation rule just once for a given 491# input/output directory combination 492ifeq ($($(TRUNNER_BPF_PROGS_DIR)$(if $2,-)$2-bpfobjs),) 493$(TRUNNER_BPF_PROGS_DIR)$(if $2,-)$2-bpfobjs := y 494$(TRUNNER_BPF_OBJS): $(TRUNNER_OUTPUT)/%.bpf.o: \ 495 $(TRUNNER_BPF_PROGS_DIR)/%.c \ 496 $(TRUNNER_BPF_PROGS_DIR)/*.h \ 497 $$(INCLUDE_DIR)/vmlinux.h \ 498 $(wildcard $(BPFDIR)/bpf_*.h) \ 499 $(wildcard $(BPFDIR)/*.bpf.h) \ 500 | $(TRUNNER_OUTPUT) $$(BPFOBJ) 501 $$(call $(TRUNNER_BPF_BUILD_RULE),$$<,$$@, \ 502 $(TRUNNER_BPF_CFLAGS)) 503 504$(TRUNNER_BPF_SKELS): %.skel.h: %.bpf.o $(BPFTOOL) | $(TRUNNER_OUTPUT) 505 $$(call msg,GEN-SKEL,$(TRUNNER_BINARY),$$@) 506 $(Q)$$(BPFTOOL) gen object $$(<:.o=.linked1.o) $$< 507 $(Q)$$(BPFTOOL) gen object $$(<:.o=.linked2.o) $$(<:.o=.linked1.o) 508 $(Q)$$(BPFTOOL) gen object $$(<:.o=.linked3.o) $$(<:.o=.linked2.o) 509 $(Q)diff $$(<:.o=.linked2.o) $$(<:.o=.linked3.o) 510 $(Q)$$(BPFTOOL) gen skeleton $$(<:.o=.linked3.o) name $$(notdir $$(<:.bpf.o=)) > $$@ 511 $(Q)$$(BPFTOOL) gen subskeleton $$(<:.o=.linked3.o) name $$(notdir $$(<:.bpf.o=)) > $$(@:.skel.h=.subskel.h) 512 513$(TRUNNER_BPF_LSKELS): %.lskel.h: %.bpf.o $(BPFTOOL) | $(TRUNNER_OUTPUT) 514 $$(call msg,GEN-SKEL,$(TRUNNER_BINARY),$$@) 515 $(Q)$$(BPFTOOL) gen object $$(<:.o=.llinked1.o) $$< 516 $(Q)$$(BPFTOOL) gen object $$(<:.o=.llinked2.o) $$(<:.o=.llinked1.o) 517 $(Q)$$(BPFTOOL) gen object $$(<:.o=.llinked3.o) $$(<:.o=.llinked2.o) 518 $(Q)diff $$(<:.o=.llinked2.o) $$(<:.o=.llinked3.o) 519 $(Q)$$(BPFTOOL) gen skeleton -L $$(<:.o=.llinked3.o) name $$(notdir $$(<:.bpf.o=_lskel)) > $$@ 520 521$(TRUNNER_BPF_SKELS_LINKED): $(TRUNNER_BPF_OBJS) $(BPFTOOL) | $(TRUNNER_OUTPUT) 522 $$(call msg,LINK-BPF,$(TRUNNER_BINARY),$$(@:.skel.h=.bpf.o)) 523 $(Q)$$(BPFTOOL) gen object $$(@:.skel.h=.linked1.o) $$(addprefix $(TRUNNER_OUTPUT)/,$$($$(@F)-deps)) 524 $(Q)$$(BPFTOOL) gen object $$(@:.skel.h=.linked2.o) $$(@:.skel.h=.linked1.o) 525 $(Q)$$(BPFTOOL) gen object $$(@:.skel.h=.linked3.o) $$(@:.skel.h=.linked2.o) 526 $(Q)diff $$(@:.skel.h=.linked2.o) $$(@:.skel.h=.linked3.o) 527 $$(call msg,GEN-SKEL,$(TRUNNER_BINARY),$$@) 528 $(Q)$$(BPFTOOL) gen skeleton $$(@:.skel.h=.linked3.o) name $$(notdir $$(@:.skel.h=)) > $$@ 529 $(Q)$$(BPFTOOL) gen subskeleton $$(@:.skel.h=.linked3.o) name $$(notdir $$(@:.skel.h=)) > $$(@:.skel.h=.subskel.h) 530endif 531 532# ensure we set up tests.h header generation rule just once 533ifeq ($($(TRUNNER_TESTS_DIR)-tests-hdr),) 534$(TRUNNER_TESTS_DIR)-tests-hdr := y 535$(TRUNNER_TESTS_HDR): $(TRUNNER_TESTS_DIR)/*.c 536 $$(call msg,TEST-HDR,$(TRUNNER_BINARY),$$@) 537 $$(shell (echo '/* Generated header, do not edit */'; \ 538 sed -n -E 's/^void (serial_)?test_([a-zA-Z0-9_]+)\((void)?\).*/DEFINE_TEST(\2)/p' \ 539 $(TRUNNER_TESTS_DIR)/*.c | sort ; \ 540 ) > $$@) 541endif 542 543# compile individual test files 544# Note: we cd into output directory to ensure embedded BPF object is found 545$(TRUNNER_TEST_OBJS): $(TRUNNER_OUTPUT)/%.test.o: \ 546 $(TRUNNER_TESTS_DIR)/%.c \ 547 $(TRUNNER_EXTRA_HDRS) \ 548 $(TRUNNER_BPF_OBJS) \ 549 $(TRUNNER_BPF_SKELS) \ 550 $(TRUNNER_BPF_LSKELS) \ 551 $(TRUNNER_BPF_SKELS_LINKED) \ 552 $$(BPFOBJ) | $(TRUNNER_OUTPUT) 553 $$(call msg,TEST-OBJ,$(TRUNNER_BINARY),$$@) 554 $(Q)cd $$(@D) && $$(CC) -I. $$(CFLAGS) -c $(CURDIR)/$$< $$(LDLIBS) -o $$(@F) 555 556$(TRUNNER_EXTRA_OBJS): $(TRUNNER_OUTPUT)/%.o: \ 557 %.c \ 558 $(TRUNNER_EXTRA_HDRS) \ 559 $(TRUNNER_TESTS_HDR) \ 560 $$(BPFOBJ) | $(TRUNNER_OUTPUT) 561 $$(call msg,EXT-OBJ,$(TRUNNER_BINARY),$$@) 562 $(Q)$$(CC) $$(CFLAGS) -c $$< $$(LDLIBS) -o $$@ 563 564# non-flavored in-srctree builds receive special treatment, in particular, we 565# do not need to copy extra resources (see e.g. test_btf_dump_case()) 566$(TRUNNER_BINARY)-extras: $(TRUNNER_EXTRA_FILES) | $(TRUNNER_OUTPUT) 567ifneq ($2:$(OUTPUT),:$(shell pwd)) 568 $$(call msg,EXT-COPY,$(TRUNNER_BINARY),$(TRUNNER_EXTRA_FILES)) 569 $(Q)rsync -aq $$^ $(TRUNNER_OUTPUT)/ 570endif 571 572$(OUTPUT)/$(TRUNNER_BINARY): $(TRUNNER_TEST_OBJS) \ 573 $(TRUNNER_EXTRA_OBJS) $$(BPFOBJ) \ 574 $(RESOLVE_BTFIDS) \ 575 $(TRUNNER_BPFTOOL) \ 576 | $(TRUNNER_BINARY)-extras 577 $$(call msg,BINARY,,$$@) 578 $(Q)$$(CC) $$(CFLAGS) $$(filter %.a %.o,$$^) $$(LDLIBS) -o $$@ 579 $(Q)$(RESOLVE_BTFIDS) --btf $(TRUNNER_OUTPUT)/btf_data.bpf.o $$@ 580 $(Q)ln -sf $(if $2,..,.)/tools/build/bpftool/$(USE_BOOTSTRAP)bpftool \ 581 $(OUTPUT)/$(if $2,$2/)bpftool 582 583endef 584 585# Define test_progs test runner. 586TRUNNER_TESTS_DIR := prog_tests 587TRUNNER_BPF_PROGS_DIR := progs 588TRUNNER_EXTRA_SOURCES := test_progs.c \ 589 cgroup_helpers.c \ 590 trace_helpers.c \ 591 network_helpers.c \ 592 testing_helpers.c \ 593 btf_helpers.c \ 594 cap_helpers.c \ 595 unpriv_helpers.c \ 596 netlink_helpers.c \ 597 test_loader.c \ 598 xsk.c \ 599 disasm.c \ 600 json_writer.c \ 601 flow_dissector_load.h \ 602 ip_check_defrag_frags.h 603TRUNNER_EXTRA_FILES := $(OUTPUT)/urandom_read $(OUTPUT)/bpf_testmod.ko \ 604 $(OUTPUT)/liburandom_read.so \ 605 $(OUTPUT)/xdp_synproxy \ 606 $(OUTPUT)/sign-file \ 607 $(OUTPUT)/uprobe_multi \ 608 ima_setup.sh \ 609 verify_sig_setup.sh \ 610 $(wildcard progs/btf_dump_test_case_*.c) \ 611 $(wildcard progs/*.bpf.o) 612TRUNNER_BPF_BUILD_RULE := CLANG_BPF_BUILD_RULE 613TRUNNER_BPF_CFLAGS := $(BPF_CFLAGS) $(CLANG_CFLAGS) -DENABLE_ATOMICS_TESTS 614$(eval $(call DEFINE_TEST_RUNNER,test_progs)) 615 616# Define test_progs-no_alu32 test runner. 617TRUNNER_BPF_BUILD_RULE := CLANG_NOALU32_BPF_BUILD_RULE 618TRUNNER_BPF_CFLAGS := $(BPF_CFLAGS) $(CLANG_CFLAGS) 619$(eval $(call DEFINE_TEST_RUNNER,test_progs,no_alu32)) 620 621# Define test_progs-cpuv4 test runner. 622ifneq ($(CLANG_CPUV4),) 623TRUNNER_BPF_BUILD_RULE := CLANG_CPUV4_BPF_BUILD_RULE 624TRUNNER_BPF_CFLAGS := $(BPF_CFLAGS) $(CLANG_CFLAGS) 625$(eval $(call DEFINE_TEST_RUNNER,test_progs,cpuv4)) 626endif 627 628# Define test_progs BPF-GCC-flavored test runner. 629ifneq ($(BPF_GCC),) 630TRUNNER_BPF_BUILD_RULE := GCC_BPF_BUILD_RULE 631TRUNNER_BPF_CFLAGS := $(BPF_CFLAGS) $(call get_sys_includes,gcc,) 632$(eval $(call DEFINE_TEST_RUNNER,test_progs,bpf_gcc)) 633endif 634 635# Define test_maps test runner. 636TRUNNER_TESTS_DIR := map_tests 637TRUNNER_BPF_PROGS_DIR := progs 638TRUNNER_EXTRA_SOURCES := test_maps.c 639TRUNNER_EXTRA_FILES := 640TRUNNER_BPF_BUILD_RULE := $$(error no BPF objects should be built) 641TRUNNER_BPF_CFLAGS := 642$(eval $(call DEFINE_TEST_RUNNER,test_maps)) 643 644# Define test_verifier test runner. 645# It is much simpler than test_maps/test_progs and sufficiently different from 646# them (e.g., test.h is using completely pattern), that it's worth just 647# explicitly defining all the rules explicitly. 648verifier/tests.h: verifier/*.c 649 $(shell ( cd verifier/; \ 650 echo '/* Generated header, do not edit */'; \ 651 echo '#ifdef FILL_ARRAY'; \ 652 ls *.c 2> /dev/null | sed -e 's@\(.*\)@#include \"\1\"@'; \ 653 echo '#endif' \ 654 ) > verifier/tests.h) 655$(OUTPUT)/test_verifier: test_verifier.c verifier/tests.h $(BPFOBJ) | $(OUTPUT) 656 $(call msg,BINARY,,$@) 657 $(Q)$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@ 658 659# Include find_bit.c to compile xskxceiver. 660EXTRA_SRC := $(TOOLSDIR)/lib/find_bit.c 661$(OUTPUT)/xskxceiver: $(EXTRA_SRC) xskxceiver.c xskxceiver.h $(OUTPUT)/xsk.o $(OUTPUT)/xsk_xdp_progs.skel.h $(BPFOBJ) | $(OUTPUT) 662 $(call msg,BINARY,,$@) 663 $(Q)$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@ 664 665$(OUTPUT)/xdp_hw_metadata: xdp_hw_metadata.c $(OUTPUT)/network_helpers.o $(OUTPUT)/xsk.o $(OUTPUT)/xdp_hw_metadata.skel.h | $(OUTPUT) 666 $(call msg,BINARY,,$@) 667 $(Q)$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@ 668 669$(OUTPUT)/xdp_features: xdp_features.c $(OUTPUT)/network_helpers.o $(OUTPUT)/xdp_features.skel.h | $(OUTPUT) 670 $(call msg,BINARY,,$@) 671 $(Q)$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@ 672 673# Make sure we are able to include and link libbpf against c++. 674$(OUTPUT)/test_cpp: test_cpp.cpp $(OUTPUT)/test_core_extern.skel.h $(BPFOBJ) 675 $(call msg,CXX,,$@) 676 $(Q)$(CXX) $(CFLAGS) $(filter %.a %.o %.cpp,$^) $(LDLIBS) -o $@ 677 678# Benchmark runner 679$(OUTPUT)/bench_%.o: benchs/bench_%.c bench.h $(BPFOBJ) 680 $(call msg,CC,,$@) 681 $(Q)$(CC) $(CFLAGS) -O2 -c $(filter %.c,$^) $(LDLIBS) -o $@ 682$(OUTPUT)/bench_rename.o: $(OUTPUT)/test_overhead.skel.h 683$(OUTPUT)/bench_trigger.o: $(OUTPUT)/trigger_bench.skel.h 684$(OUTPUT)/bench_ringbufs.o: $(OUTPUT)/ringbuf_bench.skel.h \ 685 $(OUTPUT)/perfbuf_bench.skel.h 686$(OUTPUT)/bench_bloom_filter_map.o: $(OUTPUT)/bloom_filter_bench.skel.h 687$(OUTPUT)/bench_bpf_loop.o: $(OUTPUT)/bpf_loop_bench.skel.h 688$(OUTPUT)/bench_strncmp.o: $(OUTPUT)/strncmp_bench.skel.h 689$(OUTPUT)/bench_bpf_hashmap_full_update.o: $(OUTPUT)/bpf_hashmap_full_update_bench.skel.h 690$(OUTPUT)/bench_local_storage.o: $(OUTPUT)/local_storage_bench.skel.h 691$(OUTPUT)/bench_local_storage_rcu_tasks_trace.o: $(OUTPUT)/local_storage_rcu_tasks_trace_bench.skel.h 692$(OUTPUT)/bench_local_storage_create.o: $(OUTPUT)/bench_local_storage_create.skel.h 693$(OUTPUT)/bench_bpf_hashmap_lookup.o: $(OUTPUT)/bpf_hashmap_lookup.skel.h 694$(OUTPUT)/bench_htab_mem.o: $(OUTPUT)/htab_mem_bench.skel.h 695$(OUTPUT)/bench.o: bench.h testing_helpers.h $(BPFOBJ) 696$(OUTPUT)/bench: LDLIBS += -lm 697$(OUTPUT)/bench: $(OUTPUT)/bench.o \ 698 $(TESTING_HELPERS) \ 699 $(TRACE_HELPERS) \ 700 $(CGROUP_HELPERS) \ 701 $(OUTPUT)/bench_count.o \ 702 $(OUTPUT)/bench_rename.o \ 703 $(OUTPUT)/bench_trigger.o \ 704 $(OUTPUT)/bench_ringbufs.o \ 705 $(OUTPUT)/bench_bloom_filter_map.o \ 706 $(OUTPUT)/bench_bpf_loop.o \ 707 $(OUTPUT)/bench_strncmp.o \ 708 $(OUTPUT)/bench_bpf_hashmap_full_update.o \ 709 $(OUTPUT)/bench_local_storage.o \ 710 $(OUTPUT)/bench_local_storage_rcu_tasks_trace.o \ 711 $(OUTPUT)/bench_bpf_hashmap_lookup.o \ 712 $(OUTPUT)/bench_local_storage_create.o \ 713 $(OUTPUT)/bench_htab_mem.o \ 714 # 715 $(call msg,BINARY,,$@) 716 $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $(filter %.a %.o,$^) $(LDLIBS) -o $@ 717 718$(OUTPUT)/veristat.o: $(BPFOBJ) 719$(OUTPUT)/veristat: $(OUTPUT)/veristat.o 720 $(call msg,BINARY,,$@) 721 $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $(filter %.a %.o,$^) $(LDLIBS) -o $@ 722 723$(OUTPUT)/uprobe_multi: uprobe_multi.c 724 $(call msg,BINARY,,$@) 725 $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@ 726 727EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(SCRATCH_DIR) $(HOST_SCRATCH_DIR) \ 728 prog_tests/tests.h map_tests/tests.h verifier/tests.h \ 729 feature bpftool \ 730 $(addprefix $(OUTPUT)/,*.o *.skel.h *.lskel.h *.subskel.h \ 731 no_alu32 cpuv4 bpf_gcc bpf_testmod.ko \ 732 liburandom_read.so) 733 734.PHONY: docs docs-clean 735 736# Delete partially updated (corrupted) files on error 737.DELETE_ON_ERROR: 738 739DEFAULT_INSTALL_RULE := $(INSTALL_RULE) 740override define INSTALL_RULE 741 $(DEFAULT_INSTALL_RULE) 742 @for DIR in $(TEST_INST_SUBDIRS); do \ 743 mkdir -p $(INSTALL_PATH)/$$DIR; \ 744 rsync -a $(OUTPUT)/$$DIR/*.bpf.o $(INSTALL_PATH)/$$DIR;\ 745 done 746endef 747