#!/bin/sh # SPDX-License-Identifier: GPL-2.0 # This is not an autoconf generated configure # # Output file which is input to Makefile CONFIG_FINAL=config.mk CONFIG=".${CONFIG}.tmp" # Make a temp directory in build tree. TMPDIR=$(mktemp -d config.XXXXXX) trap 'status=$?; rm -rf $TMPDIR; rm -f $CONFIG; exit $status' EXIT HUP INT QUIT TERM check_opts() { : ${PRODUCTION:=0} : ${DYNAMIC_LIBXDP:=0} : ${MAX_DISPATCHER_ACTIONS:=10} : ${BPF_TARGET:=bpf} echo "PRODUCTION:=${PRODUCTION}" >>$CONFIG echo "DYNAMIC_LIBXDP:=${DYNAMIC_LIBXDP}" >>$CONFIG echo "MAX_DISPATCHER_ACTIONS:=${MAX_DISPATCHER_ACTIONS}" >>$CONFIG echo "BPF_TARGET:=${BPF_TARGET}" >>$CONFIG } check_toolchain() { local emacs_version local clang_version : ${PKG_CONFIG:=pkg-config} : ${CC=gcc} : ${CLANG=clang} : ${LLC=llc} : ${M4=m4} : ${EMACS=emacs} : ${ARCH_INCLUDES=} for TOOL in $PKG_CONFIG $CC $CLANG $LLC $M4; do if [ ! $(command -v ${TOOL} 2>/dev/null) ]; then echo "*** ERROR: Cannot find tool ${TOOL}" ; exit 1; fi; done clang_version=$($CLANG --version | grep -Po '(?<=clang version )[[:digit:]]+') echo "Found clang binary '$CLANG' with version $clang_version (from '$($CLANG --version | head -n 1)')" if [ "$clang_version" -lt "10" ]; then echo "*** ERROR: Need LLVM version 10+, '$CLANG' is version $clang_version" [ -n "$RELAXED_LLVM_VERSION" ] || exit 1 fi if ! command -v $EMACS >/dev/null 2>&1; then EMACS="" else emacs_version=$($EMACS --version 2>/dev/null | head -n 1) if echo $emacs_version | grep -Eq 'GNU Emacs 2[6789]'; then echo "using emacs: $emacs_version" else echo "not using emacs: $emacs_version" EMACS="" fi fi if [ -z "$EMACS" ] && [ "${FORCE_EMACS:-0}" -eq "1" ]; then echo "FORCE_EMACS is set, but no usable emacs found on system" rm -f "$CONFIG" exit 1 fi if [ -z "$ARCH_INCLUDES" ]; then for dir in $(echo | $CC -Wp,-v -E - 2>&1 | grep '^ '); do local idir idir="${dir}/$(uname -m)-linux-gnu/" [ -d "$idir" ] && ARCH_INCLUDES="-I${idir} $ARCH_INCLUDES" done fi echo "PKG_CONFIG:=${PKG_CONFIG}" >>$CONFIG echo "CC:=${CC}" >>$CONFIG echo "CLANG:=${CLANG}" >>$CONFIG echo "LLC:=${LLC}" >>$CONFIG echo "M4:=${M4}" >>$CONFIG echo "EMACS:=${EMACS}" >>$CONFIG echo "ARCH_INCLUDES:=$ARCH_INCLUDES" >> $CONFIG } check_elf() { if ${PKG_CONFIG} libelf --exists; then echo "HAVE_ELF:=y" >>$CONFIG echo "yes" echo 'CFLAGS += -DHAVE_ELF' `${PKG_CONFIG} libelf --cflags` >> $CONFIG echo 'LDLIBS += ' `${PKG_CONFIG} libelf --libs` >>$CONFIG else echo "missing - this is required" return 1 fi } check_pcap() { local libpcap_err if ${PKG_CONFIG} libpcap --exists; then LIBPCAP_CFLAGS=$(${PKG_CONFIG} libpcap --cflags) LIBPCAP_LDLIBS=$(${PKG_CONFIG} libpcap --libs) else LIBPCAP_CFLAGS="" LIBPCAP_LDLIBS="-lpcap" fi cat >$TMPDIR/libpcaptest.c < #include int main(int argc, char **argv) { pcap_t *pcap = pcap_open_live("ifname", 100, 1, 1000, NULL); return 0; } EOF libpcap_err=$($CC -o $TMPDIR/libpcaptest $TMPDIR/libpcaptest.c $LIBPCAP_CFLAGS $LIBPCAP_LDLIBS 2>&1) if [ "$?" -eq "0" ]; then echo "HAVE_PCAP:=y" >>$CONFIG [ -n "$LIBPCAP_CFLAGS" ] && echo 'CFLAGS += ' $LIBPCAP_CFLAGS >> $CONFIG echo "yes" else echo "missing - this is required" echo "error: $libpcap_err" return 1 fi } check_zlib() { if ${PKG_CONFIG} zlib --exists; then echo "HAVE_ZLIB:=y" >>$CONFIG echo "yes" echo 'CFLAGS += -DHAVE_ZLIB' `${PKG_CONFIG} zlib --cflags` >> $CONFIG echo 'LDLIBS += ' `${PKG_CONFIG} zlib --libs` >>$CONFIG else echo "missing - this is required" return 1 fi } check_perf_consume() { cat >$TMPDIR/libbpftest.c < int main(int argc, char **argv) { perf_buffer__consume(NULL); return 0; } EOF libbpf_err=$($CC -o $TMPDIR/libbpftest $TMPDIR/libbpftest.c $LIBBPF_CFLAGS $LIBBPF_LDLIBS 2>&1) if [ "$?" -eq "0" ]; then echo "HAVE_LIBBPF_PERF_BUFFER__CONSUME:=y" >>"$CONFIG" echo "yes" else echo "HAVE_LIBBPF_PERF_BUFFER__CONSUME:=n" >>"$CONFIG" echo "no" fi } get_libbpf_version() { local libbpf_dir local version libbpf_dir="$1" if [ -f "${libbpf_dir}/libbpf.map" ]; then version=$(grep -oE '^LIBBPF_([0-9.]+)' "${libbpf_dir}/libbpf.map" | sort -rV | head -n1 | cut -d'_' -f2) else version=unknown fi echo $version } check_libbpf() { local libbpf_err if [ "${FORCE_SUBDIR_LIBBPF:-0}" -ne "1" ] && ${PKG_CONFIG} libbpf --exists || [ -n "$LIBBPF_DIR" ]; then if [ -n "$LIBBPF_DIR" ]; then LIBBPF_CFLAGS="-I${LIBBPF_DIR}/include -L${LIBBPF_DIR}/lib" LIBBPF_LDLIBS="-lbpf" LIBBPF_VERSION=$(get_libbpf_version "$LIBBPF_DIR") else LIBBPF_CFLAGS=$(${PKG_CONFIG} libbpf --cflags) LIBBPF_LDLIBS=$(${PKG_CONFIG} libbpf --libs) LIBBPF_VERSION=$(${PKG_CONFIG} libbpf --modversion) fi cat >$TMPDIR/libbpftest.c < #include int main(int argc, char **argv) { void *ptr; DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, .pin_root_path = "/path"); DECLARE_LIBBPF_OPTS(bpf_xdp_set_link_opts, xlopts, .old_fd = -1); DECLARE_LIBBPF_OPTS(bpf_link_create_opts, lopts, .target_btf_id = 0); (void) bpf_object__open_file("file", &opts); (void) bpf_program__name(ptr); (void) bpf_map__set_initial_value(ptr, ptr, 0); (void) bpf_set_link_xdp_fd_opts(0, 0, 0, &lopts); return 0; } EOF libbpf_err=$($CC -o $TMPDIR/libbpftest $TMPDIR/libbpftest.c $LIBBPF_CFLAGS -lbpf 2>&1) if [ "$?" -eq "0" ]; then echo "SYSTEM_LIBBPF:=y" >>$CONFIG echo "LIBBPF_VERSION=$LIBBPF_VERSION" >>$CONFIG echo 'CFLAGS += ' $LIBBPF_CFLAGS >> $CONFIG echo 'LDLIBS += ' $LIBBPF_LDLIBS >>$CONFIG echo 'OBJECT_LIBBPF = ' >>$CONFIG echo "system v$LIBBPF_VERSION" echo -n "perf_buffer__consume support: " check_perf_consume return 0 fi else libbpf_err="${PKG_CONFIG} couldn't find libbpf" fi if [ "${FORCE_SYSTEM_LIBBPF:-0}" -eq "1" ]; then echo "FORCE_SYSTEM_LIBBPF is set, but no usable libbpf found on system" echo "error: $libbpf_err" rm -f "$CONFIG" exit 1 fi LIBBPF_VERSION=$(get_libbpf_version "lib/libbpf/src") echo "submodule v$LIBBPF_VERSION" echo "SYSTEM_LIBBPF:=n" >> $CONFIG echo "LIBBPF_VERSION=$LIBBPF_VERSION" >>$CONFIG echo 'CFLAGS += -I$(LIB_DIR)/libbpf/src/root/usr/include' >>$CONFIG echo 'BPF_CFLAGS += -I$(LIB_DIR)/libbpf/src/root/usr/include' >>$CONFIG echo 'LDFLAGS += -L$(LIB_DIR)/libbpf/src' >>$CONFIG echo 'LDLIBS += -l:libbpf.a' >>$CONFIG echo 'OBJECT_LIBBPF = $(LIB_DIR)/libbpf/src/libbpf.a' >>$CONFIG if ! [ -d "lib/libbpf/src" ] && [ -f ".gitmodules" ] && [ -e ".git" ]; then git submodule init && git submodule update fi echo -n "ELF support: " check_elf || exit 1 echo -n "pcap support: " check_pcap || exit 1 echo -n "zlib support: " check_zlib || exit 1 # For the build submodule library we know it does support this API, so we # hard code it. Also due to the fact it's hard to build a test app as # libbpf.a has not been build at configure time. echo "HAVE_LIBBPF_PERF_BUFFER__CONSUME:=y" >>"$CONFIG" } check_secure_getenv() { cat >$TMPDIR/secure_getenv.c < int main(int argc, char **argv) { secure_getenv("test"); return 0; } EOF secure_getenv_err=$($CC -o $TMPDIR/secure_getenv $TMPDIR/secure_getenv.c 2>&1) if [ "$?" -eq "0" ]; then echo "HAVE_SECURE_GETENV:=y" >>"$CONFIG" echo "yes" else echo "HAVE_SECURE_GETENV:=n" >>"$CONFIG" echo "no" fi } quiet_config() { cat <$CONFIG quiet_config >> $CONFIG check_opts check_toolchain echo -n "libbpf support: " check_libbpf echo -n "secure_getenv support: " check_secure_getenv if [ -n "$KERNEL_HEADERS" ]; then echo "kernel headers: $KERNEL_HEADERS" echo "CFLAGS += -I$KERNEL_HEADERS" >>$CONFIG echo "BPF_CFLAGS += -I$KERNEL_HEADERS" >>$CONFIG fi mv $CONFIG $CONFIG_FINAL