Skip to content

Commit aaf6022

Browse files
authored
Add zstd support for Python 3.14+ on Unix (#682)
This task was deferred from the initial Python 3.14 support. There's already support on Windows.
1 parent 9bb8bcb commit aaf6022

File tree

7 files changed

+98
-7
lines changed

7 files changed

+98
-7
lines changed

cpython-unix/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,9 @@ $(OUTDIR)/xz-$(XZ_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/
236236
$(OUTDIR)/zlib-$(ZLIB_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-zlib.sh
237237
$(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) zlib
238238

239+
$(OUTDIR)/zstd-$(ZSTD_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-zstd.sh
240+
$(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) zstd
241+
239242
PYTHON_HOST_DEPENDS := \
240243
$(PYTHON_DEP_DEPENDS) \
241244
$(HERE)/build-cpython-host.sh \
@@ -272,6 +275,7 @@ PYTHON_DEPENDS_$(1) := \
272275
$$(if $$(NEED_UUID),$$(OUTDIR)/uuid-$$(UUID_VERSION)-$$(PACKAGE_SUFFIX).tar) \
273276
$$(if $$(NEED_XZ),$$(OUTDIR)/xz-$$(XZ_VERSION)-$$(PACKAGE_SUFFIX).tar) \
274277
$$(if $$(NEED_ZLIB),$$(OUTDIR)/zlib-$$(ZLIB_VERSION)-$$(PACKAGE_SUFFIX).tar) \
278+
$$(if $$(NEED_ZSTD),$$(OUTDIR)/zstd-$$(ZSTD_VERSION)-$$(PACKAGE_SUFFIX).tar) \
275279
$$(NULL)
276280

277281
ALL_PYTHON_DEPENDS_$(1) = \

cpython-unix/build-cpython.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1213,7 +1213,7 @@ ${BUILD_PYTHON} ${ROOT}/fix_shebangs.py ${ROOT}/out/python/install
12131213
# downstream consumers.
12141214
OBJECT_DIRS="Objects Parser Parser/lexer Parser/pegen Parser/tokenizer Programs Python Python/deepfreeze"
12151215
OBJECT_DIRS="${OBJECT_DIRS} Modules"
1216-
for ext in _blake2 cjkcodecs _ctypes _ctypes/darwin _decimal _expat _hacl _io _multiprocessing _sha3 _sqlite _sre _testinternalcapi _xxtestfuzz ; do
1216+
for ext in _blake2 cjkcodecs _ctypes _ctypes/darwin _decimal _expat _hacl _io _multiprocessing _sha3 _sqlite _sre _testinternalcapi _xxtestfuzz _zstd; do
12171217
OBJECT_DIRS="${OBJECT_DIRS} Modules/${ext}"
12181218
done
12191219

cpython-unix/build-zstd.sh

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/env bash
2+
# This Source Code Form is subject to the terms of the Mozilla Public
3+
# License, v. 2.0. If a copy of the MPL was not distributed with this
4+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
5+
6+
set -ex
7+
8+
ROOT=`pwd`
9+
10+
export PATH=${TOOLS_PATH}/${TOOLCHAIN}/bin:${TOOLS_PATH}/host/bin:$PATH
11+
export PREFIX="/tools/deps"
12+
13+
tar -xf zstd-${ZSTD_VERSION}.tar.gz
14+
15+
pushd cpython-source-deps-zstd-${ZSTD_VERSION}/lib
16+
17+
if [ "${CC}" = "musl-clang" ]; then
18+
# In order to build the library with SSE2, BMI, and AVX2 intrinstics, we need musl-clang to find
19+
# headers that provide access to the intrinsics, as they are not provided by musl. These are
20+
# part of the include files that are part of clang. But musl-clang eliminates them from the
21+
# default include path. So copy them into place.
22+
for h in ${TOOLS_PATH}/${TOOLCHAIN}/lib/clang/*/include/*intrin.h ${TOOLS_PATH}/${TOOLCHAIN}/lib/clang/*/include/{__wmmintrin_aes.h,__wmmintrin_pclmul.h,emmintrin.h,immintrin.h,mm_malloc.h}; do
23+
filename=$(basename "$h")
24+
if [ -e "${TOOLS_PATH}/host/include/${filename}" ]; then
25+
echo "warning: ${filename} already exists"
26+
fi
27+
cp "$h" ${TOOLS_PATH}/host/include/
28+
done
29+
EXTRA_TARGET_CFLAGS="${EXTRA_TARGET_CFLAGS} -I${TOOLS_PATH}/host/include/"
30+
31+
# `qsort_r` is only available in musl 1.2.3+ but we use 1.2.2. The zstd source provides a
32+
# fallback implementation, but they do not have a `configure`-style detection of whether
33+
# `qsort_r` is actually available so we patch it to include a check for glibc.
34+
patch -p1 <<EOF
35+
diff --git a/dictBuilder/cover.c b/dictBuilder/cover.c
36+
index 5e6e8bc..6ca72a1 100644
37+
--- a/dictBuilder/cover.c
38+
+++ b/dictBuilder/cover.c
39+
@@ -241,7 +241,7 @@ typedef struct {
40+
unsigned d;
41+
} COVER_ctx_t;
42+
43+
-#if !defined(_GNU_SOURCE) && !defined(__APPLE__) && !defined(_MSC_VER)
44+
+#if !(defined(_GNU_SOURCE) && defined(__GLIBC__)) && !defined(__APPLE__) && !defined(_MSC_VER)
45+
/* C90 only offers qsort() that needs a global context. */
46+
static COVER_ctx_t *g_coverCtx = NULL;
47+
#endif
48+
@@ -328,7 +328,7 @@ static void stableSort(COVER_ctx_t *ctx) {
49+
qsort_r(ctx->suffix, ctx->suffixSize, sizeof(U32),
50+
ctx,
51+
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp));
52+
-#elif defined(_GNU_SOURCE)
53+
+#elif defined(_GNU_SOURCE) && defined(__GLIBC__)
54+
qsort_r(ctx->suffix, ctx->suffixSize, sizeof(U32),
55+
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp),
56+
ctx);
57+
EOF
58+
fi
59+
60+
CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" make -j ${NUM_CPUS} libzstd.a
61+
make -j ${NUM_CPUS} install-static DESTDIR=${ROOT}/out
62+
make -j ${NUM_CPUS} install-includes DESTDIR=${ROOT}/out
63+
make -j ${NUM_CPUS} install-pc DESTDIR=${ROOT}/out

cpython-unix/build.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,7 @@ def main():
11631163
"xtrans",
11641164
"xz",
11651165
"zlib",
1166+
"zstd",
11661167
):
11671168
tools_path = "host" if action in ("m4", "patchelf") else "deps"
11681169

cpython-unix/extension-modules.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -772,15 +772,14 @@ _xxtestfuzz:
772772
- _xxtestfuzz/fuzzer.c
773773

774774
_zstd:
775-
# Disable on all targets until we add a zstd library
776-
disabled-targets:
777-
- .*
778775
minimum-python-version: '3.14'
779776
sources:
780777
- _zstd/_zstdmodule.c
781-
- _zstd/zdict.c
778+
- _zstd/zstddict.c
782779
- _zstd/compressor.c
783780
- _zstd/decompressor.c
781+
links:
782+
- zstd
784783

785784
_zoneinfo:
786785
minimum-python-version: "3.9"

cpython-unix/targets.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ aarch64-apple-darwin:
108108
- tk
109109
- uuid
110110
- xz
111+
- zstd
111112
openssl_target: darwin64-arm64-cc
112113

113114
aarch64-apple-ios:
@@ -151,6 +152,7 @@ aarch64-apple-ios:
151152
- openssl-3.0
152153
- sqlite
153154
- xz
155+
- zstd
154156
openssl_target: ios64-cross
155157

156158
aarch64-unknown-linux-gnu:
@@ -198,6 +200,7 @@ aarch64-unknown-linux-gnu:
198200
- xorgproto
199201
- xz
200202
- zlib
203+
- zstd
201204
openssl_target: linux-aarch64
202205
# Blocked on:
203206
# BOLT-ERROR: Cannot relax adr in non-simple function
@@ -245,6 +248,7 @@ arm64-apple-tvos:
245248
- openssl-3.0
246249
- sqlite
247250
- xz
251+
- zstd
248252
openssl_target: todo
249253

250254
armv7-unknown-linux-gnueabi:
@@ -286,6 +290,7 @@ armv7-unknown-linux-gnueabi:
286290
- xorgproto
287291
- xz
288292
- zlib
293+
- zstd
289294
openssl_target: linux-armv4
290295

291296
armv7-unknown-linux-gnueabihf:
@@ -327,6 +332,7 @@ armv7-unknown-linux-gnueabihf:
327332
- xorgproto
328333
- xz
329334
- zlib
335+
- zstd
330336
openssl_target: linux-armv4
331337

332338
mips-unknown-linux-gnu:
@@ -368,6 +374,7 @@ mips-unknown-linux-gnu:
368374
- xorgproto
369375
- xz
370376
- zlib
377+
- zstd
371378
openssl_target: linux-mips32
372379

373380
mipsel-unknown-linux-gnu:
@@ -409,6 +416,7 @@ mipsel-unknown-linux-gnu:
409416
- xorgproto
410417
- xz
411418
- zlib
419+
- zstd
412420
openssl_target: linux-mips32
413421

414422
ppc64le-unknown-linux-gnu:
@@ -450,6 +458,7 @@ ppc64le-unknown-linux-gnu:
450458
- xorgproto
451459
- xz
452460
- zlib
461+
- zstd
453462
openssl_target: linux-ppc64le
454463

455464
riscv64-unknown-linux-gnu:
@@ -491,6 +500,7 @@ riscv64-unknown-linux-gnu:
491500
- xorgproto
492501
- xz
493502
- zlib
503+
- zstd
494504
openssl_target: linux64-riscv64
495505

496506
s390x-unknown-linux-gnu:
@@ -532,6 +542,7 @@ s390x-unknown-linux-gnu:
532542
- xorgproto
533543
- xz
534544
- zlib
545+
- zstd
535546
openssl_target: linux64-s390x
536547

537548
thumb7k-apple-watchos:
@@ -574,6 +585,7 @@ thumb7k-apple-watchos:
574585
- openssl-3.0
575586
- sqlite
576587
- xz
588+
- zstd
577589
openssl_target: todo
578590

579591
# Intel macOS.
@@ -629,6 +641,7 @@ x86_64-apple-darwin:
629641
- tk
630642
- uuid
631643
- xz
644+
- zstd
632645
openssl_target: darwin64-x86_64-cc
633646

634647
x86_64-apple-ios:
@@ -672,6 +685,7 @@ x86_64-apple-ios:
672685
- openssl-3.0
673686
- sqlite
674687
- xz
688+
- zstd
675689
openssl_target: darwin64-x86_64-cc
676690

677691
x86_64-apple-tvos:
@@ -714,6 +728,7 @@ x86_64-apple-tvos:
714728
- openssl-3.0
715729
- sqlite
716730
- xz
731+
- zstd
717732
openssl_target: todo
718733

719734
x86_64-apple-watchos:
@@ -756,6 +771,7 @@ x86_64-apple-watchos:
756771
- openssl-3.0
757772
- sqlite
758773
- xz
774+
- zstd
759775
openssl_target: todo
760776

761777
x86_64-unknown-linux-gnu:
@@ -801,6 +817,7 @@ x86_64-unknown-linux-gnu:
801817
- xorgproto
802818
- xz
803819
- zlib
820+
- zstd
804821
openssl_target: linux-x86_64
805822
bolt_capable: true
806823

@@ -848,6 +865,7 @@ x86_64_v2-unknown-linux-gnu:
848865
- xorgproto
849866
- xz
850867
- zlib
868+
- zstd
851869
openssl_target: linux-x86_64
852870
bolt_capable: true
853871

@@ -895,6 +913,7 @@ x86_64_v3-unknown-linux-gnu:
895913
- xorgproto
896914
- xz
897915
- zlib
916+
- zstd
898917
openssl_target: linux-x86_64
899918
bolt_capable: true
900919

@@ -942,6 +961,7 @@ x86_64_v4-unknown-linux-gnu:
942961
- xorgproto
943962
- xz
944963
- zlib
964+
- zstd
945965
openssl_target: linux-x86_64
946966
bolt_capable: true
947967

@@ -987,6 +1007,7 @@ x86_64-unknown-linux-musl:
9871007
- xorgproto
9881008
- xz
9891009
- zlib
1010+
- zstd
9901011
openssl_target: linux-x86_64
9911012

9921013
x86_64_v2-unknown-linux-musl:
@@ -1032,6 +1053,7 @@ x86_64_v2-unknown-linux-musl:
10321053
- xorgproto
10331054
- xz
10341055
- zlib
1056+
- zstd
10351057
openssl_target: linux-x86_64
10361058

10371059
x86_64_v3-unknown-linux-musl:
@@ -1077,6 +1099,7 @@ x86_64_v3-unknown-linux-musl:
10771099
- xorgproto
10781100
- xz
10791101
- zlib
1102+
- zstd
10801103
openssl_target: linux-x86_64
10811104

10821105
x86_64_v4-unknown-linux-musl:
@@ -1122,4 +1145,5 @@ x86_64_v4-unknown-linux-musl:
11221145
- xorgproto
11231146
- xz
11241147
- zlib
1148+
- zstd
11251149
openssl_target: linux-x86_64

src/validation.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,7 @@ const GLOBAL_EXTENSIONS_PYTHON_3_14: &[&str] = &[
778778
"_zoneinfo",
779779
"_hmac",
780780
"_types",
781+
"_zstd",
781782
];
782783

783784
const GLOBAL_EXTENSIONS_MACOS: &[&str] = &["_scproxy"];
@@ -813,8 +814,7 @@ const GLOBAL_EXTENSIONS_WINDOWS: &[&str] = &[
813814
"winsound",
814815
];
815816

816-
// TODO(zanieb): Move `_zstd` to non-Windows specific once we add support on Unix.
817-
const GLOBAL_EXTENSIONS_WINDOWS_3_14: &[&str] = &["_wmi", "_zstd"];
817+
const GLOBAL_EXTENSIONS_WINDOWS_3_14: &[&str] = &["_wmi"];
818818

819819
const GLOBAL_EXTENSIONS_WINDOWS_PRE_3_13: &[&str] = &["_msi"];
820820

0 commit comments

Comments
 (0)