diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index 3dbfe2ac6..6fde78c36 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -684,6 +684,17 @@ jobs: make -C programs zstd-pgo ./programs/zstd -b + musl-build: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: Install musl-tools + run: | + sudo apt install -y musl-tools + - name: Compile the project with musl-gcc + run: | + CC=musl-gcc CPPFLAGS=-DZSTD_USE_C90_QSORT make -j V=1 zstd + intel-cet-compatibility: runs-on: ubuntu-latest steps: diff --git a/lib/README.md b/lib/README.md index b37f5fc4f..9df516c5a 100644 --- a/lib/README.md +++ b/lib/README.md @@ -193,6 +193,10 @@ The file structure is designed to make this selection manually achievable for an and assembly decoding loops. You may want to use this macro if these loops are slower on your platform. +- The macro `ZSTD_USE_C90_QSORT` forces usage of C90's `qsort()`, + for situations where the code cannot determine that `qsort_r()` is not supported, + such as, for example, older versions of `musl`. + #### Windows : using MinGW+MSYS to create DLL DLL can be created using MinGW+MSYS with the `make libzstd` command. diff --git a/lib/dictBuilder/cover.c b/lib/dictBuilder/cover.c index a71370c72..6d8889669 100644 --- a/lib/dictBuilder/cover.c +++ b/lib/dictBuilder/cover.c @@ -24,9 +24,9 @@ /* qsort_r is an extension. */ #if defined(__linux) || defined(__linux__) || defined(linux) || defined(__gnu_linux__) || \ defined(__CYGWIN__) || defined(__MSYS__) -#if !defined(_GNU_SOURCE) && !defined(__ANDROID__) /* NDK doesn't ship qsort_r(). */ -#define _GNU_SOURCE -#endif +# if !defined(_GNU_SOURCE) && !defined(__ANDROID__) /* NDK doesn't ship qsort_r(). */ +# define _GNU_SOURCE +# endif #endif #include /* fprintf */ @@ -241,8 +241,9 @@ typedef struct { unsigned d; } COVER_ctx_t; -#if !defined(_GNU_SOURCE) && !defined(__APPLE__) && !defined(_MSC_VER) -/* C90 only offers qsort() that needs a global context. */ +#if defined(ZSTD_USE_C90_QSORT) \ + || (!defined(_GNU_SOURCE) && !defined(__APPLE__) && !defined(_MSC_VER)) +/* Use global context for non-reentrant sort functions */ static COVER_ctx_t *g_coverCtx = NULL; #endif @@ -328,7 +329,7 @@ static void stableSort(COVER_ctx_t *ctx) { qsort_r(ctx->suffix, ctx->suffixSize, sizeof(U32), ctx, (ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp)); -#elif defined(_GNU_SOURCE) +#elif defined(_GNU_SOURCE) && !defined(ZSTD_USE_C90_QSORT) qsort_r(ctx->suffix, ctx->suffixSize, sizeof(U32), (ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp), ctx); @@ -342,7 +343,7 @@ static void stableSort(COVER_ctx_t *ctx) { (ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp)); #else /* C90 fallback.*/ g_coverCtx = ctx; - /* TODO(cavalcanti): implement a reentrant qsort() when is not available. */ + /* TODO(cavalcanti): implement a reentrant qsort() when _r is not available. */ qsort(ctx->suffix, ctx->suffixSize, sizeof(U32), (ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp)); #endif