Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cpython-unix/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ $(OUTDIR)/xz-$(XZ_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/
$(OUTDIR)/zlib-$(ZLIB_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-zlib.sh
$(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) zlib

$(OUTDIR)/zstd-$(ZSTD_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-zstd.sh
$(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) zstd

PYTHON_HOST_DEPENDS := \
$(PYTHON_DEP_DEPENDS) \
$(HERE)/build-cpython-host.sh \
Expand Down Expand Up @@ -272,6 +275,7 @@ PYTHON_DEPENDS_$(1) := \
$$(if $$(NEED_UUID),$$(OUTDIR)/uuid-$$(UUID_VERSION)-$$(PACKAGE_SUFFIX).tar) \
$$(if $$(NEED_XZ),$$(OUTDIR)/xz-$$(XZ_VERSION)-$$(PACKAGE_SUFFIX).tar) \
$$(if $$(NEED_ZLIB),$$(OUTDIR)/zlib-$$(ZLIB_VERSION)-$$(PACKAGE_SUFFIX).tar) \
$$(if $$(NEED_ZSTD),$$(OUTDIR)/zstd-$$(ZSTD_VERSION)-$$(PACKAGE_SUFFIX).tar) \
$$(NULL)

ALL_PYTHON_DEPENDS_$(1) = \
Expand Down
2 changes: 1 addition & 1 deletion cpython-unix/build-cpython.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1213,7 +1213,7 @@ ${BUILD_PYTHON} ${ROOT}/fix_shebangs.py ${ROOT}/out/python/install
# downstream consumers.
OBJECT_DIRS="Objects Parser Parser/lexer Parser/pegen Parser/tokenizer Programs Python Python/deepfreeze"
OBJECT_DIRS="${OBJECT_DIRS} Modules"
for ext in _blake2 cjkcodecs _ctypes _ctypes/darwin _decimal _expat _hacl _io _multiprocessing _sha3 _sqlite _sre _testinternalcapi _xxtestfuzz ; do
for ext in _blake2 cjkcodecs _ctypes _ctypes/darwin _decimal _expat _hacl _io _multiprocessing _sha3 _sqlite _sre _testinternalcapi _xxtestfuzz _zstd; do
OBJECT_DIRS="${OBJECT_DIRS} Modules/${ext}"
done

Expand Down
63 changes: 63 additions & 0 deletions cpython-unix/build-zstd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env bash
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

set -ex

ROOT=`pwd`

export PATH=${TOOLS_PATH}/${TOOLCHAIN}/bin:${TOOLS_PATH}/host/bin:$PATH
export PREFIX="/tools/deps"

tar -xf zstd-${ZSTD_VERSION}.tar.gz

pushd cpython-source-deps-zstd-${ZSTD_VERSION}/lib

if [ "${CC}" = "musl-clang" ]; then
# In order to build the library with SSE2, BMI, and AVX2 intrinstics, we need musl-clang to find
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is modeled off of

# In order to build the _blake2 extension module with SSE3+ instructions, we need
# musl-clang to find headers that provide access to the intrinsics, as they are not
# provided by musl. These are part of the include files that are part of clang.
# But musl-clang eliminates them from the default include path. So copy them into
# place.
for h in /tools/${TOOLCHAIN}/lib/clang/*/include/*intrin.h /tools/${TOOLCHAIN}/lib/clang/*/include/{__wmmintrin_aes.h,__wmmintrin_pclmul.h,mm_malloc.h,cpuid.h}; do
filename=$(basename "$h")
if [ -e "/tools/host/include/${filename}" ]; then
echo "${filename} already exists; don't need to copy!"
exit 1
fi
cp "$h" /tools/host/include/
done

Copy link
Member Author

@zanieb zanieb Jul 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Annoyingly, I didn't realize this was the problem until I was pretty far in. We might want to generalize this at some point, e.g., by fixing musl-clang or rolling our own.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I've been wanting to do that, filed #684.

On a separate note - I assume zstd is smart enough to correctly detect availability of the intrinsics and we don't need to patch these out for x86-64-v1? I guess put another way, do we have tests that our x86-64-v1 builds don't include things that aren't supported on that microarch? If not we should add some (either with objdump or I think qemu can do it with machine options).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume zstd is smart enough to correctly detect availability of the intrinsics and we don't need to patch these out for x86-64-v1?

Things looked properly gated from the poking around I did to get this working. I don't know of explicit test coverage.

# headers that provide access to the intrinsics, as they are not provided by musl. These are
# part of the include files that are part of clang. But musl-clang eliminates them from the
# default include path. So copy them into place.
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
filename=$(basename "$h")
if [ -e "${TOOLS_PATH}/host/include/${filename}" ]; then
echo "warning: ${filename} already exists"
fi
cp "$h" ${TOOLS_PATH}/host/include/
done
EXTRA_TARGET_CFLAGS="${EXTRA_TARGET_CFLAGS} -I${TOOLS_PATH}/host/include/"

# `qsort_r` is only available in musl 1.2.3+ but we use 1.2.2. The zstd source provides a
# fallback implementation, but they do not have a `configure`-style detection of whether
# `qsort_r` is actually available so we patch it to include a check for glibc.
patch -p1 <<EOF
diff --git a/dictBuilder/cover.c b/dictBuilder/cover.c
index 5e6e8bc..6ca72a1 100644
--- a/dictBuilder/cover.c
+++ b/dictBuilder/cover.c
@@ -241,7 +241,7 @@ typedef struct {
unsigned d;
} COVER_ctx_t;

-#if !defined(_GNU_SOURCE) && !defined(__APPLE__) && !defined(_MSC_VER)
+#if !(defined(_GNU_SOURCE) && defined(__GLIBC__)) && !defined(__APPLE__) && !defined(_MSC_VER)
/* C90 only offers qsort() that needs a global context. */
static COVER_ctx_t *g_coverCtx = NULL;
#endif
@@ -328,7 +328,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(__GLIBC__)
qsort_r(ctx->suffix, ctx->suffixSize, sizeof(U32),
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp),
ctx);
EOF
fi

CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" make -j ${NUM_CPUS} libzstd.a
make -j ${NUM_CPUS} install-static DESTDIR=${ROOT}/out
make -j ${NUM_CPUS} install-includes DESTDIR=${ROOT}/out
make -j ${NUM_CPUS} install-pc DESTDIR=${ROOT}/out
1 change: 1 addition & 0 deletions cpython-unix/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,7 @@ def main():
"xtrans",
"xz",
"zlib",
"zstd",
):
tools_path = "host" if action in ("m4", "patchelf") else "deps"

Expand Down
7 changes: 3 additions & 4 deletions cpython-unix/extension-modules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -772,15 +772,14 @@ _xxtestfuzz:
- _xxtestfuzz/fuzzer.c

_zstd:
# Disable on all targets until we add a zstd library
disabled-targets:
- .*
minimum-python-version: '3.14'
sources:
- _zstd/_zstdmodule.c
- _zstd/zdict.c
- _zstd/zstddict.c
- _zstd/compressor.c
- _zstd/decompressor.c
links:
- zstd

_zoneinfo:
minimum-python-version: "3.9"
Expand Down
24 changes: 24 additions & 0 deletions cpython-unix/targets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ aarch64-apple-darwin:
- tk
- uuid
- xz
- zstd
openssl_target: darwin64-arm64-cc

aarch64-apple-ios:
Expand Down Expand Up @@ -151,6 +152,7 @@ aarch64-apple-ios:
- openssl-3.0
- sqlite
- xz
- zstd
openssl_target: ios64-cross

aarch64-unknown-linux-gnu:
Expand Down Expand Up @@ -198,6 +200,7 @@ aarch64-unknown-linux-gnu:
- xorgproto
- xz
- zlib
- zstd
openssl_target: linux-aarch64
# Blocked on:
# BOLT-ERROR: Cannot relax adr in non-simple function
Expand Down Expand Up @@ -245,6 +248,7 @@ arm64-apple-tvos:
- openssl-3.0
- sqlite
- xz
- zstd
openssl_target: todo

armv7-unknown-linux-gnueabi:
Expand Down Expand Up @@ -286,6 +290,7 @@ armv7-unknown-linux-gnueabi:
- xorgproto
- xz
- zlib
- zstd
openssl_target: linux-armv4

armv7-unknown-linux-gnueabihf:
Expand Down Expand Up @@ -327,6 +332,7 @@ armv7-unknown-linux-gnueabihf:
- xorgproto
- xz
- zlib
- zstd
openssl_target: linux-armv4

mips-unknown-linux-gnu:
Expand Down Expand Up @@ -368,6 +374,7 @@ mips-unknown-linux-gnu:
- xorgproto
- xz
- zlib
- zstd
openssl_target: linux-mips32

mipsel-unknown-linux-gnu:
Expand Down Expand Up @@ -409,6 +416,7 @@ mipsel-unknown-linux-gnu:
- xorgproto
- xz
- zlib
- zstd
openssl_target: linux-mips32

ppc64le-unknown-linux-gnu:
Expand Down Expand Up @@ -450,6 +458,7 @@ ppc64le-unknown-linux-gnu:
- xorgproto
- xz
- zlib
- zstd
openssl_target: linux-ppc64le

riscv64-unknown-linux-gnu:
Expand Down Expand Up @@ -491,6 +500,7 @@ riscv64-unknown-linux-gnu:
- xorgproto
- xz
- zlib
- zstd
openssl_target: linux64-riscv64

s390x-unknown-linux-gnu:
Expand Down Expand Up @@ -532,6 +542,7 @@ s390x-unknown-linux-gnu:
- xorgproto
- xz
- zlib
- zstd
openssl_target: linux64-s390x

thumb7k-apple-watchos:
Expand Down Expand Up @@ -574,6 +585,7 @@ thumb7k-apple-watchos:
- openssl-3.0
- sqlite
- xz
- zstd
openssl_target: todo

# Intel macOS.
Expand Down Expand Up @@ -629,6 +641,7 @@ x86_64-apple-darwin:
- tk
- uuid
- xz
- zstd
openssl_target: darwin64-x86_64-cc

x86_64-apple-ios:
Expand Down Expand Up @@ -672,6 +685,7 @@ x86_64-apple-ios:
- openssl-3.0
- sqlite
- xz
- zstd
openssl_target: darwin64-x86_64-cc

x86_64-apple-tvos:
Expand Down Expand Up @@ -714,6 +728,7 @@ x86_64-apple-tvos:
- openssl-3.0
- sqlite
- xz
- zstd
openssl_target: todo

x86_64-apple-watchos:
Expand Down Expand Up @@ -756,6 +771,7 @@ x86_64-apple-watchos:
- openssl-3.0
- sqlite
- xz
- zstd
openssl_target: todo

x86_64-unknown-linux-gnu:
Expand Down Expand Up @@ -801,6 +817,7 @@ x86_64-unknown-linux-gnu:
- xorgproto
- xz
- zlib
- zstd
openssl_target: linux-x86_64
bolt_capable: true

Expand Down Expand Up @@ -848,6 +865,7 @@ x86_64_v2-unknown-linux-gnu:
- xorgproto
- xz
- zlib
- zstd
openssl_target: linux-x86_64
bolt_capable: true

Expand Down Expand Up @@ -895,6 +913,7 @@ x86_64_v3-unknown-linux-gnu:
- xorgproto
- xz
- zlib
- zstd
openssl_target: linux-x86_64
bolt_capable: true

Expand Down Expand Up @@ -942,6 +961,7 @@ x86_64_v4-unknown-linux-gnu:
- xorgproto
- xz
- zlib
- zstd
openssl_target: linux-x86_64
bolt_capable: true

Expand Down Expand Up @@ -987,6 +1007,7 @@ x86_64-unknown-linux-musl:
- xorgproto
- xz
- zlib
- zstd
openssl_target: linux-x86_64

x86_64_v2-unknown-linux-musl:
Expand Down Expand Up @@ -1032,6 +1053,7 @@ x86_64_v2-unknown-linux-musl:
- xorgproto
- xz
- zlib
- zstd
openssl_target: linux-x86_64

x86_64_v3-unknown-linux-musl:
Expand Down Expand Up @@ -1077,6 +1099,7 @@ x86_64_v3-unknown-linux-musl:
- xorgproto
- xz
- zlib
- zstd
openssl_target: linux-x86_64

x86_64_v4-unknown-linux-musl:
Expand Down Expand Up @@ -1122,4 +1145,5 @@ x86_64_v4-unknown-linux-musl:
- xorgproto
- xz
- zlib
- zstd
openssl_target: linux-x86_64
4 changes: 2 additions & 2 deletions src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,7 @@ const GLOBAL_EXTENSIONS_PYTHON_3_14: &[&str] = &[
"_zoneinfo",
"_hmac",
"_types",
"_zstd",
];

const GLOBAL_EXTENSIONS_MACOS: &[&str] = &["_scproxy"];
Expand Down Expand Up @@ -813,8 +814,7 @@ const GLOBAL_EXTENSIONS_WINDOWS: &[&str] = &[
"winsound",
];

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

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

Expand Down