41. Development Kit Build System
DPDK需要一个编译系统环境来进行编译活动等操作。本节描述DPDK框架中使用的约束和机制。
该框架有两个用例:
- 编译DPDK库和示例应用程序;该框架生成特定的二进制库,包括文件和示例应用程序
- 使用已安装的DPDK二进制库编译外部应用程序或库
41.1. Building the Development Kit Binary
下面提供如何构建DPDK二进制文件的详细信息。
41.1.1. Build Directory Concept
安装之后,将创建一个目录结构。每个目录包含文件、库和应用程序。
构建目录对应于特定的配置,配置包括体系架构+执行环境+工具链。可以构建多个目录,这些目录共享不同配置的相同源。
例如,使用默认配置模板config /defconfig_x86_64- linuxapp,创建一个名为my_sdk_build_dir的新构建目录,我们使用:
cd ${RTE_SDK}
make config T=x86_64-native-linuxapp-gcc O=my_sdk_build_dir
这会创建一个新的my_sdk_build_dir目录。之后,我们可以通过:
cd my_sdk_build_dir
make
相当于:
make O=my_sdk_build_dir
my_sdk_build_dir的内容是:
-- .config # used configuration
-- Makefile # wrapper that calls head Makefile
# with $PWD as build directory
-- build #All temporary files used during build
+--app # process, including . o, .d, and .cmd files.
| +-- test # For libraries, we have the .a file.
| +-- test.o # For applications, we have the elf file.
| `-- ...
+-- lib
+-- librte_eal
| `-- ...
+-- librte_mempool
| +-- mempool-file1.o
| +-- .mempool-file1.o.cmd
| +-- .mempool-file1.o.d
| +-- mempool-file2.o
| +-- .mempool-file2.o.cmd
| +-- .mempool-file2.o.d
| `-- mempool.a
`-- ...
-- include # All include files installed by libraries
+-- librte_mempool.h # and applications are located in this
+-- rte_eal.h # directory. The installed files can depend
+-- rte_spinlock.h # on configuration if needed (environment,
+-- rte_atomic.h # architecture, ..)
`-- \*.h ...
-- lib # all compiled libraries are copied in this
+-- librte_eal.a # directory
+-- librte_mempool.a
`-- \*.a ...
-- app # All compiled applications are installed
+ --test # here. It includes the binary in elf format
请参考 Development Kit Root Makefile Help获得dpdk根目录下make命令的详细信息。
41.2. Building External Applications
由于DPDK本质上是一个开发工具包,最终用户的第一个目标就是使用这个SDK创建一个应用程序。要编译一个应用程序,用户必须设置RTE_SDK和RTE_TARGET环境变量。
export RTE_SDK=/opt/DPDK
export RTE_TARGET=x86_64-native-linuxapp-gcc
cd /path/to/my_app
对于一个新的应用程序,用户必须创建自己的Makefile,其中包含一些 .mk文件。如$ {RTE_SDK}/mk/ rte.vars。$ { RTE_SDK } /mk/ rte.app.mk。在 Building Your Own Application中有详细描述。
根据在Makefile或环境变量中定义的选定目标(体系架构、机器、执行环境、工具链),应用程序和库将使用适当.h文件和适当的.a文件进行编译。这些文件位于${RTE_SDK}/arch-machine-execenv-toolchain中,由$ {RTE_BIN_SDK}内部引用。
要编译他们的应用程序,用户只需调用make。编译结果将位于/ path/to/my_app/ build目录。
示例目录中提供了示例应用程序。
41.3. Makefile Description
41.3.1. General Rules For DPDK Makefiles
在DPDK中,makefile始终遵循相同的规则:
- 在开始处包含$(RTE_SDK)/mk/rte.vars.mk
- 为RTE构建系统定义特定的变量。
- 包含指定的 $(RTE_SDK)/mk/rte.XYZ.mk,xyz可以是app,lib,extapp,extlib,obj ,gnuconfigure等,依赖于你想构建什么样的目标。详细参考下面的See Makefile Types
- 包括用户定义的规则和变量。
下面是一个非常简单的外部应用程序Makefile示例:
include $(RTE_SDK)/mk/rte.vars.mk
# binary name
APP = helloworld
# all source are stored in SRCS-y
SRCS-y := main.c
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
include $(RTE_SDK)/mk/rte.extapp.mk
41.3.2. Makefile Types
根据用户Makefile末尾的.mk文件,Makefile将扮演不同的角色。请注意,在同一个Makefile中构建一个库和一个应用程序是不可能的。为此,用户必须创建两个独立的makefile,可能在两个不同的目录中。
无论如何,rte.vars.mkfile必须包含在用户Makefile中。
41.3.2.1. Application
这些makefile生成一个二进制应用程序。
- rte.app.mk:开发工具包框架中的应用程序
- rte.extapp.mk:外部程序
- rte.hostapp.mk:构建DPDK的必备工具
41.3.2.2. Library
生成.a库
- rte.lib.mk:开发工具包框架中的库
- rte.extlib.mk:外部库
- rte.hostlib.mk:开发工具包框架中host库
41.3.2.3. Install
- rte.install.mk:不构建任何东西,它只用于创建链接或将文件复制到安装目录。这对于包括开发工具包框架中的文件非常有用。
41.3.2.4. Kernel Module
- rte.module.mk:在开发工具包框架中构建一个内核模块。
41.3.2.5. Objects
- rte.obj.mk:开发工具包框架中的目标文件合并(合并多个.o文件)
- rte.extobj.mk:开发工具包框架外的目标文件合并(合并多个.o文件)
41.3.2.6. Misc
- rte.doc.mk:开发工具包框架文档
- rte.gnuconfigure.mk:构建一个基于配置的应用程序。
- rte.subdir.mk:在开发工具包框架中构建几个目录。
41.3.3. Internally Generated Build Tools
app/dpdk-pmdinfogen
dpdk-pmdinfogen
扫描.o文件获取各种著名的符号名,这些著名的符号名称由各种宏定义,用于为pmd文件导出硬件支持的重要信息。例如宏:
RTE_PMD_REGISTER_PCI(name, drv)
创建以下符号:
static char this_pmd_name0[] __attribute__((used)) = "<name>";
上面的被dpdk-pmdinfogen扫描。使用此信息,可以从对象文件导出其他相关的位数据,并用于生成硬件支持描述,dpdk - pmdinfogen将编码成json格式的字符串,格式如下:
static char <name_pmd_string>="PMD_INFO_STRING=\"{'name' : '<name>', ...}\"";
然后,可以通过外部工具搜索这些字符串,以确定给定库或应用程序的硬件支持。
41.3.4. Useful Variables Provided by the Build System
- RTE_SDK:DPDK源文件的绝对路径。在编译开发工具包时,这个变量是由框架自动设置的。如果编译外部应用程序,它必须由用户定义为环境变量。
- RTE_SRCDIR:源文件根目录绝对路径。在编译开发工具包时,RTE_SRCDIR = RTE_SDK。在编译外部应用程序时,变量指向外部应用程序源文件的根目录。
- RTE_OUTPUT:配置输出文件路径。通常,它等于$(RTE_SRCDIR)/build,但是也可以在命令行上使用O=?选项设置。
- RET_TARGET:用于识别我们构建的目标的字符串。格式为 arch-machine-execenv-toolchain。编译SDK时,由构建系统从配置(. config)推导出目标。在构建外部应用程序时,必须由Makefile中的用户或环境变量指定。
- RTE_SDK_BIN:参考 $(RTE_SDK)/$(RTE_TARGET)。
- RTE_ARCH:定义架构(i686,x86_64)。它与CONFIG_RTE_ARCH相同,但是字符串周围没有双引号。
- RTE_MACHINE:定义cpu特性。它与CONFIG_RTE_MACHINE相同,但是字符串周围没有双引号。
- RTE_TOOLCHAIN:定义工具链(gcc,icc)。它的值与CONFIG_RTE_TOOLCHAIN相同,但是字符串中没有双引号。
- RTE_EXEC_ENV:定义执行环境(linuxapp),它的值与CONFIG_RTE_EXEC_ENV相同,但是字符串中没有双引号。
- RTE_KERNELDIR:此变量包含用于编译内核模块的内核源代码的绝对路径。内核头文件必须和目标机器上使用的(运行应用程序的机器)的相同。默认情况下,改变了设置为/lib/modules/$(shell uname -r)/build,当目标机器也是构建机器时,这是正确的。
- RTE_DEVEL_BUILD:严格选项(警告即停止)。它在git树中默认为y。
41.3.5. Variables that Can be Set/Overridden in a Makefile Only
- VPATH:构建系统将搜索源文件的路径列表。默认情况下,RTE_SRCDIR将包含在VPATH中。
- CFLAGS:C编译flag。用户应该使用 +=在这个变量中追加flag。
- LDFLAGS:链接flag。用户应该使用 +=在这个变量中追加flag。
- ASFLAGS:装配flag。用户应该使用 +=在这个变量中追加flag。
- CPPFLAGS:C预处理flag(只用于需要装配.S文件时)。用户应该使用 +=在这个变量中追加flag。
- LDLIBS:在应用程序中,要链接的lib列表(例如,-L /path/to/libfoo -lfoo)
- SRC-y:在应用程序、库或目标makefile中的源文件列表(.c,.S, .o),对于VPATH而言,这些源文件必须可用。
- INSTALL-y-$(INSTPATH):在$(INSTPATH)中要安装的文件列表。对于VPATH而言,这些文件必须可用并且在$(RTE_OUTPUT)/$(INSTPATH)可以被复制。几乎可以在任何RTE Makefile中使用。
- SYMLINK-y-$(INSTPATH):在$(INSTPATH)中要安装的文件列表。对于VPATH而言,这些文件必须可用并且在$(RTE_OUTPUT)/$(INSTPATH).可以被链接(象征性的)。这个变量可以在几乎任何DPDK Makefile中使用。
- PREBUILD:在建立之前要采取的先决操作清单。用户应该使用 +=在这个变量中追加flag。
- POSTBUILD:在主构建之后要采取的操作清单。用户应该使用 +=在这个变量中追加flag。
- PREINSTALL:在安装之前要采取的先决操作清单。用户应该使用 +=在这个变量中追加flag。
- POSTINSTALL:安装之后要采取的操作清单。用户应该使用 +=在这个变量中追加flag。
- PRECLEAN:清理之前要采取的先决操作清单。用户应该使用 +=在这个变量中追加flag。
- POSTCLEAN:清理之后要采取的先决操作清单。用户应该使用 +=在这个变量中追加flag。
- DEPDIRS-$(DIR):只在开发工具包框架中使用,以指定当前目录的构建是否依赖于另一个目录的构建。这需要正确地支持并行构建。
41.3.6. Variables that can be Set/Overridden by the User on the Command Line Only
可以使用一些变量来配置构建系统行为。详情参考Development Kit Root Makefile Help 和 External Application/Library Makefile Help
- WERROR_CFLAGS:默认情况下,这将设置为依赖于编译器的特定值。鼓励用户使用以下变量:
CFLAGS += $(WERROR_CFLAGS)
这避免了根据编译器(icc或gcc)使用不同的情况。此外,该变量可以从命令行中重写,允许为测试目的绕过这些flag。
41.3.7. Variables that Can be Set/Overridden by the User in a Makefile or Command Line
- CFLAGS_my_file.o:用于编译my_file.c的指定标志。
- LDFLAGS_my_app:用于链接my_app的指定标志。
- EXTRA_CFLAGS:在编译时,这个变量的内容附加在CFLAGS之后。
- EXTRA_LDFLAGS:当链接时,这个变量的内容附加在LDFLAGS之后。
- EXTRA_LDLIBS:当链接时,这个变量的内容附加在LDLIBS之后。
- EXTRA_ASFLAGS:当装配时,这个变量的内容附加在ASFLAGS之后。
- EXTRA_CPPFLAGS:当使用C预处理程序处理文件集时,这个变量的内容附加在CPPFLAGS之后。