Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 89 additions & 1 deletion Common++/header/PcapPlusPlusVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,97 @@
/// @brief The main namespace for the PcapPlusPlus lib
namespace pcpp
{
/// @def PCAPPLUSPLUS_VERSION_YEAR
/// @brief The year component of the PcapPlusPlus version (e.g., 25 for 2025)
#define PCAPPLUSPLUS_VERSION_YEAR 25

/// @def PCAPPLUSPLUS_VERSION_MONTH
/// @brief The month component of the PcapPlusPlus version (e.g., 5 for May)
#define PCAPPLUSPLUS_VERSION_MONTH 5

/// @def PCAPPLUSPLUS_VERSION_PATCH
/// @brief The patch number component of the PcapPlusPlus version
#define PCAPPLUSPLUS_VERSION_PATCH 0

/// @def PCAPPLUSPLUS_VERSION_DEV
/// @brief Development flag: non-zero for development/nightly builds, zero for official releases
#define PCAPPLUSPLUS_VERSION_DEV 1

/// @def PCAPPLUSPLUS_VERSION
/// @brief Short version string (e.g., "25.05" for official release or "25.05+" for development)
#define PCAPPLUSPLUS_VERSION "25.05+"

@seladb seladb May 4, 2026

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

It's possible to create this string using macros, but it'll be very complex, so maybe it's easier to keep it as is...

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.

I suppose we can manually set it.

A potential alternative is to have the cmake build system generate the version file, like it does with the package config files. I think that is generally more flexible and we would only need to change the version in the CMakeLists.


Also, do you think we should include the patch number in all versions? (eg. 25.05.0), so people always expect it if they decide to do magic with the version string?

@Dimi1010 Dimi1010 May 5, 2026

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.

A potential alternative is to have the cmake build system generate the version file, like it does with the package config files. I think that is generally more flexible and we would only need to change the version in the CMakeLists.

@seladb Additional discussion may be needed separately, but I managed to get CMake to compile a version from the git tags. The versioning is based on the signature major.minor.patch.tweak.

It fetches the MAJOR, MINOR, PATCH from the most recent tag. (eg. last release)
It then calculates the Tweak version as the number of commits past the most recent tag the build is.

If we are precisely on the release commit, the tweak version will be 0 and the full version maj.min.patch.0, if we are 1 commit past it it will be maj.min.patch.1. This can then be used to determine official releases (tweak 0) vs nightly / dev builds (tweak != 0).

The solution will allow us to have rolling versions unique for each development build commit, so we don't have just a nebulous "DEV" version flag. For example the current master would be 25.05.0.201.

A extended version string can also be added with a commit hash, if we need to differentiate between commits on different branches, but I think most will be used from the master / dev line.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

I'm not sure we need a build version because we never publish those versions. We don't even publish patch versions... I think year.month.patch is enough for the version.

I managed to get CMake to compile a version from the git tags

I'm curious how does it work?

  • When does it run and fetch the tag from git? In every commit?
  • Does it fetch the latest tag?

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.

I think year.month.patch is enough for the version.

Sure. I guess that works.

I'm curious how does it work?

  • When does it run and fetch the tag from git? In every commit?
  • Does it fetch the latest tag?

It is based on git describe --tags --long --always, which is called during the CMake configure step. The command results in a string like v25.05-211-g1a2ad56b which can then be reformatted. From what I have seen, it fetches the latest tag that the current commit is derived from. The command can be configured to select only annotated tags (default), or any tags (--tags).

Also, on second thoughts it does have some inconvenient drawbacks. Main one is that it establishes a dependency on the git repo being available at configure time to compute the correct version. This leads to some problems when remote compilation is used, like building on WSL since the default behaviour of rsync does not copy the .git folder since it is not needed. The requirement should only be relevant when the lib is build from source tho, since installs don't really run the configure the same way.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Yes I agree. Version should probably be static and not rely on CMake configuration or on git.

Should we stick with what we have in this PR?

@Dimi1010 Dimi1010 May 17, 2026

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.

Version should probably be static and not rely on CMake configuration or on git.

Hmm, it might be fine to rely on CMake configuration to generate the Version.h header as long as the version in the configuration is static? We could have the cmake project version to be the "source of truth" for version.

project(MyLib VERSION 2.4.1)

configure_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/version.h.in
    ${CMAKE_CURRENT_BINARY_DIR}/generated/version.h
    @ONLY)

As a sidenote, setting project version would also allow consuming packages to designate required versions for the package directly in the build system like this find_package(PcapPlusPlus 25.04 ...).

Anyway, that can be handled in a separate PR, if we decide to do it as it does not strictly relate to the current PR.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

I'm not sure I understand this comment. Do you suggest adding another file version.h in addition to PcapPlusPlusVersion.h that is based on CMake?

As you said, we can probably merge this PR as is and address this separately later.

#define PCAPPLUSPLUS_VERSION_OFFICIAL "non-official release"

/// @def PCAPPLUSPLUS_VERSION_OFFICIAL
/// @brief String indicating whether this is an official or non-official release
#if PCAPPLUSPLUS_VERSION_DEV
# define PCAPPLUSPLUS_VERSION_OFFICIAL "non-official release"
#else
# define PCAPPLUSPLUS_VERSION_OFFICIAL "official release"
#endif

/// @def PCAPPLUSPLUS_MAKE_VERSION_FULL(year, month, patch, dev)
/// @brief Create a comparable numeric version from year, month, patch, and dev components
/// @param year The year component (e.g., 25 for 2025)
/// @param month The month component (1-12)
/// @param patch The patch number
/// @param dev The development flag (0 for official, 1 for dev)
#define PCAPPLUSPLUS_MAKE_VERSION_FULL(year, month, patch, dev) ((year) * 100000 + (month) * 1000 + (patch) * 10 + dev)

/// @def PCAPPLUSPLUS_MAKE_VERSION(year, month, patch)
/// @brief Create a comparable numeric version for official releases (dev=0)
/// @param year The year component
/// @param month The month component
/// @param patch The patch number
#define PCAPPLUSPLUS_MAKE_VERSION(year, month, patch) PCAPPLUSPLUS_MAKE_VERSION_FULL(year, month, patch, 0)

/// @def PCAPPLUSPLUS_VERSION_NUM
/// @brief The current PcapPlusPlus version as a comparable numeric value
#define PCAPPLUSPLUS_VERSION_NUM \
PCAPPLUSPLUS_MAKE_VERSION_FULL(PCAPPLUSPLUS_VERSION_YEAR, PCAPPLUSPLUS_VERSION_MONTH, PCAPPLUSPLUS_VERSION_PATCH, \
PCAPPLUSPLUS_VERSION_DEV)

/// @def PCAPPLUSPLUS_VERSION_EQUALS(major, minor, patch)
/// @brief Check if the current version equals the specified version
/// @param major The major (year) component to compare
/// @param minor The minor (month) component to compare
/// @param patch The patch number to compare
#define PCAPPLUSPLUS_VERSION_EQUALS(major, minor, patch) \
PCAPPLUSPLUS_VERSION_NUM == PCAPPLUSPLUS_MAKE_VERSION(major, minor, patch)

/// @def PCAPPLUSPLUS_VERSION_LOWER_THAN(year, month, patch)
/// @brief Check if the current version is lower than the specified version
/// @param year The year component to compare
/// @param month The month component to compare
/// @param patch The patch number to compare
#define PCAPPLUSPLUS_VERSION_LOWER_THAN(year, month, patch) \
PCAPPLUSPLUS_VERSION_NUM < PCAPPLUSPLUS_MAKE_VERSION(year, month, patch)

/// @def PCAPPLUSPLUS_VERSION_LOWER_OR_EQUAL_THAN(year, month, patch)
/// @brief Check if the current version is lower than or equal to the specified version
/// @param year The year component to compare
/// @param month The month component to compare
/// @param patch The patch number to compare
#define PCAPPLUSPLUS_VERSION_LOWER_OR_EQUAL_THAN(year, month, patch) \
PCAPPLUSPLUS_VERSION_NUM <= PCAPPLUSPLUS_MAKE_VERSION(year, month, patch)

/// @def PCAPPLUSPLUS_VERSION_HIGHER_THAN(year, month, patch)
/// @brief Check if the current version is higher than the specified version
/// @param year The year component to compare
/// @param month The month component to compare
/// @param patch The patch number to compare
#define PCAPPLUSPLUS_VERSION_HIGHER_THAN(year, month, patch) \
PCAPPLUSPLUS_VERSION_NUM > PCAPPLUSPLUS_MAKE_VERSION(year, month, patch)

/// @def PCAPPLUSPLUS_VERSION_HIGHER_OR_EQUAL_THAN(year, month, patch)
/// @brief Check if the current version is higher than or equal to the specified version
/// @param year The year component to compare
/// @param month The month component to compare
/// @param patch The patch number to compare
#define PCAPPLUSPLUS_VERSION_HIGHER_OR_EQUAL_THAN(year, month, patch) \
PCAPPLUSPLUS_VERSION_NUM >= PCAPPLUSPLUS_MAKE_VERSION(year, month, patch)

/// @def PCAPPLUSPLUS_VERSION_FULL
/// @brief Full version string including version and release type (e.g., "v25.05+ (non-official release)")
#define PCAPPLUSPLUS_VERSION_FULL "v" PCAPPLUSPLUS_VERSION " (" PCAPPLUSPLUS_VERSION_OFFICIAL ")"

/// @return PcapPlusPlus current version, e.g: 23.09. Notice that for non-official releases (which were pulled from
Expand Down
Loading