IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 【DPDK】dpdk-l3fwd测试用例单独编译 -> 正文阅读

[开发测试]【DPDK】dpdk-l3fwd测试用例单独编译

DPDK-20.11.3版本使用mesonninja进行编译安装,过程可参考之前的一篇DPDK-20.11.3在CentOS8.4上编译运行文章,按照这个步骤,编译安装完成之后,可以发现build/appbuild/example目录下已经生成了测试用例可执行程序。

这时就可以根据各个用例启动命令去进行启动执行了。

但是,如果想要在测试用例中加些打印信息该怎么办呢?下面就简单介绍一下,如何对dpdk测试用例进行单独编译

提前说明:

1、DPDK版本号为20.11.3,操作系统为CentOS 8.4

2、由于mesonninja工具不熟悉,因此测试用例还是通过Makefile进行编译;

3、DPDK的测试用例有很多,不能一一列举,因此使用l3fwd用例进行说明;

4、测试用例下已经存在可以直接编译的Makefile文件,但是编译依赖DPDK的安装环境,而下面需要做到的就是不依赖DPDK安装环境,也能进行编译。(即将编译所需静态库、动态库、头文件、*.c文件放入到一个文件下,这样即使将改文件移动到其它未安装过DPDK的操作系统中也可以编译执行,实际应用过程中也正是这样,即只是将项目工程中依赖的静态库和头文件放到指定路径下,既可以调用相关API使用)。

简要步骤:

1、创建工程目录dpdk-l3fwd,将所需静态库、动态库、头文件、*.c文件复制到该文件;

2、修改Makefile文件,主要设置编译所需环境变量和链接库路径;

3、编译(静态编译和动态编译);

4、总结。

1、创建工程

1.1、创建dpdk-l3fwd目录

如下创建dpdk-l3fw工程目录及子目录和相关文件。

[root@LFTF dpdk-l3fwd]# ll
total 36
drwxr-xr-x. 2 root root   128 Dec 29 13:15 app
drwxr-xr-x. 2 root root     6 Dec 29 10:39 include
drwxr-xr-x. 2 root root     6 Dec 29 10:39 lib
-rw-r--r--. 1 root root     0 Dec 29 13:23 Makefile
drwxr-xr-x. 2 root root     6 Dec 29 13:23 pkgconfig

其中

app为代码子目录,用来存放除了main.c其他.c文件;

include为头文件目录,用来存放dpdk相关头文件和app目录下.c依赖的头文件;

lib为库文件目录,用来存放dpdk源代买编译出的静态库文件;

Makefileexample例子中自带的Makefile文件,但需要修改一点内容;

pkgconfig文件里有两个.pc文件,用来维护链接dpdk静态库和动态库的路径;(后面详细说明);

1.2、源文件和库文件

1.2.1、复制静态/动态库和相关头文件

DPDK-20.11.3在编译安装完成后,会生成相关静态库、动态库文件到Linux系统目录/usr/local/lib64/下,可以使用以下ll命令查看,其中dpdk相关头文件usr/local/include路径下:

查看静态库文件

[root@LFTF ~]# ll /usr/local/lib64/*rte*.a
-rw-r--r--. 1 root root  170924 Dec 25 11:53 /usr/local/lib64/librte_acl.a
-rw-r--r--. 1 root root   76982 Dec 25 11:55 /usr/local/lib64/librte_baseband_acc100.a
...
#截取部分

查看动态库文件

[root@localhost ~]# ll /usr/local/lib64/*rte*.so
lrwxrwxrwx. 1 root root 16 Dec 25 11:57 /usr/local/lib64/librte_acl.so -> librte_acl.so.21
lrwxrwxrwx. 1 root root 40 Dec 25 11:57 /usr/local/lib64/librte_baseband_acc100.so -> dpdk/pmds-21.0/librte_baseband_acc100.so
lrwxrwxrwx. 1 root root 47 Dec 25 11:57 /usr/local/lib64/librte_baseband_fpga_5gnr_fec.so -> dpdk/pmds-21.0/librte_baseband_fpga_5gnr_fec.so
lrwxrwxrwx. 1 root root 46 Dec 25 11:57 /usr/local/lib64/librte_baseband_fpga_lte_fec.so -> dpdk/pmds-21.0/librte_baseband_fpga_lte_fec.so
...
#截取部分

查看DPDK相关头文件

[root@localhost ~]# ll /usr/local/include/rte*.h
-rw-r--r--. 1 root root   3350 Sep  6 18:28 /usr/local/include/rte_acc100_cfg.h
-rw-r--r--. 1 root root  11081 Sep  6 18:28 /usr/local/include/rte_acl.h
-rw-r--r--. 1 root root    883 Sep  6 18:28 /usr/local/include/rte_acl_osdep.h
-rw-r--r--. 1 root root   2305 Sep  6 18:28 /usr/local/include/rte_alarm.h
-rw-r--r--. 1 root root   1684 Sep  6 18:28 /usr/local/include/rte_approx.h
-rw-r--r--. 1 root root   1914 Sep  6 18:28 /usr/local/include/rte_arp.h
-rw-r--r--. 1 root root   4454 Sep  6 18:28 /usr/local/include/rte_atomic_32.h
-rw-r--r--. 1 root root   4186 Sep  6 18:28 /usr/local/include/rte_atomic_64.h
-rw-r--r--. 1 root root   6598 Sep  6 18:28 /usr/local/include/rte_atomic.h
...
#截取部分

dpdk-l3fwd/lib目录下创建一个dpdk文件,将/usr/local/lib64/路径下关于dpdk的静态库和动态库复制过去

[root@LFTF lib]# mkdir dpdk
[root@LFTF lib]# 
[root@LFTF lib]# ll
total 0
drwxr-xr-x. 2 root root 6 Dec 29 13:47 dpdk

复制静态库

[root@LFTF lib]# cp /usr/local/lib64/*rte*.a /home/dpdk-l3fwd/lib/dpdk/
[root@LFTF lib]# 

复制动态库

[root@localhost ~]# cp /mnt/hgfs/code/dpdk/dpdk-l3fwd/lib/dpdk/*.so* /home/dpdk-l3fwd/lib/dpdk
[root@localhost ~]# 

如果只需要静态库或者需要动态库,按需操作。

dpdk-l3fwd/include目录下创建一个dpdk文件,将/usr/local/include/路径下关于dpdk的头文件复制过去

[root@LFTF include]# pwd
/home/dpdk-l3fwd/include
[root@LFTF include]# 
[root@LFTF include]# mkdir dpdk
[root@LFTF include]# ll
total 0
drwxr-xr-x. 2 root root 6 Dec 29 17:24 dpdk

复制头文件

[root@localhost ~]# cp /usr/local/include/rte*.h /home/dpdk-l3fwd/include/dpdk/
[root@localhost ~]# cp -rf /usr/local/include/generic/ /home/dpdk-l3fwd/include/dpdk/
[root@localhost ~]# 

1.2.2、复制pkgconfig文件

pkg-config原理和用法可自行搜索,也可参考pkg-config原理及用法

这里只说明dpdk相关的.pc文件存放路径为/usr/local/lib64/pkgconfi

[root@localhost ~]# ll /usr/local/lib64/pkgconfig/
total 8
-rw-r--r--. 1 root root 1055 Dec 25 11:52 libdpdk-libs.pc
-rw-r--r--. 1 root root 4082 Dec 25 11:52 libdpdk.pc

将该目录下的两个文件复制到dpdk-l3fwd/pkgconfig

[root@localhost ~]# cp -r /usr/local/lib64/pkgconfig/ /home/dpdk-l3fwd/pkgconfig/
[root@localhost ~]# 

后面执行Makefile的时候就依赖这个路径下的.pc内容,所以需要更改.pc路径

libdpdk.pc更改前:

prefix=/usr/local
libdir=${prefix}/lib64
includedir=${prefix}/include

Name: DPDK
Description: The Data Plane Development Kit (DPDK).
Note that CFLAGS might contain an -march flag higher than typical baseline.
This is required for a number of static inline functions in the public headers.
Version: 20.11.3
Requires: libdpdk-libs
...

libdpdk.pc更改后:

prefix=/home/dpdk-l3fwd/pkgconfig
libdir=${prefix}/lib
includedir=${prefix}/include

Name: DPDK
Description: The Data Plane Development Kit (DPDK).
Note that CFLAGS might contain an -march flag higher than typical baseline.
This is required for a number of static inline functions in the public headers.
Version: 20.11.3
Requires: libdpdk-libs
...

libdpdk-libs.pc更改前:

prefix=/usr/local
libdir=${prefix}/lib64
includedir=${prefix}/include

Name: dpdk-libs
Description: Internal-only DPDK pkgconfig file. Not for direct use.
Use libdpdk.pc instead of this file to query DPDK compile/link arguments
Version: 20.11.3
Libs: -Wl,--as-needed -L${libdir} -lrte_node -lrte_graph -lrte_bpf -lrte_flow_classify -lrte_pipeline -lrte_table -lrte_port -lrte_fib -lrte_ipsec -lrte_vhost -lrte_stack -lrte_security -lrte_sched -lrte_reorder -lrte_rib -lrte_regexdev -lrte_rawdev -lrte_pdump -lrte_power -lrte_member -lrte_lpm -lrte_latencystats -lrte_kni -lrte_jobstats -lrte_ip_frag -lrte_gso -lrte_gro -lrte_eventdev -lrte_efd
...

libdpdk-libs.pc更改后:

prefix=/home/dpdk-l3fwd/pkgconfig
libdir=${prefix}/lib
includedir=${prefix}/include

Name: dpdk-libs
Description: Internal-only DPDK pkgconfig file. Not for direct use.
Use libdpdk.pc instead of this file to query DPDK compile/link arguments
Version: 20.11.3
Libs: -Wl,--as-needed -L${libdir} -lrte_node -lrte_graph -lrte_bpf -lrte_flow_classify -lrte_pipeline -lrte_table -lrte_port -lrte_fib -lrte_ipsec -lrte_vhost -lrte_stack -lrte_security -lrte_sched -lrte_reorder -lrte_rib -lrte_regexdev -lrte_rawdev -lrte_pdump -lrte_power -lrte_member -lrte_lpm -lrte_latencystats -lrte_kni -lrte_jobstats -lrte_ip_frag -lrte_gso -lrte_gro -lrte_eventdev -lrte_efd
...

简言之之前依赖dpdk安装到系统目录下的动态库和静态库路径,现在要依赖当前工程下的静态库和动态库路径。

1.2.3、复制l3fwd源代码

dpdk-20.11.3源代码example/l3fwd路径下的源码复制到指定路径下。

[root@localhost l3fwd]# pwd
/home/dpdk-stable-20.11.3/examples/l3fwd
[root@localhost l3fwd]# ll
total 220
-rw-rw-r--. 1 root root  6601 Sep  6 18:28 l3fwd_altivec.h
-rw-rw-r--. 1 root root  6129 Sep  6 18:28 l3fwd_common.h
-rw-rw-r--. 1 root root 24787 Sep  6 18:28 l3fwd_em.c
-rw-rw-r--. 1 root root  4830 Sep  6 18:28 l3fwd_em.h
-rw-rw-r--. 1 root root  8524 Sep  6 18:28 l3fwd_em_hlm.h
-rw-rw-r--. 1 root root  1275 Sep  6 18:28 l3fwd_em_hlm_neon.h
-rw-rw-r--. 1 root root  1336 Sep  6 18:28 l3fwd_em_hlm_sse.h
-rw-rw-r--. 1 root root  3077 Sep  6 18:28 l3fwd_em_sequential.h
-rw-rw-r--. 1 root root  7305 Sep  6 18:28 l3fwd_event.c
-rw-rw-r--. 1 root root  9983 Sep  6 18:28 l3fwd_event_generic.c
-rw-rw-r--. 1 root root  2246 Sep  6 18:28 l3fwd_event.h
-rw-rw-r--. 1 root root  8851 Sep  6 18:28 l3fwd_event_internal_port.c
-rw-rw-r--. 1 root root  5798 Sep  6 18:28 l3fwd.h
-rw-rw-r--. 1 root root  3823 Sep  6 18:28 l3fwd_lpm_altivec.h
-rw-rw-r--. 1 root root 16472 Sep  6 18:28 l3fwd_lpm.c
-rw-rw-r--. 1 root root  2718 Sep  6 18:28 l3fwd_lpm.h
-rw-rw-r--. 1 root root  4226 Sep  6 18:28 l3fwd_lpm_neon.h
-rw-rw-r--. 1 root root  3410 Sep  6 18:28 l3fwd_lpm_sse.h
-rw-rw-r--. 1 root root  5886 Sep  6 18:28 l3fwd_neon.h
-rw-rw-r--. 1 root root  5726 Sep  6 18:28 l3fwd_sse.h
-rw-rw-r--. 1 root root 34192 Sep  6 18:28 main.c
-rw-rw-r--. 1 root root  1278 Dec 29 10:07 Makefile
-rw-rw-r--. 1 root root   457 Sep  6 18:28 meson.build

其中

l3fw**.c文件复制到app目录下;

main.c文件复制到dpdk-l3fwd目录下;

l3fwd**.h文件复制到include目录下;

Makefile文件复制到dpdk-l3fwd目录下;

如下所示:

[root@LFTF dpdk-l3fwd]# ls
app  include  lib  main.c  Makefile  pkgconfig
[root@LFTF dpdk-l3fwd]# ll *
-rw-r--r--. 1 root root 34192 Dec 29 13:16 main.c
-rw-r--r--. 1 root root     0 Dec 29 13:23 Makefile

app:
total 80
-rw-r--r--. 1 root root 24787 Dec 29 13:15 l3fwd_em.c
-rw-r--r--. 1 root root  7305 Dec 29 13:15 l3fwd_event.c
-rw-r--r--. 1 root root  9983 Dec 29 13:15 l3fwd_event_generic.c
-rw-r--r--. 1 root root  8851 Dec 29 13:15 l3fwd_event_internal_port.c
-rw-r--r--. 1 root root 16472 Dec 29 13:15 l3fwd_lpm.c

include:
total 112
drwxr-xr-x. 3 root root 12288 Dec 29 17:27 dpdk
-rw-r--r--. 1 root root  6601 Dec 29 17:31 l3fwd_altivec.h
-rw-r--r--. 1 root root  6129 Dec 29 17:31 l3fwd_common.h
-rw-r--r--. 1 root root  4830 Dec 29 17:31 l3fwd_em.h
-rw-r--r--. 1 root root  8524 Dec 29 17:31 l3fwd_em_hlm.h
-rw-r--r--. 1 root root  1275 Dec 29 17:31 l3fwd_em_hlm_neon.h
-rw-r--r--. 1 root root  1336 Dec 29 17:31 l3fwd_em_hlm_sse.h
-rw-r--r--. 1 root root  3077 Dec 29 17:31 l3fwd_em_sequential.h
-rw-r--r--. 1 root root  2246 Dec 29 17:31 l3fwd_event.h
-rw-r--r--. 1 root root  5798 Dec 29 17:31 l3fwd.h
-rw-r--r--. 1 root root  3823 Dec 29 17:31 l3fwd_lpm_altivec.h
-rw-r--r--. 1 root root  2718 Dec 29 17:31 l3fwd_lpm.h
-rw-r--r--. 1 root root  4226 Dec 29 17:31 l3fwd_lpm_neon.h
-rw-r--r--. 1 root root  3410 Dec 29 17:31 l3fwd_lpm_sse.h
-rw-r--r--. 1 root root  5886 Dec 29 17:31 l3fwd_neon.h
-rw-r--r--. 1 root root  5726 Dec 29 17:31 l3fwd_sse.h

lib:
total 16
drwxr-xr-x. 2 root root 12288 Dec 29 13:48 dpdk

pkgconfig:
total 0
[root@LFTF dpdk-l3fwd]# 

2、Makefile

2.1、Makefile更改前注释说明

[root@LFTF dpdk-l3fwd]# cat Makefile
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2010-2016 Intel Corporation

# binary name #编译出的程序名
APP = l3fwd

# all source are stored in SRCS-y	# 源代码,需要编译的.c文件有哪些
SRCS-y := main.c l3fwd_lpm.c l3fwd_em.c l3fwd_event.c
SRCS-y += l3fwd_event_generic.c l3fwd_event_internal_port.c

#pkg-config  用于使用.pc文件指定要链接静态库或者动态库路径
PKGCONF ?= pkg-config

# Build using pkg-config variables if possible  #查看是否能使用pkg-config构建
ifneq ($(shell $(PKGCONF) --exists libdpdk && echo 0),0)
$(error "no installation of DPDK found")
endif

#静态编译 or 动态编译
all: static
.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 $(PKGCONF) --path libdpdk 2>/dev/null)
# 获取头文件路径
CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk)
# Added for 'rte_eth_link_to_str()'
CFLAGS += -DALLOW_EXPERIMENTAL_API
# 获取静态库文件路径
LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk)
# 获取动态库文件路径
LDFLAGS_STATIC = $(shell $(PKGCONF) --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
	test -d build && rmdir -p build || true

2.2、Makefile更改后注释说明

# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2010-2016 Intel Corporation

# 获取环境变量
PKG_DIR = pkgconfig
PKG_ENV = PKG_CONFIG_PATH=$(ROOT_DIR)/$(PKG_DIR)

# 需要加载编译文件后缀
PS = c

# binary name #程序名
APP = l3fwd

# all source are stored in SRCS-y #源代码,遍历主目录和子目录下所有的.c文件(通配符)
SRCS-y := $(wildcard $(ROOT_DIR)/*.$(PS) $(addsuffix /*.$(PS), $(ROOT_DIR)/$(SUB_DIR)))
OBJS-y = $(foreach x,.c,$(patsubst %$(x),%.o,$(filter %$(x),$(SRCS-y))))

# 打印需要链接的.o文件和环境变量
$(info OBJS1:${OBJS-y})
$(info PKG:$(PKG_ENV))

PKGCONF ?= pkg-config

# Build using pkg-config variables if possible #查看是否能使用pkg-config构建
ifneq ($(shell $(PKG_ENV) $(PKGCONF) --exists libdpdk && echo 0),0)
$(error "no installation of DPDK found")
endif

# 静态编译 or 动态编译
all: static
.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_ENV) $(PKGCONF) --path libdpdk 2>/dev/null)
# 忽略警告
CFLAGS+=-W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wno-unused-function -Wno-implicit-fallthrough
# 头文件路径
CFLAGS += -O3 $(shell $(PKG_ENV) $(PKGCONF) --cflags libdpdk) -I${ROOT_DIR}/include -I${ROOT_DIR}/include/dpdk -I${ROOT_DIR}/app -std=gnu99 -fPIC -DPIC -DUSE_DPDK
# 动态库路径  最后面是系统动态库,如果不依赖也可以不加
LDFLAGS_SHARED = $(shell $(PKG_ENV) $(PKGCONF) --libs libdpdk) -lssl -lcrypto -lz -ldl -lpthread -lrt -lstdc++ -lnuma -lm -lpcap
# 静态库路径  最后面是系统动态库,如果不依赖也可以不加
LDFLAGS_STATIC = $(shell $(PKG_ENV) $(PKGCONF) --static --libs libdpdk) -lssl -lcrypto -lz -ldl -lpthread -lrt -lstdc++ -lnuma -lm -lpcap

CFLAGS += -DALLOW_EXPERIMENTAL_API

%.o: %.c  
	$(CC) -c $(CFLAGS) -o $@ $<  

# 动态编译
build/$(APP)-shared: $(OBJS-y) Makefile $(PC_FILE) | build
	$(CC) $(CFLAGS) $(OBJS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) 

# 静态编译
build/$(APP)-static: $(OBJS-y) Makefile $(PC_FILE) | build
	$(CC) $(CFLAGS) $(OBJS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)

build:
	@mkdir -p $@

.PHONY: clean
clean:
	rm -f $(OBJS-y)
	rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
	test -d build && rmdir -p build || true

2.3、前后对比

修改的地方有3点:

1、需要编译的.c文件有工程路径和通配符来获取,更加灵活方便;

2、pkg-config执行时的环境变量为当前工程所在路径,这样链接静态库和动态库的时候依赖当前工程下的pkgconfig下的.pc文件;

3、之前的Makefile未生成.o中间文件,也添加上去了。

3、编译

通过修改Makefile里的语句可以控制去链接静态库还是链接动态库

3.1、静态编译

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

编译过程

[root@localhost dpdk-l3fwd]# make
OBJS1:/home/dpdk-l3fwd/main.o /home/dpdk-l3fwd/app/l3fwd_lpm.o /home/dpdk-l3fwd/app/l3fwd_em.o /home/dpdk-l3fwd/app/l3fwd_event_internal_port.o /home/dpdk-l3fwd/app/l3fwd_event.o /home/dpdk-l3fwd/app/l3fwd_event_generic.o
PKG:PKG_CONFIG_PATH=/home/dpdk-l3fwd/pkgconfig
cc -c -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wno-unused-function -Wno-implicit-fallthrough -O3 -I/home/dpdk-l3fwd/pkgconfig/include -include rte_config.h -march=native -I/usr/usr/include  -I/home/dpdk-l3fwd/include -I/home/dpdk-l3fwd/include/dpdk -I/home/dpdk-l3fwd/app -std=gnu99 -fPIC -DPIC -DUSE_DPDK -DALLOW_EXPERIMENTAL_API -o /home/dpdk-l3fwd/main.o /home/dpdk-l3fwd/main.c  
cc -c -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wno-unused-function -Wno-implicit-fallthrough -O3 -I/home/dpdk-l3fwd/pkgconfig/include -include rte_config.h -march=native -I/usr/usr/include  -I/home/dpdk-l3fwd/include -I/home/dpdk-l3fwd/include/dpdk -I/home/dpdk-l3fwd/app -std=gnu99 -fPIC -DPIC -DUSE_DPDK -DALLOW_EXPERIMENTAL_API -o /home/dpdk-l3fwd/app/l3fwd_lpm.o /home/dpdk-l3fwd/app/l3fwd_lpm.c  
cc -c -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wno-unused-function -Wno-implicit-fallthrough -O3 -I/home/dpdk-l3fwd/pkgconfig/include -include rte_config.h -march=native -I/usr/usr/include  -I/home/dpdk-l3fwd/include -I/home/dpdk-l3fwd/include/dpdk -I/home/dpdk-l3fwd/app -std=gnu99 -fPIC -DPIC -DUSE_DPDK -DALLOW_EXPERIMENTAL_API -o /home/dpdk-l3fwd/app/l3fwd_em.o /home/dpdk-l3fwd/app/l3fwd_em.c  
cc -c -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wno-unused-function -Wno-implicit-fallthrough -O3 -I/home/dpdk-l3fwd/pkgconfig/include -include rte_config.h -march=native -I/usr/usr/include  -I/home/dpdk-l3fwd/include -I/home/dpdk-l3fwd/include/dpdk -I/home/dpdk-l3fwd/app -std=gnu99 -fPIC -DPIC -DUSE_DPDK -DALLOW_EXPERIMENTAL_API -o /home/dpdk-l3fwd/app/l3fwd_event_internal_port.o /home/dpdk-l3fwd/app/l3fwd_event_internal_port.c  
cc -c -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wno-unused-function -Wno-implicit-fallthrough -O3 -I/home/dpdk-l3fwd/pkgconfig/include -include rte_config.h -march=native -I/usr/usr/include  -I/home/dpdk-l3fwd/include -I/home/dpdk-l3fwd/include/dpdk -I/home/dpdk-l3fwd/app -std=gnu99 -fPIC -DPIC -DUSE_DPDK -DALLOW_EXPERIMENTAL_API -o /home/dpdk-l3fwd/app/l3fwd_event.o /home/dpdk-l3fwd/app/l3fwd_event.c  
cc -c -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wno-unused-function -Wno-implicit-fallthrough -O3 -I/home/dpdk-l3fwd/pkgconfig/include -include rte_config.h -march=native -I/usr/usr/include  -I/home/dpdk-l3fwd/include -I/home/dpdk-l3fwd/include/dpdk -I/home/dpdk-l3fwd/app -std=gnu99 -fPIC -DPIC -DUSE_DPDK -DALLOW_EXPERIMENTAL_API -o /home/dpdk-l3fwd/app/l3fwd_event_generic.o /home/dpdk-l3fwd/app/l3fwd_event_generic.c  
cc -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wno-unused-function -Wno-implicit-fallthrough -O3 -I/home/dpdk-l3fwd/pkgconfig/include -include rte_config.h -march=native -I/usr/usr/include  -I/home/dpdk-l3fwd/include -I/home/dpdk-l3fwd/include/dpdk -I/home/dpdk-l3fwd/app -std=gnu99 -fPIC -DPIC -DUSE_DPDK -DALLOW_EXPERIMENTAL_API /home/dpdk-l3fwd/main.o /home/dpdk-l3fwd/app/l3fwd_lpm.o /home/dpdk-l3fwd/app/l3fwd_em.o /home/dpdk-l3fwd/app/l3fwd_event_internal_port.o /home/dpdk-l3fwd/app/l3fwd_event.o /home/dpdk-l3fwd/app/l3fwd_event_generic.o -o build/l3fwd-static  -Wl,--whole-archive -L/home/dpdk-l3fwd/pkgconfig/lib -l:librte_common_cpt.a -l:librte_common_dpaax.a -l:librte_common_iavf.a -l:librte_common_octeontx.a -l:librte_common_octeontx2.a -l:librte_common_sfc_efx.a -l:librte_bus_dpaa.a -l:librte_bus_fslmc.a -l:librte_bus_ifpga.a -l:librte_bus_pci.a -l:librte_bus_vdev.a -l:librte_bus_vmbus.a -l:librte_common_mlx5.a -l:librte_common_qat.a -l:librte_mempool_bucket.a -l:librte_mempool_dpaa.a -l:librte_mempool_dpaa2.a -l:librte_mempool_octeontx.a -l:librte_mempool_octeontx2.a -l:librte_mempool_ring.a -l:librte_mempool_stack.a -l:librte_net_af_packet.a -l:librte_net_ark.a -l:librte_net_atlantic.a -l:librte_net_avp.a -l:librte_net_axgbe.a -l:librte_net_bond.a -l:librte_net_bnx2x.a -l:librte_net_bnxt.a -l:librte_net_cxgbe.a -l:librte_net_dpaa.a -l:librte_net_dpaa2.a -l:librte_net_e1000.a -l:librte_net_ena.a -l:librte_net_enetc.a -l:librte_net_enic.a -l:librte_net_failsafe.a -l:librte_net_fm10k.a -l:librte_net_i40e.a -l:librte_net_hinic.a -l:librte_net_hns3.a -l:librte_net_iavf.a -l:librte_net_ice.a -l:librte_net_igc.a -l:librte_net_ixgbe.a -l:librte_net_kni.a -l:librte_net_liquidio.a -l:librte_net_memif.a -l:librte_net_mlx4.a -l:librte_net_mlx5.a -l:librte_net_netvsc.a -l:librte_net_nfp.a -l:librte_net_null.a -l:librte_net_octeontx.a -l:librte_net_octeontx2.a -l:librte_net_pcap.a -l:librte_net_pfe.a -l:librte_net_qede.a -l:librte_net_ring.a -l:librte_net_sfc.a -l:librte_net_softnic.a -l:librte_net_tap.a -l:librte_net_thunderx.a -l:librte_net_txgbe.a -l:librte_net_vdev_netvsc.a -l:librte_net_vhost.a -l:librte_net_virtio.a -l:librte_net_vmxnet3.a -l:librte_raw_dpaa2_cmdif.a -l:librte_raw_dpaa2_qdma.a -l:librte_raw_ioat.a -l:librte_raw_ntb.a -l:librte_raw_octeontx2_dma.a -l:librte_raw_octeontx2_ep.a -l:librte_raw_skeleton.a -l:librte_crypto_bcmfs.a -l:librte_crypto_caam_jr.a -l:librte_crypto_ccp.a -l:librte_crypto_dpaa_sec.a -l:librte_crypto_dpaa2_sec.a -l:librte_crypto_nitrox.a -l:librte_crypto_null.a -l:librte_crypto_octeontx.a -l:librte_crypto_octeontx2.a -l:librte_crypto_openssl.a -l:librte_crypto_scheduler.a -l:librte_crypto_virtio.a -l:librte_compress_octeontx.a -l:librte_compress_zlib.a -l:librte_regex_mlx5.a -l:librte_regex_octeontx2.a -l:librte_vdpa_ifc.a -l:librte_vdpa_mlx5.a -l:librte_event_dlb.a -l:librte_event_dlb2.a -l:librte_event_dpaa.a -l:librte_event_dpaa2.a -l:librte_event_octeontx2.a -l:librte_event_opdl.a -l:librte_event_skeleton.a -l:librte_event_sw.a -l:librte_event_dsw.a -l:librte_event_octeontx.a -l:librte_baseband_null.a -l:librte_baseband_turbo_sw.a -l:librte_baseband_fpga_lte_fec.a -l:librte_baseband_fpga_5gnr_fec.a -l:librte_baseband_acc100.a -l:librte_node.a -l:librte_graph.a -l:librte_bpf.a -l:librte_flow_classify.a -l:librte_pipeline.a -l:librte_table.a -l:librte_port.a -l:librte_fib.a -l:librte_ipsec.a -l:librte_vhost.a -l:librte_stack.a -l:librte_security.a -l:librte_sched.a -l:librte_reorder.a -l:librte_rib.a -l:librte_regexdev.a -l:librte_rawdev.a -l:librte_pdump.a -l:librte_power.a -l:librte_member.a -l:librte_lpm.a -l:librte_latencystats.a -l:librte_kni.a -l:librte_jobstats.a -l:librte_ip_frag.a -l:librte_gso.a -l:librte_gro.a -l:librte_eventdev.a -l:librte_efd.a -l:librte_distributor.a -l:librte_cryptodev.a -l:librte_compressdev.a -l:librte_cfgfile.a -l:librte_bitratestats.a -l:librte_bbdev.a -l:librte_acl.a -l:librte_timer.a -l:librte_hash.a -l:librte_metrics.a -l:librte_cmdline.a -l:librte_pci.a -l:librte_ethdev.a -l:librte_meter.a -l:librte_net.a -l:librte_mbuf.a -l:librte_mempool.a -l:librte_rcu.a -l:librte_ring.a -l:librte_eal.a -l:librte_telemetry.a -l:librte_kvargs.a -Wl,--no-whole-archive -Wl,--export-dynamic -lpcap -Wl,--as-needed -lrte_node -lrte_graph -lrte_bpf -lrte_flow_classify -lrte_pipeline -lrte_table -lrte_port -lrte_fib -lrte_ipsec -lrte_vhost -lrte_stack -lrte_security -lrte_sched -lrte_reorder -lrte_rib -lrte_regexdev -lrte_rawdev -lrte_pdump -lrte_power -lrte_member -lrte_lpm -lrte_latencystats -lrte_kni -lrte_jobstats -lrte_ip_frag -lrte_gso -lrte_gro -lrte_eventdev -lrte_efd -lrte_distributor -lrte_cryptodev -lrte_compressdev -lrte_cfgfile -lrte_bitratestats -lrte_bbdev -lrte_acl -lrte_timer -lrte_hash -lrte_metrics -lrte_cmdline -lrte_pci -lrte_ethdev -lrte_meter -lrte_net -lrte_mbuf -lrte_mempool -lrte_rcu -lrte_ring -lrte_eal -lrte_telemetry -lrte_kvargs -pthread -lm -ldl -lnuma -lpcap -L/usr/usr/lib64 -lmlx5 -lpthread -L/usr/usr/lib64 -lpthread -libverbs -lpthread -lcrypto -ldl -pthread -lz -lmlx4 -lpthread -L/usr/usr/lib64 -libverbs -lpthread -lelf -lz  -lssl -lcrypto -lz -ldl -lpthread -lrt -lstdc++ -lnuma -lm -lpcap
ln -sf l3fwd-static build/l3fwd
[root@localhost dpdk-l3fwd]# 

查看可执行程序运行需要链接的动态库

[root@localhost dpdk-l3fwd]# ldd build/l3fwd
	linux-vdso.so.1 (0x00007ffe60ff5000)
	libpcap.so.1 => /lib64/libpcap.so.1 (0x00007fd942a66000)
	libm.so.6 => /lib64/libm.so.6 (0x00007fd9426e4000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007fd9424e0000)
	libnuma.so.1 => /lib64/libnuma.so.1 (0x00007fd9422d4000)
	libmlx5.so.1 => /lib64/libmlx5.so.1 (0x00007fd942081000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fd941e61000)
	libibverbs.so.1 => /lib64/libibverbs.so.1 (0x00007fd941c41000)
	libcrypto.so.1.1 => /lib64/libcrypto.so.1.1 (0x00007fd941758000)
	libz.so.1 => /lib64/libz.so.1 (0x00007fd941541000)
	libmlx4.so.1 => /lib64/libmlx4.so.1 (0x00007fd941334000)
	libelf.so.1 => /lib64/libelf.so.1 (0x00007fd94111b000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fd940d56000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fd942cb1000)
	libnl-route-3.so.200 => /lib64/libnl-route-3.so.200 (0x00007fd940ad0000)
	libnl-3.so.200 => /lib64/libnl-3.so.200 (0x00007fd9408ad000)
[root@localhost dpdk-l3fwd]# 

可以看出链接的全是系统下的动态库,没有dpdk相关的。

静态编译出可执行程序大小19MB~

[root@localhost dpdk-l3fwd]# ll -h build/l3fwd-static 
-rwxr-xr-x. 1 root root 19M Dec 30 10:19 build/l3fwd-static

3.2、动态编译

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)

编译过程

[root@localhost dpdk-l3fwd]# make 
OBJS1:/home/dpdk-l3fwd/main.o /home/dpdk-l3fwd/app/l3fwd_lpm.o /home/dpdk-l3fwd/app/l3fwd_em.o /home/dpdk-l3fwd/app/l3fwd_event_internal_port.o /home/dpdk-l3fwd/app/l3fwd_event.o /home/dpdk-l3fwd/app/l3fwd_event_generic.o
PKG:PKG_CONFIG_PATH=/home/dpdk-l3fwd/pkgconfig
cc -c -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wno-unused-function -Wno-implicit-fallthrough -O3 -I/home/dpdk-l3fwd/pkgconfig/include -include rte_config.h -march=native -I/usr/usr/include  -I/home/dpdk-l3fwd/include -I/home/dpdk-l3fwd/include/dpdk -I/home/dpdk-l3fwd/app -std=gnu99 -fPIC -DPIC -DUSE_DPDK -DALLOW_EXPERIMENTAL_API -o /home/dpdk-l3fwd/main.o /home/dpdk-l3fwd/main.c  
cc -c -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wno-unused-function -Wno-implicit-fallthrough -O3 -I/home/dpdk-l3fwd/pkgconfig/include -include rte_config.h -march=native -I/usr/usr/include  -I/home/dpdk-l3fwd/include -I/home/dpdk-l3fwd/include/dpdk -I/home/dpdk-l3fwd/app -std=gnu99 -fPIC -DPIC -DUSE_DPDK -DALLOW_EXPERIMENTAL_API -o /home/dpdk-l3fwd/app/l3fwd_lpm.o /home/dpdk-l3fwd/app/l3fwd_lpm.c  
cc -c -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wno-unused-function -Wno-implicit-fallthrough -O3 -I/home/dpdk-l3fwd/pkgconfig/include -include rte_config.h -march=native -I/usr/usr/include  -I/home/dpdk-l3fwd/include -I/home/dpdk-l3fwd/include/dpdk -I/home/dpdk-l3fwd/app -std=gnu99 -fPIC -DPIC -DUSE_DPDK -DALLOW_EXPERIMENTAL_API -o /home/dpdk-l3fwd/app/l3fwd_em.o /home/dpdk-l3fwd/app/l3fwd_em.c  
cc -c -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wno-unused-function -Wno-implicit-fallthrough -O3 -I/home/dpdk-l3fwd/pkgconfig/include -include rte_config.h -march=native -I/usr/usr/include  -I/home/dpdk-l3fwd/include -I/home/dpdk-l3fwd/include/dpdk -I/home/dpdk-l3fwd/app -std=gnu99 -fPIC -DPIC -DUSE_DPDK -DALLOW_EXPERIMENTAL_API -o /home/dpdk-l3fwd/app/l3fwd_event_internal_port.o /home/dpdk-l3fwd/app/l3fwd_event_internal_port.c  
cc -c -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wno-unused-function -Wno-implicit-fallthrough -O3 -I/home/dpdk-l3fwd/pkgconfig/include -include rte_config.h -march=native -I/usr/usr/include  -I/home/dpdk-l3fwd/include -I/home/dpdk-l3fwd/include/dpdk -I/home/dpdk-l3fwd/app -std=gnu99 -fPIC -DPIC -DUSE_DPDK -DALLOW_EXPERIMENTAL_API -o /home/dpdk-l3fwd/app/l3fwd_event.o /home/dpdk-l3fwd/app/l3fwd_event.c  
cc -c -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wno-unused-function -Wno-implicit-fallthrough -O3 -I/home/dpdk-l3fwd/pkgconfig/include -include rte_config.h -march=native -I/usr/usr/include  -I/home/dpdk-l3fwd/include -I/home/dpdk-l3fwd/include/dpdk -I/home/dpdk-l3fwd/app -std=gnu99 -fPIC -DPIC -DUSE_DPDK -DALLOW_EXPERIMENTAL_API -o /home/dpdk-l3fwd/app/l3fwd_event_generic.o /home/dpdk-l3fwd/app/l3fwd_event_generic.c  
cc -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wno-unused-function -Wno-implicit-fallthrough -O3 -I/home/dpdk-l3fwd/pkgconfig/include -include rte_config.h -march=native -I/usr/usr/include  -I/home/dpdk-l3fwd/include -I/home/dpdk-l3fwd/include/dpdk -I/home/dpdk-l3fwd/app -std=gnu99 -fPIC -DPIC -DUSE_DPDK -DALLOW_EXPERIMENTAL_API /home/dpdk-l3fwd/main.o /home/dpdk-l3fwd/app/l3fwd_lpm.o /home/dpdk-l3fwd/app/l3fwd_em.o /home/dpdk-l3fwd/app/l3fwd_event_internal_port.o /home/dpdk-l3fwd/app/l3fwd_event.o /home/dpdk-l3fwd/app/l3fwd_event_generic.o -o build/l3fwd-shared  -Wl,--as-needed -L/home/dpdk-l3fwd/pkgconfig/lib -lrte_node -lrte_graph -lrte_bpf -lrte_flow_classify -lrte_pipeline -lrte_table -lrte_port -lrte_fib -lrte_ipsec -lrte_vhost -lrte_stack -lrte_security -lrte_sched -lrte_reorder -lrte_rib -lrte_regexdev -lrte_rawdev -lrte_pdump -lrte_power -lrte_member -lrte_lpm -lrte_latencystats -lrte_kni -lrte_jobstats -lrte_ip_frag -lrte_gso -lrte_gro -lrte_eventdev -lrte_efd -lrte_distributor -lrte_cryptodev -lrte_compressdev -lrte_cfgfile -lrte_bitratestats -lrte_bbdev -lrte_acl -lrte_timer -lrte_hash -lrte_metrics -lrte_cmdline -lrte_pci -lrte_ethdev -lrte_meter -lrte_net -lrte_mbuf -lrte_mempool -lrte_rcu -lrte_ring -lrte_eal -lrte_telemetry -lrte_kvargs  -lssl -lcrypto -lz -ldl -lpthread -lrt -lstdc++ -lnuma -lm -lpcap 
ln -sf l3fwd-shared build/l3fwd
[root@localhost dpdk-l3fwd]# 

查看可执行程序运行需要链接的动态库

[root@localhost dpdk-l3fwd]# 
[root@localhost dpdk-l3fwd]# ldd build/l3fwd
	linux-vdso.so.1 (0x00007ffc19355000)
	librte_lpm.so.21 => /lib64/librte_lpm.so.21 (0x00007f3654d7a000)
	librte_eventdev.so.21 => /lib64/librte_eventdev.so.21 (0x00007f3654b4f000)
	librte_hash.so.21 => /lib64/librte_hash.so.21 (0x00007f365493d000)
	librte_cmdline.so.21 => /lib64/librte_cmdline.so.21 (0x00007f3654733000)
	librte_ethdev.so.21 => /lib64/librte_ethdev.so.21 (0x00007f3654487000)
	librte_net.so.21 => /lib64/librte_net.so.21 (0x00007f365427f000)
	librte_mbuf.so.21 => /lib64/librte_mbuf.so.21 (0x00007f365406d000)
	librte_mempool.so.21 => /lib64/librte_mempool.so.21 (0x00007f3653e63000)
	librte_eal.so.21 => /lib64/librte_eal.so.21 (0x00007f3653b73000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f3653953000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f365358e000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f3654f81000)
	libm.so.6 => /lib64/libm.so.6 (0x00007f365320c000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007f3653008000)
	libnuma.so.1 => /lib64/libnuma.so.1 (0x00007f3652dfc000)
	librte_kvargs.so.21 => /lib64/librte_kvargs.so.21 (0x00007f3652bf9000)
	librte_telemetry.so.21 => /lib64/librte_telemetry.so.21 (0x00007f36529f0000)
	librte_ring.so.21 => /lib64/librte_ring.so.21 (0x00007f36527ec000)
	librte_rcu.so.21 => /lib64/librte_rcu.so.21 (0x00007f36525e7000)
	librte_meter.so.21 => /lib64/librte_meter.so.21 (0x00007f36523e4000)
	librte_timer.so.21 => /lib64/librte_timer.so.21 (0x00007f36521e0000)
	librte_cryptodev.so.21 => /lib64/librte_cryptodev.so.21 (0x00007f3651fcf000)

可以看出依赖了dpdk相关的动态库。

动态编译出可执行程序大小仅有102KB

[root@localhost dpdk-l3fwd]# ll -h build/l3fwd-shared 
-rwxr-xr-x. 1 root root 102K Dec 30 10:15 build/l3fwd-shared

4、总结

其中静态编译和动态编译的区别可自行搜索查看~

dpdk-l3fwd可单独编译源码已经压缩上传,如果需要可下载使用dpdk-l3fwd

点个赞呗~(? ω ?)(

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-01-01 14:14:47  更:2022-01-01 14:17:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 4:38:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码