Skip to content

Provide common cmake project interface. - #2153

Open
Dimi1010 wants to merge 10 commits into
seladb:devfrom
Dimi1010:cmake/universal-interface
Open

Provide common cmake project interface.#2153
Dimi1010 wants to merge 10 commits into
seladb:devfrom
Dimi1010:cmake/universal-interface

Conversation

@Dimi1010

Copy link
Copy Markdown
Collaborator

Background

There are two common ways CMake packages are consumed: as an installed package or as a subdirectory. Currently the way PcapPlusPlus is consumed between the two methods is inconsistent in the following ways:

  • #include signatures can differ. #include <pcapplusplus/ArpLayer.h> is only available on <INSTALL_INTERFACE>.
  • CMake targets differ. PcapPlusPlus::Pcap++ vs Pcap++

Standardization of include signatures

PR #1789, added a new include signature #include <pcapplusplus/ArpLayer.h>. This was a partial implementation of #1586, with the intention of eventually transitioning fully to the <pcapplusplus/xxx> syntax. However the change was not ported to the <BUILD_INTERFACE>.

This inconsistency is addressed by moving all public headers into a subdirectory pcapplusplus (e.g. header/ArpLayer.h becomes header/pcapplusplus/ArpLayer.h). The change allows <BUILD_INTERFACE> to also utilize the include syntax #include <pcapplusplus/ArpLayer.h>.

Breaking changes and backwards compatibility

The relocation of the header files in a subfolder has the potential to break the following include signatures:

  • Direct include paths: #include "./<pcppRoot>/headers/ArpLayer.h". These paths do not rely on the include directory mechanism and explicitly define a path from their source to the include file. Since usage of these paths is rare across project boundaries, no compatibility layer was provided.

  • Old style include paths: #include "ArpLayer.h". To keep backwards compatibility, the <BUILD_INTERFACE> defines two include directories for the project headers: <pcppRoot>/headers and <pcppRoot>/headers/pcapplusplus. This allows both #include <ArpLayer.h> and #include <pcapplusplus/ArpLayer.h> to be resolved correctly.

The old signatures should eventually be deprecated, but this is outside the scope of this PR.

Standardization of CMake targets

CMake targets that are being imported from an installed package generally come in a Package::Target naming convention. This differs from normal targets which generally lack the Package:: prefix. This makes all targets included from a subdirectory inconsistent with their imported counterparts. To solve that problem, CMake provides an ALIAS target type, which is a pseudo target that acts as a read-only symbolic link to an actual target.

The PR adds the following ALIAS targets to standardize the CMake target API:

  • PcapPlusPlus::Common++ (alias for Common++)
  • PcapPlusPlus::Packet++ (alias for Packet++)
  • PcapPlusPlus::Pcap++ (alias for Pcap++)

The following targets were not provided with an alias target, even though they are exported during install:

  • light_pcapng - The target is generally exported as a byproduct of an internal dependency. It should not be linked directly.
  • Executable targets inside the Examples/ folder.

Minor fixes

  • Fixed CotpLayer.h to utilize include paths instead of relying on relative path ../headers/CotpLayer.h.

Additional notes

  • The PR does not change any include paths inside the project's sources. Both the core modules and the examples continue to use old style #include <ArpLayer.h> signatures for the moment.

Dimi1010 added 2 commits May 25, 2026 18:46
The old include paths are preserved by adding an additional "<BUILD_INTERFACE>/pcapplusplus" directive.

Fixed `CotopLayer.cpp` which relied on `../headers/CotpLayer.h` instead of using the include directories.
Remove alias definition in Examples.
@Dimi1010 Dimi1010 added build any build issue refactoring labels May 25, 2026
@codecov

codecov Bot commented May 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.79%. Comparing base (ead1dc8) to head (b850a3f).

Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #2153      +/-   ##
==========================================
- Coverage   82.79%   82.79%   -0.01%     
==========================================
  Files         331      331              
  Lines       60047    60040       -7     
  Branches    12388    12657     +269     
==========================================
- Hits        49714    49708       -6     
+ Misses       9452     9450       -2     
- Partials      881      882       +1     
Flag Coverage Δ
23.11.6 7.25% <ø> (-0.01%) ⬇️
24.11.5 7.26% <ø> (-0.04%) ⬇️
25.11.1 7.30% <ø> (+0.01%) ⬆️
alpine320 76.86% <ø> (ø)
fedora42 76.42% <ø> (-0.01%) ⬇️
macos-14 82.26% <ø> (ø)
macos-15 82.25% <ø> (-0.01%) ⬇️
mingw32 70.97% <ø> (ø)
mingw64 70.92% <ø> (+0.06%) ⬆️
npcap ?
rhel94 76.23% <ø> (ø)
ubuntu2204 76.27% <ø> (+<0.01%) ⬆️
ubuntu2204-icpx 59.32% <ø> (ø)
ubuntu2404 76.56% <ø> (+<0.01%) ⬆️
ubuntu2404-arm64 76.55% <ø> (ø)
ubuntu2604 76.50% <ø> (-0.03%) ⬇️
unittest 82.79% <ø> (-0.01%) ⬇️
windows-2022 85.81% <ø> (+0.12%) ⬆️
windows-2025 85.54% <ø> (+0.12%) ⬆️
winpcap 85.84% <ø> (+0.20%) ⬆️
xdp 52.88% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Dimi1010
Dimi1010 marked this pull request as ready for review June 24, 2026 06:47
@Dimi1010
Dimi1010 requested a review from seladb as a code owner June 24, 2026 06:47

@tigercosmos tigercosmos left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@seladb

seladb commented Jul 9, 2026

Copy link
Copy Markdown
Owner

I don't like moving all headers under pcapplusplus/. I asked Claude and it suggested the following:

1. Generate a "shim" directory of forwarding headers (most common alternative)
At configure time (or via a small script), generate a pcapplusplus/ directory in the build tree containing thin wrapper headers, e.g.:

// build/generated_include/pcapplusplus/ArpLayer.h
#include "ArpLayer.h"

Then add that generated directory to the BUILD_INTERFACE:

cmaketarget_include_directories(PacketPP PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/generated_include>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/header>
    $<INSTALL_INTERFACE:include>
    $<INSTALL_INTERFACE:include/pcapplusplus>
)

This is what a lot of projects do (e.g. via file(GENERATE ...) per header, or a foreach loop over the header list creating each shim with configure_file/file(WRITE ...)). It keeps the real files exactly where they are, so no source-tree reorganization, no updates to #include "..." paths inside the library's own .cpp files, and no churn in the git history/blame for every header.

@Dimi1010

Dimi1010 commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator Author

I somewhat dislike shims, tbh. I have seen them used for backwards compatibility for when headers are moved and no other option is available, but I would prefer to avoid them otherwise, since they generate build system churn.

From #1586 and #1789, I thought the long term goal was to eventually migrate to <pcapplusplus/xxx.h> being the primary include signature, with the <xxx.h> signature being deprecated? If that is the case, IMO it makes more sense to have the primary signature not require file generation, instead of the opposite. It also makes the new include structure clearer at a glance when looking at the project from the source tree.

Why do you dislike the headers being moved under pcapplusplus subfolder, btw?

@seladb

seladb commented Jul 12, 2026

Copy link
Copy Markdown
Owner

since they generate build system churn.

What do you mean by that? Can you give examples?

Why do you dislike the headers being moved under pcapplusplus subfolder, btw?

If we put the common interface aside, this folder structure seems weird and redundant:

PcapPlusPlus
  |- Common++
    |- header
      |- pcapplusplus
        ...
  |- Packet++
    |- header
      |- pcapplusplus
        ...
  |- Pcap++
    |- header
      |- pcapplusplus
        ...

I need to think about it more, but maybe it'd make more sense to have a structure like this?

include
  |- Common++
  |- Packet++
  |- Pcap++
src
  |- Common++
  |- Packet++
  |- Pcap++

@Dimi1010

Copy link
Copy Markdown
Collaborator Author

What do you mean by that? Can you give examples?

Mostly that they generate files that aren't strictly speaking needed.

On another note, the shims would break if we want to have a switch to enforce strict conformance to the package style #include <pcapplusplus/ArpLayer.h> headers (e.g. disable #include "ArpLayer.h" includes from working). I think such a switch would be nice to have eventually.

The entire shim architecture stems requires keeping the old style #include "ArpLayer.h" working indefinitely, which I thought we were trying to move away from. IMO, compatibility shims (if needed) should try to adapt the old interfaces to new ones, instead of the other way around if possible.

If we put the common interface aside, this folder structure seems weird and redundant:

PcapPlusPlus
  |- Common++
    |- header
      |- pcapplusplus
        ...
  |- Packet++
    |- header
      |- pcapplusplus
        ...
  |- Pcap++
    |- header
      |- pcapplusplus
        ...

I need to think about it more, but maybe it'd make more sense to have a structure like this?

include
  |- Common++
  |- Packet++
  |- Pcap++
src
  |- Common++
  |- Packet++
  |- Pcap++

Hmm, option 1 does appear a bit redundant. I am not super happy with it either, but it is a somewhat common convention as it is simple to setup and maintain out of the box as it works identical for both build and install interfaces. No extra steps needed. The install step is also a simple copy.

The issue I have with option 2 is that it removes all project module boundaries (module per top level folder). I think it might have been fine if they all compiled to one target, but we have Common, Packet and Pcap as separate targets / libraries. Keeping them separate is better, since CMake works better with a single folder per submodule, than a module split across 2 folders, which also contain files from other modules.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build any build issue refactoring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants