I want to use the C++ library PcapPlusPlus and it‘s header files in my SYCL code. More exactly I want to compile it with the Intel C++ Compiler (icpx
). I know how to program and know how C, Java and Python work but seem to have issues to work with C++ and using external libraries. I can't seem to make it work, to compile and link the library correctly. I tried it with CMake which I had to read into because I really had to use it the first time but more on this further down.
I am using CentOS Stream 8 and oneAPI Base Toolkit 2023.1 which I tested successfully with code that doesn't use 3rd party libraries.
So I downloaded the Github repository because I have to build it myself for CentOS Stream 8. I put the files into my project folder and went into package to start the build of the library like in the instructions with CMake and the compiler I want to use it with (icpx).
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx -DCMAKE_INSTALL_PREFIX=/path/to/PcapPlusPlus
As the instructions say, build and install it.
cmake --build build
cmake --install build
After that I tried to compile the code example of PcapPlusPlus with the instructions and CMake file they provide. This worked but did not use the icpx
compiler.
So I went ahead and searched on how I could link the libraries and header files with just using the icpx
command in the CLI. I stumbled upon the parameters -I
to add the path to the header files, -L
for the libraries and -l
to give the name of the library. PcapPlusPlus creates 3 static libraries.
icpx -I/path/to/installed/PcapPlusPlus/include -L/path/to/installed/PcapPlusPlus/lib -lCommon++ -lPacket++ -lPcap++ mysrc.cpp -o myexe
This command created a lot of "undefined reference" errors pointing at lines in the header files of Packet.h
. icpx
exits with the error:
icpx: error: linker command failed with exit code 1
Another try was to create a CMakeLists.txt
file that uses the icpx
compiler with the help of the CMakeLists.txt of the example of PcapPlusPlus and this documentation of Intel. It resulted in the following CMakeLists.txt
file
if (CMAKE_HOST_WIN32)
# need at least CMake 3.23 for IntelLLVM support of IntelSYCL package on Windows
cmake_minimum_required(VERSION 3.23)
else()
# CMake 3.20.5 is the minimum recommended for IntelLLVM on Linux
cmake_minimum_required(VERSION 3.20.5)
endif()
project(simple-sycl LANGUAGES CXX)
set(CMAKE_CXX_COMPILER icpx)
# popen()/pclose() are not C++ standards
set(CMAKE_CXX_EXTENSIONS ON)
find_package(PcapPlusPlus REQUIRED)
add_executable("${PROJECT_NAME}" main.cpp)
# We want to have the binary compiled in the same folder as the .cpp to be near the PCAP file
set_target_properties("${PROJECT_NAME}" PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
# Link with Pcap++ libraries
target_link_libraries("${PROJECT_NAME}" PUBLIC PcapPlusPlus::Pcap++)
I erased find_package(IntelSYCL REQUIRED)
as it led to errors of not finding IntelSYCL
The command to start the cmake
process was following:
cmake -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx -DPcapPlusPlus_ROOT=/path/to/PcapPlusPlus
This worked until the find_package
line for the PcapPlusPlus package, as it creates a C-file which the icpx
cannot read of course. When adding C
to the project()
it went through with no error but not creating a binary.
I also tried to use one of the oneAPI samples and modify the CMakeLists.txt
and adding the lines to find the package with the same errors.
Now I am stuck because I can't seem to find a solution for this linking issue and was wondering what I am doing wrong or if it is possible to use the library.
So with some help of @paleonix (thank you) and an idea I have come to an easy solution.
First of all, what I noticed that find_package(PcapPlusPlus REQUIRED)
needs, is the header files in the path /usr/local/include/pcapplusplus
so I copied them from the installation folders into there.
OneAPI has its own example projects and come with their CMakeLists.txt
which is easier to build upon and add the needed lines from the PcapPlusPlus library.
So I choose the vector-add example, downloaded it and replaced the code in src/vector-add-buffers.cpp
with the code of the PcapPlusPlus example. Keeping includes for sycl/sycl.hpp
and <sycl/ext/intel/fpga_extensions.hpp>
as that is what I need later on.
The first modification has to be made in CMakeLists.txt to prevent the issue that the detect_pcap_version.c
can't be read. Therefore the line:
project(VectorAdd CXX)
needs a "C" added to it and should look like project(VectorAdd CXX C)
Next in the src/CMakeLists.txt needs to be added the find_package(PcapPlusPlus REQUIRED)
line. I placed it in SECTION 1
right above the add_executable(${TARGET_NAME} ${SOURCE_FILE})
.
Also it needs the line target_link_libraries(${TARGET_NAME} PUBLIC PcapPlusPlus::Pcap++)
after the set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "${LINK_FLAGS}")
line. This slightly modified function from the PcapPlusPlus example needs to be added in each SECTION
with the according TARGET_NAME
variable.
The next step is following oneAPIs instructions in the README.md to build the project and adding the compiler parameters to the cmake
command:
mkdir build
cd build
cmake -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx ..
With these steps a Makefile should be created in this build
folder which can now be executed. As the README.md states, one can choose from the options, for this example I used make cpu-gpu
and wait until the process finishes.
Now that the binary is created. To use it, we still need the pcap of PcapPlusPlus placed in this folder. With ./vector-add-buffers
it executes successfully as SYCL code.