1*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyuninclude ../../../../scripts/Kbuild.include 3*4882a593Smuzhiyuninclude ../../../scripts/Makefile.arch 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunCXX ?= $(CROSS_COMPILE)g++ 6*4882a593Smuzhiyun 7*4882a593SmuzhiyunCURDIR := $(abspath .) 8*4882a593SmuzhiyunTOOLSDIR := $(abspath ../../..) 9*4882a593SmuzhiyunLIBDIR := $(TOOLSDIR)/lib 10*4882a593SmuzhiyunBPFDIR := $(LIBDIR)/bpf 11*4882a593SmuzhiyunTOOLSINCDIR := $(TOOLSDIR)/include 12*4882a593SmuzhiyunBPFTOOLDIR := $(TOOLSDIR)/bpf/bpftool 13*4882a593SmuzhiyunAPIDIR := $(TOOLSINCDIR)/uapi 14*4882a593SmuzhiyunGENDIR := $(abspath ../../../../include/generated) 15*4882a593SmuzhiyunGENHDR := $(GENDIR)/autoconf.h 16*4882a593Smuzhiyun 17*4882a593Smuzhiyunifneq ($(wildcard $(GENHDR)),) 18*4882a593Smuzhiyun GENFLAGS := -DHAVE_GENHDR 19*4882a593Smuzhiyunendif 20*4882a593Smuzhiyun 21*4882a593SmuzhiyunCLANG ?= clang 22*4882a593SmuzhiyunLLC ?= llc 23*4882a593SmuzhiyunLLVM_OBJCOPY ?= llvm-objcopy 24*4882a593SmuzhiyunBPF_GCC ?= $(shell command -v bpf-gcc;) 25*4882a593SmuzhiyunSAN_CFLAGS ?= 26*4882a593SmuzhiyunCFLAGS += -g -rdynamic -Wall -O2 $(GENFLAGS) $(SAN_CFLAGS) \ 27*4882a593Smuzhiyun -I$(CURDIR) -I$(INCLUDE_DIR) -I$(GENDIR) -I$(LIBDIR) \ 28*4882a593Smuzhiyun -I$(TOOLSINCDIR) -I$(APIDIR) \ 29*4882a593Smuzhiyun -Dbpf_prog_load=bpf_prog_test_load \ 30*4882a593Smuzhiyun -Dbpf_load_program=bpf_test_load_program 31*4882a593SmuzhiyunLDLIBS += -lcap -lelf -lz -lrt -lpthread 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun# Order correspond to 'make run_tests' order 34*4882a593SmuzhiyunTEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \ 35*4882a593Smuzhiyun test_verifier_log test_dev_cgroup test_tcpbpf_user \ 36*4882a593Smuzhiyun test_sock test_sockmap get_cgroup_id_user test_socket_cookie \ 37*4882a593Smuzhiyun test_cgroup_storage \ 38*4882a593Smuzhiyun test_netcnt test_tcpnotify_user test_sysctl \ 39*4882a593Smuzhiyun test_progs-no_alu32 \ 40*4882a593Smuzhiyun test_current_pid_tgid_new_ns 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun# Also test bpf-gcc, if present 43*4882a593Smuzhiyunifneq ($(BPF_GCC),) 44*4882a593SmuzhiyunTEST_GEN_PROGS += test_progs-bpf_gcc 45*4882a593Smuzhiyunendif 46*4882a593Smuzhiyun 47*4882a593SmuzhiyunTEST_GEN_FILES = 48*4882a593SmuzhiyunTEST_FILES = test_lwt_ip_encap.o \ 49*4882a593Smuzhiyun test_tc_edt.o 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun# Order correspond to 'make run_tests' order 52*4882a593SmuzhiyunTEST_PROGS := test_kmod.sh \ 53*4882a593Smuzhiyun test_xdp_redirect.sh \ 54*4882a593Smuzhiyun test_xdp_meta.sh \ 55*4882a593Smuzhiyun test_xdp_veth.sh \ 56*4882a593Smuzhiyun test_offload.py \ 57*4882a593Smuzhiyun test_sock_addr.sh \ 58*4882a593Smuzhiyun test_tunnel.sh \ 59*4882a593Smuzhiyun test_lwt_seg6local.sh \ 60*4882a593Smuzhiyun test_lirc_mode2.sh \ 61*4882a593Smuzhiyun test_skb_cgroup_id.sh \ 62*4882a593Smuzhiyun test_flow_dissector.sh \ 63*4882a593Smuzhiyun test_xdp_vlan_mode_generic.sh \ 64*4882a593Smuzhiyun test_xdp_vlan_mode_native.sh \ 65*4882a593Smuzhiyun test_lwt_ip_encap.sh \ 66*4882a593Smuzhiyun test_tcp_check_syncookie.sh \ 67*4882a593Smuzhiyun test_tc_tunnel.sh \ 68*4882a593Smuzhiyun test_tc_edt.sh \ 69*4882a593Smuzhiyun test_xdping.sh \ 70*4882a593Smuzhiyun test_bpftool_build.sh \ 71*4882a593Smuzhiyun test_bpftool.sh \ 72*4882a593Smuzhiyun test_bpftool_metadata.sh \ 73*4882a593Smuzhiyun 74*4882a593SmuzhiyunTEST_PROGS_EXTENDED := with_addr.sh \ 75*4882a593Smuzhiyun with_tunnels.sh \ 76*4882a593Smuzhiyun tcp_client.py \ 77*4882a593Smuzhiyun tcp_server.py \ 78*4882a593Smuzhiyun test_xdp_vlan.sh 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun# Compile but not part of 'make run_tests' 81*4882a593SmuzhiyunTEST_GEN_PROGS_EXTENDED = test_sock_addr test_skb_cgroup_id_user \ 82*4882a593Smuzhiyun flow_dissector_load test_flow_dissector test_tcp_check_syncookie_user \ 83*4882a593Smuzhiyun test_lirc_mode2_user xdping test_cpp runqslower bench 84*4882a593Smuzhiyun 85*4882a593SmuzhiyunTEST_CUSTOM_PROGS = urandom_read 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun# Emit succinct information message describing current building step 88*4882a593Smuzhiyun# $1 - generic step name (e.g., CC, LINK, etc); 89*4882a593Smuzhiyun# $2 - optional "flavor" specifier; if provided, will be emitted as [flavor]; 90*4882a593Smuzhiyun# $3 - target (assumed to be file); only file name will be emitted; 91*4882a593Smuzhiyun# $4 - optional extra arg, emitted as-is, if provided. 92*4882a593Smuzhiyunifeq ($(V),1) 93*4882a593SmuzhiyunQ = 94*4882a593Smuzhiyunmsg = 95*4882a593Smuzhiyunelse 96*4882a593SmuzhiyunQ = @ 97*4882a593Smuzhiyunmsg = @printf ' %-8s%s %s%s\n' "$(1)" "$(if $(2), [$(2)])" "$(notdir $(3))" "$(if $(4), $(4))"; 98*4882a593SmuzhiyunMAKEFLAGS += --no-print-directory 99*4882a593Smuzhiyunsubmake_extras := feature_display=0 100*4882a593Smuzhiyunendif 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun# override lib.mk's default rules 103*4882a593SmuzhiyunOVERRIDE_TARGETS := 1 104*4882a593Smuzhiyunoverride define CLEAN 105*4882a593Smuzhiyun $(call msg,CLEAN) 106*4882a593Smuzhiyun $(Q)$(RM) -r $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) $(EXTRA_CLEAN) 107*4882a593Smuzhiyunendef 108*4882a593Smuzhiyun 109*4882a593Smuzhiyuninclude ../lib.mk 110*4882a593Smuzhiyun 111*4882a593SmuzhiyunSCRATCH_DIR := $(OUTPUT)/tools 112*4882a593SmuzhiyunBUILD_DIR := $(SCRATCH_DIR)/build 113*4882a593SmuzhiyunINCLUDE_DIR := $(SCRATCH_DIR)/include 114*4882a593SmuzhiyunBPFOBJ := $(BUILD_DIR)/libbpf/libbpf.a 115*4882a593SmuzhiyunRESOLVE_BTFIDS := $(BUILD_DIR)/resolve_btfids/resolve_btfids 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun# Define simple and short `make test_progs`, `make test_sysctl`, etc targets 118*4882a593Smuzhiyun# to build individual tests. 119*4882a593Smuzhiyun# NOTE: Semicolon at the end is critical to override lib.mk's default static 120*4882a593Smuzhiyun# rule for binaries. 121*4882a593Smuzhiyun$(notdir $(TEST_GEN_PROGS) \ 122*4882a593Smuzhiyun $(TEST_PROGS) \ 123*4882a593Smuzhiyun $(TEST_PROGS_EXTENDED) \ 124*4882a593Smuzhiyun $(TEST_GEN_PROGS_EXTENDED) \ 125*4882a593Smuzhiyun $(TEST_CUSTOM_PROGS)): %: $(OUTPUT)/% ; 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun$(OUTPUT)/%.o: %.c 128*4882a593Smuzhiyun $(call msg,CC,,$@) 129*4882a593Smuzhiyun $(Q)$(CC) $(CFLAGS) -c $(filter %.c,$^) $(LDLIBS) -o $@ 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun$(OUTPUT)/%:%.c 132*4882a593Smuzhiyun $(call msg,BINARY,,$@) 133*4882a593Smuzhiyun $(Q)$(LINK.c) $^ $(LDLIBS) -o $@ 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun$(OUTPUT)/urandom_read: urandom_read.c 136*4882a593Smuzhiyun $(call msg,BINARY,,$@) 137*4882a593Smuzhiyun $(Q)$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS) -Wl,--build-id=sha1 138*4882a593Smuzhiyun 139*4882a593Smuzhiyun$(OUTPUT)/test_stub.o: test_stub.c $(BPFOBJ) 140*4882a593Smuzhiyun $(call msg,CC,,$@) 141*4882a593Smuzhiyun $(Q)$(CC) -c $(CFLAGS) -o $@ $< 142*4882a593Smuzhiyun 143*4882a593SmuzhiyunVMLINUX_BTF_PATHS ?= $(if $(O),$(O)/vmlinux) \ 144*4882a593Smuzhiyun $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux) \ 145*4882a593Smuzhiyun ../../../../vmlinux \ 146*4882a593Smuzhiyun /sys/kernel/btf/vmlinux \ 147*4882a593Smuzhiyun /boot/vmlinux-$(shell uname -r) 148*4882a593SmuzhiyunVMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS)))) 149*4882a593Smuzhiyunifeq ($(VMLINUX_BTF),) 150*4882a593Smuzhiyun$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)") 151*4882a593Smuzhiyunendif 152*4882a593Smuzhiyun 153*4882a593SmuzhiyunDEFAULT_BPFTOOL := $(SCRATCH_DIR)/sbin/bpftool 154*4882a593Smuzhiyun 155*4882a593Smuzhiyun$(OUTPUT)/runqslower: $(BPFOBJ) | $(DEFAULT_BPFTOOL) 156*4882a593Smuzhiyun $(Q)$(MAKE) $(submake_extras) -C $(TOOLSDIR)/bpf/runqslower \ 157*4882a593Smuzhiyun OUTPUT=$(SCRATCH_DIR)/ VMLINUX_BTF=$(VMLINUX_BTF) \ 158*4882a593Smuzhiyun BPFOBJ=$(BPFOBJ) BPF_INCLUDE=$(INCLUDE_DIR) && \ 159*4882a593Smuzhiyun cp $(SCRATCH_DIR)/runqslower $@ 160*4882a593Smuzhiyun 161*4882a593Smuzhiyun$(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/test_stub.o $(BPFOBJ) 162*4882a593Smuzhiyun 163*4882a593Smuzhiyun$(OUTPUT)/test_dev_cgroup: cgroup_helpers.c 164*4882a593Smuzhiyun$(OUTPUT)/test_skb_cgroup_id_user: cgroup_helpers.c 165*4882a593Smuzhiyun$(OUTPUT)/test_sock: cgroup_helpers.c 166*4882a593Smuzhiyun$(OUTPUT)/test_sock_addr: cgroup_helpers.c 167*4882a593Smuzhiyun$(OUTPUT)/test_socket_cookie: cgroup_helpers.c 168*4882a593Smuzhiyun$(OUTPUT)/test_sockmap: cgroup_helpers.c 169*4882a593Smuzhiyun$(OUTPUT)/test_tcpbpf_user: cgroup_helpers.c 170*4882a593Smuzhiyun$(OUTPUT)/test_tcpnotify_user: cgroup_helpers.c trace_helpers.c 171*4882a593Smuzhiyun$(OUTPUT)/get_cgroup_id_user: cgroup_helpers.c 172*4882a593Smuzhiyun$(OUTPUT)/test_cgroup_storage: cgroup_helpers.c 173*4882a593Smuzhiyun$(OUTPUT)/test_netcnt: cgroup_helpers.c 174*4882a593Smuzhiyun$(OUTPUT)/test_sock_fields: cgroup_helpers.c 175*4882a593Smuzhiyun$(OUTPUT)/test_sysctl: cgroup_helpers.c 176*4882a593Smuzhiyun 177*4882a593SmuzhiyunBPFTOOL ?= $(DEFAULT_BPFTOOL) 178*4882a593Smuzhiyun$(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) \ 179*4882a593Smuzhiyun $(BPFOBJ) | $(BUILD_DIR)/bpftool 180*4882a593Smuzhiyun $(Q)$(MAKE) $(submake_extras) -C $(BPFTOOLDIR) \ 181*4882a593Smuzhiyun OUTPUT=$(BUILD_DIR)/bpftool/ \ 182*4882a593Smuzhiyun prefix= DESTDIR=$(SCRATCH_DIR)/ install 183*4882a593Smuzhiyun $(Q)mkdir -p $(BUILD_DIR)/bpftool/Documentation 184*4882a593Smuzhiyun $(Q)RST2MAN_OPTS="--exit-status=1" $(MAKE) $(submake_extras) \ 185*4882a593Smuzhiyun -C $(BPFTOOLDIR)/Documentation \ 186*4882a593Smuzhiyun OUTPUT=$(BUILD_DIR)/bpftool/Documentation/ \ 187*4882a593Smuzhiyun prefix= DESTDIR=$(SCRATCH_DIR)/ install 188*4882a593Smuzhiyun 189*4882a593Smuzhiyun$(BPFOBJ): $(wildcard $(BPFDIR)/*.[ch] $(BPFDIR)/Makefile) \ 190*4882a593Smuzhiyun ../../../include/uapi/linux/bpf.h \ 191*4882a593Smuzhiyun | $(INCLUDE_DIR) $(BUILD_DIR)/libbpf 192*4882a593Smuzhiyun $(Q)$(MAKE) $(submake_extras) -C $(BPFDIR) OUTPUT=$(BUILD_DIR)/libbpf/ \ 193*4882a593Smuzhiyun DESTDIR=$(SCRATCH_DIR) prefix= all install_headers 194*4882a593Smuzhiyun 195*4882a593Smuzhiyun$(BUILD_DIR)/libbpf $(BUILD_DIR)/bpftool $(BUILD_DIR)/resolve_btfids $(INCLUDE_DIR): 196*4882a593Smuzhiyun $(call msg,MKDIR,,$@) 197*4882a593Smuzhiyun $(Q)mkdir -p $@ 198*4882a593Smuzhiyun 199*4882a593Smuzhiyun$(INCLUDE_DIR)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL) | $(INCLUDE_DIR) 200*4882a593Smuzhiyunifeq ($(VMLINUX_H),) 201*4882a593Smuzhiyun $(call msg,GEN,,$@) 202*4882a593Smuzhiyun $(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@ 203*4882a593Smuzhiyunelse 204*4882a593Smuzhiyun $(call msg,CP,,$@) 205*4882a593Smuzhiyun $(Q)cp "$(VMLINUX_H)" $@ 206*4882a593Smuzhiyunendif 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun$(RESOLVE_BTFIDS): $(BPFOBJ) | $(BUILD_DIR)/resolve_btfids \ 209*4882a593Smuzhiyun $(TOOLSDIR)/bpf/resolve_btfids/main.c \ 210*4882a593Smuzhiyun $(TOOLSDIR)/lib/rbtree.c \ 211*4882a593Smuzhiyun $(TOOLSDIR)/lib/zalloc.c \ 212*4882a593Smuzhiyun $(TOOLSDIR)/lib/string.c \ 213*4882a593Smuzhiyun $(TOOLSDIR)/lib/ctype.c \ 214*4882a593Smuzhiyun $(TOOLSDIR)/lib/str_error_r.c 215*4882a593Smuzhiyun $(Q)$(MAKE) $(submake_extras) -C $(TOOLSDIR)/bpf/resolve_btfids \ 216*4882a593Smuzhiyun OUTPUT=$(BUILD_DIR)/resolve_btfids/ BPFOBJ=$(BPFOBJ) 217*4882a593Smuzhiyun 218*4882a593Smuzhiyun# Get Clang's default includes on this system, as opposed to those seen by 219*4882a593Smuzhiyun# '-target bpf'. This fixes "missing" files on some architectures/distros, 220*4882a593Smuzhiyun# such as asm/byteorder.h, asm/socket.h, asm/sockios.h, sys/cdefs.h etc. 221*4882a593Smuzhiyun# 222*4882a593Smuzhiyun# Use '-idirafter': Don't interfere with include mechanics except where the 223*4882a593Smuzhiyun# build would have failed anyways. 224*4882a593Smuzhiyundefine get_sys_includes 225*4882a593Smuzhiyun$(shell $(1) -v -E - </dev/null 2>&1 \ 226*4882a593Smuzhiyun | sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') \ 227*4882a593Smuzhiyun$(shell $(1) -dM -E - </dev/null | grep '#define __riscv_xlen ' | sed 's/#define /-D/' | sed 's/ /=/') 228*4882a593Smuzhiyunendef 229*4882a593Smuzhiyun 230*4882a593Smuzhiyun# Determine target endianness. 231*4882a593SmuzhiyunIS_LITTLE_ENDIAN = $(shell $(CC) -dM -E - </dev/null | \ 232*4882a593Smuzhiyun grep 'define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__') 233*4882a593SmuzhiyunMENDIAN=$(if $(IS_LITTLE_ENDIAN),-mlittle-endian,-mbig-endian) 234*4882a593Smuzhiyun 235*4882a593SmuzhiyunCLANG_SYS_INCLUDES = $(call get_sys_includes,$(CLANG)) 236*4882a593SmuzhiyunBPF_CFLAGS = -g -D__TARGET_ARCH_$(SRCARCH) $(MENDIAN) \ 237*4882a593Smuzhiyun -I$(INCLUDE_DIR) -I$(CURDIR) -I$(APIDIR) \ 238*4882a593Smuzhiyun -I$(abspath $(OUTPUT)/../usr/include) 239*4882a593Smuzhiyun 240*4882a593SmuzhiyunCLANG_CFLAGS = $(CLANG_SYS_INCLUDES) \ 241*4882a593Smuzhiyun -Wno-compare-distinct-pointer-types 242*4882a593Smuzhiyun 243*4882a593Smuzhiyun$(OUTPUT)/test_l4lb_noinline.o: BPF_CFLAGS += -fno-inline 244*4882a593Smuzhiyun$(OUTPUT)/test_xdp_noinline.o: BPF_CFLAGS += -fno-inline 245*4882a593Smuzhiyun 246*4882a593Smuzhiyun$(OUTPUT)/flow_dissector_load.o: flow_dissector_load.h 247*4882a593Smuzhiyun 248*4882a593Smuzhiyun# Build BPF object using Clang 249*4882a593Smuzhiyun# $1 - input .c file 250*4882a593Smuzhiyun# $2 - output .o file 251*4882a593Smuzhiyun# $3 - CFLAGS 252*4882a593Smuzhiyun# $4 - LDFLAGS 253*4882a593Smuzhiyundefine CLANG_BPF_BUILD_RULE 254*4882a593Smuzhiyun $(call msg,CLNG-LLC,$(TRUNNER_BINARY),$2) 255*4882a593Smuzhiyun $(Q)($(CLANG) $3 -O2 -target bpf -emit-llvm \ 256*4882a593Smuzhiyun -c $1 -o - || echo "BPF obj compilation failed") | \ 257*4882a593Smuzhiyun $(LLC) -mattr=dwarfris -march=bpf -mcpu=v3 $4 -filetype=obj -o $2 258*4882a593Smuzhiyunendef 259*4882a593Smuzhiyun# Similar to CLANG_BPF_BUILD_RULE, but with disabled alu32 260*4882a593Smuzhiyundefine CLANG_NOALU32_BPF_BUILD_RULE 261*4882a593Smuzhiyun $(call msg,CLNG-LLC,$(TRUNNER_BINARY),$2) 262*4882a593Smuzhiyun $(Q)($(CLANG) $3 -O2 -target bpf -emit-llvm \ 263*4882a593Smuzhiyun -c $1 -o - || echo "BPF obj compilation failed") | \ 264*4882a593Smuzhiyun $(LLC) -march=bpf -mcpu=v2 $4 -filetype=obj -o $2 265*4882a593Smuzhiyunendef 266*4882a593Smuzhiyun# Similar to CLANG_BPF_BUILD_RULE, but using native Clang and bpf LLC 267*4882a593Smuzhiyundefine CLANG_NATIVE_BPF_BUILD_RULE 268*4882a593Smuzhiyun $(call msg,CLNG-BPF,$(TRUNNER_BINARY),$2) 269*4882a593Smuzhiyun $(Q)($(CLANG) $3 -O2 -emit-llvm \ 270*4882a593Smuzhiyun -c $1 -o - || echo "BPF obj compilation failed") | \ 271*4882a593Smuzhiyun $(LLC) -march=bpf -mcpu=v3 $4 -filetype=obj -o $2 272*4882a593Smuzhiyunendef 273*4882a593Smuzhiyun# Build BPF object using GCC 274*4882a593Smuzhiyundefine GCC_BPF_BUILD_RULE 275*4882a593Smuzhiyun $(call msg,GCC-BPF,$(TRUNNER_BINARY),$2) 276*4882a593Smuzhiyun $(Q)$(BPF_GCC) $3 $4 -O2 -c $1 -o $2 277*4882a593Smuzhiyunendef 278*4882a593Smuzhiyun 279*4882a593SmuzhiyunSKEL_BLACKLIST := btf__% test_pinning_invalid.c test_sk_assign.c 280*4882a593Smuzhiyun 281*4882a593Smuzhiyun# Set up extra TRUNNER_XXX "temporary" variables in the environment (relies on 282*4882a593Smuzhiyun# $eval()) and pass control to DEFINE_TEST_RUNNER_RULES. 283*4882a593Smuzhiyun# Parameters: 284*4882a593Smuzhiyun# $1 - test runner base binary name (e.g., test_progs) 285*4882a593Smuzhiyun# $2 - test runner extra "flavor" (e.g., no_alu32, gcc-bpf, etc) 286*4882a593Smuzhiyundefine DEFINE_TEST_RUNNER 287*4882a593Smuzhiyun 288*4882a593SmuzhiyunTRUNNER_OUTPUT := $(OUTPUT)$(if $2,/)$2 289*4882a593SmuzhiyunTRUNNER_BINARY := $1$(if $2,-)$2 290*4882a593SmuzhiyunTRUNNER_TEST_OBJS := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.test.o, \ 291*4882a593Smuzhiyun $$(notdir $$(wildcard $(TRUNNER_TESTS_DIR)/*.c))) 292*4882a593SmuzhiyunTRUNNER_EXTRA_OBJS := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.o, \ 293*4882a593Smuzhiyun $$(filter %.c,$(TRUNNER_EXTRA_SOURCES))) 294*4882a593SmuzhiyunTRUNNER_EXTRA_HDRS := $$(filter %.h,$(TRUNNER_EXTRA_SOURCES)) 295*4882a593SmuzhiyunTRUNNER_TESTS_HDR := $(TRUNNER_TESTS_DIR)/tests.h 296*4882a593SmuzhiyunTRUNNER_BPF_SRCS := $$(notdir $$(wildcard $(TRUNNER_BPF_PROGS_DIR)/*.c)) 297*4882a593SmuzhiyunTRUNNER_BPF_OBJS := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.o, $$(TRUNNER_BPF_SRCS)) 298*4882a593SmuzhiyunTRUNNER_BPF_SKELS := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.skel.h, \ 299*4882a593Smuzhiyun $$(filter-out $(SKEL_BLACKLIST), \ 300*4882a593Smuzhiyun $$(TRUNNER_BPF_SRCS))) 301*4882a593SmuzhiyunTEST_GEN_FILES += $$(TRUNNER_BPF_OBJS) 302*4882a593Smuzhiyun 303*4882a593Smuzhiyun# Evaluate rules now with extra TRUNNER_XXX variables above already defined 304*4882a593Smuzhiyun$$(eval $$(call DEFINE_TEST_RUNNER_RULES,$1,$2)) 305*4882a593Smuzhiyun 306*4882a593Smuzhiyunendef 307*4882a593Smuzhiyun 308*4882a593Smuzhiyun# Using TRUNNER_XXX variables, provided by callers of DEFINE_TEST_RUNNER and 309*4882a593Smuzhiyun# set up by DEFINE_TEST_RUNNER itself, create test runner build rules with: 310*4882a593Smuzhiyun# $1 - test runner base binary name (e.g., test_progs) 311*4882a593Smuzhiyun# $2 - test runner extra "flavor" (e.g., no_alu32, gcc-bpf, etc) 312*4882a593Smuzhiyundefine DEFINE_TEST_RUNNER_RULES 313*4882a593Smuzhiyun 314*4882a593Smuzhiyunifeq ($($(TRUNNER_OUTPUT)-dir),) 315*4882a593Smuzhiyun$(TRUNNER_OUTPUT)-dir := y 316*4882a593Smuzhiyun$(TRUNNER_OUTPUT): 317*4882a593Smuzhiyun $$(call msg,MKDIR,,$$@) 318*4882a593Smuzhiyun $(Q)mkdir -p $$@ 319*4882a593Smuzhiyunendif 320*4882a593Smuzhiyun 321*4882a593Smuzhiyun# ensure we set up BPF objects generation rule just once for a given 322*4882a593Smuzhiyun# input/output directory combination 323*4882a593Smuzhiyunifeq ($($(TRUNNER_BPF_PROGS_DIR)$(if $2,-)$2-bpfobjs),) 324*4882a593Smuzhiyun$(TRUNNER_BPF_PROGS_DIR)$(if $2,-)$2-bpfobjs := y 325*4882a593Smuzhiyun$(TRUNNER_BPF_OBJS): $(TRUNNER_OUTPUT)/%.o: \ 326*4882a593Smuzhiyun $(TRUNNER_BPF_PROGS_DIR)/%.c \ 327*4882a593Smuzhiyun $(TRUNNER_BPF_PROGS_DIR)/*.h \ 328*4882a593Smuzhiyun $$(INCLUDE_DIR)/vmlinux.h \ 329*4882a593Smuzhiyun $(wildcard $(BPFDIR)/bpf_*.h) \ 330*4882a593Smuzhiyun | $(TRUNNER_OUTPUT) $$(BPFOBJ) 331*4882a593Smuzhiyun $$(call $(TRUNNER_BPF_BUILD_RULE),$$<,$$@, \ 332*4882a593Smuzhiyun $(TRUNNER_BPF_CFLAGS), \ 333*4882a593Smuzhiyun $(TRUNNER_BPF_LDFLAGS)) 334*4882a593Smuzhiyun 335*4882a593Smuzhiyun$(TRUNNER_BPF_SKELS): $(TRUNNER_OUTPUT)/%.skel.h: \ 336*4882a593Smuzhiyun $(TRUNNER_OUTPUT)/%.o \ 337*4882a593Smuzhiyun $(BPFTOOL) \ 338*4882a593Smuzhiyun | $(TRUNNER_OUTPUT) 339*4882a593Smuzhiyun $$(call msg,GEN-SKEL,$(TRUNNER_BINARY),$$@) 340*4882a593Smuzhiyun $(Q)$$(BPFTOOL) gen skeleton $$< > $$@ 341*4882a593Smuzhiyunendif 342*4882a593Smuzhiyun 343*4882a593Smuzhiyun# ensure we set up tests.h header generation rule just once 344*4882a593Smuzhiyunifeq ($($(TRUNNER_TESTS_DIR)-tests-hdr),) 345*4882a593Smuzhiyun$(TRUNNER_TESTS_DIR)-tests-hdr := y 346*4882a593Smuzhiyun$(TRUNNER_TESTS_HDR): $(TRUNNER_TESTS_DIR)/*.c 347*4882a593Smuzhiyun $$(call msg,TEST-HDR,$(TRUNNER_BINARY),$$@) 348*4882a593Smuzhiyun $$(shell ( cd $(TRUNNER_TESTS_DIR); \ 349*4882a593Smuzhiyun echo '/* Generated header, do not edit */'; \ 350*4882a593Smuzhiyun ls *.c 2> /dev/null | \ 351*4882a593Smuzhiyun sed -e 's@\([^\.]*\)\.c@DEFINE_TEST(\1)@'; \ 352*4882a593Smuzhiyun ) > $$@) 353*4882a593Smuzhiyunendif 354*4882a593Smuzhiyun 355*4882a593Smuzhiyun# compile individual test files 356*4882a593Smuzhiyun# Note: we cd into output directory to ensure embedded BPF object is found 357*4882a593Smuzhiyun$(TRUNNER_TEST_OBJS): $(TRUNNER_OUTPUT)/%.test.o: \ 358*4882a593Smuzhiyun $(TRUNNER_TESTS_DIR)/%.c \ 359*4882a593Smuzhiyun $(TRUNNER_EXTRA_HDRS) \ 360*4882a593Smuzhiyun $(TRUNNER_BPF_OBJS) \ 361*4882a593Smuzhiyun $(TRUNNER_BPF_SKELS) \ 362*4882a593Smuzhiyun $$(BPFOBJ) | $(TRUNNER_OUTPUT) 363*4882a593Smuzhiyun $$(call msg,TEST-OBJ,$(TRUNNER_BINARY),$$@) 364*4882a593Smuzhiyun $(Q)cd $$(@D) && $$(CC) -I. $$(CFLAGS) -c $(CURDIR)/$$< $$(LDLIBS) -o $$(@F) 365*4882a593Smuzhiyun 366*4882a593Smuzhiyun$(TRUNNER_EXTRA_OBJS): $(TRUNNER_OUTPUT)/%.o: \ 367*4882a593Smuzhiyun %.c \ 368*4882a593Smuzhiyun $(TRUNNER_EXTRA_HDRS) \ 369*4882a593Smuzhiyun $(TRUNNER_TESTS_HDR) \ 370*4882a593Smuzhiyun $$(BPFOBJ) | $(TRUNNER_OUTPUT) 371*4882a593Smuzhiyun $$(call msg,EXT-OBJ,$(TRUNNER_BINARY),$$@) 372*4882a593Smuzhiyun $(Q)$$(CC) $$(CFLAGS) -c $$< $$(LDLIBS) -o $$@ 373*4882a593Smuzhiyun 374*4882a593Smuzhiyun# only copy extra resources if in flavored build 375*4882a593Smuzhiyun$(TRUNNER_BINARY)-extras: $(TRUNNER_EXTRA_FILES) | $(TRUNNER_OUTPUT) 376*4882a593Smuzhiyunifneq ($2,) 377*4882a593Smuzhiyun $$(call msg,EXT-COPY,$(TRUNNER_BINARY),$(TRUNNER_EXTRA_FILES)) 378*4882a593Smuzhiyun $(Q)cp -a $$^ $(TRUNNER_OUTPUT)/ 379*4882a593Smuzhiyunendif 380*4882a593Smuzhiyun 381*4882a593Smuzhiyun$(OUTPUT)/$(TRUNNER_BINARY): $(TRUNNER_TEST_OBJS) \ 382*4882a593Smuzhiyun $(TRUNNER_EXTRA_OBJS) $$(BPFOBJ) \ 383*4882a593Smuzhiyun $(RESOLVE_BTFIDS) \ 384*4882a593Smuzhiyun | $(TRUNNER_BINARY)-extras 385*4882a593Smuzhiyun $$(call msg,BINARY,,$$@) 386*4882a593Smuzhiyun $(Q)$$(CC) $$(CFLAGS) $$(filter %.a %.o,$$^) $$(LDLIBS) -o $$@ 387*4882a593Smuzhiyun $(Q)$(RESOLVE_BTFIDS) --no-fail --btf btf_data.o $$@ 388*4882a593Smuzhiyun 389*4882a593Smuzhiyunendef 390*4882a593Smuzhiyun 391*4882a593Smuzhiyun# Define test_progs test runner. 392*4882a593SmuzhiyunTRUNNER_TESTS_DIR := prog_tests 393*4882a593SmuzhiyunTRUNNER_BPF_PROGS_DIR := progs 394*4882a593SmuzhiyunTRUNNER_EXTRA_SOURCES := test_progs.c cgroup_helpers.c trace_helpers.c \ 395*4882a593Smuzhiyun network_helpers.c testing_helpers.c \ 396*4882a593Smuzhiyun flow_dissector_load.h 397*4882a593SmuzhiyunTRUNNER_EXTRA_FILES := $(OUTPUT)/urandom_read \ 398*4882a593Smuzhiyun $(wildcard progs/btf_dump_test_case_*.c) 399*4882a593SmuzhiyunTRUNNER_BPF_BUILD_RULE := CLANG_BPF_BUILD_RULE 400*4882a593SmuzhiyunTRUNNER_BPF_CFLAGS := $(BPF_CFLAGS) $(CLANG_CFLAGS) 401*4882a593SmuzhiyunTRUNNER_BPF_LDFLAGS := -mattr=+alu32 402*4882a593Smuzhiyun$(eval $(call DEFINE_TEST_RUNNER,test_progs)) 403*4882a593Smuzhiyun 404*4882a593Smuzhiyun# Define test_progs-no_alu32 test runner. 405*4882a593SmuzhiyunTRUNNER_BPF_BUILD_RULE := CLANG_NOALU32_BPF_BUILD_RULE 406*4882a593SmuzhiyunTRUNNER_BPF_LDFLAGS := 407*4882a593Smuzhiyun$(eval $(call DEFINE_TEST_RUNNER,test_progs,no_alu32)) 408*4882a593Smuzhiyun 409*4882a593Smuzhiyun# Define test_progs BPF-GCC-flavored test runner. 410*4882a593Smuzhiyunifneq ($(BPF_GCC),) 411*4882a593SmuzhiyunTRUNNER_BPF_BUILD_RULE := GCC_BPF_BUILD_RULE 412*4882a593SmuzhiyunTRUNNER_BPF_CFLAGS := $(BPF_CFLAGS) $(call get_sys_includes,gcc) 413*4882a593SmuzhiyunTRUNNER_BPF_LDFLAGS := 414*4882a593Smuzhiyun$(eval $(call DEFINE_TEST_RUNNER,test_progs,bpf_gcc)) 415*4882a593Smuzhiyunendif 416*4882a593Smuzhiyun 417*4882a593Smuzhiyun# Define test_maps test runner. 418*4882a593SmuzhiyunTRUNNER_TESTS_DIR := map_tests 419*4882a593SmuzhiyunTRUNNER_BPF_PROGS_DIR := progs 420*4882a593SmuzhiyunTRUNNER_EXTRA_SOURCES := test_maps.c 421*4882a593SmuzhiyunTRUNNER_EXTRA_FILES := 422*4882a593SmuzhiyunTRUNNER_BPF_BUILD_RULE := $$(error no BPF objects should be built) 423*4882a593SmuzhiyunTRUNNER_BPF_CFLAGS := 424*4882a593SmuzhiyunTRUNNER_BPF_LDFLAGS := 425*4882a593Smuzhiyun$(eval $(call DEFINE_TEST_RUNNER,test_maps)) 426*4882a593Smuzhiyun 427*4882a593Smuzhiyun# Define test_verifier test runner. 428*4882a593Smuzhiyun# It is much simpler than test_maps/test_progs and sufficiently different from 429*4882a593Smuzhiyun# them (e.g., test.h is using completely pattern), that it's worth just 430*4882a593Smuzhiyun# explicitly defining all the rules explicitly. 431*4882a593Smuzhiyunverifier/tests.h: verifier/*.c 432*4882a593Smuzhiyun $(shell ( cd verifier/; \ 433*4882a593Smuzhiyun echo '/* Generated header, do not edit */'; \ 434*4882a593Smuzhiyun echo '#ifdef FILL_ARRAY'; \ 435*4882a593Smuzhiyun ls *.c 2> /dev/null | sed -e 's@\(.*\)@#include \"\1\"@'; \ 436*4882a593Smuzhiyun echo '#endif' \ 437*4882a593Smuzhiyun ) > verifier/tests.h) 438*4882a593Smuzhiyun$(OUTPUT)/test_verifier: test_verifier.c verifier/tests.h $(BPFOBJ) | $(OUTPUT) 439*4882a593Smuzhiyun $(call msg,BINARY,,$@) 440*4882a593Smuzhiyun $(Q)$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@ 441*4882a593Smuzhiyun 442*4882a593Smuzhiyun# Make sure we are able to include and link libbpf against c++. 443*4882a593Smuzhiyun$(OUTPUT)/test_cpp: test_cpp.cpp $(OUTPUT)/test_core_extern.skel.h $(BPFOBJ) 444*4882a593Smuzhiyun $(call msg,CXX,,$@) 445*4882a593Smuzhiyun $(Q)$(CXX) $(CFLAGS) $^ $(LDLIBS) -o $@ 446*4882a593Smuzhiyun 447*4882a593Smuzhiyun# Benchmark runner 448*4882a593Smuzhiyun$(OUTPUT)/bench_%.o: benchs/bench_%.c bench.h 449*4882a593Smuzhiyun $(call msg,CC,,$@) 450*4882a593Smuzhiyun $(Q)$(CC) $(CFLAGS) -c $(filter %.c,$^) $(LDLIBS) -o $@ 451*4882a593Smuzhiyun$(OUTPUT)/bench_rename.o: $(OUTPUT)/test_overhead.skel.h 452*4882a593Smuzhiyun$(OUTPUT)/bench_trigger.o: $(OUTPUT)/trigger_bench.skel.h 453*4882a593Smuzhiyun$(OUTPUT)/bench_ringbufs.o: $(OUTPUT)/ringbuf_bench.skel.h \ 454*4882a593Smuzhiyun $(OUTPUT)/perfbuf_bench.skel.h 455*4882a593Smuzhiyun$(OUTPUT)/bench.o: bench.h testing_helpers.h 456*4882a593Smuzhiyun$(OUTPUT)/bench: LDLIBS += -lm 457*4882a593Smuzhiyun$(OUTPUT)/bench: $(OUTPUT)/bench.o $(OUTPUT)/testing_helpers.o \ 458*4882a593Smuzhiyun $(OUTPUT)/bench_count.o \ 459*4882a593Smuzhiyun $(OUTPUT)/bench_rename.o \ 460*4882a593Smuzhiyun $(OUTPUT)/bench_trigger.o \ 461*4882a593Smuzhiyun $(OUTPUT)/bench_ringbufs.o 462*4882a593Smuzhiyun $(call msg,BINARY,,$@) 463*4882a593Smuzhiyun $(Q)$(CC) $(LDFLAGS) -o $@ $(filter %.a %.o,$^) $(LDLIBS) 464*4882a593Smuzhiyun 465*4882a593SmuzhiyunEXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(SCRATCH_DIR) \ 466*4882a593Smuzhiyun prog_tests/tests.h map_tests/tests.h verifier/tests.h \ 467*4882a593Smuzhiyun feature \ 468*4882a593Smuzhiyun $(addprefix $(OUTPUT)/,*.o *.skel.h no_alu32 bpf_gcc) 469