编译期间未找到外部头文件

时间:2018-10-15 15:43:23

标签: linux makefile clang bpf xdp

我正在尝试在树外编译bpf示例。 这是我的文件夹:

.
├── bpf_load.c
├── bpf_load.h
├── bpf_load.o
├── libbpf.h
├── Makefile
├── xdp1
├── xdp1_kern.c
├── xdp1_kern.o
├── xdp1_user.c
├── xdp2_kern.c
└── xdp2_user.c

这是Makefile:

#
# Makefile for out-of-tree building eBPF programs
#  similar to kernel/samples/bpf/
#
# Still depend on a kernel source tree.
#
TARGETS = xdp1

TOOLS_PATH = /usr/src/kernels/$(shell uname -r)/tools

TARGETS_ALL = $(TARGETS)

# Generate file name-scheme based on TARGETS
KERN_SOURCES = ${TARGETS_ALL:=_kern.c}
USER_SOURCES = ${TARGETS_ALL:=_user.c}
KERN_OBJECTS = ${KERN_SOURCES:.c=.o}
USER_OBJECTS = ${USER_SOURCES:.c=.o}

# Notice: the kbuilddir can be redefined on make cmdline
kbuilddir ?= /lib/modules/`uname -r`/build/
KERNEL=$(kbuilddir)

CFLAGS := -g -O2 -Wall

# Local copy of include/linux/bpf.h kept under ./kernel-usr-include
#
CFLAGS += /usr/include/linux/bpf.h
#
# Interacting with libbpf
CFLAGS += -I$(TOOLS_PATH)/lib
CFLAGS += -I$(TOOLS_PATH)/testing/selftests/bpf

LDFLAGS= -lelf

# Objects that xxx_user program is linked with:
OBJECT_LOADBPF = bpf_load.o
OBJECTS = $(OBJECT_LOADBPF)
#
# The static libbpf library
LIBBPF = $(TOOLS_PATH)/lib/bpf/libbpf.a

# Allows pointing LLC/CLANG to another LLVM backend, redefine on cmdline:
#  make LLC=~/git/llvm/build/bin/llc CLANG=~/git/llvm/build/bin/clang
LLC ?= llc
CLANG ?= clang

CC = gcc

NOSTDINC_FLAGS := -nostdinc -isystem $(shell $(CC) -print-file-name=include)

# TODO: can we remove(?) copy of uapi/linux/bpf.h stored here: ./tools/include/
# LINUXINCLUDE := -I./tools/include/
#
# bpf_helper.h need newer version of uapi/linux/bpf.h
# (as this git-repo use new devel kernel features)
KERNEL_PATH = /usr/src/kernels/$(shell uname -r)
LINUXINCLUDE := -I$(KERNEL_PATH)/include
#
LINUXINCLUDE += -I$(KERNEL_PATH)/arch/x86/include
LINUXINCLUDE += -I$(KERNEL_PATH)/arch/x86/include/generated/uapi
LINUXINCLUDE += -I$(KERNEL_PATH)/arch/x86/include/generated
LINUXINCLUDE += -I$(KERNEL_PATH)/include
LINUXINCLUDE += -I$(KERNEL_PATH)/arch/x86/include/uapi
LINUXINCLUDE += -I$(KERNEL_PATH)/include/uapi
LINUXINCLUDE += -I$(KERNEL_PATH)/include/generated/uapi
LINUXINCLUDE += -include $(KERNEL_PATH)/include/linux/kconfig.h
#LINUXINCLUDE += -I$(KERNEL)/tools/lib
EXTRA_CFLAGS=-Werror

all: dependencies $(TARGETS_ALL) $(KERN_OBJECTS)

.PHONY: dependencies clean verify_cmds verify_llvm_target_bpf $(CLANG) $(LLC)

# Most xxx_user program still depend on old bpf_load.c
$(OBJECT_LOADBPF): bpf_load.c bpf_load.h
    $(CC) $(CFLAGS) -o $@ -c $<

LIBBPF_SOURCES  = $(TOOLS_PATH)/lib/bpf/*.c

# New ELF-loaded avail in libbpf (in bpf/libbpf.c)
$(LIBBPF): $(LIBBPF_SOURCES) $(TOOLS_PATH)/lib/bpf/Makefile
    make -C $(TOOLS_PATH)/lib/bpf/ all

# Compiling of eBPF restricted-C code with LLVM
#  clang option -S generated output file with suffix .ll
#   which is the non-binary LLVM assembly language format
#   (normally LLVM bitcode format .bc is generated)
#
# Use -Wno-address-of-packed-member as eBPF verifier enforces
# unaligned access checks where necessary
#
$(KERN_OBJECTS): %.o: %.c Makefile
    $(CLANG) -S $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(EXTRA_CFLAGS) \
        -D__KERNEL__ -D__ASM_SYSREG_H \
        -D__BPF_TRACING__ \
        -Wall \
        -Wno-unused-value -Wno-pointer-sign \
        -D__TARGET_ARCH_$(ARCH) \
        -Wno-compare-distinct-pointer-types \
        -Wno-gnu-variable-sized-type-not-at-end \
        -Wno-tautological-compare \
        -Wno-unknown-warning-option \
        -Wno-address-of-packed-member \
        -O2 -emit-llvm -c $< -o ${@:.o=.ll}
    $(LLC) -march=bpf -filetype=obj -o $@ ${@:.o=.ll}

$(TARGETS): %: xdp1_user.c $(OBJECTS) $(LIBBPF) Makefile
    $(CC) $(CFLAGS) $(OBJECTS) $(LDFLAGS) -o $@ $<  $(LIBBPF)

我几乎只是复制了在这里找到的makfile: https://github.com/netoptimizer/prototype-kernel/blob/master/kernel/samples/bpf/Makefile 并删除了一堆我不需要的东西,并且将其更改为更具动态性,并使用'uname -r'计算不同的路径。 问题在于原始Makefile假定bfp_helpers.h与文件位于同一目录中。但是我的xdp1_kern.c使用它,因此无法在同一目录中使用它。我添加了-I(bpf_helpers.h的路径),但是在运行它时仍会引发错误。

 make LLC=<path to llc> CLANG=<path to clang>
gcc -g -O2 -Wall /usr/include/linux/bpf.h -I/usr/src/kernels/4.18.0-mlnx/tools/lib -I/usr/src/kernels/4.18.0-mlnx/tools/testing/selftests/bpf bpf_load.o -lelf -o xdp1 xdp1_user.c  /usr/src/kernels/4.18.0-mlnx/tools/lib/bpf/libbpf.a
/.autodirect/net_linux_verification/tools/clang+llvm-3.8.0-linux-x86_64-centos6/bin/clang -S -nostdinc -isystem /usr/lib/gcc/x86_64-redhat-linux/7/include -I/usr/src/kernels/4.18.0-mlnx/include -I/usr/src/kernels/4.18.0-mlnx/arch/x86/include -I/usr/src/kernels/4.18.0-mlnx/arch/x86/include/generated/uapi -I/usr/src/kernels/4.18.0-mlnx/arch/x86/include/generated -I/usr/src/kernels/4.18.0-mlnx/include -I/usr/src/kernels/4.18.0-mlnx/arch/x86/include/uapi -I/usr/src/kernels/4.18.0-mlnx/include/uapi -I/usr/src/kernels/4.18.0-mlnx/include/generated/uapi -include /usr/src/kernels/4.18.0-mlnx/include/linux/kconfig.h -Werror \
    -D__KERNEL__ -D__ASM_SYSREG_H \
    -D__BPF_TRACING__ \
    -Wall \
    -Wno-unused-value -Wno-pointer-sign \
    -D__TARGET_ARCH_ \
    -Wno-compare-distinct-pointer-types \
    -Wno-gnu-variable-sized-type-not-at-end \
    -Wno-tautological-compare \
    -Wno-unknown-warning-option \
    -Wno-address-of-packed-member \
    -O2 -emit-llvm -c xdp1_kern.c -o xdp1_kern.ll
xdp1_kern.c:15:10: fatal error: 'bpf_helpers.h' file not found
#include "bpf_helpers.h"
         ^
1 error generated.
make: *** [Makefile:93: xdp1_kern.o] Error 1

我确定添加-I / usr / src / kernels / 4.18.0-mlnx / tools / testing / selftests / bpf可以解决此问题,因为这是我的机器上bpf_helpers.h所在的位置。但事实并非如此,它只是解决了bpf_utils.h的包含。

1 个答案:

答案 0 :(得分:0)

在尝试编译BPF程序时,请勿使用修改后的CFLAGS

您在编译用户空间程序时确实使用了CFLAGS

# Most xxx_user program still depend on old bpf_load.c
$(OBJECT_LOADBPF): bpf_load.c bpf_load.h
    $(CC) $(CFLAGS) -o $@ -c $<

$(TARGETS): %: xdp1_user.c $(OBJECTS) $(LIBBPF) Makefile
    $(CC) $(CFLAGS) $(OBJECTS) $(LDFLAGS) -o $@ $<  $(LIBBPF)

后者提供了您的前两行输出,您的搜索目录确实出现在其中:

 make LLC=<path to llc> CLANG=<path to clang>
gcc -g -O2 -Wall [...] -I/usr/src/kernels/4.18.0-mlnx/tools/testing/selftests/bpf [...]

但是,从下一行开始,这是一条不同的命令,调用clang来编译BPF程序。它来自该Makefile代码:

$(KERN_OBJECTS): %.o: %.c Makefile
    $(CLANG) -S $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(EXTRA_CFLAGS) \
        [...]

...不使用$(CFLAGS)。只需将其添加到Makefile中的clang命令中,即可解决您的问题。