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) <[email protected]> > --- > 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 >

