blob: ff3476bc40a4978aaf0f4925b5a5d1499cdc55fa [file] [edit]
# SPDX-License-Identifier: GPL-2.0
#
# Toolchain, path and flag definitions for the BPF selftests build,
# kept apart from the rules so that more than one makefile can include
# them. Included by the Makefile after ../lib.mk and by Makefile.runner
# in its place - the note above the Makefile's include explains how the
# flags are ordered around it.
TOOLSDIR := $(abspath ../../..)
LIBDIR := $(TOOLSDIR)/lib
BPFDIR := $(LIBDIR)/bpf
TOOLSINCDIR := $(TOOLSDIR)/include
TOOLSARCHINCDIR := $(TOOLSDIR)/arch/$(SRCARCH)/include
APIDIR := $(TOOLSINCDIR)/uapi
ifneq ($(O),)
GENDIR := $(O)/include/generated
else
GENDIR := $(abspath ../../../../include/generated)
endif
GENHDR := $(GENDIR)/autoconf.h
PKG_CONFIG ?= $(CROSS_COMPILE)pkg-config
ifneq ($(wildcard $(GENHDR)),)
GENFLAGS := -DHAVE_GENHDR
endif
ifdef ASAN
SAN_CFLAGS ?= -fsanitize=address -fno-omit-frame-pointer
else
SAN_CFLAGS ?=
endif
SAN_LDFLAGS ?= $(SAN_CFLAGS)
RELEASE ?=
OPT_FLAGS ?= $(if $(RELEASE),-O2,-O0)
LIBELF_CFLAGS := $(shell $(PKG_CONFIG) libelf --cflags 2>/dev/null)
LIBELF_LIBS := $(shell $(PKG_CONFIG) libelf --libs 2>/dev/null || echo -lelf)
# When BPF_STRICT_BUILD is 1, any BPF object, skeleton, test object, or
# benchmark compilation failure is fatal. Set to 0 to tolerate failures
# and continue building the remaining tests.
BPF_STRICT_BUILD ?= 1
PERMISSIVE := $(filter 0,$(BPF_STRICT_BUILD))
# Permissive-mode recipe suffix: on failure, remove the target, emit a
# SKIP marker and report success so the rest of the build continues.
# $(1) - SKIP tag (BPF, TEST, BENCH, SKEL, LINK, ...)
# $(2) - optional extra files to remove alongside the target
# $(3) - optional note appended to the SKIP message
skip_on_fail = $(if $(PERMISSIVE),|| { $(RM) $@ $(2); \
printf ' %-12s %s\n' 'SKIP-$(1)' '$(notdir $@)$(if $(3), $(3))' 1>&2; })
# Permissive-mode recipe prefix: when a prerequisite object is missing
# (its compile failed and was skipped), remove the target and $(3),
# emit a SKIP marker and report success without running the rest of
# the recipe.
# $(1) - SKIP tag
# $(2) - input files to check
# $(3) - optional extra files to remove alongside the target
skip_if_missing = $(if $(PERMISSIVE),for f in $(2); do [ -f $$f ] || { \
$(RM) $@ $(3); \
printf ' %-12s %s\n' 'SKIP-$(1)' '$(notdir $@)' 1>&2; exit 0; }; done;)
ifeq ($(srctree),)
srctree := $(patsubst %/,%,$(dir $(CURDIR)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
endif
COMMON_CFLAGS = -g $(OPT_FLAGS) -rdynamic -std=gnu11 \
-Wall -Werror -fno-omit-frame-pointer \
-Wno-unused-but-set-variable \
$(GENFLAGS) $(SAN_CFLAGS) $(LIBELF_CFLAGS) \
-I$(CURDIR) -I$(INCLUDE_DIR) -I$(GENDIR) -I$(LIBDIR) \
-I$(TOOLSINCDIR) -I$(TOOLSARCHINCDIR) -I$(APIDIR) -I$(OUTPUT) \
-I$(CURDIR)/libarena/include
LDLIBS += $(LIBELF_LIBS) -lz -lrt -lpthread
PCAP_CFLAGS := $(shell $(PKG_CONFIG) --cflags libpcap 2>/dev/null && echo "-DTRAFFIC_MONITOR=1")
PCAP_LIBS := $(shell $(PKG_CONFIG) --libs libpcap 2>/dev/null)
LDLIBS += $(PCAP_LIBS)
ifneq ($(LLVM),)
# Silence some warnings when compiled with clang
CLANG_WARN_CFLAGS := -Wno-unused-command-line-argument
endif
# Check whether clang supports BPF address sanitizer (requires LLVM 22+).
# This runs after ../lib.mk has resolved CLANG from LLVM=<suffix or path>,
# so it probes the compiler that builds the BPF objects.
CLANG_HAS_ARENA_ASAN := $(shell echo 'int x;' | \
$(CLANG) --target=bpf -fsanitize=kernel-address \
-mllvm -asan-shadow-addr-space=1 \
-x c -c - -o /dev/null 2>/dev/null && echo 1)
SCRATCH_DIR := $(OUTPUT)/tools
BUILD_DIR := $(SCRATCH_DIR)/build
INCLUDE_DIR := $(SCRATCH_DIR)/include
BPFOBJ := $(BUILD_DIR)/libbpf/libbpf.a
ifneq ($(CROSS_COMPILE),)
HOST_BUILD_DIR := $(BUILD_DIR)/host
HOST_SCRATCH_DIR := $(OUTPUT)/host-tools
HOST_INCLUDE_DIR := $(HOST_SCRATCH_DIR)/include
else
HOST_BUILD_DIR := $(BUILD_DIR)
HOST_SCRATCH_DIR := $(SCRATCH_DIR)
HOST_INCLUDE_DIR := $(INCLUDE_DIR)
endif
RESOLVE_BTFIDS := $(HOST_BUILD_DIR)/resolve_btfids/resolve_btfids
# Programs in Rust are built by upstream rustc. It has no prebuilt core for
# the bpf target, so it has to come with the source of core:
# rustup component add rust-src
# core is built as edition 2024, which it is since rustc 1.87.
# rustc emits LLVM bitcode and clang makes the object of it, so clang has to be
# 23 or newer and not older than LLVM of rustc.
# Otherwise RUST_CORE is empty and the tests are skipped.
RUSTC ?= rustc
RUST_CORE_SRC := $(wildcard $(shell $(RUSTC) --print sysroot 2>/dev/null)$\
/lib/rustlib/src/rust/library/core/src/lib.rs)
ifneq ($(RUST_CORE_SRC),)
ifeq ($(shell { clang=$$(echo __clang_major__ | $(CLANG) -E -P -x c -) && \
llvm=$$($(srctree)/scripts/rustc-llvm-version.sh $(RUSTC)) && \
[ $$($(srctree)/scripts/rustc-version.sh $(RUSTC)) -ge 108700 ] && \
[ $$clang -ge 23 ] && [ $$clang -ge $$((llvm / 10000)) ]; } \
2>/dev/null && echo y),y)
RUST_CORE := $(BUILD_DIR)/rust/libcore.rlib
endif
endif
# RUSTC_BOOTSTRAP=1 is to build core with a stable rustc, like the kernel does.
# panic=abort is a stop gap until panic=unwind is supported.
RUSTC_BPF = RUSTC_BOOTSTRAP=1 $(RUSTC) -O -C panic=abort --crate-type rlib \
--target $(if $(IS_LITTLE_ENDIAN),bpfel,bpfeb)-unknown-none \
-L $(dir $(RUST_CORE))
DEFAULT_BPFTOOL := $(HOST_SCRATCH_DIR)/sbin/bpftool
ifneq ($(CROSS_COMPILE),)
CROSS_BPFTOOL := $(SCRATCH_DIR)/sbin/bpftool
TRUNNER_BPFTOOL := $(CROSS_BPFTOOL)
USE_BOOTSTRAP := ""
else
TRUNNER_BPFTOOL := $(DEFAULT_BPFTOOL)
USE_BOOTSTRAP := "bootstrap/"
endif
BPFTOOL ?= $(DEFAULT_BPFTOOL)
# Determine target endianness.
IS_LITTLE_ENDIAN := $(shell $(CC) -dM -E - </dev/null | \
grep 'define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__')
MENDIAN:=$(if $(IS_LITTLE_ENDIAN),-mlittle-endian,-mbig-endian)
BPF_CFLAGS = -g -Wall -Werror -D__TARGET_ARCH_$(SRCARCH) $(MENDIAN) \
-I$(INCLUDE_DIR) -I$(CURDIR) -I$(APIDIR) \
-I$(TOOLSINCDIR) -I$(CURDIR)/libarena/include \
-I$(abspath $(OUTPUT)/../usr/include) \
-std=gnu11 \
-fno-strict-aliasing \
-Wno-microsoft-anon-tag \
-fms-extensions \
-Wno-compare-distinct-pointer-types \
-Wno-initializer-overrides \
#
# TODO: enable me -Wsign-compare
VERIFY_SIG_SETUP := $(CURDIR)/verify_sig_setup.sh
VERIFICATION_CERT := $(BUILD_DIR)/signing_key.der
PRIVATE_KEY := $(BUILD_DIR)/signing_key.pem
LIBARENA_SKEL := libarena/libarena.skel.h
ifneq ($(CLANG_HAS_ARENA_ASAN),)
LIBARENA_ASAN_SKEL := libarena/libarena_asan.skel.h
CFLAGS += -DHAS_BPF_ARENA_ASAN
endif
RUNNER_OBJS-test_progs := $(addprefix $(OUTPUT)/, \
test_progs.o cgroup_helpers.o trace_helpers.o \
network_helpers.o testing_helpers.o btf_helpers.o \
cap_helpers.o unpriv_helpers.o sysctl_helpers.o \
netlink_helpers.o jit_disasm_helpers.o io_helpers.o \
test_loader.o xsk.o disasm.o disasm_helpers.o \
json_writer.o bpftool_helpers.o usdt_1.o usdt_2.o \
find_bit.o)
RUNNER_OBJS-test_maps := $(addprefix $(OUTPUT)/, \
test_maps.o testing_helpers.o)