Skip to content

Enable native builds on Linux aarch64 #670

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 1, 2025
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
18 changes: 9 additions & 9 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: linux

on:
push:
branches: [main]
branches: [ main ]
pull_request:

concurrency:
Expand Down Expand Up @@ -58,7 +58,7 @@ jobs:
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.generate-matrix.outputs.docker-build-matrix) }}
name: image / ${{ matrix.name }}
name: image / ${{ matrix.arch }} / ${{ matrix.name }}
runs-on: ${{ matrix.runner }}
permissions:
packages: write
Expand Down Expand Up @@ -100,23 +100,23 @@ jobs:
# Cache from the default branch of the canonical repo so forks can have cache hits.
# Ignore errors on cache writes so CI of forks works without a valid GHCR config.
cache-from: |
type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-${{ env.GIT_REF_NAME }}
type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-main
type=registry,ref=ghcr.io/astral-sh/python-build-standalone:${{ matrix.name }}-main
type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-linux_${{ matrix.arch }}-${{ env.GIT_REF_NAME }}
type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-linux_${{ matrix.arch }}-main
type=registry,ref=ghcr.io/astral-sh/python-build-standalone:${{ matrix.name }}-linux_${{ matrix.arch }}-main
cache-to: |
type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-${{ env.GIT_REF_NAME }},ignore-error=true
type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-linux_${{ matrix.arch }}-${{ env.GIT_REF_NAME }},ignore-error=true
outputs: |
type=docker,dest=build/image-${{ matrix.name }}.tar
type=docker,dest=build/image-${{ matrix.name }}.linux_${{ matrix.arch }}.tar
- name: Compress Image
run: |
echo ${{ steps.build-image.outputs.imageid }} > build/image-${{ matrix.name }}
echo ${{ steps.build-image.outputs.imageid }} > build/image-${{ matrix.name }}.linux_${{ matrix.arch }}
zstd -v -T0 -6 --rm build/image-*.tar
- name: Upload Docker Image
uses: actions/upload-artifact@v4
with:
name: image-${{ matrix.name }}
name: image-${{ matrix.name }}-linux_${{ matrix.arch }}
path: build/image-*

generate-matrix:
Expand Down
2 changes: 2 additions & 0 deletions ci-matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
{"name": "build", "arch": "x86_64"},
{"name": "build.cross", "arch": "x86_64"},
{"name": "build.cross-riscv64", "arch": "x86_64"},
{"name": "build.debian9", "arch": "aarch64"},
Copy link
Collaborator

Choose a reason for hiding this comment

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

In general - is "debian9" here because we're mostly using Debian 8 and that's too old for aarch64?

If we upgrade our base builds to Debian 9, can we use the normal build Dockerfile for aarch64?

Copy link
Member Author

Choose a reason for hiding this comment

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

In general - is "debian9" here because we're mostly using Debian 8 and that's too old for aarch64?

I presume so, that's where I got stuck at #484 (comment) but this was Greg's choice.

{"name": "gcc", "arch": "x86_64"},
{"name": "gcc.debian9", "arch": "aarch64"},
]


Expand Down
9 changes: 4 additions & 5 deletions ci-runners.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ depot-ubuntu-22.04:
platform: linux
free: false

# TODO: Enable this runner to perform native builds for aarch64
# depot-ubuntu-22.04-arm:
# arch: aarch64
# platform: linux
# free: false
depot-ubuntu-22.04-arm:
arch: aarch64
platform: linux
free: false

depot-macos-latest:
arch: x86_64
Expand Down
6 changes: 2 additions & 4 deletions ci-targets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,11 @@ linux:
- "3.14"
build_options:
- debug
- noopt
- lto
- pgo+lto
build_options_conditional:
- options:
- freethreaded+debug
- freethreaded+noopt
- freethreaded+lto
- freethreaded+pgo+lto
minimum-python-version: "3.13"

armv7-unknown-linux-gnueabi:
Expand Down
12 changes: 6 additions & 6 deletions cpython-unix/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ TOOLCHAIN_DEPENDS := \

PYTHON_DEP_DEPENDS := \
$(OUTDIR)/targets/$(TARGET_TRIPLE) \
$(if $(PYBUILD_NO_DOCKER),,$(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).tar) \
$(if $(PYBUILD_NO_DOCKER),,$(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).$(HOST_PLATFORM).tar) \
$(TOOLCHAIN_DEPENDS) \
$(NULL)

Expand All @@ -75,18 +75,18 @@ HOST_PYTHON_DEPENDS := $(OUTDIR)/cpython-$(PYTHON_MAJOR_VERSION)-$(CPYTHON_$(PYT
default: $(OUTDIR)/cpython-$(CPYTHON_$(PYTHON_MAJOR_VERSION)_VERSION)-$(PACKAGE_SUFFIX).tar

ifndef PYBUILD_NO_DOCKER
$(OUTDIR)/image-%.tar: $(OUTDIR)/%.Dockerfile
$(OUTDIR)/image-%.$(HOST_PLATFORM).tar: $(OUTDIR)/%.Dockerfile
$(RUN_BUILD) --toolchain image-$*
endif

$(OUTDIR)/binutils-$(BINUTILS_VERSION)-$(HOST_PLATFORM).tar: $(OUTDIR)/image-gcc.tar $(HERE)/build-binutils.sh
$(RUN_BUILD) --toolchain binutils
$(OUTDIR)/binutils-$(BINUTILS_VERSION)-$(HOST_PLATFORM).tar: $(HERE)/build-binutils.sh
$(RUN_BUILD) --toolchain --docker-image $(DOCKER_IMAGE_GCC) binutils

$(OUTDIR)/$(CLANG_FILENAME):
$(RUN_BUILD) --toolchain clang --target-triple $(TARGET_TRIPLE)

$(OUTDIR)/musl-$(MUSL_VERSION)-$(HOST_PLATFORM).tar: $(BASE_TOOLCHAIN_DEPENDS) $(HERE)/build-musl.sh
$(RUN_BUILD) --toolchain musl
$(RUN_BUILD) --toolchain musl --docker-image $(DOCKER_IMAGE_GCC)

ifeq ($(HOST_PLATFORM),linux_x86_64)
TOOLCHAIN_TARGET := $(OUTDIR)/musl-$(MUSL_VERSION)-$(HOST_PLATFORM).tar
Expand Down Expand Up @@ -125,7 +125,7 @@ $(OUTDIR)/libffi-3.3-$(LIBFFI_3.3_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_D
$(OUTDIR)/libffi-$(LIBFFI_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-libffi.sh
$(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) libffi

$(OUTDIR)/libpthread-stubs-$(LIBPTHREAD_STUBS_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-libpthread-stubs.sh $(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).tar
$(OUTDIR)/libpthread-stubs-$(LIBPTHREAD_STUBS_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-libpthread-stubs.sh $(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).$(HOST_PLATFORM).tar
$(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) libpthread-stubs

LIBX11_DEPENDS = \
Expand Down
38 changes: 38 additions & 0 deletions cpython-unix/base.debian9.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Debian Stretch.
FROM debian@sha256:c5c5200ff1e9c73ffbf188b4a67eb1c91531b644856b4aefe86a58d2f0cb05be
MAINTAINER Gregory Szorc <[email protected]>

RUN groupadd -g 1000 build && \
useradd -u 1000 -g 1000 -d /build -s /bin/bash -m build && \
mkdir /tools && \
chown -R build:build /build /tools

ENV HOME=/build \
SHELL=/bin/bash \
USER=build \
LOGNAME=build \
HOSTNAME=builder \
DEBIAN_FRONTEND=noninteractive

CMD ["/bin/bash", "--login"]
WORKDIR '/build'

RUN for s in debian_stretch debian_stretch-updates debian-security_stretch/updates; do \
echo "deb http://snapshot.debian.org/archive/${s%_*}/20230423T032736Z/ ${s#*_} main"; \
done > /etc/apt/sources.list && \
( echo 'quiet "true";'; \
echo 'APT::Get::Assume-Yes "true";'; \
echo 'APT::Install-Recommends "false";'; \
echo 'Acquire::Check-Valid-Until "false";'; \
echo 'Acquire::Retries "5";'; \
) > /etc/apt/apt.conf.d/99cpython-portable

# apt iterates all available file descriptors up to rlim_max and calls
# fcntl(fd, F_SETFD, FD_CLOEXEC). This can result in millions of system calls
# (we've seen 1B in the wild) and cause operations to take seconds to minutes.
# Setting a fd limit mitigates.
#
# Attempts at enforcing the limit globally via /etc/security/limits.conf and
# /root/.bashrc were not successful. Possibly because container image builds
# don't perform a login or use a shell the way we expect.
RUN ulimit -n 10000 && apt-get update
8 changes: 7 additions & 1 deletion cpython-unix/build-binutils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,15 @@ tar -xf binutils-${BINUTILS_VERSION}.tar.xz
mkdir binutils-objdir
pushd binutils-objdir

if [ "$(uname -m)" = "x86_64" ]; then
triple="x86_64-unknown-linux-gnu"
else
triple="aarch64-unknown-linux-gnu"
fi

# gprofng requires a bison newer than what we have. So just disable it.
../binutils-${BINUTILS_VERSION}/configure \
--build=x86_64-unknown-linux-gnu \
--build=${triple} \
--prefix=/tools/host \
--enable-plugins \
--enable-gprofng=no \
Expand Down
1 change: 1 addition & 0 deletions cpython-unix/build-main.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ def main():
"toolchain-image-build",
"toolchain-image-build.cross",
"toolchain-image-build.cross-riscv64",
"toolchain-image-build.debian9",
"toolchain-image-gcc",
"toolchain-image-xcb",
"toolchain-image-xcb.cross",
Expand Down
16 changes: 16 additions & 0 deletions cpython-unix/build.debian9.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% include 'base.debian9.Dockerfile' %}

RUN ulimit -n 10000 && apt-get install \
bzip2 \
file \
libc6-dev \
libffi-dev \
make \
patch \
perl \
pkg-config \
tar \
xz-utils \
unzip \
zip \
zlib1g-dev
Loading