* [PATCH bpf-next 1/3] tools: bpftool: ignore make built-in rules for getting kernel version
2019-08-29 10:56 [PATCH bpf-next 0/3] tools: bpftool: improve bpftool build experience Quentin Monnet
@ 2019-08-29 10:56 ` Quentin Monnet
2019-08-29 10:56 ` [PATCH bpf-next 2/3] tools: bpftool: improve and check builds for different make invocations Quentin Monnet
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Quentin Monnet @ 2019-08-29 10:56 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann
Cc: bpf, netdev, oss-drivers, Quentin Monnet, Lorenz Bauer,
Ilya Leoshkevich, Jakub Kicinski
Bpftool calls the toplevel Makefile to get the kernel version for the
sources it is built from. But when the utility is built from the top of
the kernel repository, it may dump the following error message for
certain architectures (including x86):
$ make tools/bpf
[...]
make[3]: *** [checkbin] Error 1
[...]
This does not prevent bpftool compilation, but may feel disconcerting.
The "checkbin" arch-dependent target is not supposed to be called for
target "kernelversion", which is a simple "echo" of the version number.
It turns out this is caused by the make invocation in tools/bpf/bpftool,
which attempts to find implicit rules to apply. Extract from debug
output:
Reading makefiles...
Reading makefile 'Makefile'...
Reading makefile 'scripts/Kbuild.include' (search path) (no ~ expansion)...
Reading makefile 'scripts/subarch.include' (search path) (no ~ expansion)...
Reading makefile 'arch/x86/Makefile' (search path) (no ~ expansion)...
Reading makefile 'scripts/Makefile.kcov' (search path) (no ~ expansion)...
Reading makefile 'scripts/Makefile.gcc-plugins' (search path) (no ~ expansion)...
Reading makefile 'scripts/Makefile.kasan' (search path) (no ~ expansion)...
Reading makefile 'scripts/Makefile.extrawarn' (search path) (no ~ expansion)...
Reading makefile 'scripts/Makefile.ubsan' (search path) (no ~ expansion)...
Updating makefiles....
Considering target file 'scripts/Makefile.ubsan'.
Looking for an implicit rule for 'scripts/Makefile.ubsan'.
Trying pattern rule with stem 'Makefile.ubsan'.
[...]
Trying pattern rule with stem 'Makefile.ubsan'.
Trying implicit prerequisite 'scripts/Makefile.ubsan.o'.
Looking for a rule with intermediate file 'scripts/Makefile.ubsan.o'.
Avoiding implicit rule recursion.
Trying pattern rule with stem 'Makefile.ubsan'.
Trying rule prerequisite 'prepare'.
Trying rule prerequisite 'FORCE'.
Found an implicit rule for 'scripts/Makefile.ubsan'.
Considering target file 'prepare'.
File 'prepare' does not exist.
Considering target file 'prepare0'.
File 'prepare0' does not exist.
Considering target file 'archprepare'.
File 'archprepare' does not exist.
Considering target file 'archheaders'.
File 'archheaders' does not exist.
Finished prerequisites of target file 'archheaders'.
Must remake target 'archheaders'.
Putting child 0x55976f4f6980 (archheaders) PID 31743 on the chain.
To avoid that, pass the -r and -R flags to eliminate the use of make
built-in rules (and while at it, built-in variables) when running
command "make kernelversion" from bpftool's Makefile.
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
---
tools/bpf/bpftool/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
index f284c207765a..cd0fc05464e7 100644
--- a/tools/bpf/bpftool/Makefile
+++ b/tools/bpf/bpftool/Makefile
@@ -24,7 +24,7 @@ endif
LIBBPF = $(BPF_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
--
2.17.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH bpf-next 2/3] tools: bpftool: improve and check builds for different make invocations
2019-08-29 10:56 [PATCH bpf-next 0/3] tools: bpftool: improve bpftool build experience Quentin Monnet
2019-08-29 10:56 ` [PATCH bpf-next 1/3] tools: bpftool: ignore make built-in rules for getting kernel version Quentin Monnet
@ 2019-08-29 10:56 ` Quentin Monnet
2019-08-29 16:03 ` Ilya Leoshkevich
2019-08-29 10:56 ` [PATCH bpf-next 3/3] tools: bpftool: do not link twice against libbpf.a in Makefile Quentin Monnet
2019-08-29 17:25 ` [PATCH bpf-next 0/3] tools: bpftool: improve bpftool build experience Jakub Kicinski
3 siblings, 1 reply; 7+ messages in thread
From: Quentin Monnet @ 2019-08-29 10:56 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann
Cc: bpf, netdev, oss-drivers, Quentin Monnet, Lorenz Bauer,
Ilya Leoshkevich, Jakub Kicinski
There are a number of alternative "make" invocations that can be used to
compile bpftool. The following invocations are expected to work:
- through the kbuild system, from the top of the repository
(make tools/bpf)
- by telling make to change to the bpftool directory
(make -C tools/bpf/bpftool)
- by building the BPF tools from tools/
(cd tools && make bpf)
- by running make from bpftool directory
(cd tools/bpf/bpftool && make)
Additionally, setting the O or OUTPUT variables should tell the build
system to use a custom output path, for each of these alternatives.
The following patch fixes the following invocations:
$ make tools/bpf
$ make tools/bpf O=<dir>
$ make -C tools/bpf/bpftool OUTPUT=<dir>
$ make -C tools/bpf/bpftool O=<dir>
$ cd tools/ && make bpf O=<dir>
$ cd tools/bpf/bpftool && make OUTPUT=<dir>
$ cd tools/bpf/bpftool && make O=<dir>
After this commit, the build still fails for two variants when passing
the OUTPUT variable:
$ make tools/bpf OUTPUT=<dir>
$ cd tools/ && make bpf OUTPUT=<dir>
In order to remember and check what make invocations are supposed to
work, and to document the ones which do not, a new script is added to
the BPF selftests. Note that some invocations require the kernel to be
configured, so the script skips them if no .config file is found.
Reported-by: Lorenz Bauer <lmb@cloudflare.com>
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
---
tools/bpf/bpftool/Makefile | 12 +-
tools/testing/selftests/bpf/Makefile | 3 +-
.../selftests/bpf/test_bpftool_build.sh | 137 ++++++++++++++++++
3 files changed, 146 insertions(+), 6 deletions(-)
create mode 100755 tools/testing/selftests/bpf/test_bpftool_build.sh
diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
index cd0fc05464e7..3fc82ff9b52c 100644
--- a/tools/bpf/bpftool/Makefile
+++ b/tools/bpf/bpftool/Makefile
@@ -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 -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
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 1faad0c3c3c9..c7595b4ed55d 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -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 \
diff --git a/tools/testing/selftests/bpf/test_bpftool_build.sh b/tools/testing/selftests/bpf/test_bpftool_build.sh
new file mode 100755
index 000000000000..15dbea809a38
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_bpftool_build.sh
@@ -0,0 +1,137 @@
+#!/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 [ $# -ge 1 ] ; then
+ check ${@: -1}
+ else
+ check .
+ fi
+ (
+ if [ $# -eq 1 ] ; then
+ cd ${@: -1}/bpftool
+ 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
+ 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
--
2.17.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH bpf-next 2/3] tools: bpftool: improve and check builds for different make invocations
2019-08-29 10:56 ` [PATCH bpf-next 2/3] tools: bpftool: improve and check builds for different make invocations Quentin Monnet
@ 2019-08-29 16:03 ` Ilya Leoshkevich
2019-08-30 10:58 ` Quentin Monnet
0 siblings, 1 reply; 7+ messages in thread
From: Ilya Leoshkevich @ 2019-08-29 16:03 UTC (permalink / raw)
To: Quentin Monnet
Cc: Alexei Starovoitov, Daniel Borkmann, bpf, netdev, oss-drivers,
Lorenz Bauer, Jakub Kicinski
> Am 29.08.2019 um 12:56 schrieb Quentin Monnet <quentin.monnet@netronome.com>:
>
> +make_and_clean() {
> + echo -e "\$PWD: $PWD"
> + echo -e "command: make -s $* >/dev/null"
> + make $J -s $* >/dev/null
Would it make sense to set ERROR=1 if make produces a bpftool binary,
but still fails with a non-zero RC for whatever reason?
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH bpf-next 2/3] tools: bpftool: improve and check builds for different make invocations
2019-08-29 16:03 ` Ilya Leoshkevich
@ 2019-08-30 10:58 ` Quentin Monnet
0 siblings, 0 replies; 7+ messages in thread
From: Quentin Monnet @ 2019-08-30 10:58 UTC (permalink / raw)
To: Ilya Leoshkevich
Cc: Alexei Starovoitov, Daniel Borkmann, bpf, netdev, oss-drivers,
Lorenz Bauer, Jakub Kicinski
2019-08-29 18:03 UTC+0200 ~ Ilya Leoshkevich <iii@linux.ibm.com>
>> Am 29.08.2019 um 12:56 schrieb Quentin Monnet <quentin.monnet@netronome.com>:
>>
>> +make_and_clean() {
>> + echo -e "\$PWD: $PWD"
>> + echo -e "command: make -s $* >/dev/null"
>> + make $J -s $* >/dev/null
>
> Would it make sense to set ERROR=1 if make produces a bpftool binary,
> but still fails with a non-zero RC for whatever reason?
>
Hi Ilya,
Generating bpftool being the last thing the Makefile does, I don't know
if this could happen. But sure, that wouldn't hurt, and I will add it to
v2, thanks!
Quentin
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH bpf-next 3/3] tools: bpftool: do not link twice against libbpf.a in Makefile
2019-08-29 10:56 [PATCH bpf-next 0/3] tools: bpftool: improve bpftool build experience Quentin Monnet
2019-08-29 10:56 ` [PATCH bpf-next 1/3] tools: bpftool: ignore make built-in rules for getting kernel version Quentin Monnet
2019-08-29 10:56 ` [PATCH bpf-next 2/3] tools: bpftool: improve and check builds for different make invocations Quentin Monnet
@ 2019-08-29 10:56 ` Quentin Monnet
2019-08-29 17:25 ` [PATCH bpf-next 0/3] tools: bpftool: improve bpftool build experience Jakub Kicinski
3 siblings, 0 replies; 7+ messages in thread
From: Quentin Monnet @ 2019-08-29 10:56 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann
Cc: bpf, netdev, oss-drivers, Quentin Monnet, Lorenz Bauer,
Ilya Leoshkevich, Jakub Kicinski
In bpftool's Makefile, $(LIBS) includes $(LIBBPF), therefore the library
is used twice in the linking command. No need to have $(LIBBPF) (from
$^) on that command, let's do with "$(OBJS) $(LIBS)" (but move $(LIBBPF)
_before_ the -l flags in $(LIBS)).
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
---
tools/bpf/bpftool/Makefile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
index 3fc82ff9b52c..22b5a8f2c53d 100644
--- a/tools/bpf/bpftool/Makefile
+++ b/tools/bpf/bpftool/Makefile
@@ -55,7 +55,7 @@ ifneq ($(EXTRA_LDFLAGS),)
LDFLAGS += $(EXTRA_LDFLAGS)
endif
-LIBS = -lelf -lz $(LIBBPF)
+LIBS = $(LIBBPF) -lelf -lz
INSTALL ?= install
RM ?= rm -f
@@ -117,7 +117,7 @@ $(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 $@ $<
--
2.17.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next 0/3] tools: bpftool: improve bpftool build experience
2019-08-29 10:56 [PATCH bpf-next 0/3] tools: bpftool: improve bpftool build experience Quentin Monnet
` (2 preceding siblings ...)
2019-08-29 10:56 ` [PATCH bpf-next 3/3] tools: bpftool: do not link twice against libbpf.a in Makefile Quentin Monnet
@ 2019-08-29 17:25 ` Jakub Kicinski
3 siblings, 0 replies; 7+ messages in thread
From: Jakub Kicinski @ 2019-08-29 17:25 UTC (permalink / raw)
To: Quentin Monnet
Cc: Alexei Starovoitov, Daniel Borkmann, bpf, netdev, oss-drivers,
Lorenz Bauer, Ilya Leoshkevich
On Thu, 29 Aug 2019 11:56:42 +0100, Quentin Monnet wrote:
> Hi,
> 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.
>
> At last, third 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/
I think Ilya has a point, but otherwise looks good to me :)
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
^ permalink raw reply [flat|nested] 7+ messages in thread