Skip to content

Commit 0ca85f8

Browse files
committed
Enable native builds on Linux aarch64
I just published an LLVM 20 toolchain for aarch64. The toolchain has support for PGO and BOLT. This commit switches the Linux aarch64 builds to be performed natively on aarch64 machines. PGO and BOLT are enabled on the builds, hopefully making them a bit faster.
1 parent 65ffa41 commit 0ca85f8

16 files changed

+196
-73
lines changed

.github/workflows/linux.yml

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: linux
22

33
on:
44
push:
5-
branches: [main]
5+
branches: [ main ]
66
pull_request:
77

88
concurrency:
@@ -56,15 +56,28 @@ jobs:
5656
fail-fast: false
5757
matrix:
5858
image:
59-
- build
60-
- build.cross
61-
- build.cross-riscv64
62-
- gcc
63-
- xcb
64-
- xcb.cross
65-
- xcb.cross-riscv64
66-
name: ${{ matrix.image }}
67-
runs-on: depot-ubuntu-22.04
59+
- name: build
60+
platform: linux64
61+
- name: build.cross
62+
platform: linux64
63+
- name: build.cross-riscv64
64+
platform: linux64
65+
- name: build.debian9
66+
platform: linux_aarch64
67+
- name: gcc
68+
platform: linux64
69+
- name: gcc.debian9
70+
platform: linux_aarch64
71+
- name: xcb
72+
platform: linux64
73+
- name: xcb.cross
74+
platform: linux64
75+
- name: xcb.cross-riscv64
76+
platform: linux64
77+
- name: xcb.debian9
78+
platform: linux_aarch64
79+
name: ${{ matrix.image.name }}
80+
runs-on: ${{ matrix.image.platform == 'linux_aarch64' && 'depot-ubuntu-22.04-arm' || 'depot-ubuntu-22.04' }}
6881
permissions:
6982
packages: write
7083
steps:
@@ -98,30 +111,30 @@ jobs:
98111
uses: docker/build-push-action@v5
99112
with:
100113
context: .
101-
file: build/${{ matrix.image }}.Dockerfile
114+
file: build/${{ matrix.image.name }}.Dockerfile
102115
labels: org.opencontainers.image.source=https://github.com/${{ env.REPO_NAME }}
103116
# Cache from/to the current branch of the current repo as the primary cache key.
104117
# Cache from the default branch of the current repo so branches can have cache hits.
105118
# Cache from the default branch of the canonical repo so forks can have cache hits.
106119
# Ignore errors on cache writes so CI of forks works without a valid GHCR config.
107120
cache-from: |
108-
type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.image }}-${{ env.GIT_REF_NAME }}
109-
type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.image }}-main
110-
type=registry,ref=ghcr.io/astral-sh/python-build-standalone:${{ matrix.image }}-main
121+
type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.image.name }}-${{ matrix.image.platform }}-${{ env.GIT_REF_NAME }}
122+
type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.image.name }}-${{ matrix.image.platform }}-main
123+
type=registry,ref=ghcr.io/astral-sh/python-build-standalone:${{ matrix.image.name }}-${{ matrix.image.platform }}-main
111124
cache-to: |
112-
type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.image }}-${{ env.GIT_REF_NAME }},ignore-error=true
125+
type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.image.name }}-${{ matrix.image.platform }}-${{ env.GIT_REF_NAME }},ignore-error=true
113126
outputs: |
114-
type=docker,dest=build/image-${{ matrix.image }}.tar
127+
type=docker,dest=build/image-${{ matrix.image.name }}.${{ matrix.image.platform }}.tar
115128
116129
- name: Compress Image
117130
run: |
118-
echo ${{ steps.build-image.outputs.imageid }} > build/image-${{ matrix.image }}
131+
echo ${{ steps.build-image.outputs.imageid }} > build/image-${{ matrix.image.name }}.${{ matrix.image.platform }}
119132
zstd -v -T0 -6 --rm build/image-*.tar
120133
121134
- name: Upload Docker Image
122135
uses: actions/upload-artifact@v4
123136
with:
124-
name: image-${{ matrix.image }}
137+
name: image-${{ matrix.image.name }}-${{ matrix.image.platform }}
125138
path: build/image-*
126139

127140
generate-matrix:

ci-runners.yaml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ depot-ubuntu-22.04:
55
platform: linux
66
free: false
77

8-
# TODO: Enable this runner to perform native builds for aarch64
9-
# depot-ubuntu-22.04-arm:
10-
# arch: aarch64
11-
# platform: linux
12-
# free: false
8+
depot-ubuntu-22.04-arm:
9+
arch: aarch64
10+
platform: linux
11+
free: false
1312

1413
depot-macos-latest:
1514
arch: x86_64

ci-targets.yaml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,10 @@ linux:
1313
- "3.14"
1414
build_options:
1515
- debug
16-
- noopt
17-
- lto
16+
- pgo+lto
1817
build_options_conditional:
1918
- options:
2019
- freethreaded+debug
21-
- freethreaded+noopt
22-
- freethreaded+lto
20+
- freethreaded+pgo+lto
2321
minimum-python-version: "3.13"
2422

cpython-unix/Makefile

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,19 @@ TOOLCHAIN_DEPENDS := \
6666

6767
PYTHON_DEP_DEPENDS := \
6868
$(OUTDIR)/targets/$(TARGET_TRIPLE) \
69-
$(if $(PYBUILD_NO_DOCKER),,$(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).tar) \
69+
$(if $(PYBUILD_NO_DOCKER),,$(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).$(HOST_PLATFORM).tar) \
7070
$(TOOLCHAIN_DEPENDS) \
7171
$(NULL)
7272

7373
default: $(OUTDIR)/cpython-$(CPYTHON_$(PYTHON_MAJOR_VERSION)_VERSION)-$(PACKAGE_SUFFIX).tar
7474

7575
ifndef PYBUILD_NO_DOCKER
76-
$(OUTDIR)/image-%.tar: $(OUTDIR)/%.Dockerfile
76+
$(OUTDIR)/image-%.$(HOST_PLATFORM).tar: $(OUTDIR)/%.Dockerfile
7777
$(RUN_BUILD) --toolchain image-$*
7878
endif
7979

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

8383
$(OUTDIR)/$(CLANG_FILENAME):
8484
$(RUN_BUILD) --toolchain clang --target-triple $(TARGET_TRIPLE)
@@ -123,7 +123,7 @@ $(OUTDIR)/libffi-3.3-$(LIBFFI_3.3_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_D
123123
$(OUTDIR)/libffi-$(LIBFFI_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-libffi.sh
124124
$(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) libffi
125125

126-
$(OUTDIR)/libpthread-stubs-$(LIBPTHREAD_STUBS_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-libpthread-stubs.sh $(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).tar
126+
$(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
127127
$(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) libpthread-stubs
128128

129129
LIBX11_DEPENDS = \
@@ -150,7 +150,7 @@ $(OUTDIR)/libXau-$(LIBXAU_VERSION)-$(PACKAGE_SUFFIX).tar: $(LIBXAU_DEPENDS)
150150
LIBXCB_DEPENDS = \
151151
$(PYTHON_DEP_DEPENDS) \
152152
$(HERE)/build-libxcb.sh \
153-
$(OUTDIR)/image-$(DOCKER_IMAGE_XCB).tar \
153+
$(OUTDIR)/image-$(DOCKER_IMAGE_XCB).$(HOST_PLATFORM).tar \
154154
$(OUTDIR)/xcb-proto-$(XCB_PROTO_VERSION)-$(PACKAGE_SUFFIX).tar \
155155
$(OUTDIR)/libXau-$(LIBXAU_VERSION)-$(PACKAGE_SUFFIX).tar \
156156
$(OUTDIR)/xorgproto-$(XORGPROTO_VERSION)-$(PACKAGE_SUFFIX).tar \

cpython-unix/base.debian9.Dockerfile

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Debian Stretch.
2+
FROM debian@sha256:c5c5200ff1e9c73ffbf188b4a67eb1c91531b644856b4aefe86a58d2f0cb05be
3+
MAINTAINER Gregory Szorc <[email protected]>
4+
5+
RUN groupadd -g 1000 build && \
6+
useradd -u 1000 -g 1000 -d /build -s /bin/bash -m build && \
7+
mkdir /tools && \
8+
chown -R build:build /build /tools
9+
10+
ENV HOME=/build \
11+
SHELL=/bin/bash \
12+
USER=build \
13+
LOGNAME=build \
14+
HOSTNAME=builder \
15+
DEBIAN_FRONTEND=noninteractive
16+
17+
CMD ["/bin/bash", "--login"]
18+
WORKDIR '/build'
19+
20+
RUN for s in debian_stretch debian_stretch-updates debian-security_stretch/updates; do \
21+
echo "deb http://snapshot.debian.org/archive/${s%_*}/20230423T032736Z/ ${s#*_} main"; \
22+
done > /etc/apt/sources.list && \
23+
( echo 'quiet "true";'; \
24+
echo 'APT::Get::Assume-Yes "true";'; \
25+
echo 'APT::Install-Recommends "false";'; \
26+
echo 'Acquire::Check-Valid-Until "false";'; \
27+
echo 'Acquire::Retries "5";'; \
28+
) > /etc/apt/apt.conf.d/99cpython-portable
29+
30+
# apt iterates all available file descriptors up to rlim_max and calls
31+
# fcntl(fd, F_SETFD, FD_CLOEXEC). This can result in millions of system calls
32+
# (we've seen 1B in the wild) and cause operations to take seconds to minutes.
33+
# Setting a fd limit mitigates.
34+
#
35+
# Attempts at enforcing the limit globally via /etc/security/limits.conf and
36+
# /root/.bashrc were not successful. Possibly because container image builds
37+
# don't perform a login or use a shell the way we expect.
38+
RUN ulimit -n 10000 && apt-get update

cpython-unix/build-binutils.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,15 @@ if [ -x "${SCCACHE}" ]; then
2222
export STAGE_CC_WRAPPER="${SCCACHE}"
2323
fi
2424

25+
if [ "$(uname -m)" = "x86_64" ]; then
26+
triple="x86_64-unknown-linux-gnu"
27+
else
28+
triple="aarch64-unknown-linux-gnu"
29+
fi
30+
2531
# gprofng requires a bison newer than what we have. So just disable it.
2632
../binutils-${BINUTILS_VERSION}/configure \
27-
--build=x86_64-unknown-linux-gnu \
33+
--build=${triple} \
2834
--prefix=/tools/host \
2935
--enable-plugins \
3036
--enable-gprofng=no \

cpython-unix/build-main.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,13 @@
2929

3030
def main():
3131
if sys.platform == "linux":
32-
host_platform = "linux64"
33-
default_target_triple = "x86_64-unknown-linux-gnu"
32+
machine = platform.machine()
33+
if machine == "aarch64":
34+
host_platform = "linux_aarch64"
35+
default_target_triple = "aarch64-unknown-linux-gnu"
36+
else:
37+
host_platform = "linux64"
38+
default_target_triple = "x86_64-unknown-linux-gnu"
3439
elif sys.platform == "darwin":
3540
host_platform = "macos"
3641
machine = platform.machine()
@@ -109,10 +114,12 @@ def main():
109114
"toolchain-image-build",
110115
"toolchain-image-build.cross",
111116
"toolchain-image-build.cross-riscv64",
117+
"toolchain-image-build.debian9",
112118
"toolchain-image-gcc",
113119
"toolchain-image-xcb",
114120
"toolchain-image-xcb.cross",
115121
"toolchain-image-xcb.cross-riscv64",
122+
"toolchain-image-xcb.debian9",
116123
},
117124
default="default",
118125
help="The make target to evaluate",

cpython-unix/build.debian9.Dockerfile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{% include 'base.debian9.Dockerfile' %}
2+
3+
RUN ulimit -n 10000 && apt-get install \
4+
bzip2 \
5+
file \
6+
libc6-dev \
7+
libffi-dev \
8+
make \
9+
patch \
10+
perl \
11+
pkg-config \
12+
tar \
13+
xz-utils \
14+
unzip \
15+
zip \
16+
zlib1g-dev

0 commit comments

Comments
 (0)