Inclusion pcapplusplus in project via CMake

1.3k Views Asked by At

I installed pcapplusplus on Ubuntu (Downloaded package from here: https://github.com/seladb/PcapPlusPlus/releases/tag/v21.11). The example that was in the archive compiles and works, everything is fine with it! But when I try to include the library in my project using CMake nothing works.

I write a line in CMakeLists.txt file:

include_directories("/usr/local/include/pcapplusplus")

After that, the header files are connected to the project. However, the project does not compile, various errors appear depending on the functions that I use. Most likely the linker does not see the files: libCommon++.a, libPacket++.a, and libPcap++.a. I tried to connect them like this:

target_link_libraries(${PROJECT_NAME} libCommon++.a libPacket++.a libPcap++.a)

But it did not help. Tried this:

find_package(pcapplusplus REQUIRED)
include_directories(${PCAPPLUSPLUS_INCLUDE_DIRS})

This didn't help either.

In fact, other people have already encountered such a problem, for example, netleap tom wrote about this on the StackOverflow. cmake linking against static libraries - do you have to tell cmake where to look? However, no one there suggested a solution to him. I hope someone will tell me what to do.

udp.

Hello World from here for example:

#include <IPv4Layer.h>
#include <Packet.h>
#include <PcapFileDevice.h>

int main(int argc, char* argv[])
{
    pcpp::PcapFileReaderDevice reader("1_packet.pcap");
    if (!reader.open())
    {
        printf("Error opening the pcap file\n");
        return 1;
    }
    pcpp::RawPacket rawPacket;
    if (!reader.getNextPacket(rawPacket))
    {
        printf("Couldn't read the first packet in the file\n");
        return 1;
    }
    if (parsedPacket.isPacketOfType(pcpp::IPv4))
    {
        pcpp::IPv4Address srcIP = parsedPacket.getLayerOfType<pcpp::IPv4Layer>()->getSrcIpAddress();
        pcpp::IPv4Address destIP = parsedPacket.getLayerOfType<pcpp::IPv4Layer>()->getDstIpAddress();
        printf("Source IP is '%s'; Dest IP is '%s'\n", srcIP.toString().c_str(), destIP.toString().c_str());
    }
    reader.close();
    return 0;
}

If I add only this to CMake:

include_directories("/usr/local/include/pcapplusplus")

I have the following errors:

/usr/bin/ld: CMakeFiles/test.dir/main.cpp.o: in function `pcpp::Packet::~Packet()':
main.cpp:(.text._ZN4pcpp6PacketD2Ev[_ZN4pcpp6PacketD5Ev]+0x17): undefined reference to `pcpp::Packet::destructPacketData()'
/usr/bin/ld: CMakeFiles/test.dir/main.cpp.o: in function `pcpp::Packet::~Packet()':
main.cpp:(.text._ZN4pcpp6PacketD0Ev[_ZN4pcpp6PacketD5Ev]+0x17): undefined reference to `pcpp::Packet::destructPacketData()'
/usr/bin/ld: CMakeFiles/test.dir/main.cpp.o: in function `pcpp::IPv4Layer* pcpp::Packet::getLayerOfType<pcpp::IPv4Layer>(bool) const':
main.cpp:(.text._ZNK4pcpp6Packet14getLayerOfTypeINS_9IPv4LayerEEEPT_b[_ZNK4pcpp6Packet14getLayerOfTypeINS_9IPv4LayerEEEPT_b]+0x1b): undefined reference to `typeinfo for pcpp::IPv4Layer'
/usr/bin/ld: main.cpp:(.text._ZNK4pcpp6Packet14getLayerOfTypeINS_9IPv4LayerEEEPT_b[_ZNK4pcpp6Packet14getLayerOfTypeINS_9IPv4LayerEEEPT_b]+0x22): undefined reference to `typeinfo for pcpp::Layer'
/usr/bin/ld: main.cpp:(.text._ZNK4pcpp6Packet14getLayerOfTypeINS_9IPv4LayerEEEPT_b[_ZNK4pcpp6Packet14getLayerOfTypeINS_9IPv4LayerEEEPT_b]+0x4e): undefined reference to `typeinfo for pcpp::IPv4Layer'
/usr/bin/ld: main.cpp:(.text._ZNK4pcpp6Packet14getLayerOfTypeINS_9IPv4LayerEEEPT_b[_ZNK4pcpp6Packet14getLayerOfTypeINS_9IPv4LayerEEEPT_b]+0x55): undefined reference to `typeinfo for pcpp::Layer'
/usr/bin/ld: CMakeFiles/test.dir/main.cpp.o: in function `main.cold':
main.cpp:(.text.unlikely+0x58): undefined reference to `pcpp::Packet::destructPacketData()'
/usr/bin/ld: main.cpp:(.text.unlikely+0x63): undefined reference to `pcpp::RawPacket::~RawPacket()'
/usr/bin/ld: main.cpp:(.text.unlikely+0x8a): undefined reference to `pcpp::IFileDevice::~IFileDevice()'

More here: image.

If I add this to CMake:

target_link_libraries(${PROJECT_NAME} libCommon++.a libPacket++.a libPcap++.a)

I have the following errors (first five):

/usr/bin/ld: /usr/local/lib/libPacket++.a(EthLayer.o): in function `pcpp::EthLayer::toString[abi:cxx11]() const':
/tmp/cirrus-ci-build/PcapPlusPlus/Packet++/src/EthLayer.cpp:104: undefined reference to `pcpp::MacAddress::toString[abi:cxx11]() const'
/usr/bin/ld: /tmp/cirrus-ci-build/PcapPlusPlus/Packet++/src/EthLayer.cpp:104: undefined reference to `pcpp::MacAddress::toString[abi:cxx11]() const'
/usr/bin/ld: /usr/local/lib/libPacket++.a(EthDot3Layer.o): in function `pcpp::EthDot3Layer::toString[abi:cxx11]() const':
/tmp/cirrus-ci-build/PcapPlusPlus/Packet++/src/EthDot3Layer.cpp:36: undefined reference to `pcpp::MacAddress::toString[abi:cxx11]() const'
/usr/bin/ld: /tmp/cirrus-ci-build/PcapPlusPlus/Packet++/src/EthDot3Layer.cpp:36: undefined reference to `pcpp::MacAddress::toString[abi:cxx11]() const'
/usr/bin/ld: /usr/local/lib/libPacket++.a(DhcpLayer.o): in function `pcpp::DhcpLayer::getClientHardwareAddress() const':
/tmp/cirrus-ci-build/PcapPlusPlus/Packet++/src/DhcpLayer.cpp:83: undefined reference to `pcpp::MacAddress::Zero'
/usr/bin/ld: /usr/local/lib/libPacket++.a(PayloadLayer.o): in function `pcpp::PayloadLayer::PayloadLayer(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
/tmp/cirrus-ci-build/PcapPlusPlus/Packet++/src/PayloadLayer.cpp:24: undefined reference to `pcpp::hexStringToByteArray(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned char*, unsigned long)'

More here: image2

 undefined reference to `pcpp::IFileReaderDevice::IFileReaderDevice(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/usr/bin/ld: main.cpp:(.text.startup+0x63): undefined reference to `vtable for pcpp::PcapFileReaderDevice'
/usr/bin/ld: main.cpp:(.text.startup+0xb5): undefined reference to `pcpp::IFileDevice::~IFileDevice()'
/usr/bin/ld: CMakeFiles/test.dir/main.cpp.o:(.data.rel.ro._ZTIN4pcpp17IFileReaderDeviceE[_ZTIN4pcpp17IFileReaderDeviceE]+0x10): undefined reference to `typeinfo for pcpp::IFileDevice'
/usr/bin/ld: CMakeFiles/test.dir/main.cpp.o:(.data.rel.ro._ZTVN4pcpp17IFileReaderDeviceE[_ZTVN4pcpp17IFileReaderDeviceE]+0x28): undefined reference to `pcpp::IFileDevice::close()'
/usr/bin/ld: CMakeFiles/test.dir/main.cpp.o:(.data.rel.ro._ZTVN4pcpp17IFileReaderDeviceE[_ZTVN4pcpp17IFileReaderDeviceE]+0x38): undefined reference to `pcpp::IPcapDevice::setFilter(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
/usr/bin/ld: CMakeFiles/test.dir/main.cpp.o:(.data.rel.ro._ZTVN4pcpp17IFileReaderDeviceE[_ZTVN4pcpp17IFileReaderDeviceE]+0x40): undefined reference to `pcpp::IPcapDevice::clearFilter()'
/usr/bin/ld: CMakeFiles/test.dir/main.cpp.o:(.data.rel.ro._ZTVN4pcpp17IFileReaderDeviceE[_ZTVN4pcpp17IFileReaderDeviceE]+0x78): undefined reference to `non-virtual thunk to pcpp::IPcapDevice::setFilter(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
/usr/bin/ld: CMakeFiles/test.dir/main.cpp.o:(.data.rel.ro._ZTVN4pcpp17IFileReaderDeviceE[_ZTVN4pcpp17IFileReaderDeviceE]+0x80): undefined reference to `non-virtual thunk to pcpp::IPcapDevice::clearFilter()'
collect2: error: ld returned 1 exit status
2

There are 2 best solutions below

0
chel_random On

Solution: https://github.com/gleb-kun/pcappp_hw

As expected, errors occurred due to incorrect library connection using CMake.

A file FindPcapPlusPlus.cmake is required to connect. Add the following lines to the main file CMakeLists.txt:

find_package(PcapPlusPlus REQUIRED)
target_link_libraries(${PROJECT_NAME} ${PcapPlusPlus_LIBRARIES})

FindPcapPlusPlus.cmake file contents:

if (PC_PcapPlusPlus_INCLUDEDIR AND PC_PcapPlusPlus_LIBDIR)
    set(PcapPlusPlus_FIND_QUIETLY TRUE)
endif ()

find_package(PkgConfig REQUIRED)
pkg_check_modules(PC_PcapPlusPlus REQUIRED PcapPlusPlus)

set(PcapPlusPlus_VERSION ${PC_PcapPlusPlus_VERSION})

mark_as_advanced(PcapPlusPlus_INCLUDE_DIR PcapPlusPlus_LIBRARY)

foreach (LIB_NAME ${PC_PcapPlusPlus_LIBRARIES})
    find_library(${LIB_NAME}_PATH ${LIB_NAME} HINTS ${PC_PcapPlusPlus_LIBDIR})
    if (${LIB_NAME}_PATH)
        list(APPEND PcapPlusPlus_LIBS ${${LIB_NAME}_PATH})
    endif ()
endforeach ()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PcapPlusPlus
        REQUIRED_VARS PC_PcapPlusPlus_INCLUDEDIR PC_PcapPlusPlus_LIBDIR
        VERSION_VAR PcapPlusPlus_VERSION
        )

if (PcapPlusPlus_FOUND)
    set(PcapPlusPlus_INCLUDE_DIRS ${PC_PcapPlusPlus_INCLUDEDIR})
    set(PcapPlusPlus_LIBRARIES ${PcapPlusPlus_LIBS})
endif ()

if (PcapPlusPlus_FOUND AND NOT TARGET PcapPlusPlus::PcapPlusPlus)
    add_library(PcapPlusPlus::PcapPlusPlus INTERFACE IMPORTED)
    set_target_properties(PcapPlusPlus::PcapPlusPlus PROPERTIES
            INTERFACE_INCLUDE_DIRECTORIES "${PcapPlusPlus_INCLUDE_DIRS}"
            INTERFACE_LINK_LIBRARIES "${PcapPlusPlus_LIBRARIES}"
            INTERFACE_COMPILE_FLAGS "${PC_PcapPlusPlus_CFLAGS}"
            )
endif ()
0
qwerty_warrior On

try this

target_link_libraries(${PROJECT_NAME} Pcap++ Packet++ Common++ pcap pthread)

this is the order as listed in the pcapplusplus example mk file /usr/local/etc/PcapPlusPlus.mk