DPDK — 扩展私有函数库

目录

DPDK 扩展第三方函数库

在开发 DPDK App 的时候难免会需要在 DPDK 中扩展自己的库或者直接引入第三方函数库。

  • 本文版本:DPDK 18.08
  • 官方参考网页:https://dpdk-docs.readthedocs.io/en/latest/prog_guide/extend_dpdk.html

扩展一个新的 libfoo 库

添加扩展库的启用配置

for f in config/\*; do \
    echo CONFIG_RTE_LIBFOO=y >> $f; done

上述脚本的作用是为所有的 目标环境(Target Env) 中添加扩展库的配置项,表示编译该扩展库。

$ ll  ${RTE_SDK}/config/

以最常见的 x86_64-native-linuxapp-gcc 为例,文件为 ${RTE_SDK}/config/defconfig_x86_64-native-linuxapp-gcc:

#include "common_linuxapp"

CONFIG_RTE_MACHINE="native"

CONFIG_RTE_ARCH="x86_64"
CONFIG_RTE_ARCH_X86_64=y
CONFIG_RTE_ARCH_X86=y
CONFIG_RTE_ARCH_64=y

CONFIG_RTE_TOOLCHAIN="gcc"
CONFIG_RTE_TOOLCHAIN_GCC=y

# Extended libfoo library.
CONFIG_RTE_LIBFOO=y

实现扩展库

创建源码目录:

$ mkdir ${RTE_SDK}/lib/libfoo
$ touch ${RTE_SDK}/lib/libfoo/foo.c
$ touch ${RTE_SDK}/lib/libfoo/foo.h

我们要扩展的是 DPDK 库,所以库目录自然也创建在 ${RTE_SDK}/lib 路径下。

源文件 foo.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "foo.h"


void foo(void)
{
    printf("libfoo test appliation.\n");
    fprintf(stdout, "%s %d\n", __func__, __LINE__);
}·

头文件 foo.h:

#ifndef _RTE_FOO_H_
#define _RTE_FOO_H_

extern void foo(void);

#endif

添加扩展库的 Makefile

首先我们需要添加扩展库的 Makefile,可以从 mempool Makefile 获取模板:

$ cp ${RTE_SDK}/lib/librte_mempool/Makefile ${RTE_SDK}/lib/libfoo/

替换 ${RTE_SDK}/lib/libfoo/Makefile 的内容:

  • 静态库文件:librte_mempool.a -> libfoo.a
  • 原文件名:rte_mempool.c -> foo.c
  • 头文件:rte_mempool.h -> foo.h
  • 中间编译的符号映射文件:rte_mempool_version.map -> foo_version.map
  • 扩展库配置项名称:CONFIG_RTE_LIBRTE_MEMPOOL -> CONFIG_RTE_LIBFOO
include $(RTE_SDK)/mk/rte.vars.mk

# library name
LIB = libfoo.a

CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
CFLAGS += -DALLOW_EXPERIMENTAL_API
LDLIBS += -lrte_eal -lrte_ring

EXPORT_MAP := foo_version.map

LIBABIVER := 5

# memseg walk is not yet part of stable API
CFLAGS += -DALLOW_EXPERIMENTAL_API

# all source are stored in SRCS-y
SRCS-$(CONFIG_RTE_LIBFOO) += foo.c

# install includes
SYMLINK-$(CONFIG_RTE_LIBFOO)-include := foo.h

include $(RTE_SDK)/mk/rte.lib.mk

然后,更新总库的 Makefile:${RTE_SDK}/lib/Makefile

...
DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool
DIRS-$(CONFIG_RTE_LIBFOO) += libfoo

最后,还需要更新 ${RTE_SDK}/mk/rte.app.mk 文件,添加 -lfoo 选项到 LDLIBS 变量中:

...
_LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
_LDLIBS-$(CONFIG_RTE_LIBFOO)                += -lfoo

如此的,在编译 DPDK 的时候就会连带的编译 libfoo 扩展库了。

重新编译安装 DPDK 的目标环境

rm -rf ${RTE_SDK}/x86_64-native-linuxapp-gcc
cd ${RTE_SDK}
make config T=x86_64-native-linuxapp-gcc
make
make install T=x86_64-native-linuxapp-gcc

如果扩展库 libfoo 安装成功,DPDK 会自动创建 foo.h 的链接文件和创建 libfoo.a 静态链接库文件:

$ ll ${RTE_SDK}/x86_64-native-linuxapp-gcc/include/ | grep foo
lrwxrwxrwx 1 root root    22 6月  19 00:03 foo.h -> ../../lib/libfoo/foo.h

$ ll ${RTE_SDK}/x86_64-native-linuxapp-gcc/lib/ | grep foo
-rw-r--r-- 1 root root   1964 6月  19 00:03 libfoo.a

在自己的 DPDK App 中使用扩展库

创建 DPDK App 项目:

$ ~/workspace/myapp/

源文件 main.c:

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <sys/queue.h>

#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_launch.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_debug.h>

#include <foo.h>


int main(void)
{
    foo();
    return 0;
}

获取 App 的 Makefile 模板:

$ cp ${RTE_SDK}/examples/helloworld/Makefile  ~/workspace/myapp/Makefile

替换成:

# binary name
APP = myapp

# all source are stored in SRCS-y
SRCS-y := main.c

# Build using pkg-config variables if possible
$(shell pkg-config --exists libdpdk)
ifeq ($(.SHELLSTATUS),0)

all: shared
.PHONY: shared static
shared: build/$(APP)-shared
    ln -sf $(APP)-shared build/$(APP)
static: build/$(APP)-static
    ln -sf $(APP)-static build/$(APP)

PC_FILE := $(shell pkg-config --path libdpdk)
CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)

build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
    $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)

build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
    $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)

build:
    @mkdir -p $@

.PHONY: clean
clean:
    rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
    rmdir --ignore-fail-on-non-empty build

else

ifeq ($(RTE_SDK),)
$(error "Please define RTE_SDK environment variable")
endif

# Default target, can be overridden by command line or environment
RTE_TARGET ?= x86_64-native-linuxapp-gcc

include $(RTE_SDK)/mk/rte.vars.mk

CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)

include $(RTE_SDK)/mk/rte.extapp.mk

endif

编译 App:

$ make -C ~/workspace/myapp/
make: 进入目录“/root/workspace/myapp”
  CC main.o
  LD myapp
  INSTALL-APP myapp
  INSTALL-MAP myapp.map

$ # ll ~/workspace/myapp/
总用量 8
drwxr-xr-x 3 root root  188 6月  19 00:13 build
-rw-r--r-- 1 root root  355 6月  19 00:13 main.c
-rw-r--r-- 1 root root 1381 6月  19 00:11 Makefile

$ ll ~/workspace/myapp/build/
总用量 10680
drwxr-xr-x 2 root root      36 6月  19 00:13 app
-rw-r--r-- 1 root root       0 6月  19 00:13 _install
-rw-r--r-- 1 root root    1448 6月  19 00:13 main.o
-rwxr-xr-x 1 root root 7174064 6月  19 00:13 myapp
-rw-r--r-- 1 root root 3754908 6月  19 00:13 myapp.map
-rw-r--r-- 1 root root       0 6月  19 00:13 _postbuild
-rw-r--r-- 1 root root       0 6月  19 00:13 _postinstall
-rw-r--r-- 1 root root       0 6月  19 00:13 _preinstall

执行:

$ ./myapp/build/myapp
libfoo test appliation.
foo 11

猜你喜欢

转载自blog.csdn.net/Jmilk/article/details/106798358