Including DPDK libs into your C++ project

DPDK is written in C and it is expected to be used in C environments. Yes I know, there are exports ready for C++ usage all over the lib, but if you ever tried to include DPDK code into your C++ application then you’ve already discovered that’s actually quite tricky to build DPDK with C++ toolchains. I mean don’t get me wrong, I’m not saying that’s not possible but only that’s very annoying.

So, what’ I’m going present you here is a solution which do not require too much mixing with the makefiles (or MakeLists) and still allow you to benefit of this powerful packet processing library in you C++ code. I’ll need to make things extremely simple for the sake of this explanation, but don’t worry the simple example can scale quite well to big projects… (Yeah, sure..).

Alright, let’s say we have those functions in our DPDK LIB:

The struct nic_port is just a small structure that supposedly is going to contain all the NIC port informations, again, this is just a banal example please don’t blame me for writing useless code, probably I should have avoided error checking at all in this piece to avoid confusion.. Oh man, confusion is the worst thing ever when writing code.. Whatever… This is the nic_port structure:

Cool. This code can be compiled using DPDK makefiles quite easily, I can add a main entry and test this functionality (by calling init_dpdk_capture, in case you can’t guess it youself :), on my machine the output is:

Which is the basic EAL and PMD init output plus a couple of additional prints. To build this code as a lib you should use the makefile /mk/rte.lib.mk from your DPDK installation directory, there’s nothing really fancy here just read THIS and you should good to go. well.. no.. The point of all this post is that the instruction on the DPDK web page are not completely honest on the amount of stuff to do in order to make this thing work, let’s say we have the following C++ application:

And, your bare bone makefile would look probably like this:

To make it work you should use some proper paths, also here I’m assuming that the name of the LIB created using the DPDK toolkit is your_dpdk_lib. Now, this makefile is perfectly fine and can compile our powerful C++ application, sadly the output of it’s execution is a bit disappointing:

Where’s all the EAL and PMD stuff? No NIC was discovered! The problem is banal, but also very painful to debug if you don’t read my blog, as probably you’ll be spending quite some time asking yourself why the included DPDK lib does not initialize properly EAL and PMD.

The issue here is that DPDK use a bunch of constructor functions to initialize all it’s stuff before main is even executed, those constructors are not referenced directly in any of the code above so the linker assume that those are not needed and remove them from the binary. Shit storm, right?

Long story short, you need to include in your hand made makefile the linker flags that will force the inclusion of all the DPDK stuff:

Which will include all of the DPDK stuff into your binary, most probably you might want to fine tune the inclusion to only the piece of the lib that you’re actually using; Also, I’m adding mlx5 and libverbs that are needed to compile all the code above.

With the new makefile, the output of ./test is correct:

I’m removing from the snipped all the prints from EAL and PMD which I have already copy-pasted earlier.

Cool, now you can include the DPDK libs into your C++ application with really no effort, just a simple modification of your Makefile should work.

Leave a Reply