Some BPF programs cannot be built on distro kernels because required BTF
types or features are missing. A single failure currently aborts the
selftests/bpf build.

Make BPF object and skeleton generation best effort in permissive mode:
emit SKIP-BPF or SKIP-SKEL to stderr, remove failed outputs so downstream
rules can detect absence, and continue with remaining tests. Apply the same
tolerance to linked skeletons (TRUNNER_BPF_SKELS_LINKED), which depend on
multiple .bpf.o files and abort the build when any dependency is missing.

Note that progress messages (GEN-SKEL, LINK-BPF) are also redirected to
stderr as a side effect of rewriting the recipes into single-shell
pipelines; the $(call msg,...) macro is a make-recipe construct that cannot
be used inside an &&-chained shell command sequence.

Signed-off-by: Ricardo B. Marlière <[email protected]>
---
 tools/testing/selftests/bpf/Makefile | 108 +++++++++++++++++++++++------------
 1 file changed, 73 insertions(+), 35 deletions(-)

diff --git a/tools/testing/selftests/bpf/Makefile 
b/tools/testing/selftests/bpf/Makefile
index cc6ee7a2df93..b104c687dcf0 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -485,22 +485,26 @@ $(OUTPUT)/cgroup_getset_retval_hooks.o: 
cgroup_getset_retval_hooks.h
 # $4 - binary name
 define CLANG_BPF_BUILD_RULE
        $(call msg,CLNG-BPF,$4,$2)
-       $(Q)$(CLANG) $3 -O2 $(BPF_TARGET_ENDIAN) -c $1 -mcpu=v3 -o $2
+       $(Q)$(CLANG) $3 -O2 $(BPF_TARGET_ENDIAN) -c $1 -mcpu=v3 -o $2 $(if 
$(PERMISSIVE),|| \
+               ($(RM) $2; printf '  %-12s %s\n' 'SKIP-BPF' '$(notdir $2)' 
1>&2))
 endef
 # Similar to CLANG_BPF_BUILD_RULE, but with disabled alu32
 define CLANG_NOALU32_BPF_BUILD_RULE
        $(call msg,CLNG-BPF,$4,$2)
-       $(Q)$(CLANG) $3 -O2 $(BPF_TARGET_ENDIAN) -c $1 -mcpu=v2 -o $2
+       $(Q)$(CLANG) $3 -O2 $(BPF_TARGET_ENDIAN) -c $1 -mcpu=v2 -o $2 $(if 
$(PERMISSIVE),|| \
+               ($(RM) $2; printf '  %-12s %s\n' 'SKIP-BPF' '$(notdir $2)' 
1>&2))
 endef
 # Similar to CLANG_BPF_BUILD_RULE, but with cpu-v4
 define CLANG_CPUV4_BPF_BUILD_RULE
        $(call msg,CLNG-BPF,$4,$2)
-       $(Q)$(CLANG) $3 -O2 $(BPF_TARGET_ENDIAN) -c $1 -mcpu=v4 -o $2
+       $(Q)$(CLANG) $3 -O2 $(BPF_TARGET_ENDIAN) -c $1 -mcpu=v4 -o $2 $(if 
$(PERMISSIVE),|| \
+               ($(RM) $2; printf '  %-12s %s\n' 'SKIP-BPF' '$(notdir $2)' 
1>&2))
 endef
 # Build BPF object using GCC
 define GCC_BPF_BUILD_RULE
        $(call msg,GCC-BPF,$4,$2)
-       $(Q)$(BPF_GCC) $3 -DBPF_NO_PRESERVE_ACCESS_INDEX -Wno-attributes -O2 -c 
$1 -o $2
+       $(Q)$(BPF_GCC) $3 -DBPF_NO_PRESERVE_ACCESS_INDEX -Wno-attributes -O2 -c 
$1 -o $2 $(if $(PERMISSIVE),|| \
+               ($(RM) $2; printf '  %-12s %s\n' 'SKIP-BPF' '$(notdir $2)' 
1>&2))
 endef
 
 SKEL_BLACKLIST := btf__% test_pinning_invalid.c test_sk_assign.c
@@ -607,47 +611,81 @@ $(TRUNNER_BPF_OBJS): $(TRUNNER_OUTPUT)/%.bpf.o:           
                \
                                          $$($$<-$2-CFLAGS),$(TRUNNER_BINARY))
 
 $(TRUNNER_BPF_SKELS): %.skel.h: %.bpf.o $(BPFTOOL) | $(TRUNNER_OUTPUT)
-       $$(call msg,GEN-SKEL,$(TRUNNER_BINARY),$$@)
-       $(Q)$$(BPFTOOL) gen object $$(<:.o=.linked1.o) $$<
-       $(Q)$$(BPFTOOL) gen object $$(<:.o=.linked2.o) $$(<:.o=.linked1.o)
-       $(Q)$$(BPFTOOL) gen object $$(<:.o=.linked3.o) $$(<:.o=.linked2.o)
-       $(Q)diff $$(<:.o=.linked2.o) $$(<:.o=.linked3.o)
-       $(Q)$$(BPFTOOL) gen skeleton $$(<:.o=.linked3.o) name $$(notdir 
$$(<:.bpf.o=)) > $$@
-       $(Q)$$(BPFTOOL) gen subskeleton $$(<:.o=.linked3.o) name $$(notdir 
$$(<:.bpf.o=)) > $$(@:.skel.h=.subskel.h)
-       $(Q)rm -f $$(<:.o=.linked1.o) $$(<:.o=.linked2.o) $$(<:.o=.linked3.o)
+       $(Q)$(if $(PERMISSIVE),if [ ! -f $$< ]; then                    \
+               $$(RM) $$@ $$(@:.skel.h=.subskel.h);                    \
+               printf '  %-12s %s\n' 'SKIP-SKEL' '$$(notdir $$@)' 1>&2; \
+               exit 0;                                                 \
+       fi;)                                                            \
+       printf '  %-12s %s\n' 'GEN-SKEL' '[$(TRUNNER_BINARY)] $$(notdir $$@)' 
1>&2; \
+       $$(BPFTOOL) gen object $$(<:.o=.linked1.o) $$< &&               \
+       $$(BPFTOOL) gen object $$(<:.o=.linked2.o) $$(<:.o=.linked1.o) && \
+       $$(BPFTOOL) gen object $$(<:.o=.linked3.o) $$(<:.o=.linked2.o) && \
+       diff $$(<:.o=.linked2.o) $$(<:.o=.linked3.o) &&         \
+       $$(BPFTOOL) gen skeleton $$(<:.o=.linked3.o) name $$(notdir 
$$(<:.bpf.o=)) > $$@ && \
+       $$(BPFTOOL) gen subskeleton $$(<:.o=.linked3.o) name $$(notdir 
$$(<:.bpf.o=)) > $$(@:.skel.h=.subskel.h) $(if $(PERMISSIVE),|| { \
+               $$(RM) $$@ $$(@:.skel.h=.subskel.h); \
+               printf '  %-12s %s\n' 'SKIP-SKEL' '$$(notdir $$@)' 1>&2; \
+       }) && \
+       rm -f $$(<:.o=.linked1.o) $$(<:.o=.linked2.o) $$(<:.o=.linked3.o)
 
 $(TRUNNER_BPF_LSKELS): %.lskel.h: %.bpf.o $(BPFTOOL) | $(TRUNNER_OUTPUT)
-       $$(call msg,GEN-SKEL,$(TRUNNER_BINARY),$$@)
-       $(Q)$$(BPFTOOL) gen object $$(<:.o=.llinked1.o) $$<
-       $(Q)$$(BPFTOOL) gen object $$(<:.o=.llinked2.o) $$(<:.o=.llinked1.o)
-       $(Q)$$(BPFTOOL) gen object $$(<:.o=.llinked3.o) $$(<:.o=.llinked2.o)
-       $(Q)diff $$(<:.o=.llinked2.o) $$(<:.o=.llinked3.o)
-       $(Q)$$(BPFTOOL) gen skeleton -L $$(<:.o=.llinked3.o) name $$(notdir 
$$(<:.bpf.o=_lskel)) > $$@
-       $(Q)rm -f $$(<:.o=.llinked1.o) $$(<:.o=.llinked2.o) $$(<:.o=.llinked3.o)
+       $(Q)$(if $(PERMISSIVE),if [ ! -f $$< ]; then                    \
+               $$(RM) $$@;                                             \
+               printf '  %-12s %s\n' 'SKIP-SKEL' '$$(notdir $$@)' 1>&2; \
+               exit 0;                                                 \
+       fi;)                                                            \
+       printf '  %-12s %s\n' 'GEN-SKEL' '[$(TRUNNER_BINARY)] $$(notdir $$@)' 
1>&2; \
+       $$(BPFTOOL) gen object $$(<:.o=.llinked1.o) $$< &&              \
+       $$(BPFTOOL) gen object $$(<:.o=.llinked2.o) $$(<:.o=.llinked1.o) && \
+       $$(BPFTOOL) gen object $$(<:.o=.llinked3.o) $$(<:.o=.llinked2.o) && \
+       diff $$(<:.o=.llinked2.o) $$(<:.o=.llinked3.o) &&               \
+       $$(BPFTOOL) gen skeleton -L $$(<:.o=.llinked3.o) name $$(notdir 
$$(<:.bpf.o=_lskel)) > $$@ $(if $(PERMISSIVE),|| { \
+               $$(RM) $$@; \
+               printf '  %-12s %s\n' 'SKIP-SKEL' '$$(notdir $$@)' 1>&2; \
+       }) && \
+       rm -f $$(<:.o=.llinked1.o) $$(<:.o=.llinked2.o) $$(<:.o=.llinked3.o)
 
 $(TRUNNER_BPF_LSKELS_SIGNED): %.lskel.h: %.bpf.o $(BPFTOOL) | $(TRUNNER_OUTPUT)
-       $$(call msg,GEN-SKEL,$(TRUNNER_BINARY) (signed),$$@)
-       $(Q)$$(BPFTOOL) gen object $$(<:.o=.llinked1.o) $$<
-       $(Q)$$(BPFTOOL) gen object $$(<:.o=.llinked2.o) $$(<:.o=.llinked1.o)
-       $(Q)$$(BPFTOOL) gen object $$(<:.o=.llinked3.o) $$(<:.o=.llinked2.o)
-       $(Q)diff $$(<:.o=.llinked2.o) $$(<:.o=.llinked3.o)
-       $(Q)$$(BPFTOOL) gen skeleton $(LSKEL_SIGN) $$(<:.o=.llinked3.o) name 
$$(notdir $$(<:.bpf.o=_lskel)) > $$@
-       $(Q)rm -f $$(<:.o=.llinked1.o) $$(<:.o=.llinked2.o) $$(<:.o=.llinked3.o)
+       $(Q)$(if $(PERMISSIVE),if [ ! -f $$< ]; then                    \
+               $$(RM) $$@;                                             \
+               printf '  %-12s %s\n' 'SKIP-SKEL' '$$(notdir $$@)' 1>&2; \
+               exit 0;                                                 \
+       fi;)                                                            \
+       printf '  %-12s %s\n' 'GEN-SKEL' '[$(TRUNNER_BINARY) (signed)] 
$$(notdir $$@)' 1>&2; \
+       $$(BPFTOOL) gen object $$(<:.o=.llinked1.o) $$< &&              \
+       $$(BPFTOOL) gen object $$(<:.o=.llinked2.o) $$(<:.o=.llinked1.o) && \
+       $$(BPFTOOL) gen object $$(<:.o=.llinked3.o) $$(<:.o=.llinked2.o) && \
+       diff $$(<:.o=.llinked2.o) $$(<:.o=.llinked3.o) &&               \
+       $$(BPFTOOL) gen skeleton $(LSKEL_SIGN) $$(<:.o=.llinked3.o) name 
$$(notdir $$(<:.bpf.o=_lskel)) > $$@ $(if $(PERMISSIVE),|| { \
+               $$(RM) $$@; \
+               printf '  %-12s %s\n' 'SKIP-SKEL' '$$(notdir $$@)' 1>&2; \
+       }) && \
+       rm -f $$(<:.o=.llinked1.o) $$(<:.o=.llinked2.o) $$(<:.o=.llinked3.o)
 
 $(LINKED_BPF_OBJS): %: $(TRUNNER_OUTPUT)/%
 
 # .SECONDEXPANSION here allows to correctly expand %-deps variables as 
prerequisites
 .SECONDEXPANSION:
 $(TRUNNER_BPF_SKELS_LINKED): $(TRUNNER_OUTPUT)/%: $$$$(%-deps) $(BPFTOOL) | 
$(TRUNNER_OUTPUT)
-       $$(call msg,LINK-BPF,$(TRUNNER_BINARY),$$(@:.skel.h=.bpf.o))
-       $(Q)$$(BPFTOOL) gen object $$(@:.skel.h=.linked1.o) $$(addprefix 
$(TRUNNER_OUTPUT)/,$$($$(@F)-deps))
-       $(Q)$$(BPFTOOL) gen object $$(@:.skel.h=.linked2.o) 
$$(@:.skel.h=.linked1.o)
-       $(Q)$$(BPFTOOL) gen object $$(@:.skel.h=.linked3.o) 
$$(@:.skel.h=.linked2.o)
-       $(Q)diff $$(@:.skel.h=.linked2.o) $$(@:.skel.h=.linked3.o)
-       $$(call msg,GEN-SKEL,$(TRUNNER_BINARY),$$@)
-       $(Q)$$(BPFTOOL) gen skeleton $$(@:.skel.h=.linked3.o) name $$(notdir 
$$(@:.skel.h=)) > $$@
-       $(Q)$$(BPFTOOL) gen subskeleton $$(@:.skel.h=.linked3.o) name $$(notdir 
$$(@:.skel.h=)) > $$(@:.skel.h=.subskel.h)
-       $(Q)rm -f $$(@:.skel.h=.linked1.o) $$(@:.skel.h=.linked2.o) 
$$(@:.skel.h=.linked3.o)
+       $(Q)$(if $(PERMISSIVE),for f in $$(addprefix 
$(TRUNNER_OUTPUT)/,$$($$(@F)-deps)); do \
+               if [ ! -f $$$$f ]; then                                         
\
+                       $$(RM) $$@ $$(@:.skel.h=.subskel.h);            \
+                       printf '  %-12s %s\n' 'SKIP-SKEL' '$$(notdir $$@)' 
1>&2; \
+                       exit 0;                                                 
\
+               fi;                                                             
\
+       done;)                                                                  
\
+       printf '  %-12s %s\n' 'LINK-BPF' '[$(TRUNNER_BINARY)] $$(notdir 
$$(@:.skel.h=.bpf.o))' 1>&2; \
+       $$(BPFTOOL) gen object $$(@:.skel.h=.linked1.o) $$(addprefix 
$(TRUNNER_OUTPUT)/,$$($$(@F)-deps)) && \
+       $$(BPFTOOL) gen object $$(@:.skel.h=.linked2.o) 
$$(@:.skel.h=.linked1.o) && \
+       $$(BPFTOOL) gen object $$(@:.skel.h=.linked3.o) 
$$(@:.skel.h=.linked2.o) && \
+       diff $$(@:.skel.h=.linked2.o) $$(@:.skel.h=.linked3.o) &&       \
+       printf '  %-12s %s\n' 'GEN-SKEL' '[$(TRUNNER_BINARY)] $$(notdir $$@)' 
1>&2 && \
+       $$(BPFTOOL) gen skeleton $$(@:.skel.h=.linked3.o) name $$(notdir 
$$(@:.skel.h=)) > $$@ && \
+       $$(BPFTOOL) gen subskeleton $$(@:.skel.h=.linked3.o) name $$(notdir 
$$(@:.skel.h=)) > $$(@:.skel.h=.subskel.h) $(if $(PERMISSIVE),|| { \
+               $$(RM) $$@ $$(@:.skel.h=.subskel.h);                    \
+               printf '  %-12s %s\n' 'SKIP-SKEL' '$$(notdir $$@)' 1>&2; \
+       }) &&                                                                   
\
+       rm -f $$(@:.skel.h=.linked1.o) $$(@:.skel.h=.linked2.o) 
$$(@:.skel.h=.linked3.o)
 
 # When the compiler generates a %.d file, only skel basenames (not
 # full paths) are specified as prerequisites for corresponding %.o

-- 
2.54.0


Reply via email to