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.
Solution
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/pcapplusplusso I copied them from the installation folders into there.OneAPI has its own example projects and come with their
CMakeLists.txtwhich is easier to build upon and add the needed lines from the PcapPlusPlus library.Modifications to the Code
So I choose the vector-add example, downloaded it and replaced the code in
src/vector-add-buffers.cppwith the code of the PcapPlusPlus example. Keeping includes forsycl/sycl.hppand<sycl/ext/intel/fpga_extensions.hpp>as that is what I need later on.Modifications to the CMakeLists.txt files
The first modification has to be made in CMakeLists.txt to prevent the issue that the
detect_pcap_version.ccan't be read. Therefore the line:project(VectorAdd CXX)needs a "C" added to it and should look likeproject(VectorAdd CXX C)Next in the src/CMakeLists.txt needs to be added the
find_package(PcapPlusPlus REQUIRED)line. I placed it inSECTION 1right above theadd_executable(${TARGET_NAME} ${SOURCE_FILE}).Also it needs the line
target_link_libraries(${TARGET_NAME} PUBLIC PcapPlusPlus::Pcap++)after theset_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "${LINK_FLAGS}")line. This slightly modified function from the PcapPlusPlus example needs to be added in eachSECTIONwith the accordingTARGET_NAMEvariable.Build
The next step is following oneAPIs instructions in the README.md to build the project and adding the compiler parameters to the
cmakecommand:mkdir buildcd buildcmake -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx ..With these steps a Makefile should be created in this
buildfolder which can now be executed. As the README.md states, one can choose from the options, for this example I usedmake cpu-gpuand wait until the process finishes.Execute
Now that the binary is created. To use it, we still need the pcap of PcapPlusPlus placed in this folder. With
./vector-add-buffersit executes successfully as SYCL code.