Commit c5a2c734 authored by Daniel Borkmann's avatar Daniel Borkmann

Merge branch 'bpf-bpftool-build-improvements'

Quentin Monnet says:

====================
This set attempts to make it easier to build bpftool, in particular when
passing a specific output directory. This is a follow-up to the
conversation held last month by Lorenz, Ilya and Jakub [0].

The first patch is a minor fix to bpftool's Makefile, regarding the
retrieval of kernel version (which currently prints a non-relevant make
warning on some invocations).

Second patch improves the Makefile commands to support more "make"
invocations, or to fix building with custom output directory. On Jakub's
suggestion, a script is also added to BPF selftests in order to keep track
of the supported build variants.

Building bpftool with "make tools/bpf" from the top of the repository
generates files in "libbpf/" and "feature/" directories under tools/bpf/
and tools/bpf/bpftool/. The third patch ensures such directories are taken
care of on "make clean", and add them to the relevant .gitignore files.

At last, fourth patch is a sligthly modified version of Ilya's fix
regarding libbpf.a appearing twice on the linking command for bpftool.

[0] https://lore.kernel.org/bpf/CACAyw9-CWRHVH3TJ=Tke2x8YiLsH47sLCijdp=V+5M836R9aAA@mail.gmail.com/

v2:
- Return error from check script if one of the make invocations returns
  non-zero (even if binary is successfully produced).
- Run "make clean" from bpf/ and not only bpf/bpftool/ in that same script,
  when relevant.
- Add a patch to clean up generated "feature/" and "libbpf/" directories.
====================
Acked-by: default avatarIlya Leoshkevich <iii@linux.ibm.com>
Tested-by: default avatarIlya Leoshkevich <iii@linux.ibm.com>
Cc: Lorenz Bauer <lmb@cloudflare.com>
Cc: Ilya Leoshkevich <iii@linux.ibm.com>
Cc: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parents 1c8f9b91 5b84ad2e
FEATURE-DUMP.bpf
feature
bpf_asm
bpf_dbg
bpf_exp.yacc.*
......
......@@ -81,10 +81,11 @@ $(OUTPUT)bpf_exp.lex.o: $(OUTPUT)bpf_exp.lex.c
clean: bpftool_clean
$(call QUIET_CLEAN, bpf-progs)
$(Q)rm -rf $(OUTPUT)*.o $(OUTPUT)bpf_jit_disasm $(OUTPUT)bpf_dbg \
$(Q)$(RM) -r -- $(OUTPUT)*.o $(OUTPUT)bpf_jit_disasm $(OUTPUT)bpf_dbg \
$(OUTPUT)bpf_asm $(OUTPUT)bpf_exp.yacc.* $(OUTPUT)bpf_exp.lex.*
$(call QUIET_CLEAN, core-gen)
$(Q)rm -f $(OUTPUT)FEATURE-DUMP.bpf
$(Q)$(RM) -- $(OUTPUT)FEATURE-DUMP.bpf
$(Q)$(RM) -r -- $(OUTPUT)feature
install: $(PROGS) bpftool_install
$(call QUIET_INSTALL, bpf_jit_disasm)
......
......@@ -3,3 +3,5 @@
bpftool*.8
bpf-helpers.*
FEATURE-DUMP.bpftool
feature
libbpf
......@@ -17,21 +17,23 @@ endif
BPF_DIR = $(srctree)/tools/lib/bpf/
ifneq ($(OUTPUT),)
BPF_PATH = $(OUTPUT)
LIBBPF_OUTPUT = $(OUTPUT)/libbpf/
LIBBPF_PATH = $(LIBBPF_OUTPUT)
else
BPF_PATH = $(BPF_DIR)
LIBBPF_PATH = $(BPF_DIR)
endif
LIBBPF = $(BPF_PATH)libbpf.a
LIBBPF = $(LIBBPF_PATH)libbpf.a
BPFTOOL_VERSION := $(shell make --no-print-directory -sC ../../.. kernelversion)
BPFTOOL_VERSION := $(shell make -rR --no-print-directory -sC ../../.. kernelversion)
$(LIBBPF): FORCE
$(Q)$(MAKE) -C $(BPF_DIR) OUTPUT=$(OUTPUT) $(OUTPUT)libbpf.a
$(if $(LIBBPF_OUTPUT),@mkdir -p $(LIBBPF_OUTPUT))
$(Q)$(MAKE) -C $(BPF_DIR) OUTPUT=$(LIBBPF_OUTPUT) $(LIBBPF_OUTPUT)libbpf.a
$(LIBBPF)-clean:
$(call QUIET_CLEAN, libbpf)
$(Q)$(MAKE) -C $(BPF_DIR) OUTPUT=$(OUTPUT) clean >/dev/null
$(Q)$(MAKE) -C $(BPF_DIR) OUTPUT=$(LIBBPF_OUTPUT) clean >/dev/null
prefix ?= /usr/local
bash_compdir ?= /usr/share/bash-completion/completions
......@@ -53,7 +55,7 @@ ifneq ($(EXTRA_LDFLAGS),)
LDFLAGS += $(EXTRA_LDFLAGS)
endif
LIBS = -lelf -lz $(LIBBPF)
LIBS = $(LIBBPF) -lelf -lz
INSTALL ?= install
RM ?= rm -f
......@@ -115,16 +117,18 @@ $(OUTPUT)disasm.o: $(srctree)/kernel/bpf/disasm.c
$(OUTPUT)feature.o: | zdep
$(OUTPUT)bpftool: $(OBJS) $(LIBBPF)
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
$(OUTPUT)%.o: %.c
$(QUIET_CC)$(COMPILE.c) -MMD -o $@ $<
clean: $(LIBBPF)-clean
$(call QUIET_CLEAN, bpftool)
$(Q)$(RM) $(OUTPUT)bpftool $(OUTPUT)*.o $(OUTPUT)*.d
$(Q)$(RM) -- $(OUTPUT)bpftool $(OUTPUT)*.o $(OUTPUT)*.d
$(Q)$(RM) -r -- $(OUTPUT)libbpf/
$(call QUIET_CLEAN, core-gen)
$(Q)$(RM) $(OUTPUT)FEATURE-DUMP.bpftool
$(Q)$(RM) -- $(OUTPUT)FEATURE-DUMP.bpftool
$(Q)$(RM) -r -- $(OUTPUT)feature/
install: $(OUTPUT)bpftool
$(call QUIET_INSTALL, bpftool)
......@@ -135,8 +139,8 @@ install: $(OUTPUT)bpftool
uninstall:
$(call QUIET_UNINST, bpftool)
$(Q)$(RM) $(DESTDIR)$(prefix)/sbin/bpftool
$(Q)$(RM) $(DESTDIR)$(bash_compdir)/bpftool
$(Q)$(RM) -- $(DESTDIR)$(prefix)/sbin/bpftool
$(Q)$(RM) -- $(DESTDIR)$(bash_compdir)/bpftool
doc:
$(call descend,Documentation)
......
......@@ -63,7 +63,8 @@ TEST_PROGS := test_kmod.sh \
test_tcp_check_syncookie.sh \
test_tc_tunnel.sh \
test_tc_edt.sh \
test_xdping.sh
test_xdping.sh \
test_bpftool_build.sh
TEST_PROGS_EXTENDED := with_addr.sh \
with_tunnels.sh \
......
#!/bin/bash
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
ERROR=0
TMPDIR=
# If one build fails, continue but return non-0 on exit.
return_value() {
if [ -d "$TMPDIR" ] ; then
rm -rf -- $TMPDIR
fi
exit $ERROR
}
trap return_value EXIT
case $1 in
-h|--help)
echo -e "$0 [-j <n>]"
echo -e "\tTest the different ways of building bpftool."
echo -e ""
echo -e "\tOptions:"
echo -e "\t\t-j <n>:\tPass -j flag to 'make'."
exit
;;
esac
J=$*
# Assume script is located under tools/testing/selftests/bpf/. We want to start
# build attempts from the top of kernel repository.
SCRIPT_REL_PATH=$(realpath --relative-to=$PWD $0)
SCRIPT_REL_DIR=$(dirname $SCRIPT_REL_PATH)
KDIR_ROOT_DIR=$(realpath $PWD/$SCRIPT_REL_DIR/../../../../)
cd $KDIR_ROOT_DIR
check() {
local dir=$(realpath $1)
echo -n "binary: "
# Returns non-null if file is found (and "false" is run)
find $dir -type f -executable -name bpftool -print -exec false {} + && \
ERROR=1 && printf "FAILURE: Did not find bpftool\n"
}
make_and_clean() {
echo -e "\$PWD: $PWD"
echo -e "command: make -s $* >/dev/null"
make $J -s $* >/dev/null
if [ $? -ne 0 ] ; then
ERROR=1
fi
if [ $# -ge 1 ] ; then
check ${@: -1}
else
check .
fi
(
if [ $# -ge 1 ] ; then
cd ${@: -1}
fi
make -s clean
)
echo
}
make_with_tmpdir() {
local ARGS
TMPDIR=$(mktemp -d)
if [ $# -ge 2 ] ; then
ARGS=${@:1:(($# - 1))}
fi
echo -e "\$PWD: $PWD"
echo -e "command: make -s $ARGS ${@: -1}=$TMPDIR/ >/dev/null"
make $J -s $ARGS ${@: -1}=$TMPDIR/ >/dev/null
if [ $? -ne 0 ] ; then
ERROR=1
fi
check $TMPDIR
rm -rf -- $TMPDIR
echo
}
echo "Trying to build bpftool"
echo -e "... through kbuild\n"
if [ -f ".config" ] ; then
make_and_clean tools/bpf
## $OUTPUT is overwritten in kbuild Makefile, and thus cannot be passed
## down from toplevel Makefile to bpftool's Makefile.
# make_with_tmpdir tools/bpf OUTPUT
echo -e "skip: make tools/bpf OUTPUT=<dir> (not supported)\n"
make_with_tmpdir tools/bpf O
else
echo -e "skip: make tools/bpf (no .config found)\n"
echo -e "skip: make tools/bpf OUTPUT=<dir> (not supported)\n"
echo -e "skip: make tools/bpf O=<dir> (no .config found)\n"
fi
echo -e "... from kernel source tree\n"
make_and_clean -C tools/bpf/bpftool
make_with_tmpdir -C tools/bpf/bpftool OUTPUT
make_with_tmpdir -C tools/bpf/bpftool O
echo -e "... from tools/\n"
cd tools/
make_and_clean bpf
## In tools/bpf/Makefile, function "descend" is called and passes $(O) and
## $(OUTPUT). We would like $(OUTPUT) to have "bpf/bpftool/" appended before
## calling bpftool's Makefile, but this is not the case as the "descend"
## function focuses on $(O)/$(subdir). However, in the present case, updating
## $(O) to have $(OUTPUT) recomputed from it in bpftool's Makefile does not
## work, because $(O) is not defined from command line and $(OUTPUT) is not
## updated in tools/scripts/Makefile.include.
##
## Workarounds would require to a) edit "descend" or use an alternative way to
## call bpftool's Makefile, b) modify the conditions to update $(OUTPUT) and
## other variables in tools/scripts/Makefile.include (at the risk of breaking
## the build of other tools), or c) append manually the "bpf/bpftool" suffix to
## $(OUTPUT) in bpf's Makefile, which may break if targets for other directories
## use "descend" in the future.
# make_with_tmpdir bpf OUTPUT
echo -e "skip: make bpf OUTPUT=<dir> (not supported)\n"
make_with_tmpdir bpf O
echo -e "... from bpftool's dir\n"
cd bpf/bpftool
make_and_clean
make_with_tmpdir OUTPUT
make_with_tmpdir O
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment