From 2686f6510d32c636714d60e55e7f43205910c416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Wed, 1 Jul 2026 11:08:25 +0200 Subject: [PATCH 1/2] Harden byte order detection Use __BYTE_ORDER__ for GCC/Clang, and include Linux/BSD-specific headers for endian detection. Fixes #135. --- include/protozero/config.hpp | 45 ++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/include/protozero/config.hpp b/include/protozero/config.hpp index 6fc774904..a12cb6438 100644 --- a/include/protozero/config.hpp +++ b/include/protozero/config.hpp @@ -22,17 +22,48 @@ documentation. #define PROTOZERO_BIG_ENDIAN 4321 // Find out which byte order the machine has. -#if defined(__BYTE_ORDER) -# if (__BYTE_ORDER == __LITTLE_ENDIAN) + +// __BYTE_ORDER__ is set by GCC and Clang. +#if !defined(PROTOZERO_BYTE_ORDER) && defined(__BYTE_ORDER__) +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ # define PROTOZERO_BYTE_ORDER PROTOZERO_LITTLE_ENDIAN -# endif -# if (__BYTE_ORDER == __BIG_ENDIAN) +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ # define PROTOZERO_BYTE_ORDER PROTOZERO_BIG_ENDIAN # endif -#else -// This probably isn't a very good default, but might do until we figure -// out something better. +#endif // defined(__BYTE_ORDER__) + +// On Linux, we can use endian.h. +#if !defined(PROTOZERO_BYTE_ORDER) && defined(__linux__) +# include +# if defined(__BYTE_ORDER) +# if (__BYTE_ORDER == __LITTLE_ENDIAN) +# define PROTOZERO_BYTE_ORDER PROTOZERO_LITTLE_ENDIAN +# elif (__BYTE_ORDER == __BIG_ENDIAN) +# define PROTOZERO_BYTE_ORDER PROTOZERO_BIG_ENDIAN +# endif +# endif +#endif // !defined(PROTOZERO_BYTE_ORDER) && defined(__linux__) + +// On BSD, we can use +#if !defined(PROTOZERO_BYTE_ORDER) && \ + (defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) +# include +# if defined(BYTE_ORDER) +# if (BYTE_ORDER == LITTLE_ENDIAN) +# define PROTOZERO_BYTE_ORDER PROTOZERO_LITTLE_ENDIAN +# elif (BYTE_ORDER == BIG_ENDIAN) +# define PROTOZERO_BYTE_ORDER PROTOZERO_BIG_ENDIAN +# endif +# endif +#endif + +// On Windows, we assume little endian. +#if !defined(PROTOZERO_BYTE_ORDER) && defined(_MSC_VER) # define PROTOZERO_BYTE_ORDER PROTOZERO_LITTLE_ENDIAN +#endif // !defined(PROTOZERO_BYTE_ORDER) && defined(_MSC_VER) + +#if !defined(PROTOZERO_BYTE_ORDER) +# error "Could not determine byte order; define PROTOZERO_BYTE_ORDER" #endif // Check whether __builtin_bswap is available From 7c5d19b4d8c730fcfe4253981e55a62ccf7c8da7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Wed, 1 Jul 2026 12:19:16 +0200 Subject: [PATCH 2/2] Add CI workflows for big-endian architectures Introduce new CI job for building and testing on big-endian platforms (s390x). --- .github/workflows/ci.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 69976c223..6274ebc1c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -112,6 +112,41 @@ jobs: - uses: ./.github/actions/build - uses: ./.github/actions/ctest + big-endian: + runs-on: ubuntu-24.04 + timeout-minutes: 45 + steps: + - uses: actions/checkout@v7 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: s390x + - name: Build and test on s390x (big-endian) + run: | + docker run --rm --platform linux/s390x \ + -v "${{ github.workspace }}:/src" \ + -w /src \ + -e DEBIAN_FRONTEND=noninteractive \ + debian:bookworm \ + bash -exc ' + apt-get update -qq + apt-get install -y \ + cmake \ + g++ \ + libprotobuf-dev \ + make \ + protobuf-compiler \ + python3-minimal + python3 -c "import sys; assert sys.byteorder == \"big\"" + mkdir -p build + cd build + cmake -LA .. \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_CXX_STANDARD=14 + cmake --build . --parallel 2 + ctest --output-on-failure --parallel 2 + ' + ubuntu-latest: runs-on: ubuntu-24.04 timeout-minutes: 30