31. 開發(fā)套件構(gòu)建系統(tǒng)
DPDK 需要一個(gè)構(gòu)建系統(tǒng)用于編譯等操作蜂怎。 本節(jié)介紹 DPDK 框架中使用的約束和機(jī)制。
這個(gè)框架有兩個(gè)使用場景:
- 編譯DPDK庫和示例應(yīng)用程序怨愤,該框架生成特定的二進(jìn)制庫派敷,包含文件和示例應(yīng)用程序。
- 使用安裝的DPDK二進(jìn)制編譯外部的應(yīng)用程序或庫撰洗。
31.1. 編譯DPDK二進(jìn)制文件
以下提供了如何構(gòu)建DPDK二進(jìn)制文件篮愉。
31.1.1. 建立目錄概念
安裝之后,將創(chuàng)建一個(gè)構(gòu)建目錄結(jié)構(gòu)差导。 每個(gè)構(gòu)件目錄包含文件试躏、庫和應(yīng)用程序。
構(gòu)建目錄特定于配置的體系結(jié)構(gòu)设褐、執(zhí)行環(huán)境颠蕴、工具鏈。 可以存在幾個(gè)構(gòu)建目錄共享源碼助析,但是配置不一樣的情況犀被。
例如,要使用配置模板 config/defconfig_x86_64-linuxapp 創(chuàng)建一個(gè)名為 my_sdk_build_dir 的構(gòu)建目錄外冀,我們使用如下命令:
cd ${RTE_SDK}
make config T=x86_64-native-linuxapp-gcc O=my_sdk_build_dir
這會(huì)創(chuàng)建一個(gè)新的 new my_sdk_build_dir 目錄寡键,之后,我們可以使用如下的命令進(jìn)行編譯:
cd my_sdk_build_dir
make
相當(dāng)于:
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 獲取更詳細(xì)的信息雪隧。
31.2. 構(gòu)建外部應(yīng)用程序
由于DPDK本質(zhì)上是一個(gè)開發(fā)工具包西轩,所以最終用戶的第一個(gè)目標(biāo)就是使用這個(gè)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
對于一個(gè)新的應(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 所選定的目標(biāo)(架構(gòu)韭邓、機(jī)器、執(zhí)行環(huán)境祠汇、工具鏈)或環(huán)境變量仍秤,應(yīng)用程序和庫將使用適當(dāng)?shù)膆頭文件進(jìn)行編譯熄诡,并和適當(dāng)?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等等逗宁,取決于要編譯什么樣的目標(biāo)文件。 請參閱
描述梦湘。
-
包含用戶定義的規(guī)則及變量瞎颗。
以下是一個(gè)簡單的例子,用于便于一個(gè)外部應(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將具有不同的角色哼拔。 注意到,并不能在同一個(gè)Makefile文件中同時(shí)編譯庫和應(yīng)用程序瓣颅。 因此倦逐,用戶必須創(chuàng)建兩個(gè)獨(dú)立的Makefile文件,最好是置于兩個(gè)不同的目錄中弄捕。
無論如何僻孝,rte.vars.mk 文件必須包含用戶Makefile导帝。
31.3.2.1. 應(yīng)用程序
這些 Makefiles 生成一個(gè)二進(jìn)制應(yīng)用程序。
- rte.app.mk: DPDK框架中的應(yīng)用程序穿铆。
- rte.extapp.mk: 外部應(yīng)用程序您单。
- rte.hostapp.mk: 建立DPDK的先決條件和工具。
31.3.2.2. 庫
創(chuàng)建一個(gè) .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ù)制到安裝目錄。 這對于開發(fā)包框架中包含的文件非常有用筑辨。
31.3.2.4. 內(nèi)核模塊
- rte.module.mk: 構(gòu)建DPDK內(nèi)核模塊俺驶。
31.3.2.5. 對象
- rte.obj.mk: DPDK中的目標(biāo)文件聚合(合并一些o文件成一個(gè))。
- rte.extobj.mk: 外部目標(biāo)文件聚合(合并外部的一些o文件)棍辕。
31.3.2.6. 雜
- rte.doc.mk: DPDK中的文檔暮现。
- rte.gnuconfigure.mk: 構(gòu)建一個(gè)基于配置的應(yīng)用程序。
- rte.subdir.mk: 構(gòu)建幾個(gè)目錄楚昭。
31.3.3. 內(nèi)部生成的構(gòu)建工具
app/dpdk-pmdinfogen
dpdk-pmdinfogen
掃描各種總所周知的符號(hào)名稱對象文件栖袋。這些目標(biāo)文件由各種宏定義,用于導(dǎo)出關(guān)于pmd文件的硬件支持和使用的重要信息抚太。 例如宏定義:
RTE_PMD_REGISTER_PCI(name, drv)
創(chuàng)建以下的符號(hào):
static char this_pmd_name0[] __attribute__((used)) = "<name>";
將被 dpdk-pmdinfogen
掃描塘幅。使用這個(gè)虛擬系,可以從目標(biāo)文件中導(dǎo)出其他相關(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í),該變量由框架自動(dòng)設(shè)置身冀。 如果編譯外部應(yīng)用程序钝尸,它必須由用戶定義為環(huán)境變量。
- RTE_SRCDIR: DPDK源碼根路徑搂根。 當(dāng)編譯DPDK時(shí)珍促,RTE_SRCDIR = RTE_SDK。 當(dāng)編譯外部應(yīng)用程序時(shí)剩愧,該變量指向外部應(yīng)用程序源碼的跟目錄猪叙。
- RTE_OUTPUT: 輸出文件的路徑。 通常情況下,他是 $(RTE_SRCDIR)/build穴翩,但是可以通過make命令中的 O= 選項(xiàng)來重新指定犬第。
- RTE_TARGET: 一個(gè)字符串,用于我們正在構(gòu)建的目標(biāo)芒帕。 格式是arch-machine-execenv-toolchain歉嗓。 當(dāng)編譯DPDK時(shí),目標(biāo)是有構(gòu)建系統(tǒng)從配置(.config)中推導(dǎo)出來的背蟆。 當(dāng)構(gòu)建外部應(yīng)用程序時(shí)鉴分,必須由用戶在Makefile中指定或作為環(huán)境變量。
- RTE_SDK_BIN: 參考 $(RTE_SDK)/$(RTE_TARGET)带膀。
- RTE_ARCH: 定義架構(gòu)(i686, x86_64)志珍。 它與 CONFIG_RTE_ARCH 相同,但是沒有字符串的雙引號(hào)垛叨。
- RTE_MACHINE: 定義機(jī)器伦糯。 它與 CONFIG_RTE_MACHINE 相同,但是沒有字符串的雙引號(hào)点额。
- RTE_TOOLCHAIN: 定義工具鏈 (gcc , icc)舔株。 它與 CONFIG_RTE_TOOLCHAIN 相同莺琳,但是沒有字符串的雙引號(hào)还棱。
- RTE_EXEC_ENV: 定義運(yùn)行環(huán)境 (linuxapp)。 它與 CONFIG_RTE_EXEC_ENV 相同惭等,但是沒有字符串的雙引號(hào)珍手。
- RTE_KERNELDIR: 這個(gè)變量包含了將被用于編譯內(nèi)核模塊的內(nèi)核源的絕對路徑。 內(nèi)核頭文件必須與目標(biāo)機(jī)器(將運(yùn)行應(yīng)用程序的機(jī)器)上使用的頭文件相同辞做。 默認(rèn)情況下琳要,變量設(shè)置為 /lib/modules/$(shell uname -r)/build,當(dāng)目標(biāo)機(jī)器也是構(gòu)建機(jī)器時(shí)秤茅,這是正確的稚补。
- RTE_DEVEL_BUILD: 更嚴(yán)格的選項(xiàng)(停止警告)。 它在默認(rèn)的git樹中框喳。
31.3.5. 只能在Makefile中設(shè)置/覆蓋的變量
- VPATH: 構(gòu)建系統(tǒng)將搜索源碼的路徑列表课幕。默認(rèn)情況下,RTE_SRCDIR將被包含在VPATH中五垮。
- CFLAGS: 用于C編譯的標(biāo)志乍惊。用戶應(yīng)該使用+=在這個(gè)變量中附加數(shù)據(jù)。
- LDFLAGS: 用于鏈接的標(biāo)志放仗。用戶應(yīng)該使用+=在這個(gè)變量中附加數(shù)據(jù)润绎。
- ASFLAGS: 用于匯編的標(biāo)志。用戶應(yīng)該使用+=在這個(gè)變量中附加數(shù)據(jù)。
- CPPFLAGS: 用于給C預(yù)處理器賦予標(biāo)志的標(biāo)志(僅在匯編.S文件時(shí)有用)莉撇。用戶應(yīng)該使用+=在這個(gè)變量中附加數(shù)據(jù)呢蛤。
- LDLIBS: 在應(yīng)用程序中,鏈接的庫列表(例如棍郎,-L / path / to / libfoo -lfoo)顾稀。用戶應(yīng)該使用+=在這個(gè)變量中附加數(shù)據(jù)。
- SRC-y: 在應(yīng)用程序坝撑,庫或?qū)ο驧akefiles的情況下静秆,源文件列表(.c,.S或.o巡李,如果源是二進(jìn)制文件)抚笔。源文件必須可從VPATH獲得。
- INSTALL-y-$(INSTPATH): 需要安裝到 $(INSTPATH) 的文件列表侨拦。 這些文件必須在VPATH中可用殊橙,并將復(fù)制到 $(RTE_OUTPUT)/$(INSTPATH)。幾乎可以在任何 RTE Makefile 中可用狱从。
- SYMLINK-y-$(INSTPATH): 需要安裝到 $(INSTPATH) 的文件列表膨蛮。 這些文件必須在VPATH中可用并將鏈接到 (symbolically) 在 $(RTE_OUTPUT)/$(INSTPATH)。 幾乎可以在任何 RTE Makefile 中可用季研。
- PREBUILD: 構(gòu)建之前要采取的先決條件列表敞葛。用戶應(yīng)該使用+=在這個(gè)變量中附加數(shù)據(jù)。
- POSTBUILD: 主構(gòu)建之后要執(zhí)行的操作列表与涡。用戶應(yīng)該使用+=在這個(gè)變量中附加數(shù)據(jù)惹谐。
- PREINSTALL: 安裝前要執(zhí)行的先決條件操作的列表。 用戶應(yīng)該使用+=在這個(gè)變量中附加數(shù)據(jù)驼卖。
- POSTINSTALL: 安裝后要執(zhí)行的操作列表氨肌。用戶應(yīng)該使用+=在這個(gè)變量中附加數(shù)據(jù)。
- PRECLEAN: 清除前要執(zhí)行的先決條件操作列表酌畜。用戶應(yīng)該使用+=在這個(gè)變量中附加數(shù)據(jù)怎囚。
- POSTCLEAN: 清除后要執(zhí)行的先決條件操作列表。用戶應(yīng)該使用+=在這個(gè)變量中附加數(shù)據(jù)桥胞。
- DEPDIRS-$(DIR): 僅在開發(fā)工具包框架中用于指定當(dāng)前目錄的構(gòu)建是否依賴于另一個(gè)的構(gòu)建恳守。這是正確支持并行構(gòu)建所必需的。
31.3.6. 只能在命令行上由用戶設(shè)置/覆蓋的變量
一些變量可以用來配置構(gòu)建系統(tǒng)的行為埠戳。在文件 Development Kit Root Makefile Help 及 External Application/Library Makefile Help 中有描述井誉。
- WERROR_CFLAGS: 默認(rèn)情況下,它被設(shè)置為一個(gè)依賴于編譯器的特定值整胃。 鼓勵(lì)用戶使用這個(gè)變量颗圣,如下所示:
CFLAGS += $(WERROR_CFLAGS)
這避免了根據(jù)編譯器(icc或gcc)使用不同的情況。而且,這個(gè)變量可以從命令行覆蓋在岂,這允許繞過標(biāo)志用于測試目的奔则。
31.3.7. 可以在Makefile或命令行中由用戶設(shè)置/覆蓋的變量
- CFLAGS_my_file.o: 為my_file.c的C編譯添加的特定標(biāo)志。
- LDFLAGS_my_app: 鏈接my_app時(shí)添加的特定標(biāo)志蔽午。
- EXTRA_CFLAGS: 在編譯時(shí)易茬,這個(gè)變量的內(nèi)容被附加在CFLAGS之后。
- EXTRA_LDFLAGS: 鏈接后及老,將此變量的內(nèi)容添加到LDFLAGS之后抽莱。
- EXTRA_LDLIBS: 鏈接后,此變量的內(nèi)容被添加到LDLIBS之后骄恶。
- EXTRA_ASFLAGS: 組裝后這個(gè)變量的內(nèi)容被附加在ASFLAGS之后食铐。
- EXTRA_CPPFLAGS: 在匯編文件上使用C預(yù)處理器時(shí),此變量的內(nèi)容將附加在CPPFLAGS之后僧鲁。