diff mbox series

[PATCHv4,iproute2-next,1/5] configure: add check_libbpf() for later libbpf support

Message ID 20201109070802.3638167-2-haliu@redhat.com (mailing list archive)
State Not Applicable
Delegated to: Stephen Hemminger
Headers show
Series iproute2: add libbpf support | expand

Checks

Context Check Description
netdev/tree_selection success Not a local patch

Commit Message

Hangbin Liu Nov. 9, 2020, 7:07 a.m. UTC
This patch adds a check to see if we have libbpf support. By default the
system libbpf will be used, but static linking against a custom libbpf
version can be achieved by passing LIBBPF_DIR to configure.

Add another variable LIBBPF_FORCE to control whether to build iproute2
with libbpf. If set to on, then force to build with libbpf and exit if
not available. If set to off, then force to not build with libbpf.

Signed-off-by: Hangbin Liu <haliu@redhat.com>

v4:
1) Remove duplicate LIBBPF_CFLAGS
2) Remove un-needed -L since using static libbpf.a
3) Fix == not supported in dash
4) Extend LIBBPF_FORCE to support on/off, when set to on, stop building when
   there is no libbpf support. If set to off, discard libbpf check.
5) Print libbpf version after checking

v3:
Check function bpf_program__section_name() separately and only use it
on higher libbpf version.

v2:
No update
---
 configure | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)

Comments

David Ahern Nov. 14, 2020, 3:26 a.m. UTC | #1
On 11/9/20 12:07 AM, Hangbin Liu wrote:
> This patch adds a check to see if we have libbpf support. By default the
> system libbpf will be used, but static linking against a custom libbpf
> version can be achieved by passing LIBBPF_DIR to configure.
> 
> Add another variable LIBBPF_FORCE to control whether to build iproute2
> with libbpf. If set to on, then force to build with libbpf and exit if
> not available. If set to off, then force to not build with libbpf.
> 
> Signed-off-by: Hangbin Liu <haliu@redhat.com>
> 
> v4:
> 1) Remove duplicate LIBBPF_CFLAGS
> 2) Remove un-needed -L since using static libbpf.a
> 3) Fix == not supported in dash
> 4) Extend LIBBPF_FORCE to support on/off, when set to on, stop building when
>    there is no libbpf support. If set to off, discard libbpf check.
> 5) Print libbpf version after checking
> 
> v3:
> Check function bpf_program__section_name() separately and only use it
> on higher libbpf version.
> 
> v2:
> No update
> ---
>  configure | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 108 insertions(+)
> 
> diff --git a/configure b/configure
> index 307912aa..3081a2ac 100755
> --- a/configure
> +++ b/configure
> @@ -2,6 +2,11 @@
>  # SPDX-License-Identifier: GPL-2.0
>  # This is not an autoconf generated configure
>  #
> +# Influential LIBBPF environment variables:
> +#   LIBBPF_FORCE={on,off}   on: require link against libbpf;
> +#                           off: disable libbpf probing
> +#   LIBBPF_LIBDIR           Path to libbpf to use
> +
>  INCLUDE=${1:-"$PWD/include"}
>  
>  # Output file which is input to Makefile
> @@ -240,6 +245,106 @@ check_elf()
>      fi
>  }
>  
> +have_libbpf_basic()
> +{
> +    cat >$TMPDIR/libbpf_test.c <<EOF
> +#include <bpf/libbpf.h>
> +int main(int argc, char **argv) {
> +    bpf_program__set_autoload(NULL, false);
> +    bpf_map__ifindex(NULL);
> +    bpf_map__set_pin_path(NULL, NULL);
> +    bpf_object__open_file(NULL, NULL);
> +    return 0;
> +}
> +EOF
> +
> +    $CC -o $TMPDIR/libbpf_test $TMPDIR/libbpf_test.c $LIBBPF_CFLAGS $LIBBPF_LDLIBS >/dev/null 2>&1
> +    local ret=$?
> +
> +    rm -f $TMPDIR/libbpf_test.c $TMPDIR/libbpf_test
> +    return $ret
> +}
> +
> +have_libbpf_sec_name()
> +{
> +    cat >$TMPDIR/libbpf_sec_test.c <<EOF
> +#include <bpf/libbpf.h>
> +int main(int argc, char **argv) {
> +    void *ptr;
> +    bpf_program__section_name(NULL);
> +    return 0;
> +}
> +EOF
> +
> +    $CC -o $TMPDIR/libbpf_sec_test $TMPDIR/libbpf_sec_test.c $LIBBPF_CFLAGS $LIBBPF_LDLIBS >/dev/null 2>&1
> +    local ret=$?
> +
> +    rm -f $TMPDIR/libbpf_sec_test.c $TMPDIR/libbpf_sec_test
> +    return $ret
> +}
> +
> +check_force_libbpf_on()
> +{
> +    # if set LIBBPF_FORCE=on but no libbpf support, just exist the config
> +    # process to make sure we don't build without libbpf.
> +    if [ "$LIBBPF_FORCE" = on ]; then
> +        echo "	LIBBPF_FORCE=on set, but couldn't find a usable libbpf"
> +        exit 1
> +    fi
> +}
> +
> +check_libbpf()
> +{
> +    # if set LIBBPF_FORCE=off, disable libbpf entirely
> +    if [ "$LIBBPF_FORCE" = off ]; then
> +        echo "no"
> +        return
> +    fi
> +
> +    if ! ${PKG_CONFIG} libbpf --exists && [ -z "$LIBBPF_DIR" ] ; then
> +        echo "no"
> +        check_force_libbpf_on
> +        return
> +    fi
> +
> +    if [ $(uname -m) = x86_64 ]; then
> +        local LIBBPF_LIBDIR="${LIBBPF_DIR}/lib64"
> +    else
> +        local LIBBPF_LIBDIR="${LIBBPF_DIR}/lib"
> +    fi
> +
> +    if [ -n "$LIBBPF_DIR" ]; then
> +        LIBBPF_CFLAGS="-I${LIBBPF_DIR}/include"
> +        LIBBPF_LDLIBS="${LIBBPF_LIBDIR}/libbpf.a -lz -lelf"
> +        LIBBPF_VERSION=$(PKG_CONFIG_LIBDIR=${LIBBPF_LIBDIR}/pkgconfig ${PKG_CONFIG} libbpf --modversion)
> +    else
> +        LIBBPF_CFLAGS=$(${PKG_CONFIG} libbpf --cflags)
> +        LIBBPF_LDLIBS=$(${PKG_CONFIG} libbpf --libs)
> +        LIBBPF_VERSION=$(${PKG_CONFIG} libbpf --modversion)
> +    fi
> +
> +    if ! have_libbpf_basic; then
> +        echo "no"
> +        echo "	libbpf version $LIBBPF_VERSION is too low, please update it to at least 0.1.0"
> +        check_force_libbpf_on
> +        return
> +    else
> +        echo "HAVE_LIBBPF:=y" >>$CONFIG
> +        echo 'CFLAGS += -DHAVE_LIBBPF ' $LIBBPF_CFLAGS >> $CONFIG
> +        echo 'LDLIBS += ' $LIBBPF_LDLIBS >>$CONFIG
> +    fi
> +
> +    # bpf_program__title() is deprecated since libbpf 0.2.0, use
> +    # bpf_program__section_name() instead if we support
> +    if have_libbpf_sec_name; then
> +        echo "HAVE_LIBBPF_SECTION_NAME:=y" >>$CONFIG
> +        echo 'CFLAGS += -DHAVE_LIBBPF_SECTION_NAME ' >> $CONFIG
> +    fi
> +
> +    echo "yes"
> +    echo "	libbpf version $LIBBPF_VERSION"
> +}
> +
>  check_selinux()
>  # SELinux is a compile time option in the ss utility
>  {
> @@ -385,6 +490,9 @@ check_setns
>  echo -n "SELinux support: "
>  check_selinux
>  
> +echo -n "libbpf support: "
> +check_libbpf
> +
>  echo -n "ELF support: "
>  check_elf
>  
> 

Something is off with the version detection.

# LIBBPF_LIBDIR=/tmp/libbpf ./configure
TC schedulers
 ATM	no

libc has setns: yes
SELinux support: no
libbpf support: yes
	libbpf version 0.1.0
ELF support: yes

/tmp/libbpf has an install of top of tree as of today which is:

/tmp/libbpf/usr/lib64/libbpf.so.0.3.0

This is using Ubuntu 20.10.
Hangbin Liu Nov. 16, 2020, 4:30 a.m. UTC | #2
On Fri, Nov 13, 2020 at 08:26:51PM -0700, David Ahern wrote:
> > +# Influential LIBBPF environment variables:
> > +#   LIBBPF_FORCE={on,off}   on: require link against libbpf;
> > +#                           off: disable libbpf probing
> > +#   LIBBPF_LIBDIR           Path to libbpf to use
> > +

...
> > +check_libbpf()
> > +{
> > +    # if set LIBBPF_FORCE=off, disable libbpf entirely
> > +    if [ "$LIBBPF_FORCE" = off ]; then
> > +        echo "no"
> > +        return
> > +    fi
> > +
> > +    if ! ${PKG_CONFIG} libbpf --exists && [ -z "$LIBBPF_DIR" ] ; then
> > +        echo "no"
> > +        check_force_libbpf_on
> > +        return
> > +    fi

...

> 
> Something is off with the version detection.
> 
> # LIBBPF_LIBDIR=/tmp/libbpf ./configure

My copy-past error. It should take LIBBPF_DIR, but I wrote LIBBPF_LIBDIR in
the description... Also the folder should be libbpf dest dir, not libbpf
dir directly. To be consistent with the libbpf document. I will change
LIBBPF_DIR to LIBBPF_DESTDIR(Please tell me if you think the name is not
suitable). The fix diff will looks like

diff --git a/configure b/configure
index 3081a2ac..5ca10337 100755
--- a/configure
+++ b/configure
@@ -5,7 +5,7 @@
 # Influential LIBBPF environment variables:
 #   LIBBPF_FORCE={on,off}   on: require link against libbpf;
 #                           off: disable libbpf probing
-#   LIBBPF_LIBDIR           Path to libbpf to use
+#   LIBBPF_DESTDIR          Path to libbpf dest dir to use
 
 INCLUDE=${1:-"$PWD/include"}
 
@@ -301,20 +301,20 @@ check_libbpf()
         return
     fi
 
-    if ! ${PKG_CONFIG} libbpf --exists && [ -z "$LIBBPF_DIR" ] ; then
+    if ! ${PKG_CONFIG} libbpf --exists && [ -z "$LIBBPF_DESTDIR" ] ; then
         echo "no"
         check_force_libbpf_on
         return
     fi
 
     if [ $(uname -m) = x86_64 ]; then
-        local LIBBPF_LIBDIR="${LIBBPF_DIR}/lib64"
+        local LIBBPF_LIBDIR="${LIBBPF_DESTDIR}/usr/lib64"
     else
-        local LIBBPF_LIBDIR="${LIBBPF_DIR}/lib"
+        local LIBBPF_LIBDIR="${LIBBPF_DESTDIR}/usr/lib"
     fi
 
-    if [ -n "$LIBBPF_DIR" ]; then
-        LIBBPF_CFLAGS="-I${LIBBPF_DIR}/include"
+    if [ -n "$LIBBPF_DESTDIR" ]; then
+        LIBBPF_CFLAGS="-I${LIBBPF_DESTDIR}/usr/include"
         LIBBPF_LDLIBS="${LIBBPF_LIBDIR}/libbpf.a -lz -lelf"
         LIBBPF_VERSION=$(PKG_CONFIG_LIBDIR=${LIBBPF_LIBDIR}/pkgconfig ${PKG_CONFIG} libbpf --modversion)
     else

When you compile libbpf, it should like

$ mkdir /tmp/libbpf_destdir
$ cd libbpf/src/
$ make
...
  CC       libbpf.so.0.2.0
$ DESTDIR=/tmp/libbpf_destdir make install

Then in iproute2, configure it with

$ LIBBPF_DIR=/tmp/libbpf_destdir ./configure
TC schedulers
 ATM    no

libc has setns: yes
SELinux support: no
libbpf support: yes
        libbpf version 0.2.0
ELF support: yes
libmnl support: yes
Berkeley DB: no
need for strlcpy: yes
libcap support: yes

Thanks
Hangbin
David Ahern Nov. 16, 2020, 4:33 a.m. UTC | #3
On 11/15/20 9:30 PM, Hangbin Liu wrote:
> diff --git a/configure b/configure
> index 3081a2ac..5ca10337 100755
> --- a/configure
> +++ b/configure
> @@ -5,7 +5,7 @@
>  # Influential LIBBPF environment variables:
>  #   LIBBPF_FORCE={on,off}   on: require link against libbpf;
>  #                           off: disable libbpf probing
> -#   LIBBPF_LIBDIR           Path to libbpf to use
> +#   LIBBPF_DESTDIR          Path to libbpf dest dir to use

DESTDIR as a name applies to an install script. I think LIBBPF_DIR
 is fine. You can enhance the description to make it clear.
diff mbox series

Patch

diff --git a/configure b/configure
index 307912aa..3081a2ac 100755
--- a/configure
+++ b/configure
@@ -2,6 +2,11 @@ 
 # SPDX-License-Identifier: GPL-2.0
 # This is not an autoconf generated configure
 #
+# Influential LIBBPF environment variables:
+#   LIBBPF_FORCE={on,off}   on: require link against libbpf;
+#                           off: disable libbpf probing
+#   LIBBPF_LIBDIR           Path to libbpf to use
+
 INCLUDE=${1:-"$PWD/include"}
 
 # Output file which is input to Makefile
@@ -240,6 +245,106 @@  check_elf()
     fi
 }
 
+have_libbpf_basic()
+{
+    cat >$TMPDIR/libbpf_test.c <<EOF
+#include <bpf/libbpf.h>
+int main(int argc, char **argv) {
+    bpf_program__set_autoload(NULL, false);
+    bpf_map__ifindex(NULL);
+    bpf_map__set_pin_path(NULL, NULL);
+    bpf_object__open_file(NULL, NULL);
+    return 0;
+}
+EOF
+
+    $CC -o $TMPDIR/libbpf_test $TMPDIR/libbpf_test.c $LIBBPF_CFLAGS $LIBBPF_LDLIBS >/dev/null 2>&1
+    local ret=$?
+
+    rm -f $TMPDIR/libbpf_test.c $TMPDIR/libbpf_test
+    return $ret
+}
+
+have_libbpf_sec_name()
+{
+    cat >$TMPDIR/libbpf_sec_test.c <<EOF
+#include <bpf/libbpf.h>
+int main(int argc, char **argv) {
+    void *ptr;
+    bpf_program__section_name(NULL);
+    return 0;
+}
+EOF
+
+    $CC -o $TMPDIR/libbpf_sec_test $TMPDIR/libbpf_sec_test.c $LIBBPF_CFLAGS $LIBBPF_LDLIBS >/dev/null 2>&1
+    local ret=$?
+
+    rm -f $TMPDIR/libbpf_sec_test.c $TMPDIR/libbpf_sec_test
+    return $ret
+}
+
+check_force_libbpf_on()
+{
+    # if set LIBBPF_FORCE=on but no libbpf support, just exist the config
+    # process to make sure we don't build without libbpf.
+    if [ "$LIBBPF_FORCE" = on ]; then
+        echo "	LIBBPF_FORCE=on set, but couldn't find a usable libbpf"
+        exit 1
+    fi
+}
+
+check_libbpf()
+{
+    # if set LIBBPF_FORCE=off, disable libbpf entirely
+    if [ "$LIBBPF_FORCE" = off ]; then
+        echo "no"
+        return
+    fi
+
+    if ! ${PKG_CONFIG} libbpf --exists && [ -z "$LIBBPF_DIR" ] ; then
+        echo "no"
+        check_force_libbpf_on
+        return
+    fi
+
+    if [ $(uname -m) = x86_64 ]; then
+        local LIBBPF_LIBDIR="${LIBBPF_DIR}/lib64"
+    else
+        local LIBBPF_LIBDIR="${LIBBPF_DIR}/lib"
+    fi
+
+    if [ -n "$LIBBPF_DIR" ]; then
+        LIBBPF_CFLAGS="-I${LIBBPF_DIR}/include"
+        LIBBPF_LDLIBS="${LIBBPF_LIBDIR}/libbpf.a -lz -lelf"
+        LIBBPF_VERSION=$(PKG_CONFIG_LIBDIR=${LIBBPF_LIBDIR}/pkgconfig ${PKG_CONFIG} libbpf --modversion)
+    else
+        LIBBPF_CFLAGS=$(${PKG_CONFIG} libbpf --cflags)
+        LIBBPF_LDLIBS=$(${PKG_CONFIG} libbpf --libs)
+        LIBBPF_VERSION=$(${PKG_CONFIG} libbpf --modversion)
+    fi
+
+    if ! have_libbpf_basic; then
+        echo "no"
+        echo "	libbpf version $LIBBPF_VERSION is too low, please update it to at least 0.1.0"
+        check_force_libbpf_on
+        return
+    else
+        echo "HAVE_LIBBPF:=y" >>$CONFIG
+        echo 'CFLAGS += -DHAVE_LIBBPF ' $LIBBPF_CFLAGS >> $CONFIG
+        echo 'LDLIBS += ' $LIBBPF_LDLIBS >>$CONFIG
+    fi
+
+    # bpf_program__title() is deprecated since libbpf 0.2.0, use
+    # bpf_program__section_name() instead if we support
+    if have_libbpf_sec_name; then
+        echo "HAVE_LIBBPF_SECTION_NAME:=y" >>$CONFIG
+        echo 'CFLAGS += -DHAVE_LIBBPF_SECTION_NAME ' >> $CONFIG
+    fi
+
+    echo "yes"
+    echo "	libbpf version $LIBBPF_VERSION"
+}
+
 check_selinux()
 # SELinux is a compile time option in the ss utility
 {
@@ -385,6 +490,9 @@  check_setns
 echo -n "SELinux support: "
 check_selinux
 
+echo -n "libbpf support: "
+check_libbpf
+
 echo -n "ELF support: "
 check_elf