31. 開發(fā)套件構(gòu)建系統(tǒng)
DPDK 需要一個構(gòu)建系統(tǒng)用于編譯等操作。 本節(jié)介紹 DPDK 框架中使用的約束和機制。
這個框架有兩個使用場景:
- 編譯DPDK庫和示例應(yīng)用程序,該框架生成特定的二進制庫,包含文件和示例應(yīng)用程序。
- 使用安裝的DPDK二進制編譯外部的應(yīng)用程序或庫。
31.1. 編譯DPDK二進制文件
以下提供了如何構(gòu)建DPDK二進制文件。
31.1.1. 建立目錄概念
安裝之后,將創(chuàng)建一個構(gòu)建目錄結(jié)構(gòu)。 每個構(gòu)件目錄包含文件、庫和應(yīng)用程序。
構(gòu)建目錄特定于配置的體系結(jié)構(gòu)、執(zhí)行環(huán)境、工具鏈。 可以存在幾個構(gòu)建目錄共享源碼,但是配置不一樣的情況。
例如,要使用配置模板 config/defconfig_x86_64-linuxapp 創(chuàng)建一個名為 my_sdk_build_dir 的構(gòu)建目錄,我們使用如下命令:
cd ${RTE_SDK}
make config T=x86_64-native-linuxapp-gcc O=my_sdk_build_dir
這會創(chuàng)建一個新的 new my_sdk_build_dir 目錄,之后,我們可以使用如下的命令進行編譯:
cd my_sdk_build_dir
make
相當于:
make O=my_sdk_build_dir
目錄 my_sdk_build_dir 的內(nèi)容是:
-- .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 獲取更詳細的信息。
31.2. 構(gòu)建外部應(yīng)用程序
由于DPDK本質(zhì)上是一個開發(fā)工具包,所以最終用戶的第一個目標就是使用這個SDK創(chuàng)建新的應(yīng)用程序。 要編譯應(yīng)用程序,用戶必須設(shè)置 RTE_SDK 和 RTE_TARGET 環(huán)境變量。
export RTE_SDK=/opt/DPDK
export RTE_TARGET=x86_64-native-linuxapp-gcc
cd /path/to/my_app
對于一個新的應(yīng)用程序,用戶必須創(chuàng)建新的 Makefile 并包含指定的 .mk 文件,如 ${RTE_SDK}/mk/rte.vars.mk 和 ${RTE_SDK}/mk/rte.app.mk。 這部分內(nèi)容描述請參考 Building Your Own Application .
根據(jù) Makefile 所選定的目標(架構(gòu)、機器、執(zhí)行環(huán)境、工具鏈)或環(huán)境變量,應(yīng)用程序和庫將使用適當?shù)膆頭文件進行編譯,并和適當?shù)腶庫鏈接。 這些文件位于 ${RTE_SDK}/arch-machine-execenv-toolchain,由 ${RTE_BIN_SDK} 內(nèi)部引用。
為了編譯應(yīng)用程序,用戶只需要調(diào)用make命令。編譯結(jié)果將置于 /path/to/my_app/build 目錄。
示例應(yīng)用程序在example目錄中提供。
31.3. Makefile 描述
31.3.1. DPDK Makefiles 的通用規(guī)則
在DPDK中,Makefiles始終遵循相同的方案:
起始處包含 $(RTE_SDK)/mk/rte.vars.mk 文件。
為RTE構(gòu)建系統(tǒng)定義特殊的變量。
-
包含指定的 $(RTE_SDK)/mk/rte.XYZ.mk 文件,其中 XYZ 可以是 app、lib、extapp, extlib、obj、gnuconfigure等等,取決于要編譯什么樣的目標文件。 請參閱
描述。
-
包含用戶定義的規(guī)則及變量。
以下是一個簡單的例子,用于便于一個外部應(yīng)用程序:
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
31.3.2. Makefile 類型
根據(jù)Makefile最后包含的 .mk 文件,Makefile將具有不同的角色。 注意到,并不能在同一個Makefile文件中同時編譯庫和應(yīng)用程序。 因此,用戶必須創(chuàng)建兩個獨立的Makefile文件,最好是置于兩個不同的目錄中。
無論如何,rte.vars.mk 文件必須包含用戶Makefile。
31.3.2.1. 應(yīng)用程序
這些 Makefiles 生成一個二進制應(yīng)用程序。
- rte.app.mk: DPDK框架中的應(yīng)用程序。
- rte.extapp.mk: 外部應(yīng)用程序。
- rte.hostapp.mk: 建立DPDK的先決條件和工具。
31.3.2.2. 庫
創(chuàng)建一個 .a 庫。
- rte.lib.mk: DPDK中的庫。
- rte.extlib.mk: 外部庫。
- rte.hostlib.mk: DPDK中的host庫。
31.3.2.3. 安裝
- rte.install.mk: 不構(gòu)建任何東西,只是用于創(chuàng)建鏈接或者將文件復制到安裝目錄。 這對于開發(fā)包框架中包含的文件非常有用。
31.3.2.4. 內(nèi)核模塊
- rte.module.mk: 構(gòu)建DPDK內(nèi)核模塊。
31.3.2.5. 對象
- rte.obj.mk: DPDK中的目標文件聚合(合并一些o文件成一個)。
- rte.extobj.mk: 外部目標文件聚合(合并外部的一些o文件)。
31.3.2.6. 雜
- rte.doc.mk: DPDK中的文檔。
- rte.gnuconfigure.mk: 構(gòu)建一個基于配置的應(yīng)用程序。
- rte.subdir.mk: 構(gòu)建幾個目錄。
31.3.3. 內(nèi)部生成的構(gòu)建工具
app/dpdk-pmdinfogen
dpdk-pmdinfogen
掃描各種總所周知的符號名稱對象文件。這些目標文件由各種宏定義,用于導出關(guān)于pmd文件的硬件支持和使用的重要信息。 例如宏定義:
RTE_PMD_REGISTER_PCI(name, drv)
創(chuàng)建以下的符號:
static char this_pmd_name0[] __attribute__((used)) = "<name>";
將被 dpdk-pmdinfogen
掃描。使用這個虛擬系,可以從目標文件中導出其他相關(guān)位信息,并用于產(chǎn)生硬件支持描述, 然后 dpdk-pmdinfogen
按照以下格式編碼成 json 格式的字符串:
static char <name_pmd_string>="PMD_INFO_STRING=\"{'name' : '<name>', ...}\"";
然后可以通過外部工具搜索這些字符串,以確定給定庫或應(yīng)用程序的硬件支持。
31.3.4. 構(gòu)建系統(tǒng)提供的有用變量
- RTE_SDK: DPDK源碼絕對路徑。 編譯DPDK時,該變量由框架自動設(shè)置。 如果編譯外部應(yīng)用程序,它必須由用戶定義為環(huán)境變量。
- RTE_SRCDIR: DPDK源碼根路徑。 當編譯DPDK時,RTE_SRCDIR = RTE_SDK。 當編譯外部應(yīng)用程序時,該變量指向外部應(yīng)用程序源碼的跟目錄。
- RTE_OUTPUT: 輸出文件的路徑。 通常情況下,他是 $(RTE_SRCDIR)/build,但是可以通過make命令中的 O= 選項來重新指定。
- RTE_TARGET: 一個字符串,用于我們正在構(gòu)建的目標。 格式是arch-machine-execenv-toolchain。 當編譯DPDK時,目標是有構(gòu)建系統(tǒng)從配置(.config)中推導出來的。 當構(gòu)建外部應(yīng)用程序時,必須由用戶在Makefile中指定或作為環(huán)境變量。
- RTE_SDK_BIN: 參考 $(RTE_SDK)/$(RTE_TARGET)。
- RTE_ARCH: 定義架構(gòu)(i686, x86_64)。 它與 CONFIG_RTE_ARCH 相同,但是沒有字符串的雙引號。
- RTE_MACHINE: 定義機器。 它與 CONFIG_RTE_MACHINE 相同,但是沒有字符串的雙引號。
- RTE_TOOLCHAIN: 定義工具鏈 (gcc , icc)。 它與 CONFIG_RTE_TOOLCHAIN 相同,但是沒有字符串的雙引號。
- RTE_EXEC_ENV: 定義運行環(huán)境 (linuxapp)。 它與 CONFIG_RTE_EXEC_ENV 相同,但是沒有字符串的雙引號。
- RTE_KERNELDIR: 這個變量包含了將被用于編譯內(nèi)核模塊的內(nèi)核源的絕對路徑。 內(nèi)核頭文件必須與目標機器(將運行應(yīng)用程序的機器)上使用的頭文件相同。 默認情況下,變量設(shè)置為 /lib/modules/$(shell uname -r)/build,當目標機器也是構(gòu)建機器時,這是正確的。
- RTE_DEVEL_BUILD: 更嚴格的選項(停止警告)。 它在默認的git樹中。
31.3.5. 只能在Makefile中設(shè)置/覆蓋的變量
- VPATH: 構(gòu)建系統(tǒng)將搜索源碼的路徑列表。默認情況下,RTE_SRCDIR將被包含在VPATH中。
- CFLAGS: 用于C編譯的標志。用戶應(yīng)該使用+=在這個變量中附加數(shù)據(jù)。
- LDFLAGS: 用于鏈接的標志。用戶應(yīng)該使用+=在這個變量中附加數(shù)據(jù)。
- ASFLAGS: 用于匯編的標志。用戶應(yīng)該使用+=在這個變量中附加數(shù)據(jù)。
- CPPFLAGS: 用于給C預處理器賦予標志的標志(僅在匯編.S文件時有用)。用戶應(yīng)該使用+=在這個變量中附加數(shù)據(jù)。
- LDLIBS: 在應(yīng)用程序中,鏈接的庫列表(例如,-L / path / to / libfoo -lfoo)。用戶應(yīng)該使用+=在這個變量中附加數(shù)據(jù)。
- SRC-y: 在應(yīng)用程序,庫或?qū)ο驧akefiles的情況下,源文件列表(.c,.S或.o,如果源是二進制文件)。源文件必須可從VPATH獲得。
- INSTALL-y-$(INSTPATH): 需要安裝到 $(INSTPATH) 的文件列表。 這些文件必須在VPATH中可用,并將復制到 $(RTE_OUTPUT)/$(INSTPATH)。幾乎可以在任何 RTE Makefile 中可用。
- SYMLINK-y-$(INSTPATH): 需要安裝到 $(INSTPATH) 的文件列表。 這些文件必須在VPATH中可用并將鏈接到 (symbolically) 在 $(RTE_OUTPUT)/$(INSTPATH)。 幾乎可以在任何 RTE Makefile 中可用。
- PREBUILD: 構(gòu)建之前要采取的先決條件列表。用戶應(yīng)該使用+=在這個變量中附加數(shù)據(jù)。
- POSTBUILD: 主構(gòu)建之后要執(zhí)行的操作列表。用戶應(yīng)該使用+=在這個變量中附加數(shù)據(jù)。
- PREINSTALL: 安裝前要執(zhí)行的先決條件操作的列表。 用戶應(yīng)該使用+=在這個變量中附加數(shù)據(jù)。
- POSTINSTALL: 安裝后要執(zhí)行的操作列表。用戶應(yīng)該使用+=在這個變量中附加數(shù)據(jù)。
- PRECLEAN: 清除前要執(zhí)行的先決條件操作列表。用戶應(yīng)該使用+=在這個變量中附加數(shù)據(jù)。
- POSTCLEAN: 清除后要執(zhí)行的先決條件操作列表。用戶應(yīng)該使用+=在這個變量中附加數(shù)據(jù)。
- DEPDIRS-$(DIR): 僅在開發(fā)工具包框架中用于指定當前目錄的構(gòu)建是否依賴于另一個的構(gòu)建。這是正確支持并行構(gòu)建所必需的。
31.3.6. 只能在命令行上由用戶設(shè)置/覆蓋的變量
一些變量可以用來配置構(gòu)建系統(tǒng)的行為。在文件 Development Kit Root Makefile Help 及 External Application/Library Makefile Help 中有描述。
- WERROR_CFLAGS: 默認情況下,它被設(shè)置為一個依賴于編譯器的特定值。 鼓勵用戶使用這個變量,如下所示:
CFLAGS += $(WERROR_CFLAGS)
這避免了根據(jù)編譯器(icc或gcc)使用不同的情況。而且,這個變量可以從命令行覆蓋,這允許繞過標志用于測試目的。
31.3.7. 可以在Makefile或命令行中由用戶設(shè)置/覆蓋的變量
- CFLAGS_my_file.o: 為my_file.c的C編譯添加的特定標志。
- LDFLAGS_my_app: 鏈接my_app時添加的特定標志。
- EXTRA_CFLAGS: 在編譯時,這個變量的內(nèi)容被附加在CFLAGS之后。
- EXTRA_LDFLAGS: 鏈接后,將此變量的內(nèi)容添加到LDFLAGS之后。
- EXTRA_LDLIBS: 鏈接后,此變量的內(nèi)容被添加到LDLIBS之后。
- EXTRA_ASFLAGS: 組裝后這個變量的內(nèi)容被附加在ASFLAGS之后。
- EXTRA_CPPFLAGS: 在匯編文件上使用C預處理器時,此變量的內(nèi)容將附加在CPPFLAGS之后。