From 555fd59f09202f4f744bf7f22fa3be2e351fb8d5 Mon Sep 17 00:00:00 2001 From: Sergey Kosukhin <sergey.kosukhin@mpimet.mpg.de> Date: Fri, 14 Feb 2025 08:59:24 +0000 Subject: [PATCH] Detect the endianness with CMake (icon-libraries/libfortran-support!111) ## What is the bug The endianness detection in `src/util_hash.c` produces a false result on macOS with GCC 13 or later. For whatever reason, [`#include <sys/param.h>`](https://gitlab.dkrz.de/icon-libraries/libfortran-support/-/blob/316d3dc6edb6ef0f4f1b9adaf9f3cb27a7bb831a/src/util_hash.c#L49) does not define the `__DARWIN_BYTE_ORDER` and `__DARWIN_LITTLE_ENDIAN` macros when [`#define _POSIX_C_SOURCE 200112L`](https://gitlab.dkrz.de/icon-libraries/libfortran-support/-/blob/316d3dc6edb6ef0f4f1b9adaf9f3cb27a7bb831a/src/util_hash.c#L45). And that leads to the wrong values of the `HASH_LITTLE_ENDIAN` and `HASH_BIG_ENDIAN` macros. See also https://gitlab.dkrz.de/icon/icon-mpim/-/merge_requests/684#note_300951. ## How do you fix it The endianness detection is delegated to CMake. Approved-by: Yen-Chen Chen <yen-chen.chen@tum.de> Merged-by: Yen-Chen Chen <yen-chen.chen@tum.de> Changelog: bugfix --- src/CMakeLists.txt | 3 +++ src/config.h.in | 2 ++ src/util_hash.c | 52 +++++----------------------------------------- src/util_hash.h | 1 + 4 files changed, 11 insertions(+), 47 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3162cb3..aecab81 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,6 +15,9 @@ check_include_files("link.h" HAVE_LINK_H) check_include_files("unwind.h" HAVE_UNWIND_H) check_include_files("sys/resource.h" HAVE_GETRUSAGE) +include(TestBigEndian) +test_big_endian(HAVE_BIG_ENDIAN) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) diff --git a/src/config.h.in b/src/config.h.in index 07b9d54..0334621 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -16,3 +16,5 @@ #cmakedefine HAVE_UNWIND_H @HAVE_UNWIND_H@ #cmakedefine HAVE_GETRUSAGE @HAVE_GETRUSAGE@ + +#cmakedefine HAVE_BIG_ENDIAN @HAVE_BIG_ENDIAN@ diff --git a/src/util_hash.c b/src/util_hash.c index a70cbb0..f68b3f2 100644 --- a/src/util_hash.c +++ b/src/util_hash.c @@ -42,63 +42,21 @@ * ------------------------------------------------------------------------------- */ -#define _POSIX_C_SOURCE 200112L +#include "config.h" -#include <stdint.h> /* defines uint32_t etc */ - -#include <sys/param.h> /* attempt to define endianness */ - -#if (defined(__APPLE__) && defined(__MACH__)) - -#if (defined(__DARWIN_BYTE_ORDER) \ - && (__DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN)) -#define HASH_LITTLE_ENDIAN 1 -#define HASH_BIG_ENDIAN 0 -#else -#define HASH_LITTLE_ENDIAN 0 -#define HASH_BIG_ENDIAN 1 -#endif +#include "util_hash.h" -#elif defined(_AIX) +#include <stddef.h> +#include <stdint.h> -#if (defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)) -#define HASH_LITTLE_ENDIAN 1 -#define HASH_BIG_ENDIAN 0 -#else +#ifdef HAVE_BIG_ENDIAN #define HASH_LITTLE_ENDIAN 0 #define HASH_BIG_ENDIAN 1 -#endif - -#elif defined(__linux) - -#include <endian.h> - -#if (defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN)) -#define HASH_LITTLE_ENDIAN 1 -#define HASH_BIG_ENDIAN 0 #else -#define HASH_LITTLE_ENDIAN 0 -#define HASH_BIG_ENDIAN 1 -#endif - -#elif defined(_SX) - -#define HASH_LITTLE_ENDIAN 0 -#define HASH_BIG_ENDIAN 1 - -#elif defined(__NEC__) - #define HASH_LITTLE_ENDIAN 1 #define HASH_BIG_ENDIAN 0 - -#else - -#error "Couldn't determine endianness." - #endif -#include "util_hash.h" - #define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k)))) /* diff --git a/src/util_hash.h b/src/util_hash.h index 154c930..9499d60 100644 --- a/src/util_hash.h +++ b/src/util_hash.h @@ -12,6 +12,7 @@ #ifndef UTIL_HASH_H #define UTIL_HASH_H +#include <stddef.h> #include <stdint.h> #ifdef __cplusplus -- GitLab