From 82d0af2c45ce44fc5519b4dddb98fa5685d57bd0 Mon Sep 17 00:00:00 2001 From: Glenn Fiedler Date: Sat, 11 Jul 2026 12:12:06 -0400 Subject: [PATCH 1/2] Prepare CMake build for vcpkg packaging Two changes needed to package netcode in the vcpkg registry, plus a version fix: - Only default CMAKE_MSVC_RUNTIME_LIBRARY to the static CRT when the integrator hasn't set it. vcpkg validates that installed libraries match the triplet's CRT linkage (dynamic on x64-windows), so the hardcoded static runtime would fail its post-build checks. - Add NETCODE_BUILD_TESTS (defaults ON at top level, following the serialize pattern) so package builds can skip the example, soak, profile and test executables that never get installed. - Bump the CMake project version to 1.3.3: v1.3.2 was tagged with the project version still reporting 1.3.1, the same missed bump that reliable v1.3.2 shipped with. Co-Authored-By: Claude Fable 5 --- CMakeLists.txt | 56 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6531f92..3635fee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,8 +5,19 @@ project(netcode VERSION 1.3.3 LANGUAGES C CXX) set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) -# static MSVC runtime, matching the previous premake configuration -set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") +# is this the top level project, or pulled in via add_subdirectory / FetchContent? +if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + set(NETCODE_TOP_LEVEL TRUE) +else() + set(NETCODE_TOP_LEVEL FALSE) +endif() + +# static MSVC runtime by default, matching the previous premake configuration. package +# managers (e.g. vcpkg) pass their own CMAKE_MSVC_RUNTIME_LIBRARY to match the CRT +# linkage their consumers expect. +if(NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") +endif() if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) @@ -32,6 +43,7 @@ endif() option(NETCODE_SANITIZE "Build with AddressSanitizer and UndefinedBehaviorSanitizer" OFF) option(NETCODE_FUZZ "Build the fuzz targets" OFF) +option(NETCODE_BUILD_TESTS "Build netcode tests and examples" ${NETCODE_TOP_LEVEL}) option(NETCODE_SYSTEM_SODIUM "Link against the system libsodium instead of the vendored copy" OFF) option(NETCODE_INSTALL "Generate the install target (netcode.h and the netcode library)" ON) @@ -108,29 +120,33 @@ if(NETCODE_INSTALL) install(FILES netcode.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) endif() -# examples and long-running harnesses +if(NETCODE_BUILD_TESTS) -foreach(example client server client_server soak profile) - add_executable(${example} ${example}.c) - target_compile_options(${example} PRIVATE ${NETCODE_WARNINGS}) - target_link_libraries(${example} PRIVATE netcode) -endforeach() + # examples and long-running harnesses -# unit tests. test.cpp compiles netcode.c into itself with NETCODE_ENABLE_TESTS, -# so it links sodium directly, not the netcode library. the target cannot be -# named "test" (reserved by CTest) so the output name is set instead. + foreach(example client server client_server soak profile) + add_executable(${example} ${example}.c) + target_compile_options(${example} PRIVATE ${NETCODE_WARNINGS}) + target_link_libraries(${example} PRIVATE netcode) + endforeach() -enable_testing() + # unit tests. test.cpp compiles netcode.c into itself with NETCODE_ENABLE_TESTS, + # so it links sodium directly, not the netcode library. the target cannot be + # named "test" (reserved by CTest) so the output name is set instead. -add_executable(netcode_test test.cpp) -set_target_properties(netcode_test PROPERTIES OUTPUT_NAME test) -target_compile_options(netcode_test PRIVATE ${NETCODE_WARNINGS}) -target_link_libraries(netcode_test PRIVATE sodium) -if(WIN32) - target_link_libraries(netcode_test PRIVATE ws2_32 iphlpapi) -endif() + enable_testing() + + add_executable(netcode_test test.cpp) + set_target_properties(netcode_test PROPERTIES OUTPUT_NAME test) + target_compile_options(netcode_test PRIVATE ${NETCODE_WARNINGS}) + target_link_libraries(netcode_test PRIVATE sodium) + if(WIN32) + target_link_libraries(netcode_test PRIVATE ws2_32 iphlpapi) + endif() -add_test(NAME netcode_test COMMAND netcode_test) + add_test(NAME netcode_test COMMAND netcode_test) + +endif() # fuzz targets. each harness compiles netcode.c into itself (like the test runner) # so it links sodium directly, not the netcode library. From 6fa4adedb872ae3756fc21cef7bf8affbb71c2f3 Mon Sep 17 00:00:00 2001 From: Glenn Fiedler Date: Sat, 11 Jul 2026 13:25:12 -0400 Subject: [PATCH 2/2] Add version macros to netcode.h and check them in the release workflow netcode.h now reports its version via NETCODE_VERSION_FULL and NETCODE_VERSION_MAJOR/MINOR/PATCH, matching the convention reliable follows. The release check workflow now verifies the header macros agree with each other, with the CMake project version, and with the release tag. Co-Authored-By: Claude Fable 5 --- .github/workflows/release-check.yml | 24 +++++++++++++++++++----- netcode.h | 5 +++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release-check.yml b/.github/workflows/release-check.yml index dffbb89..21198ef 100644 --- a/.github/workflows/release-check.yml +++ b/.github/workflows/release-check.yml @@ -18,17 +18,31 @@ jobs: - name: Check release version run: | cmake_version=$(sed -nE 's/^project\(netcode VERSION ([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' CMakeLists.txt) - if [ -z "$cmake_version" ]; then - echo "::error::Could not extract the project version from CMakeLists.txt" + header_full=$(sed -nE 's/^#define NETCODE_VERSION_FULL[[:space:]]+"([0-9]+\.[0-9]+\.[0-9]+)".*/\1/p' netcode.h) + major=$(sed -nE 's/^#define NETCODE_VERSION_MAJOR[[:space:]]+([0-9]+).*/\1/p' netcode.h) + minor=$(sed -nE 's/^#define NETCODE_VERSION_MINOR[[:space:]]+([0-9]+).*/\1/p' netcode.h) + patch=$(sed -nE 's/^#define NETCODE_VERSION_PATCH[[:space:]]+([0-9]+).*/\1/p' netcode.h) + if [ -z "$cmake_version" ] || [ -z "$header_full" ] || [ -z "$major" ] || [ -z "$minor" ] || [ -z "$patch" ]; then + echo "::error::Could not extract versions (CMakeLists.txt: '$cmake_version', NETCODE_VERSION_FULL: '$header_full', MAJOR/MINOR/PATCH: '$major.$minor.$patch')" + exit 1 + fi + echo "CMakeLists.txt project version: $cmake_version" + echo "netcode.h NETCODE_VERSION_FULL: $header_full" + echo "netcode.h MAJOR.MINOR.PATCH: $major.$minor.$patch" + if [ "$header_full" != "$major.$minor.$patch" ]; then + echo "::error::NETCODE_VERSION_FULL ($header_full) does not match NETCODE_VERSION_MAJOR/MINOR/PATCH ($major.$minor.$patch) in netcode.h" + exit 1 + fi + if [ "$cmake_version" != "$header_full" ]; then + echo "::error::project(netcode VERSION $cmake_version) in CMakeLists.txt does not match NETCODE_VERSION_FULL ($header_full) in netcode.h" exit 1 fi - echo "CMakeLists.txt project version: $cmake_version" case "$GITHUB_REF" in refs/tags/*) tag_version="${GITHUB_REF_NAME#v}" - echo "Release tag version: $tag_version" + echo "Release tag version: $tag_version" if [ "$tag_version" != "$cmake_version" ]; then - echo "::error::Tag $GITHUB_REF_NAME does not match project(netcode VERSION $cmake_version) in CMakeLists.txt — bump the CMake project version as part of the release." + echo "::error::Tag $GITHUB_REF_NAME does not match version $cmake_version in CMakeLists.txt and netcode.h — bump both as part of the release." exit 1 fi ;; diff --git a/netcode.h b/netcode.h index bf8932d..477aa56 100755 --- a/netcode.h +++ b/netcode.h @@ -25,6 +25,11 @@ #ifndef NETCODE_H #define NETCODE_H +#define NETCODE_VERSION_FULL "1.3.3" +#define NETCODE_VERSION_MAJOR 1 +#define NETCODE_VERSION_MINOR 3 +#define NETCODE_VERSION_PATCH 3 + /* IMPORTANT: netcode is single-threaded by design and is not thread safe.