DPDK編程指南(翻譯)( 三十一)

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始終遵循相同的方案:

  1. 起始處包含 $(RTE_SDK)/mk/rte.vars.mk 文件。

  2. 為RTE構(gòu)建系統(tǒng)定義特殊的變量。

  3. 包含指定的 $(RTE_SDK)/mk/rte.XYZ.mk 文件,其中 XYZ 可以是 app、lib、extapp, extlib、obj、gnuconfigure等等,取決于要編譯什么樣的目標文件。 請參閱

    See Makefile Types

    描述。

  4. 包含用戶定義的規(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 HelpExternal 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之后。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容