* [PATCH 1/3] selftests/bpf: Route generated test headers to OUTPUT
2026-07-29 0:06 [PATCH 0/3] selftests/bpf: Fixes for out-of-tree builds Ricardo B. Marlière (SUSE)
@ 2026-07-29 0:06 ` Ricardo B. Marlière (SUSE)
2026-08-06 20:32 ` Ihor Solodrai
2026-07-29 0:06 ` [PATCH 2/3] selftests/bpf: Route libarena build artifacts " Ricardo B. Marlière (SUSE)
` (3 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Ricardo B. Marlière (SUSE) @ 2026-07-29 0:06 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Shuah Khan
Cc: bpf, linux-kselftest, linux-kernel, Ricardo B. Marlière (SUSE)
When building with O= the test-runner enumeration headers
(prog_tests/tests.h, map_tests/tests.h), the verifier test list
(verifier/tests.h) and the signing certificate header (verification_cert.h)
are written into the source tree instead of the out-of-tree build
directory.
Fix TRUNNER_TESTS_HDR to resolve under $(OUTPUT) and add an order-only
prerequisite so the subdirectory exists before the recipe runs. The mkdir
must precede the shell redirect in the same command, so use '&&' rather
than nesting mkdir inside the parenthesised group (the redirect opens the
file before the subshell starts).
Fix VERIFY_SIG_HDR likewise; the recipe already writes to $@ so no further
changes are needed there.
For verifier/tests.h, also resolve the target under $(OUTPUT) and generate
absolute paths in the '#include' directives, since the relative '"file.c"'
form would resolve against the output directory rather than the source
tree.
Signed-off-by: Ricardo B. Marlière (SUSE) <ricardo@marliere.net>
---
tools/testing/selftests/bpf/Makefile | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index b642ee489ea6..b289183475d4 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -580,7 +580,7 @@ TRUNNER_EXTRA_OBJS := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.o, \
TRUNNER_LIB_OBJS := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.o, \
$$(filter %.c,$(TRUNNER_LIB_SOURCES)))
TRUNNER_EXTRA_HDRS := $$(filter %.h,$(TRUNNER_EXTRA_SOURCES))
-TRUNNER_TESTS_HDR := $(TRUNNER_TESTS_DIR)/tests.h
+TRUNNER_TESTS_HDR := $(OUTPUT)/$(TRUNNER_TESTS_DIR)/tests.h
TRUNNER_BPF_SRCS := $$(notdir $$(wildcard $(TRUNNER_BPF_PROGS_DIR)/*.c))
TRUNNER_BPF_OBJS := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.bpf.o, $$(TRUNNER_BPF_SRCS))
TRUNNER_BPF_SKELS := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.skel.h, \
@@ -720,9 +720,9 @@ endif
# ensure we set up tests.h header generation rule just once
ifeq ($($(TRUNNER_TESTS_DIR)-tests-hdr),)
$(TRUNNER_TESTS_DIR)-tests-hdr := y
-$(TRUNNER_TESTS_HDR): $(TRUNNER_TESTS_DIR)/*.c
+$(TRUNNER_TESTS_HDR): $(TRUNNER_TESTS_DIR)/*.c | $(TRUNNER_OUTPUT)
$$(call msg,TEST-HDR,$(TRUNNER_BINARY),$$@)
- $$(shell (echo '/* Generated header, do not edit */'; \
+ $$(shell mkdir -p $$(dir $$@) && (echo '/* Generated header, do not edit */'; \
sed -n -E 's/^void (serial_)?test_([a-zA-Z0-9_]+)\((void)?\).*/DEFINE_TEST(\2)/p' \
$(TRUNNER_TESTS_DIR)/*.c | sort ; \
) > $$@)
@@ -802,7 +802,7 @@ $(OUTPUT)/$(TRUNNER_BINARY): $(if $(filter test_progs%,$1),$(if $(PERMISSIVE),$$
endef
VERIFY_SIG_SETUP := $(CURDIR)/verify_sig_setup.sh
-VERIFY_SIG_HDR := verification_cert.h
+VERIFY_SIG_HDR := $(OUTPUT)/verification_cert.h
VERIFICATION_CERT := $(BUILD_DIR)/signing_key.der
PRIVATE_KEY := $(BUILD_DIR)/signing_key.pem
@@ -923,14 +923,14 @@ $(eval $(call DEFINE_TEST_RUNNER,test_maps))
# It is much simpler than test_maps/test_progs and sufficiently different from
# them (e.g., test.h is using completely pattern), that it's worth just
# explicitly defining all the rules explicitly.
-verifier/tests.h: verifier/*.c
- $(shell ( cd verifier/; \
+$(OUTPUT)/verifier/tests.h: verifier/*.c | $(OUTPUT)
+ $(shell mkdir -p $(OUTPUT)/verifier && ( \
echo '/* Generated header, do not edit */'; \
echo '#ifdef FILL_ARRAY'; \
- ls *.c 2> /dev/null | sed -e 's@\(.*\)@#include \"\1\"@'; \
+ ls verifier/*.c 2> /dev/null | sed -e 's@\(.*\)@#include "$(CURDIR)/\1"@'; \
echo '#endif' \
- ) > verifier/tests.h)
-$(OUTPUT)/test_verifier: test_verifier.c verifier/tests.h $(BPFOBJ) | $(OUTPUT)
+ ) > $(OUTPUT)/verifier/tests.h)
+$(OUTPUT)/test_verifier: test_verifier.c $(OUTPUT)/verifier/tests.h $(BPFOBJ) | $(OUTPUT)
$(call msg,BINARY,,$@)
$(Q)$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@
--
2.55.0
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH 1/3] selftests/bpf: Route generated test headers to OUTPUT
2026-07-29 0:06 ` [PATCH 1/3] selftests/bpf: Route generated test headers to OUTPUT Ricardo B. Marlière (SUSE)
@ 2026-08-06 20:32 ` Ihor Solodrai
0 siblings, 0 replies; 14+ messages in thread
From: Ihor Solodrai @ 2026-08-06 20:32 UTC (permalink / raw)
To: Ricardo B. Marlière (SUSE),
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Shuah Khan
Cc: bpf, linux-kselftest, linux-kernel
On 7/28/26 5:06 PM, Ricardo B. Marlière (SUSE) wrote:
> [...]
>
> @@ -923,14 +923,14 @@ $(eval $(call DEFINE_TEST_RUNNER,test_maps))
> # It is much simpler than test_maps/test_progs and sufficiently different from
> # them (e.g., test.h is using completely pattern), that it's worth just
> # explicitly defining all the rules explicitly.
> -verifier/tests.h: verifier/*.c
> - $(shell ( cd verifier/; \
> +$(OUTPUT)/verifier/tests.h: verifier/*.c | $(OUTPUT)
> + $(shell mkdir -p $(OUTPUT)/verifier && ( \
> echo '/* Generated header, do not edit */'; \
> echo '#ifdef FILL_ARRAY'; \
> - ls *.c 2> /dev/null | sed -e 's@\(.*\)@#include \"\1\"@'; \
> + ls verifier/*.c 2> /dev/null | sed -e 's@\(.*\)@#include "$(CURDIR)/\1"@'; \
This can break if $(CURDIR) contains '@'.
In such case sed fails, but make returns success and generates
verifier/tests.h with zero #include lines. And this would silently
skip all the tests.
Also at line 1046:
EXTRA_CLEAN := $(SCRATCH_DIR) $(HOST_SCRATCH_DIR) \
prog_tests/tests.h map_tests/tests.h verifier/tests.h \
These are the old source-tree locations. Should be updated?
> echo '#endif' \
> - ) > verifier/tests.h)
> -$(OUTPUT)/test_verifier: test_verifier.c verifier/tests.h $(BPFOBJ) | $(OUTPUT)
> + ) > $(OUTPUT)/verifier/tests.h)
> +$(OUTPUT)/test_verifier: test_verifier.c $(OUTPUT)/verifier/tests.h $(BPFOBJ) | $(OUTPUT)
> $(call msg,BINARY,,$@)
> $(Q)$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 2/3] selftests/bpf: Route libarena build artifacts to OUTPUT
2026-07-29 0:06 [PATCH 0/3] selftests/bpf: Fixes for out-of-tree builds Ricardo B. Marlière (SUSE)
2026-07-29 0:06 ` [PATCH 1/3] selftests/bpf: Route generated test headers to OUTPUT Ricardo B. Marlière (SUSE)
@ 2026-07-29 0:06 ` Ricardo B. Marlière (SUSE)
2026-08-06 20:33 ` Ihor Solodrai
2026-07-29 0:06 ` [PATCH 3/3] selftests/bpf: Route test_kmods " Ricardo B. Marlière (SUSE)
` (2 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Ricardo B. Marlière (SUSE) @ 2026-07-29 0:06 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Shuah Khan
Cc: bpf, linux-kselftest, linux-kernel, Ricardo B. Marlière (SUSE)
libarena's BPF objects, linked objects, and skeleton headers are always
written into the source tree regardless of whether an out-of-tree build
directory was specified via O=.
Add OUTPUT support to libarena/Makefile: default OUTPUT to '.' for
standalone builds, prefix all generated file targets with $(OUTPUT)/, and
use addprefix to propagate the directory into the per-object lists. Create
$(OUTPUT) at Makefile-load time with a $(shell mkdir -p) so all rules have
a valid destination.
In the parent bpf/Makefile, pass OUTPUT="$(OUTPUT)/libarena" in
LIBARENA_MAKE_ARGS and update LIBARENA_SKEL/LIBARENA_ASAN_SKEL to reflect
the new location. Pass the absolute target path as the make goal so the
sub-make goal matches the $(OUTPUT)/... rule in libarena/Makefile
regardless of the invocation directory.
Signed-off-by: Ricardo B. Marlière (SUSE) <ricardo@marliere.net>
---
tools/testing/selftests/bpf/Makefile | 11 ++++++-----
tools/testing/selftests/bpf/libarena/Makefile | 24 ++++++++++++++----------
2 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index b289183475d4..7d42632f9d42 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -826,7 +826,8 @@ LIBARENA_MAKE_ARGS = \
CLANG="$(CLANG)" \
BPF_CFLAGS="$(BPF_CFLAGS) $(CLANG_CFLAGS)" \
BPF_TARGET_ENDIAN="$(BPF_TARGET_ENDIAN)" \
- Q="$(Q)"
+ Q="$(Q)" \
+ OUTPUT="$(OUTPUT)/libarena"
LIBARENA_BPF_DEPS := $(wildcard libarena/Makefile \
libarena/include/* \
@@ -835,17 +836,17 @@ LIBARENA_BPF_DEPS := $(wildcard libarena/Makefile \
libarena/selftests/* \
libarena/*.bpf.o)
-LIBARENA_SKEL := libarena/libarena.skel.h
+LIBARENA_SKEL := $(OUTPUT)/libarena/libarena.skel.h
$(LIBARENA_SKEL): $(INCLUDE_DIR)/vmlinux.h $(BPFOBJ) $(LIBARENA_BPF_DEPS)
- +$(MAKE) -C libarena libarena.skel.h $(LIBARENA_MAKE_ARGS)
+ +$(MAKE) -C libarena $(LIBARENA_SKEL) $(LIBARENA_MAKE_ARGS)
ifneq ($(CLANG_HAS_ARENA_ASAN),)
-LIBARENA_ASAN_SKEL := libarena/libarena_asan.skel.h
+LIBARENA_ASAN_SKEL := $(OUTPUT)/libarena/libarena_asan.skel.h
CFLAGS += -DHAS_BPF_ARENA_ASAN
$(LIBARENA_ASAN_SKEL): $(INCLUDE_DIR)/vmlinux.h $(BPFOBJ) $(LIBARENA_BPF_DEPS)
- +$(MAKE) -C libarena libarena_asan.skel.h $(LIBARENA_MAKE_ARGS)
+ +$(MAKE) -C libarena $(LIBARENA_ASAN_SKEL) $(LIBARENA_MAKE_ARGS)
endif
# Define test_progs test runner.
diff --git a/tools/testing/selftests/bpf/libarena/Makefile b/tools/testing/selftests/bpf/libarena/Makefile
index 5e2ab514805e..195d5f833186 100644
--- a/tools/testing/selftests/bpf/libarena/Makefile
+++ b/tools/testing/selftests/bpf/libarena/Makefile
@@ -27,10 +27,14 @@ BPFDIR=$(abspath $(LIBARENA)/..)
INCLUDE_DIR ?= $(BPFDIR)/tools/include
LIBBPF_INCLUDE ?= $(INCLUDE_DIR)
+# Build output directory; defaults to in-tree for standalone builds.
+OUTPUT ?= .
+$(shell mkdir -p $(OUTPUT))
+
# Scan src/ and selftests/ to generate the final binaries
LIBARENA_SOURCES = $(wildcard $(LIBARENA)/src/*.bpf.c) $(wildcard $(LIBARENA)/selftests/*.bpf.c)
-LIBARENA_OBJECTS = $(notdir $(LIBARENA_SOURCES:.bpf.c=.bpf.o))
-LIBARENA_OBJECTS_ASAN = $(notdir $(LIBARENA_SOURCES:.bpf.c=_asan.bpf.o))
+LIBARENA_OBJECTS = $(addprefix $(OUTPUT)/,$(notdir $(LIBARENA_SOURCES:.bpf.c=.bpf.o)))
+LIBARENA_OBJECTS_ASAN = $(addprefix $(OUTPUT)/,$(notdir $(LIBARENA_SOURCES:.bpf.c=_asan.bpf.o)))
INCLUDES = -I$(LIBARENA)/include -I$(BPFDIR)
ifneq ($(INCLUDE_DIR),)
@@ -61,32 +65,32 @@ CFLAGS += $(INCLUDES)
vpath %.bpf.c $(LIBARENA)/src $(LIBARENA)/selftests
vpath %.c $(LIBARENA)/src $(LIBARENA)/selftests
-skeletons: libarena.skel.h libarena_asan.skel.h
+skeletons: $(OUTPUT)/libarena.skel.h $(OUTPUT)/libarena_asan.skel.h
.PHONY: skeletons
-libarena_asan.skel.h: libarena_asan.bpf.o
+$(OUTPUT)/libarena_asan.skel.h: $(OUTPUT)/libarena_asan.bpf.o
$(call msg,GEN-SKEL,libarena,$@)
$(Q)$(BPFTOOL) gen skeleton $< name "libarena_asan" > $@
-libarena.skel.h: libarena.bpf.o
+$(OUTPUT)/libarena.skel.h: $(OUTPUT)/libarena.bpf.o
$(call msg,GEN-SKEL,libarena,$@)
$(Q)$(BPFTOOL) gen skeleton $< name "libarena" > $@
-libarena_asan.bpf.o: $(LIBARENA_OBJECTS_ASAN)
+$(OUTPUT)/libarena_asan.bpf.o: $(LIBARENA_OBJECTS_ASAN)
$(call msg,GEN-OBJ,libarena,$@)
$(Q)$(BPFTOOL) gen object $@ $^
-libarena.bpf.o: $(LIBARENA_OBJECTS)
+$(OUTPUT)/libarena.bpf.o: $(LIBARENA_OBJECTS)
$(call msg,GEN-OBJ,libarena,$@)
$(Q)$(BPFTOOL) gen object $@ $^
-%_asan.bpf.o: %.bpf.c
+$(OUTPUT)/%_asan.bpf.o: %.bpf.c
$(call msg,CLNG-BPF,libarena,$@)
$(Q)$(CLANG) $(BPF_CFLAGS) $(ASAN_FLAGS) -DBPF_ARENA_ASAN $(BPF_TARGET_ENDIAN) -c $< -o $@
-%.bpf.o: %.bpf.c
+$(OUTPUT)/%.bpf.o: %.bpf.c
$(call msg,CLNG-BPF,libarena,$@)
$(Q)$(CLANG) $(BPF_CFLAGS) $(BPF_TARGET_ENDIAN) -c $< -o $@
clean:
- $(Q)rm -f *.skel.h *.bpf.o *.linked*.o
+ $(Q)rm -f $(OUTPUT)/*.skel.h $(OUTPUT)/*.bpf.o $(OUTPUT)/*.linked*.o
--
2.55.0
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH 2/3] selftests/bpf: Route libarena build artifacts to OUTPUT
2026-07-29 0:06 ` [PATCH 2/3] selftests/bpf: Route libarena build artifacts " Ricardo B. Marlière (SUSE)
@ 2026-08-06 20:33 ` Ihor Solodrai
0 siblings, 0 replies; 14+ messages in thread
From: Ihor Solodrai @ 2026-08-06 20:33 UTC (permalink / raw)
To: Ricardo B. Marlière (SUSE),
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Shuah Khan
Cc: bpf, linux-kselftest, linux-kernel
On 7/28/26 5:06 PM, Ricardo B. Marlière (SUSE) wrote:
> libarena's BPF objects, linked objects, and skeleton headers are always
> written into the source tree regardless of whether an out-of-tree build
> directory was specified via O=.
>
> Add OUTPUT support to libarena/Makefile: default OUTPUT to '.' for
> standalone builds, prefix all generated file targets with $(OUTPUT)/, and
> use addprefix to propagate the directory into the per-object lists. Create
> $(OUTPUT) at Makefile-load time with a $(shell mkdir -p) so all rules have
> a valid destination.
>
> In the parent bpf/Makefile, pass OUTPUT="$(OUTPUT)/libarena" in
> LIBARENA_MAKE_ARGS and update LIBARENA_SKEL/LIBARENA_ASAN_SKEL to reflect
> the new location. Pass the absolute target path as the make goal so the
> sub-make goal matches the $(OUTPUT)/... rule in libarena/Makefile
> regardless of the invocation directory.
>
> Signed-off-by: Ricardo B. Marlière (SUSE) <ricardo@marliere.net>
> ---
> tools/testing/selftests/bpf/Makefile | 11 ++++++-----
> tools/testing/selftests/bpf/libarena/Makefile | 24 ++++++++++++++----------
> 2 files changed, 20 insertions(+), 15 deletions(-)
>
> diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
> index b289183475d4..7d42632f9d42 100644
> --- a/tools/testing/selftests/bpf/Makefile
> +++ b/tools/testing/selftests/bpf/Makefile
> @@ -826,7 +826,8 @@ LIBARENA_MAKE_ARGS = \
> CLANG="$(CLANG)" \
> BPF_CFLAGS="$(BPF_CFLAGS) $(CLANG_CFLAGS)" \
> BPF_TARGET_ENDIAN="$(BPF_TARGET_ENDIAN)" \
> - Q="$(Q)"
> + Q="$(Q)" \
> + OUTPUT="$(OUTPUT)/libarena"
>
> LIBARENA_BPF_DEPS := $(wildcard libarena/Makefile \
> libarena/include/* \
> @@ -835,17 +836,17 @@ LIBARENA_BPF_DEPS := $(wildcard libarena/Makefile \
> libarena/selftests/* \
> libarena/*.bpf.o)
>
> -LIBARENA_SKEL := libarena/libarena.skel.h
> +LIBARENA_SKEL := $(OUTPUT)/libarena/libarena.skel.h
>
> $(LIBARENA_SKEL): $(INCLUDE_DIR)/vmlinux.h $(BPFOBJ) $(LIBARENA_BPF_DEPS)
> - +$(MAKE) -C libarena libarena.skel.h $(LIBARENA_MAKE_ARGS)
> + +$(MAKE) -C libarena $(LIBARENA_SKEL) $(LIBARENA_MAKE_ARGS)
>
> ifneq ($(CLANG_HAS_ARENA_ASAN),)
> -LIBARENA_ASAN_SKEL := libarena/libarena_asan.skel.h
> +LIBARENA_ASAN_SKEL := $(OUTPUT)/libarena/libarena_asan.skel.h
> CFLAGS += -DHAS_BPF_ARENA_ASAN
>
> $(LIBARENA_ASAN_SKEL): $(INCLUDE_DIR)/vmlinux.h $(BPFOBJ) $(LIBARENA_BPF_DEPS)
> - +$(MAKE) -C libarena libarena_asan.skel.h $(LIBARENA_MAKE_ARGS)
> + +$(MAKE) -C libarena $(LIBARENA_ASAN_SKEL) $(LIBARENA_MAKE_ARGS)
> endif
>
> # Define test_progs test runner.
> diff --git a/tools/testing/selftests/bpf/libarena/Makefile b/tools/testing/selftests/bpf/libarena/Makefile
> index 5e2ab514805e..195d5f833186 100644
> --- a/tools/testing/selftests/bpf/libarena/Makefile
> +++ b/tools/testing/selftests/bpf/libarena/Makefile
> @@ -27,10 +27,14 @@ BPFDIR=$(abspath $(LIBARENA)/..)
> INCLUDE_DIR ?= $(BPFDIR)/tools/include
> LIBBPF_INCLUDE ?= $(INCLUDE_DIR)
>
> +# Build output directory; defaults to in-tree for standalone builds.
> +OUTPUT ?= .
> +$(shell mkdir -p $(OUTPUT))
This runs while make parses the file, including under make -n, and
discards mkdir's status. Let's create $(OUTPUT) via order-only
directory prereq instead.
> +
> # Scan src/ and selftests/ to generate the final binaries
> LIBARENA_SOURCES = $(wildcard $(LIBARENA)/src/*.bpf.c) $(wildcard $(LIBARENA)/selftests/*.bpf.c)
> -LIBARENA_OBJECTS = $(notdir $(LIBARENA_SOURCES:.bpf.c=.bpf.o))
> -LIBARENA_OBJECTS_ASAN = $(notdir $(LIBARENA_SOURCES:.bpf.c=_asan.bpf.o))
> +LIBARENA_OBJECTS = $(addprefix $(OUTPUT)/,$(notdir $(LIBARENA_SOURCES:.bpf.c=.bpf.o)))
> +LIBARENA_OBJECTS_ASAN = $(addprefix $(OUTPUT)/,$(notdir $(LIBARENA_SOURCES:.bpf.c=_asan.bpf.o)))
>
> INCLUDES = -I$(LIBARENA)/include -I$(BPFDIR)
> ifneq ($(INCLUDE_DIR),)
> @@ -61,32 +65,32 @@ CFLAGS += $(INCLUDES)
> vpath %.bpf.c $(LIBARENA)/src $(LIBARENA)/selftests
> vpath %.c $(LIBARENA)/src $(LIBARENA)/selftests
>
> -skeletons: libarena.skel.h libarena_asan.skel.h
> +skeletons: $(OUTPUT)/libarena.skel.h $(OUTPUT)/libarena_asan.skel.h
> .PHONY: skeletons
>
> -libarena_asan.skel.h: libarena_asan.bpf.o
> +$(OUTPUT)/libarena_asan.skel.h: $(OUTPUT)/libarena_asan.bpf.o
> $(call msg,GEN-SKEL,libarena,$@)
> $(Q)$(BPFTOOL) gen skeleton $< name "libarena_asan" > $@
>
> -libarena.skel.h: libarena.bpf.o
> +$(OUTPUT)/libarena.skel.h: $(OUTPUT)/libarena.bpf.o
> $(call msg,GEN-SKEL,libarena,$@)
> $(Q)$(BPFTOOL) gen skeleton $< name "libarena" > $@
>
> -libarena_asan.bpf.o: $(LIBARENA_OBJECTS_ASAN)
> +$(OUTPUT)/libarena_asan.bpf.o: $(LIBARENA_OBJECTS_ASAN)
> $(call msg,GEN-OBJ,libarena,$@)
> $(Q)$(BPFTOOL) gen object $@ $^
>
> -libarena.bpf.o: $(LIBARENA_OBJECTS)
> +$(OUTPUT)/libarena.bpf.o: $(LIBARENA_OBJECTS)
> $(call msg,GEN-OBJ,libarena,$@)
> $(Q)$(BPFTOOL) gen object $@ $^
>
> -%_asan.bpf.o: %.bpf.c
> +$(OUTPUT)/%_asan.bpf.o: %.bpf.c
> $(call msg,CLNG-BPF,libarena,$@)
> $(Q)$(CLANG) $(BPF_CFLAGS) $(ASAN_FLAGS) -DBPF_ARENA_ASAN $(BPF_TARGET_ENDIAN) -c $< -o $@
>
> -%.bpf.o: %.bpf.c
> +$(OUTPUT)/%.bpf.o: %.bpf.c
> $(call msg,CLNG-BPF,libarena,$@)
> $(Q)$(CLANG) $(BPF_CFLAGS) $(BPF_TARGET_ENDIAN) -c $< -o $@
>
> clean:
> - $(Q)rm -f *.skel.h *.bpf.o *.linked*.o
> + $(Q)rm -f $(OUTPUT)/*.skel.h $(OUTPUT)/*.bpf.o $(OUTPUT)/*.linked*.o
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/3] selftests/bpf: Route test_kmods build artifacts to OUTPUT
2026-07-29 0:06 [PATCH 0/3] selftests/bpf: Fixes for out-of-tree builds Ricardo B. Marlière (SUSE)
2026-07-29 0:06 ` [PATCH 1/3] selftests/bpf: Route generated test headers to OUTPUT Ricardo B. Marlière (SUSE)
2026-07-29 0:06 ` [PATCH 2/3] selftests/bpf: Route libarena build artifacts " Ricardo B. Marlière (SUSE)
@ 2026-07-29 0:06 ` Ricardo B. Marlière (SUSE)
2026-08-06 20:35 ` Ihor Solodrai
2026-08-06 20:29 ` [PATCH 0/3] selftests/bpf: Fixes for out-of-tree builds Ihor Solodrai
2026-09-21 20:40 ` Nico Pache (Red Hat)
4 siblings, 1 reply; 14+ messages in thread
From: Ricardo B. Marlière (SUSE) @ 2026-07-29 0:06 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Shuah Khan
Cc: bpf, linux-kselftest, linux-kernel, Ricardo B. Marlière (SUSE)
When building bpf selftests with O=, the kernel module intermediates (.ko,
.o, .mod.*, .cmd files, Module.symvers, modules.order) produced by the
test_kmods sub-make are placed in the source tree instead of the
out-of-tree directory, because kbuild external-module builds always write
output to the M= source directory by default.
Introduce TEST_KMODS_OUTDIR in bpf/Makefile that resolves to
$(OUTPUT)/test_kmods when OUTPUT is set, and fall back to the in-tree
test_kmods/ directory for standalone builds. Update the pattern rule, the
RM invocation, and the copy rule to use this variable, and pass
OUTPUT=$(OUTPUT)/test_kmods to the test_kmods sub-make.
In test_kmods/Makefile, forward the received OUTPUT value as MO= to the
kernel Makefile. The top-level kernel Makefile maps MO= to
KBUILD_EXTMOD_OUTPUT, which redirects all external-module build output to
the specified directory. The kernel also creates that directory
automatically, so no explicit mkdir is needed.
Also update the CLEAN target in bpf/Makefile to propagate OUTPUT to both
the test_kmods and libarena sub-makes so that clean removes from the
correct location.
Signed-off-by: Ricardo B. Marlière (SUSE) <ricardo@marliere.net>
---
tools/testing/selftests/bpf/Makefile | 16 ++++++++++------
tools/testing/selftests/bpf/test_kmods/Makefile | 3 +++
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 7d42632f9d42..b150a66f3c25 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -135,6 +135,9 @@ TEST_PROGS_EXTENDED := \
TEST_KMODS := bpf_testmod.ko bpf_test_no_cfi.ko bpf_test_modorder_x.ko \
bpf_test_modorder_y.ko bpf_test_rqspinlock.ko
TEST_KMOD_TARGETS = $(addprefix $(OUTPUT)/,$(TEST_KMODS))
+# Build directory for kernel modules: routed to $(OUTPUT)/test_kmods when
+# OUTPUT is set so that kbuild intermediates stay out of the source tree.
+TEST_KMODS_OUTDIR := $(if $(OUTPUT),$(OUTPUT)/test_kmods,test_kmods)
# Compile but not part of 'make run_tests'
TEST_GEN_PROGS_EXTENDED = \
@@ -163,8 +166,8 @@ override define CLEAN
$(Q)$(RM) -r $(TEST_GEN_FILES)
$(Q)$(RM) -r $(TEST_KMODS)
$(Q)$(RM) -r $(EXTRA_CLEAN)
- $(Q)$(MAKE) -C test_kmods clean
- $(Q)$(MAKE) -C libarena clean
+ $(Q)$(MAKE) -C test_kmods $(if $(OUTPUT),OUTPUT=$(OUTPUT)/test_kmods) clean
+ $(Q)$(MAKE) -C libarena $(if $(OUTPUT),OUTPUT=$(OUTPUT)/libarena) clean
$(Q)$(MAKE) docs-clean
endef
@@ -301,17 +304,18 @@ $(OUTPUT)/sign-file: ../../../../scripts/sign-file.c
# support that for regular rules. However, pattern matching rules are implicitly
# treated as grouped even with older versions of make, so as a workaround, the
# subst() turns the rule into a pattern matching rule
-$(addprefix test_kmods/,$(subst .ko,%ko,$(TEST_KMODS))): $(VMLINUX_BTF) $(RESOLVE_BTFIDS) $(wildcard test_kmods/Makefile test_kmods/*.[ch])
- $(Q)$(RM) test_kmods/*.ko test_kmods/*.mod.o # force re-compilation
+$(addprefix $(TEST_KMODS_OUTDIR)/,$(subst .ko,%ko,$(TEST_KMODS))): $(VMLINUX_BTF) $(RESOLVE_BTFIDS) $(wildcard test_kmods/Makefile test_kmods/*.[ch])
+ $(Q)$(RM) $(TEST_KMODS_OUTDIR)/*.ko $(TEST_KMODS_OUTDIR)/*.mod.o # force re-compilation
$(Q)$(MAKE) $(submake_extras) -C test_kmods \
$(if $(O),O=$(abspath $(O))) \
$(if $(KBUILD_OUTPUT),KBUILD_OUTPUT=$(abspath $(KBUILD_OUTPUT)))\
+ $(if $(OUTPUT),OUTPUT=$(OUTPUT)/test_kmods) \
RESOLVE_BTFIDS=$(RESOLVE_BTFIDS) \
EXTRA_CFLAGS='' EXTRA_LDFLAGS=''
-$(TEST_KMOD_TARGETS): $(addprefix test_kmods/,$(TEST_KMODS))
+$(TEST_KMOD_TARGETS): $(addprefix $(TEST_KMODS_OUTDIR)/,$(TEST_KMODS))
$(call msg,MOD,,$@)
- $(Q)$(if $(PERMISSIVE),if [ -f test_kmods/$(@F) ]; then )cp test_kmods/$(@F) $@$(if $(PERMISSIVE),; fi)
+ $(Q)$(if $(PERMISSIVE),if [ -f $(TEST_KMODS_OUTDIR)/$(@F) ]; then )cp $(TEST_KMODS_OUTDIR)/$(@F) $@$(if $(PERMISSIVE),; fi)
DEFAULT_BPFTOOL := $(HOST_SCRATCH_DIR)/sbin/bpftool
diff --git a/tools/testing/selftests/bpf/test_kmods/Makefile b/tools/testing/selftests/bpf/test_kmods/Makefile
index 031c7454ce65..53e47e715ec4 100644
--- a/tools/testing/selftests/bpf/test_kmods/Makefile
+++ b/tools/testing/selftests/bpf/test_kmods/Makefile
@@ -32,14 +32,17 @@ PERMISSIVE := $(filter 0,$(BPF_STRICT_BUILD))
all:
ifeq ($(PERMISSIVE),)
$(Q)$(MAKE) -C $(KDIR) $(if $(KMOD_O_VALID),O=$(KMOD_O_VALID) KBUILD_OUTPUT=$(KMOD_O_VALID),KBUILD_OUTPUT=) \
+ $(if $(OUTPUT),MO=$(OUTPUT)) \
M=$(TEST_KMOD_DIR) modules
else ifneq ("$(wildcard $(KDIR))", "")
$(Q)$(MAKE) -C $(KDIR) $(if $(KMOD_O_VALID),O=$(KMOD_O_VALID) KBUILD_OUTPUT=$(KMOD_O_VALID),KBUILD_OUTPUT=) \
+ $(if $(OUTPUT),MO=$(OUTPUT)) \
M=$(TEST_KMOD_DIR) modules
endif
clean:
ifneq ("$(wildcard $(KDIR))", "")
$(Q)$(MAKE) -C $(KDIR) $(if $(KMOD_O_VALID),O=$(KMOD_O_VALID) KBUILD_OUTPUT=$(KMOD_O_VALID),KBUILD_OUTPUT=) \
+ $(if $(OUTPUT),MO=$(OUTPUT)) \
M=$(TEST_KMOD_DIR) clean
endif
--
2.55.0
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH 3/3] selftests/bpf: Route test_kmods build artifacts to OUTPUT
2026-07-29 0:06 ` [PATCH 3/3] selftests/bpf: Route test_kmods " Ricardo B. Marlière (SUSE)
@ 2026-08-06 20:35 ` Ihor Solodrai
0 siblings, 0 replies; 14+ messages in thread
From: Ihor Solodrai @ 2026-08-06 20:35 UTC (permalink / raw)
To: Ricardo B. Marlière (SUSE),
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Shuah Khan
Cc: bpf, linux-kselftest, linux-kernel
On 7/28/26 5:06 PM, Ricardo B. Marlière (SUSE) wrote:
> [...]
>
> diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
> index 7d42632f9d42..b150a66f3c25 100644
> --- a/tools/testing/selftests/bpf/Makefile
> +++ b/tools/testing/selftests/bpf/Makefile
> @@ -135,6 +135,9 @@ TEST_PROGS_EXTENDED := \
> TEST_KMODS := bpf_testmod.ko bpf_test_no_cfi.ko bpf_test_modorder_x.ko \
> bpf_test_modorder_y.ko bpf_test_rqspinlock.ko
> TEST_KMOD_TARGETS = $(addprefix $(OUTPUT)/,$(TEST_KMODS))
> +# Build directory for kernel modules: routed to $(OUTPUT)/test_kmods when
> +# OUTPUT is set so that kbuild intermediates stay out of the source tree.
> +TEST_KMODS_OUTDIR := $(if $(OUTPUT),$(OUTPUT)/test_kmods,test_kmods)
>
> # Compile but not part of 'make run_tests'
> TEST_GEN_PROGS_EXTENDED = \
> @@ -163,8 +166,8 @@ override define CLEAN
> $(Q)$(RM) -r $(TEST_GEN_FILES)
> $(Q)$(RM) -r $(TEST_KMODS)
> $(Q)$(RM) -r $(EXTRA_CLEAN)
> - $(Q)$(MAKE) -C test_kmods clean
> - $(Q)$(MAKE) -C libarena clean
> + $(Q)$(MAKE) -C test_kmods $(if $(OUTPUT),OUTPUT=$(OUTPUT)/test_kmods) clean
> + $(Q)$(MAKE) -C libarena $(if $(OUTPUT),OUTPUT=$(OUTPUT)/libarena) clean
This is broken. What happens if the caller set OUTPUT but not O= ?
If at linux root you do:
$ make defconfig && make -j$(nproc)
$ mkdir -p /tmp/kout
$ make -C tools/testing/selftests/bpf OUTPUT=/tmp/kout clean
it destroys the root Makefile:
$ git diff --stat -- Makefile
Makefile | 2364 +------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 file changed, 5 insertions(+), 2359 deletions(-)
$ cat Makefile
# Automatically generated by /home/isolodrai/sandbox/2026-08-06.review.out-of-tree-fixes/linux/Makefile: don't edit
export KBUILD_OUTPUT = /home/isolodrai/sandbox/2026-08-06.review.out-of-tree-fixes/linux
export KBUILD_EXTMOD = /home/isolodrai/sandbox/2026-08-06.review.out-of-tree-fixes/linux/tools/testing/selftests/bpf/test_kmods
export KBUILD_EXTMOD_OUTPUT = /tmp/kout/test_kmods
include /home/isolodrai/sandbox/2026-08-06.review.out-of-tree-fixes/linux/Makefile
pw-bot: cr
Also the selftests clean loop runs clean rules this way [1]:
clean:
@for TARGET in $(TARGETS) $(INSTALL_DEP_TARGETS); do \
BUILD_TARGET=$$BUILD/$$TARGET; \
$(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean;\
done;
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/testing/selftests/Makefile?h=v7.2-rc6#n325
> $(Q)$(MAKE) docs-clean
> endef
>
> [...]
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 0/3] selftests/bpf: Fixes for out-of-tree builds
2026-07-29 0:06 [PATCH 0/3] selftests/bpf: Fixes for out-of-tree builds Ricardo B. Marlière (SUSE)
` (2 preceding siblings ...)
2026-07-29 0:06 ` [PATCH 3/3] selftests/bpf: Route test_kmods " Ricardo B. Marlière (SUSE)
@ 2026-08-06 20:29 ` Ihor Solodrai
2026-08-06 20:47 ` Ricardo B. Marlière
2026-09-21 20:40 ` Nico Pache (Red Hat)
4 siblings, 1 reply; 14+ messages in thread
From: Ihor Solodrai @ 2026-08-06 20:29 UTC (permalink / raw)
To: Ricardo B. Marlière (SUSE),
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Shuah Khan
Cc: bpf, linux-kselftest, linux-kernel
On 7/28/26 5:06 PM, Ricardo B. Marlière (SUSE) wrote:
> Hello,
>
> When doing a simple out-of-tree build, e.g.:
>
> $ git clean -fdx
> $ mkdir ../build
> $ make defconfig O=../build
> $ scripts/kconfig/merge_config.sh -O ../build ../build/.config tools/testing/selftests/bpf/{config,config.x86_64}
> $ make O=../build
> $ make -C tools/testing/selftests install O=$PWD/../build SKIP_TARGETS= TARGETS=bpf
>
> Will leave behind several build artifacts:
>
> [...]
>
> This series fixes this.
Hi Ricardo,
I think we should wait for the selftests makefile refactoring series [1]
to land first, and then address the issues you've found.
When you do the respin, please test both build and clean with an
in-tree kernel build and with O=
Sending a few comments in a bit.
[1] https://lore.kernel.org/bpf/20260804170156.1709916-1-nickolay.lysenko@gmail.com/
>
> [...]
>
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH 0/3] selftests/bpf: Fixes for out-of-tree builds
2026-08-06 20:29 ` [PATCH 0/3] selftests/bpf: Fixes for out-of-tree builds Ihor Solodrai
@ 2026-08-06 20:47 ` Ricardo B. Marlière
0 siblings, 0 replies; 14+ messages in thread
From: Ricardo B. Marlière @ 2026-08-06 20:47 UTC (permalink / raw)
To: Ihor Solodrai, Ricardo B. Marlière (SUSE),
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Shuah Khan
Cc: bpf, linux-kselftest, linux-kernel
On Thu Aug 6, 2026 at 5:29 PM -03, Ihor Solodrai wrote:
> On 7/28/26 5:06 PM, Ricardo B. Marlière (SUSE) wrote:
>> Hello,
>>
>> When doing a simple out-of-tree build, e.g.:
>>
>> $ git clean -fdx
>> $ mkdir ../build
>> $ make defconfig O=../build
>> $ scripts/kconfig/merge_config.sh -O ../build ../build/.config tools/testing/selftests/bpf/{config,config.x86_64}
>> $ make O=../build
>> $ make -C tools/testing/selftests install O=$PWD/../build SKIP_TARGETS= TARGETS=bpf
>>
>> Will leave behind several build artifacts:
>>
>> [...]
>>
>> This series fixes this.
>
> Hi Ricardo,
>
> I think we should wait for the selftests makefile refactoring series [1]
> to land first, and then address the issues you've found.
Makes sense.
>
> When you do the respin, please test both build and clean with an
> in-tree kernel build and with O=
>
> Sending a few comments in a bit.
Ack, thanks for the reviews!
>
> [1] https://lore.kernel.org/bpf/20260804170156.1709916-1-nickolay.lysenko@gmail.com/
>
>
>>
>> [...]
>>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 0/3] selftests/bpf: Fixes for out-of-tree builds
2026-07-29 0:06 [PATCH 0/3] selftests/bpf: Fixes for out-of-tree builds Ricardo B. Marlière (SUSE)
` (3 preceding siblings ...)
2026-08-06 20:29 ` [PATCH 0/3] selftests/bpf: Fixes for out-of-tree builds Ihor Solodrai
@ 2026-09-21 20:40 ` Nico Pache (Red Hat)
2026-09-21 21:04 ` Eduard Zingerman
4 siblings, 1 reply; 14+ messages in thread
From: Nico Pache (Red Hat) @ 2026-09-21 20:40 UTC (permalink / raw)
To: Ricardo B. Marlière (SUSE), ihor.solodrai, nickolay.lysenko
Cc: bpf, linux-kselftest, Emil Tsalapatis, Jiri Olsa, Yonghong Song,
Song Liu, Eduard Zingerman, Andrii Nakryiko, Shuah Khan,
linux-kernel, Kumar Kartikeya Dwivedi, Alexei Starovoitov,
Daniel Borkmann, Martin KaFai Lau
On 7/28/26 6:06 PM, Ricardo B. Marlière (SUSE) wrote:
> Hello,
>
Hello! Thanks for posting this.
The Fedora build system is rather complex, especially around selftests BPF. We
are also discovering we need these changes.
Due to some other oddities in our build system, we would also like to specify a
precompiled vmlinux, rather than defaulting to $(objtree)/vmlinux.
I developed the following commit on top of these changes, and was finally able
to get a successful build in our env.
commit 616e12baf39ac44680c1dc22d31dbeea63e196b7
Author: Nico Pache <npache@redhat.com>
Date: Fri Aug 7 12:37:36 2026 -0600
kbuild, selftests/bpf: allow overriding the module BTF base
scripts/Makefile.modfinal currently hard-codes $(objtree)/vmlinux as the
BTF base used for module BTF generation. That works for in-tree builds,
but selftests/bpf/test_kmods may need to reuse a vmlinux resolved from a
prepared build tree or from /sys/kernel/btf/vmlinux.
Add a VMLINUX_BTF_BASE override so module BTF generation can use that
pre-resolved vmlinux instead.
Signed-off-by: Nico Pache <npache@redhat.com>
diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal
index 01a37ec872b9..fd16e66aa156 100644
--- a/scripts/Makefile.modfinal
+++ b/scripts/Makefile.modfinal
@@ -38,16 +38,19 @@ quiet_cmd_ld_ko_o = LD [M] $@
$(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
-T $(objtree)/scripts/module.lds -o $@ $(filter %.o, $^)
+VMLINUX_BTF_BASE ?= $(objtree)/vmlinux
+VMLINUX_BTF_BASE_PREREQ := $(wildcard $(VMLINUX_BTF_BASE))
+
quiet_cmd_btf_ko = BTF [M] $@
cmd_btf_ko = \
- if [ ! -f $(objtree)/vmlinux ]; then \
- printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \
+ if [ ! -f $(VMLINUX_BTF_BASE) ]; then \
+ printf "Skipping BTF generation for %s due to unavailability of %s\n" $@ $(VMLINUX_BTF_BASE) 1>&2; \
else \
- $(CONFIG_SHELL) $(srctree)/scripts/gen-btf.sh --btf_base $(objtree)/vmlinux $@; \
+ $(CONFIG_SHELL) $(srctree)/scripts/gen-btf.sh --btf_base $(VMLINUX_BTF_BASE) $@; \
fi;
-# Re-generate module BTFs if either module's .ko or vmlinux changed
-%.ko: %.o %.mod.o .module-common.o $(objtree)/scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),$(objtree)/vmlinux) FORCE
+# Re-generate module BTFs if either module's .ko or BTF base changed
+%.ko: %.o %.mod.o .module-common.o $(objtree)/scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(VMLINUX_BTF_BASE_PREREQ)) FORCE
+$(call if_changed,ld_ko_o)
ifdef CONFIG_DEBUG_INFO_BTF_MODULES
+$(if $(newer-prereqs),$(call cmd,btf_ko))
diff --git a/tools/testing/selftests/bpf/test_kmods/Makefile b/tools/testing/selftests/bpf/test_kmods/Makefile
index 53e47e715ec4..8580eee34f32 100644
--- a/tools/testing/selftests/bpf/test_kmods/Makefile
+++ b/tools/testing/selftests/bpf/test_kmods/Makefile
@@ -11,6 +11,8 @@ KMOD_O_VALID := $(if $(KMOD_O),$(if $(wildcard $(KMOD_O)/Module.symvers),$(KMOD_
KDIR ?= $(if $(KMOD_O_VALID),$(SRCTREE_KDIR), \
$(if $(wildcard $(SRCTREE_KDIR)/Module.symvers),$(SRCTREE_KDIR), \
/lib/modules/$(shell uname -r)/build))
+# The parent bpf/Makefile may already have resolved a usable BTF base.
+VMLINUX_BTF_BASE_ARG := $(if $(VMLINUX_BTF),VMLINUX_BTF_BASE=$(abspath $(VMLINUX_BTF)))
ifeq ($(V),1)
Q =
@@ -32,10 +34,12 @@ PERMISSIVE := $(filter 0,$(BPF_STRICT_BUILD))
all:
ifeq ($(PERMISSIVE),)
$(Q)$(MAKE) -C $(KDIR) $(if $(KMOD_O_VALID),O=$(KMOD_O_VALID) KBUILD_OUTPUT=$(KMOD_O_VALID),KBUILD_OUTPUT=) \
+ $(VMLINUX_BTF_BASE_ARG) \
$(if $(OUTPUT),MO=$(OUTPUT)) \
M=$(TEST_KMOD_DIR) modules
else ifneq ("$(wildcard $(KDIR))", "")
$(Q)$(MAKE) -C $(KDIR) $(if $(KMOD_O_VALID),O=$(KMOD_O_VALID) KBUILD_OUTPUT=$(KMOD_O_VALID),KBUILD_OUTPUT=) \
+ $(VMLINUX_BTF_BASE_ARG) \
$(if $(OUTPUT),MO=$(OUTPUT)) \
M=$(TEST_KMOD_DIR) modules
endif
Given your series was defferred, and there is a "rewrite" coming, what would
be the best approach to working together (between us three) to get these
fixes in that series too.
Cheers,
-- Nico
> When doing a simple out-of-tree build, e.g.:
>
> $ git clean -fdx
> $ mkdir ../build
> $ make defconfig O=../build
> $ scripts/kconfig/merge_config.sh -O ../build ../build/.config tools/testing/selftests/bpf/{config,config.x86_64}
> $ make O=../build
> $ make -C tools/testing/selftests install O=$PWD/../build SKIP_TARGETS= TARGETS=bpf
>
> Will leave behind several build artifacts:
>
> $ git clean -fdx
> Removing tools/testing/selftests/bpf/libarena/asan.bpf.o
> Removing tools/testing/selftests/bpf/libarena/asan_asan.bpf.o
> Removing tools/testing/selftests/bpf/libarena/buddy.bpf.o
> Removing tools/testing/selftests/bpf/libarena/buddy_asan.bpf.o
> Removing tools/testing/selftests/bpf/libarena/common.bpf.o
> Removing tools/testing/selftests/bpf/libarena/common_asan.bpf.o
> Removing tools/testing/selftests/bpf/libarena/libarena.bpf.o
> Removing tools/testing/selftests/bpf/libarena/libarena.skel.h
> Removing tools/testing/selftests/bpf/libarena/libarena_asan.bpf.o
> Removing tools/testing/selftests/bpf/libarena/libarena_asan.skel.h
> Removing tools/testing/selftests/bpf/libarena/rbtree.bpf.o
> Removing tools/testing/selftests/bpf/libarena/rbtree_asan.bpf.o
> Removing tools/testing/selftests/bpf/libarena/spmc.bpf.o
> Removing tools/testing/selftests/bpf/libarena/spmc_asan.bpf.o
> Removing tools/testing/selftests/bpf/libarena/st_asan_buddy.bpf.o
> Removing tools/testing/selftests/bpf/libarena/st_asan_buddy_asan.bpf.o
> Removing tools/testing/selftests/bpf/libarena/st_buddy.bpf.o
> Removing tools/testing/selftests/bpf/libarena/st_buddy_asan.bpf.o
> Removing tools/testing/selftests/bpf/libarena/test_parallel_spmc.bpf.o
> Removing tools/testing/selftests/bpf/libarena/test_parallel_spmc_asan.bpf.o
> Removing tools/testing/selftests/bpf/libarena/test_rbtree.bpf.o
> Removing tools/testing/selftests/bpf/libarena/test_rbtree_asan.bpf.o
> Removing tools/testing/selftests/bpf/libarena/test_spmc.bpf.o
> Removing tools/testing/selftests/bpf/libarena/test_spmc_asan.bpf.o
> Removing tools/testing/selftests/bpf/map_tests/tests.h
> Removing tools/testing/selftests/bpf/prog_tests/tests.h
> Removing tools/testing/selftests/bpf/test_kmods/..module-common.o.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.Module.symvers.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_test_modorder_x.ko.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_test_modorder_x.mod.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_test_modorder_x.mod.o.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_test_modorder_x.o.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_test_modorder_y.ko.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_test_modorder_y.mod.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_test_modorder_y.mod.o.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_test_modorder_y.o.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_test_no_cfi.ko.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_test_no_cfi.mod.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_test_no_cfi.mod.o.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_test_no_cfi.o.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_test_rqspinlock.ko.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_test_rqspinlock.mod.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_test_rqspinlock.mod.o.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_test_rqspinlock.o.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_testmod.ko.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_testmod.mod.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_testmod.mod.o.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_testmod.o.cmd
> Removing tools/testing/selftests/bpf/test_kmods/.bpf_testmod.o.d
> Removing tools/testing/selftests/bpf/test_kmods/.module-common.o
> Removing tools/testing/selftests/bpf/test_kmods/.modules.order.cmd
> Removing tools/testing/selftests/bpf/test_kmods/Module.symvers
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_modorder_x.ko
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_modorder_x.mod
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_modorder_x.mod.c
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_modorder_x.mod.o
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_modorder_x.o
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_modorder_y.ko
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_modorder_y.mod
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_modorder_y.mod.c
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_modorder_y.mod.o
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_modorder_y.o
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_no_cfi.ko
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_no_cfi.mod
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_no_cfi.mod.c
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_no_cfi.mod.o
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_no_cfi.o
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_rqspinlock.ko
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_rqspinlock.mod
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_rqspinlock.mod.c
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_rqspinlock.mod.o
> Removing tools/testing/selftests/bpf/test_kmods/bpf_test_rqspinlock.o
> Removing tools/testing/selftests/bpf/test_kmods/bpf_testmod.ko
> Removing tools/testing/selftests/bpf/test_kmods/bpf_testmod.mod
> Removing tools/testing/selftests/bpf/test_kmods/bpf_testmod.mod.c
> Removing tools/testing/selftests/bpf/test_kmods/bpf_testmod.mod.o
> Removing tools/testing/selftests/bpf/test_kmods/bpf_testmod.o
> Removing tools/testing/selftests/bpf/test_kmods/modules.order
> Removing tools/testing/selftests/bpf/verification_cert.h
> Removing tools/testing/selftests/bpf/verifier/tests.h
>
> This series fixes this.
>
> Assisted-by: claude sonnet
> Signed-off-by: Ricardo B. Marlière (SUSE) <ricardo@marliere.net>
> ---
> Ricardo B. Marlière (SUSE) (3):
> selftests/bpf: Route generated test headers to OUTPUT
> selftests/bpf: Route libarena build artifacts to OUTPUT
> selftests/bpf: Route test_kmods build artifacts to OUTPUT
>
> tools/testing/selftests/bpf/Makefile | 45 ++++++++++++++-----------
> tools/testing/selftests/bpf/libarena/Makefile | 24 +++++++------
> tools/testing/selftests/bpf/test_kmods/Makefile | 3 ++
> 3 files changed, 42 insertions(+), 30 deletions(-)
> ---
> base-commit: 62cc90241548d5570ee68e01aaba6506964e9811
> change-id: 20260728-selftests-bpf_oot-da8b59be69fc
>
> Best regards,
> --
> Ricardo B. Marlière (SUSE) <ricardo@marliere.net>
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH 0/3] selftests/bpf: Fixes for out-of-tree builds
2026-09-21 20:40 ` Nico Pache (Red Hat)
@ 2026-09-21 21:04 ` Eduard Zingerman
2026-09-21 21:15 ` Nico Pache (Red Hat)
2026-09-21 21:42 ` Alexei Starovoitov
0 siblings, 2 replies; 14+ messages in thread
From: Eduard Zingerman @ 2026-09-21 21:04 UTC (permalink / raw)
To: Nico Pache (Red Hat), Ricardo B. Marlière (SUSE),
ihor.solodrai, nickolay.lysenko
Cc: bpf, linux-kselftest, Emil Tsalapatis, Jiri Olsa, Yonghong Song,
Song Liu, Andrii Nakryiko, Shuah Khan, linux-kernel,
Kumar Kartikeya Dwivedi, Alexei Starovoitov, Daniel Borkmann,
Martin KaFai Lau
On Mon, 2026-09-21 at 14:40 -0600, Nico Pache (Red Hat) wrote:
...
> Given your series was defferred, and there is a "rewrite" coming, what would
> be the best approach to working together (between us three) to get these
> fixes in that series too.
The, "rewrite", as you call it, had landed today.
So the series in question can be re-spun.
Regarding your patch on top of it, it appears you can just post is separately.
However, I am inclined to be confrontational towards changes like this one.
The purpose of the selftests makefile is to run selftests as appropriate
for current tip of the kernel tree using a very specific kernel configuration.
Main users of this makefile are BPF developers and BPF CI.
Support for distros customizing the makefile is a non-goal.
The "PERMISSIVE" change done enough damage already.
...
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 0/3] selftests/bpf: Fixes for out-of-tree builds
2026-09-21 21:04 ` Eduard Zingerman
@ 2026-09-21 21:15 ` Nico Pache (Red Hat)
2026-09-21 21:42 ` Eduard Zingerman
2026-09-21 21:42 ` Alexei Starovoitov
1 sibling, 1 reply; 14+ messages in thread
From: Nico Pache (Red Hat) @ 2026-09-21 21:15 UTC (permalink / raw)
To: Eduard Zingerman, Ricardo B. Marlière (SUSE),
ihor.solodrai, nickolay.lysenko
Cc: bpf, linux-kselftest, Emil Tsalapatis, Jiri Olsa, Yonghong Song,
Song Liu, Andrii Nakryiko, Shuah Khan, linux-kernel,
Kumar Kartikeya Dwivedi, Alexei Starovoitov, Daniel Borkmann,
Martin KaFai Lau
On 9/21/26 3:04 PM, Eduard Zingerman wrote:
> On Mon, 2026-09-21 at 14:40 -0600, Nico Pache (Red Hat) wrote:
>
> ...
>
>> Given your series was defferred, and there is a "rewrite" coming, what would
>> be the best approach to working together (between us three) to get these
>> fixes in that series too.
>
> The, "rewrite", as you call it, had landed today.
oh thats great news. I checked on Friday and didnt see it. Thanks for the update :)
> So the series in question can be re-spun.
> Regarding your patch on top of it, it appears you can just post is separately.
> However, I am inclined to be confrontational towards changes like this one.
> The purpose of the selftests makefile is to run selftests as appropriate
> for current tip of the kernel tree using a very specific kernel configuration.
> Main users of this makefile are BPF developers and BPF CI.
Yeah we are trying to reincorporate BPF as part of our CI. It has bit rotted in
the Fedora env, and our large amount of build variant is where things are
starting to go wrong. We need to build selftests for multiple variants, and be
able to specify which variant we are building for. Hence the out-of-tree build
with specific vmlinux.
Is there any other approach you'd suggest? I personally dont work on BPF, but am
trying to cleanup/fix our selftests builds for Upstream/Fedora CI.
Thanks,
-- Nico
> Support for distros customizing the makefile is a non-goal.
> The "PERMISSIVE" change done enough damage already.
>
> ...
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 0/3] selftests/bpf: Fixes for out-of-tree builds
2026-09-21 21:15 ` Nico Pache (Red Hat)
@ 2026-09-21 21:42 ` Eduard Zingerman
0 siblings, 0 replies; 14+ messages in thread
From: Eduard Zingerman @ 2026-09-21 21:42 UTC (permalink / raw)
To: Nico Pache (Red Hat), Ricardo B. Marlière (SUSE),
ihor.solodrai, nickolay.lysenko
Cc: bpf, linux-kselftest, Emil Tsalapatis, Jiri Olsa, Yonghong Song,
Song Liu, Andrii Nakryiko, Shuah Khan, linux-kernel,
Kumar Kartikeya Dwivedi, Alexei Starovoitov, Daniel Borkmann,
Martin KaFai Lau
On Mon, 2026-09-21 at 15:15 -0600, Nico Pache (Red Hat) wrote:
>
> On 9/21/26 3:04 PM, Eduard Zingerman wrote:
> > On Mon, 2026-09-21 at 14:40 -0600, Nico Pache (Red Hat) wrote:
> >
> > ...
> >
> > > Given your series was defferred, and there is a "rewrite" coming, what would
> > > be the best approach to working together (between us three) to get these
> > > fixes in that series too.
> >
> > The, "rewrite", as you call it, had landed today.
>
> oh thats great news. I checked on Friday and didnt see it. Thanks for the update :)
>
> > So the series in question can be re-spun.
> > Regarding your patch on top of it, it appears you can just post is separately.
> > However, I am inclined to be confrontational towards changes like this one.
> > The purpose of the selftests makefile is to run selftests as appropriate
> > for current tip of the kernel tree using a very specific kernel configuration.
> > Main users of this makefile are BPF developers and BPF CI.
>
> Yeah we are trying to reincorporate BPF as part of our CI. It has bit rotted in
> the Fedora env, and our large amount of build variant is where things are
> starting to go wrong. We need to build selftests for multiple variants, and be
> able to specify which variant we are building for. Hence the out-of-tree build
> with specific vmlinux.
Why can't you build the kernel and the selftests in the same out of tree location?
The change you are proposing is contained, but it's a death by thousand cuts,
the selftests makefile is quite a Frankenstein's monster already.
> Is there any other approach you'd suggest? I personally dont work on BPF, but am
> trying to cleanup/fix our selftests builds for Upstream/Fedora CI.
How many Fedora-specific kernel patches do you carry already?
> Thanks,
> -- Nico
>
> > Support for distros customizing the makefile is a non-goal.
> > The "PERMISSIVE" change done enough damage already.
> >
> > ...
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 0/3] selftests/bpf: Fixes for out-of-tree builds
2026-09-21 21:04 ` Eduard Zingerman
2026-09-21 21:15 ` Nico Pache (Red Hat)
@ 2026-09-21 21:42 ` Alexei Starovoitov
1 sibling, 0 replies; 14+ messages in thread
From: Alexei Starovoitov @ 2026-09-21 21:42 UTC (permalink / raw)
To: Eduard Zingerman, Nico Pache (Red Hat),
Ricardo B. Marlière (SUSE),
ihor.solodrai, nickolay.lysenko
Cc: bpf, linux-kselftest, Emil Tsalapatis, Jiri Olsa, Yonghong Song,
Song Liu, Andrii Nakryiko, Shuah Khan, linux-kernel,
Kumar Kartikeya Dwivedi, Alexei Starovoitov, Daniel Borkmann,
Martin KaFai Lau
On Mon Sep 21, 2026 at 9:04 PM UTC, Eduard Zingerman wrote:
> The "PERMISSIVE" change done enough damage already.
Pls do a partial revert of it.
^ permalink raw reply [flat|nested] 14+ messages in thread