From f8fb6d3188b2694d558672790e1d83dfda094c37 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 19 Mar 2025 16:29:17 -0500 Subject: [PATCH 01/18] Add support for aarch64 musl --- ci-targets.yaml | 18 +++++++++++++++ cpython-unix/targets.yml | 47 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/ci-targets.yaml b/ci-targets.yaml index c59d5b7f..984b03cf 100644 --- a/ci-targets.yaml +++ b/ci-targets.yaml @@ -348,6 +348,24 @@ linux: minimum-python-version: "3.13" run: true + aarch64-unknown-linux-musl: + arch: aarch64 + libc: musl + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - debug+static + - noopt+static + - lto+static + - debug + - noopt + - lto + run: true + windows: i686-pc-windows-msvc: arch: x86 diff --git a/cpython-unix/targets.yml b/cpython-unix/targets.yml index d0ef4a78..e3860919 100644 --- a/cpython-unix/targets.yml +++ b/cpython-unix/targets.yml @@ -1131,3 +1131,50 @@ x86_64_v4-unknown-linux-musl: - zlib - zstd openssl_target: linux-x86_64 + +aarch64-unknown-linux-musl: + host_platforms: + - linux_x86_64 + - linux_aarch64 + pythons_supported: + - '3.9' + - '3.10' + - '3.11' + - '3.12' + - '3.13' + - '3.14' + needs_toolchain: true + docker_image_suffix: .debian9 + needs_toolchain: true + host_cc: clang + host_cxx: clang++ + target_cc: musl-clang + target_cxx: clang++ + target_cflags: + - '-fvisibility=hidden' + needs: + - autoconf + - bdb + - binutils + - bzip2 + - expat + - libedit + - libffi-3.3 + - libX11 + - libXau + - libxcb + - m4 + - mpdecimal + - musl + - ncurses + - openssl-3.0 + - patchelf + - sqlite + - tcl + - tk + - tix + - uuid + - xorgproto + - xz + - zlib + openssl_target: linux-aarch64 From ef5765373c68f450e1c4d7f0851731c00a2f083e Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 20 Aug 2025 11:32:42 -0500 Subject: [PATCH 02/18] Debug bzip2 failure --- cpython-unix/build.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cpython-unix/build.py b/cpython-unix/build.py index ea44c294..8889f15e 100755 --- a/cpython-unix/build.py +++ b/cpython-unix/build.py @@ -88,6 +88,10 @@ def add_target_env(env, build_platform, target_triple, build_env): extra_host_cflags = [] extra_host_ldflags = [] + # Add compiler-rt for aarch64-musl to resolve missing floating-point builtins + if target_triple == "aarch64-unknown-linux-musl": + extra_target_ldflags.append("--rtlib=compiler-rt") + if build_platform.startswith("linux_"): machine = platform.machine() From bc3b60f5bebefae8096241acb3af9e9bb8895578 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 20 Aug 2025 13:52:57 -0500 Subject: [PATCH 03/18] Debug openssl --- cpython-unix/build.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cpython-unix/build.py b/cpython-unix/build.py index 8889f15e..36accde5 100755 --- a/cpython-unix/build.py +++ b/cpython-unix/build.py @@ -90,6 +90,7 @@ def add_target_env(env, build_platform, target_triple, build_env): # Add compiler-rt for aarch64-musl to resolve missing floating-point builtins if target_triple == "aarch64-unknown-linux-musl": + extra_target_cflags.append("--rtlib=compiler-rt") extra_target_ldflags.append("--rtlib=compiler-rt") if build_platform.startswith("linux_"): From 7b2a0a05c170ad930fe2f5b545988e1068c49830 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 20 Aug 2025 14:10:58 -0500 Subject: [PATCH 04/18] Debug bzip2 on static musl --- cpython-unix/build-bzip2.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cpython-unix/build-bzip2.sh b/cpython-unix/build-bzip2.sh index ab9c08b5..edda8ea8 100755 --- a/cpython-unix/build-bzip2.sh +++ b/cpython-unix/build-bzip2.sh @@ -15,6 +15,20 @@ else AR=ar fi +# Copy compiler-rt builtins library for static aarch64-musl builds +if [ "${TARGET_TRIPLE}" = "aarch64-unknown-linux-musl" ] && [ "${CC}" = "musl-clang" ] && [ -n "${STATIC}" ]; then + # musl-clang eliminates default library search paths, so copy compiler-rt builtins to accessible location + for lib in ${TOOLS_PATH}/${TOOLCHAIN}/lib/clang/*/lib/linux/libclang_rt.builtins-aarch64.a; do + if [ -e "$lib" ]; then + filename=$(basename "$lib") + if [ -e "${TOOLS_PATH}/host/lib/${filename}" ]; then + echo "warning: ${filename} already exists" + fi + cp "$lib" ${TOOLS_PATH}/host/lib/ + fi + done +fi + tar -xf bzip2-${BZIP2_VERSION}.tar.gz pushd bzip2-${BZIP2_VERSION} From ac2ddaae403dbeb3074664fd95115d95edd58423 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 20 Aug 2025 14:14:24 -0500 Subject: [PATCH 05/18] Remove tix --- cpython-unix/targets.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/cpython-unix/targets.yml b/cpython-unix/targets.yml index e3860919..bfddf2ab 100644 --- a/cpython-unix/targets.yml +++ b/cpython-unix/targets.yml @@ -1172,7 +1172,6 @@ aarch64-unknown-linux-musl: - sqlite - tcl - tk - - tix - uuid - xorgproto - xz From d8111a0a0e92761e1b38353c1040d5ea67d27123 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 20 Aug 2025 14:51:18 -0500 Subject: [PATCH 06/18] Handle musl aarch64 case --- cpython-unix/build-cpython.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh index 658395a9..30b0d2b2 100755 --- a/cpython-unix/build-cpython.sh +++ b/cpython-unix/build-cpython.sh @@ -1077,8 +1077,14 @@ touch "${LIB_DYNLOAD}/.empty" # Symlink libpython so we don't have 2 copies. case "${TARGET_TRIPLE}" in -aarch64-unknown-linux-gnu) - PYTHON_ARCH="aarch64-linux-gnu" +aarch64-unknown-linux-*) + # In Python 3.13+, the musl target is identified in cross compiles and the output directory + # is named accordingly. + if [[ "${CC}" = "musl-clang" && -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]]; then + PYTHON_ARCH="aarch64-linux-musl" + else + PYTHON_ARCH="aarch64-linux-gnu" + fi ;; # This is too aggressive. But we don't have patches in place for # setting the platform name properly on non-Darwin. From b49bb50b6e84b968d565a1e0b90e2168f408ae70 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 20 Aug 2025 15:11:55 -0500 Subject: [PATCH 07/18] Debug bzip2 on static musl --- cpython-unix/build-bzip2.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cpython-unix/build-bzip2.sh b/cpython-unix/build-bzip2.sh index edda8ea8..24ca6250 100755 --- a/cpython-unix/build-bzip2.sh +++ b/cpython-unix/build-bzip2.sh @@ -18,7 +18,7 @@ fi # Copy compiler-rt builtins library for static aarch64-musl builds if [ "${TARGET_TRIPLE}" = "aarch64-unknown-linux-musl" ] && [ "${CC}" = "musl-clang" ] && [ -n "${STATIC}" ]; then # musl-clang eliminates default library search paths, so copy compiler-rt builtins to accessible location - for lib in ${TOOLS_PATH}/${TOOLCHAIN}/lib/clang/*/lib/linux/libclang_rt.builtins-aarch64.a; do + for lib in ${TOOLS_PATH}/${TOOLCHAIN}/lib/clang/*/lib/aarch64-unknown-linux-gnu/libclang_rt.builtins.a; do if [ -e "$lib" ]; then filename=$(basename "$lib") if [ -e "${TOOLS_PATH}/host/lib/${filename}" ]; then @@ -27,6 +27,9 @@ if [ "${TARGET_TRIPLE}" = "aarch64-unknown-linux-musl" ] && [ "${CC}" = "musl-cl cp "$lib" ${TOOLS_PATH}/host/lib/ fi done + + # Add explicit library path for compiler-rt builtins + export EXTRA_TARGET_LDFLAGS="${EXTRA_TARGET_LDFLAGS} -L${TOOLS_PATH}/host/lib -lclang_rt.builtins" fi tar -xf bzip2-${BZIP2_VERSION}.tar.gz From f7b5ac1c9b38bcbacaa80d3fd656b413a3802043 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 20 Aug 2025 15:48:12 -0500 Subject: [PATCH 08/18] Add to validation --- src/validation.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/validation.rs b/src/validation.rs index 6d9b5dbf..e5b43911 100644 --- a/src/validation.rs +++ b/src/validation.rs @@ -35,6 +35,7 @@ const RECOGNIZED_TRIPLES: &[&str] = &[ "aarch64-apple-ios", "aarch64-pc-windows-msvc", "aarch64-unknown-linux-gnu", + "aarch64-unknown-linux-musl", "armv7-unknown-linux-gnueabi", "armv7-unknown-linux-gnueabihf", "arm64-apple-tvos", @@ -157,6 +158,10 @@ static GLIBC_MAX_VERSION_BY_TRIPLE: Lazy> = Lazy: ("aarch64-apple-ios", "iOS-aarch64"), ("aarch64-pc-windows-msvc", "win-arm64"), ("aarch64-unknown-linux-gnu", "linux-aarch64"), + ("aarch64-unknown-linux-musl", "linux-aarch64"), ("armv7-unknown-linux-gnueabi", "linux-arm"), ("armv7-unknown-linux-gnueabihf", "linux-arm"), ("i686-pc-windows-msvc", "win32"), @@ -949,6 +955,7 @@ fn validate_elf>( let wanted_cpu_type = match target_triple { "aarch64-unknown-linux-gnu" => object::elf::EM_AARCH64, + "aarch64-unknown-linux-musl" => object::elf::EM_AARCH64, "armv7-unknown-linux-gnueabi" => object::elf::EM_ARM, "armv7-unknown-linux-gnueabihf" => object::elf::EM_ARM, "i686-unknown-linux-gnu" => object::elf::EM_386, From 6d0bb0806580b02e040c5cd0f64c17ffc2b8a6f7 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 20 Aug 2025 16:27:47 -0500 Subject: [PATCH 09/18] Add 3.14 --- ci-targets.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/ci-targets.yaml b/ci-targets.yaml index 984b03cf..b5fa847a 100644 --- a/ci-targets.yaml +++ b/ci-targets.yaml @@ -357,6 +357,7 @@ linux: - "3.11" - "3.12" - "3.13" + - "3.14" build_options: - debug+static - noopt+static From 17184590356c09d38fff7d5b538877935b511ccb Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 20 Aug 2025 16:29:20 -0500 Subject: [PATCH 10/18] Drop the static builds for now --- ci-targets.yaml | 7 ++++--- cpython-unix/build-bzip2.sh | 17 ----------------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/ci-targets.yaml b/ci-targets.yaml index b5fa847a..492b815c 100644 --- a/ci-targets.yaml +++ b/ci-targets.yaml @@ -359,9 +359,10 @@ linux: - "3.13" - "3.14" build_options: - - debug+static - - noopt+static - - lto+static + # TODO: Static support is current blocked by some compiler-rt linking issues + # - debug+static + # - noopt+static + # - lto+static - debug - noopt - lto diff --git a/cpython-unix/build-bzip2.sh b/cpython-unix/build-bzip2.sh index 24ca6250..ab9c08b5 100755 --- a/cpython-unix/build-bzip2.sh +++ b/cpython-unix/build-bzip2.sh @@ -15,23 +15,6 @@ else AR=ar fi -# Copy compiler-rt builtins library for static aarch64-musl builds -if [ "${TARGET_TRIPLE}" = "aarch64-unknown-linux-musl" ] && [ "${CC}" = "musl-clang" ] && [ -n "${STATIC}" ]; then - # musl-clang eliminates default library search paths, so copy compiler-rt builtins to accessible location - for lib in ${TOOLS_PATH}/${TOOLCHAIN}/lib/clang/*/lib/aarch64-unknown-linux-gnu/libclang_rt.builtins.a; do - if [ -e "$lib" ]; then - filename=$(basename "$lib") - if [ -e "${TOOLS_PATH}/host/lib/${filename}" ]; then - echo "warning: ${filename} already exists" - fi - cp "$lib" ${TOOLS_PATH}/host/lib/ - fi - done - - # Add explicit library path for compiler-rt builtins - export EXTRA_TARGET_LDFLAGS="${EXTRA_TARGET_LDFLAGS} -L${TOOLS_PATH}/host/lib -lclang_rt.builtins" -fi - tar -xf bzip2-${BZIP2_VERSION}.tar.gz pushd bzip2-${BZIP2_VERSION} From af4fc2a11c8173761c3bfa53963a93841a45490b Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 20 Aug 2025 17:59:50 -0500 Subject: [PATCH 11/18] Shorten message --- cpython-unix/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpython-unix/build.py b/cpython-unix/build.py index 36accde5..138a9c9b 100755 --- a/cpython-unix/build.py +++ b/cpython-unix/build.py @@ -88,7 +88,7 @@ def add_target_env(env, build_platform, target_triple, build_env): extra_host_cflags = [] extra_host_ldflags = [] - # Add compiler-rt for aarch64-musl to resolve missing floating-point builtins + # Add compiler-rt for aarch64-musl to resolve missing builtins if target_triple == "aarch64-unknown-linux-musl": extra_target_cflags.append("--rtlib=compiler-rt") extra_target_ldflags.append("--rtlib=compiler-rt") From 7d9019fca670e423c1d23da603096a246c0920e3 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 20 Aug 2025 18:10:32 -0500 Subject: [PATCH 12/18] Move glibc validation to right place --- src/validation.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/validation.rs b/src/validation.rs index e5b43911..163e7b01 100644 --- a/src/validation.rs +++ b/src/validation.rs @@ -158,10 +158,6 @@ static GLIBC_MAX_VERSION_BY_TRIPLE: Lazy Date: Wed, 27 Aug 2025 13:16:57 -0500 Subject: [PATCH 13/18] Add aarch64 cross-compile host includes --- cpython-unix/build-cpython-host.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cpython-unix/build-cpython-host.sh b/cpython-unix/build-cpython-host.sh index 99b021d7..ff7c3a45 100755 --- a/cpython-unix/build-cpython-host.sh +++ b/cpython-unix/build-cpython-host.sh @@ -70,6 +70,11 @@ case "${BUILD_TRIPLE}" in EXTRA_HOST_CPPFLAGS="${EXTRA_HOST_CPPFLAGS} -I/usr/include/x86_64-linux-gnu" EXTRA_HOST_LDFLAGS="${EXTRA_HOST_LDFLAGS} -L/usr/lib/x86_64-linux-gnu" ;; + aarch64-unknown-linux-gnu) + EXTRA_HOST_CFLAGS="${EXTRA_HOST_CFLAGS} -I/usr/include/aarch64-linux-gnu" + EXTRA_HOST_CPPFLAGS="${EXTRA_HOST_CPPFLAGS} -I/usr/include/aarch64-linux-gnu" + EXTRA_HOST_LDFLAGS="${EXTRA_HOST_LDFLAGS} -L/usr/lib/aarch64-linux-gnu" + ;; *) ;; esac From 450f3cdaf44e79158a69143949c8a1eb300febbc Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 27 Aug 2025 14:23:49 -0500 Subject: [PATCH 14/18] Add zstd --- cpython-unix/targets.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/cpython-unix/targets.yml b/cpython-unix/targets.yml index bfddf2ab..451b9840 100644 --- a/cpython-unix/targets.yml +++ b/cpython-unix/targets.yml @@ -1176,4 +1176,5 @@ aarch64-unknown-linux-musl: - xorgproto - xz - zlib + - zstd openssl_target: linux-aarch64 From 65b261783186f6602e8cc82ed7d971735bb980ac Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 27 Aug 2025 14:39:03 -0500 Subject: [PATCH 15/18] Add musl to the release triples --- src/release.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/release.rs b/src/release.rs index 0b67888d..4c123f61 100644 --- a/src/release.rs +++ b/src/release.rs @@ -339,6 +339,18 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy:: }], }, ); + h.insert( + "aarch64-unknown-linux-musl", + TripleRelease { + suffixes: vec!["debug", "lto", "noopt"], + install_only_suffix: "lto", + python_version_requirement: None, + conditional_suffixes: vec![ConditionalSuffixes { + python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(), + suffixes: linux_suffixes_musl_freethreaded.clone(), + }], + }, + ); h }); From 4dd645c3e470258b0ba4dd8ecf1c4060a4a0d7af Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 27 Aug 2025 14:43:07 -0500 Subject: [PATCH 16/18] Add missing heads for arm in zstd --- cpython-unix/build-zstd.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpython-unix/build-zstd.sh b/cpython-unix/build-zstd.sh index 5a889da5..5188f077 100755 --- a/cpython-unix/build-zstd.sh +++ b/cpython-unix/build-zstd.sh @@ -15,11 +15,11 @@ 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 + # In order to build the library with SSE2, BMI, AVX2, and ARM NEON intrinstics, 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_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 + 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,arm_neon.h,arm_neon_sve_bridge.h,arm_bf16.h,arm_fp16.h,arm_acle.h,arm_vector_types.h}; do filename=$(basename "$h") if [ -e "${TOOLS_PATH}/host/include/${filename}" ]; then echo "warning: ${filename} already exists" From 0b769cac0a9a4918c097f293942bc4e668bd3dff Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 27 Aug 2025 15:41:28 -0500 Subject: [PATCH 17/18] Update patch to resolve cover incompatibility --- cpython-unix/build-zstd.sh | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/cpython-unix/build-zstd.sh b/cpython-unix/build-zstd.sh index 5188f077..1bc774e4 100755 --- a/cpython-unix/build-zstd.sh +++ b/cpython-unix/build-zstd.sh @@ -33,7 +33,7 @@ if [ "${CC}" = "musl-clang" ]; then # `qsort_r` is actually available so we patch it to include a check for glibc. patch -p1 <suffix, ctx->suffixSize, sizeof(U32), ctx, From c952b56d2767fabcde1ae0d2d1e05fa8e84b5ccf Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 27 Aug 2025 19:15:48 -0500 Subject: [PATCH 18/18] Allow missing intrinsic files for x86-64 --- cpython-unix/build-zstd.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cpython-unix/build-zstd.sh b/cpython-unix/build-zstd.sh index 1bc774e4..bcce804b 100755 --- a/cpython-unix/build-zstd.sh +++ b/cpython-unix/build-zstd.sh @@ -15,16 +15,20 @@ 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, AVX2, and ARM NEON intrinstics, we need musl-clang to find + # In order to build the library with intrinsics, 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_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,arm_neon.h,arm_neon_sve_bridge.h,arm_bf16.h,arm_fp16.h,arm_acle.h,arm_vector_types.h}; do filename=$(basename "$h") - if [ -e "${TOOLS_PATH}/host/include/${filename}" ]; then - echo "warning: ${filename} already exists" + if [ -f "$h" ]; then + if [ -e "${TOOLS_PATH}/host/include/${filename}" ]; then + echo "warning: ${filename} already exists" + fi + cp "$h" ${TOOLS_PATH}/host/include/ + else + echo "warning: ${filename} not found (skipping)" fi - cp "$h" ${TOOLS_PATH}/host/include/ done EXTRA_TARGET_CFLAGS="${EXTRA_TARGET_CFLAGS} -I${TOOLS_PATH}/host/include/"