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

From: Jiri Olsa <[email-masked]>
Date: Wed, 27 Nov 2019 15:15:20 +0100

On Wed, Nov 27, 2019 at 01:38:55PM +0000, Quentin Monnet wrote:
> 2019-11-27 10:48 UTC+0100 ~ Jiri Olsa <[email-masked]>
> > 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 <[email-masked]>
> > ---
> >  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