Re: [PATCH 3/3] bpftool: Allow to link libbpf dynamically

Jiri Olsa
2019-11-27T14:15:47Z

On Wed, Nov 27, 2019 at 01:38:55PM +0000, Quentin Monnet wrote:
> 2019-11-27 10:48 UTC+0100 ~ Jiri Olsa <jolsa@kernel.org>
> > Currently we support only static linking with kernel's libbpf
> > (tools/lib/bpf). This patch adds LIBBPF_DYNAMIC compile variable
> > that triggers libbpf detection and bpf dynamic linking:
> >
> > $ make -C tools/bpf/bpftool make LIBBPF_DYNAMIC=1
> >
> > If libbpf is not installed, build (with LIBBPF_DYNAMIC=1) stops with:
> >
> > $ make -C tools/bpf/bpftool LIBBPF_DYNAMIC=1
> > Auto-detecting system features:
> > ... libbfd: [ on ]
> > ... disassembler-four-args: [ on ]
> > ... zlib: [ on ]
> > ... libbpf: [ OFF ]
> >
> > Makefile:102: *** Error: libbpf-devel is missing, please install it. Stop.
> >
> > Adding specific bpftool's libbpf check for libbpf_netlink_open (LIBBPF_0.0.6)
> > which is the latest we need for bpftool at the moment.
> >
> > Adding LIBBPF_DIR compile variable to allow linking with
> > libbpf installed into specific directory:
> >
> > $ make -C tools/lib/bpf/ prefix=/tmp/libbpf/ install_lib install_headers
> > $ make -C tools/bpf/bpftool/ LIBBPF_DYNAMIC=1 LIBBPF_DIR=/tmp/libbpf/
> >
> > It might be needed to clean build tree first because features
> > framework does not detect the change properly:
> >
> > $ make -C tools/build/feature clean
> > $ make -C tools/bpf/bpftool/ clean
> >
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > ---
> > tools/bpf/bpftool/Makefile | 40 ++++++++++++++++++++++++++++++-
> > tools/build/feature/test-libbpf.c | 9 +++++++
> > 2 files changed, 48 insertions(+), 1 deletion(-)
> >
> > diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
> > index 39bc6f0f4f0b..2b6ed08cb31e 100644
> > --- a/tools/bpf/bpftool/Makefile
> > +++ b/tools/bpf/bpftool/Makefile
>
> > @@ -55,7 +64,7 @@ ifneq ($(EXTRA_LDFLAGS),)
> > LDFLAGS += $(EXTRA_LDFLAGS)
> > endif
> >
> > -LIBS = $(LIBBPF) -lelf -lz
> > +LIBS = -lelf -lz
>
> Hi Jiri,
>
> This change seems to be breaking the build with the static library for
> me. I know you add back $(LIBBPF) later in the Makefile, see at the end
> of this email...
>
> >
> > INSTALL ?= install
> > RM ?= rm -f
> > @@ -64,6 +73,23 @@ FEATURE_USER = .bpftool
> > FEATURE_TESTS = libbfd disassembler-four-args reallocarray zlib
> > FEATURE_DISPLAY = libbfd disassembler-four-args zlib
> >
> > +ifdef LIBBPF_DYNAMIC
> > + # Add libbpf check with the flags to ensure bpftool
> > + # specific version is detected.
>
> Nit: We do not check for a specific bpftool version, we check for a
> recent enough libbpf version?

hi,
we check for a version that has the latest exported function
that bpftool needs, which is currently libbpf_netlink_open

please check the '#ifdef BPFTOOL' in feature/test-libbpf.c

it's like that because there's currently no support to check
for particular library version in the build/features framework

I'll make that comment more clear

>
> > + FEATURE_CHECK_CFLAGS-libbpf := -DBPFTOOL
> > + FEATURE_TESTS += libbpf
> > + FEATURE_DISPLAY += libbpf
> > +
> > + # for linking with debug library run:
> > + # make LIBBPF_DYNAMIC=1 LIBBPF_DIR=/opt/libbpf
> > + ifdef LIBBPF_DIR
> > + LIBBPF_CFLAGS := -I$(LIBBPF_DIR)/include
> > + LIBBPF_LDFLAGS := -L$(LIBBPF_DIR)/$(libdir_relative)
> > + FEATURE_CHECK_CFLAGS-libbpf := $(LIBBPF_CFLAGS)
> > + FEATURE_CHECK_LDFLAGS-libbpf := $(LIBBPF_LDFLAGS)
> > + endif
> > +endif
> > +
> > check_feat := 1
> > NON_CHECK_FEAT_TARGETS := clean uninstall doc doc-clean doc-install doc-uninstall
> > ifdef MAKECMDGOALS
> > @@ -88,6 +114,18 @@ ifeq ($(feature-reallocarray), 0)
> > CFLAGS += -DCOMPAT_NEED_REALLOCARRAY
> > endif
> >
> > +ifdef LIBBPF_DYNAMIC
> > + ifeq ($(feature-libbpf), 1)
> > + LIBS += -lbpf
> > + CFLAGS += $(LIBBPF_CFLAGS)
> > + LDFLAGS += $(LIBBPF_LDFLAGS)
> > + else
> > + dummy := $(error Error: No libbpf devel library found, please install libbpf-devel)
>
> libbpf-devel sounds like a RH/Fedora package name, but other
> distributions might have different names (Debian/Ubuntu would go by
> libbpf-dev I suppose, although I don't believe such package exists at
> the moment). Maybe use a more generic message?

sure, actually in perf we use both package names like:

Error: No libbpf devel library found, please install libbpf-devel or libbpf-dev.

or we can go with generic message:

Error: No libbpf devel library found, please install.

>
> > + endif
> > +else
> > + LIBS += $(LIBBPF)
>
> ... I believe the order of the libraries is relevant, and it seems the
> static libbpf should be passed before the dynamic libs. Here I could fix
> the build with the static library on my setup by prepending the library
> path instead, like this:
>
> LIBS := $(LIBBPF) $(LIBS)

could you please paste the build error? I don't see any on Fedora,
anyway I can make the change you're proposing

>
> On the plus side, all build attempts from
> tools/testing/selftests/bpf/test_bpftool_build.sh pass successfully on
> my setup with dynamic linking from your branch.

cool, had no idea there was such test ;-)

thanks,
jirka