如何将DPDK应用程序编译为库

时间:2018-09-12 10:54:23

标签: dpdk

我有一个使用DPDK的程序,并且正在使用示例中提供的Makefile对其进行编译。

如果我将程序编译为APP(如here所述),一切都会进行 好。 但是,我的代码是一个较大项目的一部分,为此, 单独的makefile会引起很多麻烦。 因此,如同一页所述,我将代码捆绑在一个库中。

调用库中函数的程序(用于初始化 EAL)出现此错误:

MBUF: error setting mempool handler
Cannot init mbuf pool

似乎,将应用程序编译为库时,EAL无法正确初始化。

我在这里报告使用l2fwd示例重现该问题的步骤。

背景

我按照here的描述从源代码构建了DPDK,并且有一个绑定到DPDK驱动程序的以太网接口:

$ $RTE_SDK/usertools/dpdk-devbind.py --status |head -n4
Network devices using DPDK-compatible driver
============================================
0000:01:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=igb_uio unused=ixgbe

运行 l2fwd 示例

首先复制示例文件夹,然后运行示例:

$ cp -r $RTE_SDK/examples/l2fwd $RTE_SDK/examples/l2fwd-lib/
$ cd $RTE_SDK/examples/l2fwd

$ make
CC main.o
LD l2fwd
INSTALL-APP l2fwd
INSTALL-MAP l2fwd.map

$ sudo ./build/l2fwd -l 0-3  -- -p 0x1
Port statistics ====================================
Statistics for port 0 ------------------------------
Packets sent:                        0
Packets received:                    0
Packets dropped:                     0
Aggregate statistics ===============================
Total packets sent:                  0
Total packets received:              0
Total packets dropped:               0
====================================================
  • 行得通!

构建与库相同的示例

  • cd ../l2fwd-lib/
    mv main.c l2fwd.c
    
  • 修改l2fwd.c,在顶部添加#include "l2fwd.h"并替换

    int main(int argc, char **argv)
    

    int start(int argc, char **argv)
    
  • 使用库接口创建头文件l2fwd.h:

    int start(int argc, char **argv);
    
  • 按照文档中的说明修改Makefile:

    APP = l2fwd      --->   LIB = libl2fwd.a
    SRCS-y := main.c --->   SRCS-y := l2fwd.c
    include $(RTE_SDK)/mk/rte.extapp.mk   --->   include $(RTE_SDK)/mk/rte.extlib.mk 
    
  • 编译库:

    $ make
    CC l2fwd.o
    AR libl2fwd.a
    INSTALL-LIB libl2fwd.a
    
  • 编写使用该库的程序。仅使用以下两行创建main.c文件:

    #include "l2fwd.h"
    int main (int argc, char **argv) { start(argc, argv); }
    
  • 编译它(带有所有需要的库):

    gcc -L build/lib/ -L $RTE_SDK/build/lib/ main.c -o main.o -l l2fwd -l dpdk -l numa -pthread -l dl 
    
  • 最后,使用先前使用的相同参数运行它:

    $ sudo ./main.o -l 0-3  -- -p 0x1
    EAL: Detected 40 lcore(s)
    EAL: Detected 2 NUMA nodes
    EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
    EAL: Probing VFIO support...
    MAC updating enabled
    EAL: Error - exiting with code: 1
      Cause: No Ethernet ports - bye
    

在这种情况下,EAL无法正确初始化(以太网端口仍绑定到DPDK驱动程序)。

编辑1

根据@Andriy Berestovskyy的说明,链接DPDK库时需要链接器--whole-archive选项。这样可以解决示例中的问题。 但是,我的程序现在面临另一个问题。我需要使用自定义构建系统,因此我将DPDK应用程序链接为库。在执行过程中出现错误:

MBUF: error setting mempool handler
mempool/dpaa2: Not a valid dpaa2 buffer pool

好像正在使用dpaa2驱动程序,那是错误的驱动程序(我的NIC正在使用igb_uio)。任何提示为什么会这样?作为DPDK应用程序编译时,相同的代码有效,因此它可能与链接过程有关。

编辑2

此错误是由于我使用 CONFIG_RTE_BUILD_SHARED_LIB=y选项。当DPDK构建为共享库时,必须使用-d EAL命令行选项显式设置驱动程序。 我用CONFIG_RTE_BUILD_SHARED_LIB=n重新编译了DPDK,问题解决了。

2 个答案:

答案 0 :(得分:1)

  

编译(带有所有需要的库):

npm ls webpack

我想问题在于此步骤。 DPDK使用链接级构造函数(即gcc -L build/lib/ -L $RTE_SDK/build/lib/ main.c -o main.o -l l2fwd -l dpdk -l numa -pthread -l dl )。例如,请参见__attribute__((constructor))的定义。也有回调等。

因此要正确链接DPDK,我们必须:

  • 在Makefile中使用RTE_INIT()(请参见Development Kit Build System

  • ,或者如果我们需要使用自定义构建系统,则需要在rte.app.mk选项之后链接DPDK库。

答案 1 :(得分:0)

我遇到了类似的问题,正如here中所述,我使用了-d选项来链接libray“ -d /usr/lib64/librte_mempool_ring.so”。奏效了。