Skip to content

Commit bfa45f1

Browse files
(feat): Add Linux ARM64 Builds (#1527)
* 👷 (feat): Add ARM64 Builds
1 parent b991026 commit bfa45f1

File tree

6 files changed

+170
-13
lines changed

6 files changed

+170
-13
lines changed

.github/workflows/early-access.yaml

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ jobs:
6363
fail-fast: false
6464
matrix:
6565
# binaries wanted: linux amd64, mac M1, mac intel, windows x86
66-
os: [ ubuntu-24.04, macos-15, macos-15-intel, windows-2025 ]
66+
os: [ ubuntu-24.04, ubuntu-24.04-arm, macos-15, macos-15-intel, windows-2025 ]
6767
runs-on: ${{ matrix.os }}
6868

6969
steps:
@@ -102,8 +102,8 @@ jobs:
102102
- name: 'Maven clean'
103103
run: ./mvnw clean -Dmrm=false -V -B -ntp -e
104104

105-
- name: 'Patch GraalVM libs for only requiring glibc 2.12'
106-
if: ${{ env.OS == 'linux' }}
105+
- name: 'Patch AMD64 GraalVM libs for only requiring glibc 2.12'
106+
if: ${{ env.OS == 'linux' && env.ARCH == 'amd64' }}
107107
shell: bash
108108
run: |
109109
mkdir -p client/target/graalvm-libs-for-glibc-2.12
@@ -123,18 +123,48 @@ jobs:
123123
ld -r /lib/x86_64-linux-gnu/Scrt1.o client/target/dynamic-libc-start.o -o client/target/graalvm-libs-for-glibc-2.12/Scrt1.o
124124
objcopy --redefine-syms=client/src/main/resources/glibc/glibc.redef client/target/graalvm-libs-for-glibc-2.12/Scrt1.o 2>/dev/null
125125
126+
- name: 'Patch ARM64 GraalVM libs for only requiring glibc 2.17'
127+
if: ${{ env.OS == 'linux' && env.ARCH == 'aarch64' }}
128+
shell: bash
129+
run: |
130+
mkdir -p client/target/graalvm-libs-for-glibc-2.17
131+
132+
: patch common libraries
133+
( find "$GRAALVM_HOME/lib/static/linux-aarch64/glibc" -name '*.a'
134+
ls -1 /lib/aarch64-linux-gnu/libz.a
135+
ls -1 "$GRAALVM_HOME/lib/svm/clibraries/linux-aarch64/libjvm.a"
136+
ls -1 "$GRAALVM_HOME/lib/svm/clibraries/linux-aarch64/liblibchelper.a"
137+
) | while IFS= read -r input; do
138+
output="client/target/graalvm-libs-for-glibc-2.17/$(basename -- "$input")"
139+
objcopy --redefine-syms=client/src/main/resources/glibc/glibc.redef.aarch64 -- "$input" "$output" 2>/dev/null
140+
done
141+
142+
: patch gcc startfile
143+
gcc -O3 -Os -Wall -Wextra -Werror -Wconversion -Wsign-conversion -Wcast-qual -pedantic -c -o client/target/dynamic-libc-start.o client/src/main/resources/glibc/dynamic-libc-start.c
144+
ld -r /lib/aarch64-linux-gnu/Scrt1.o client/target/dynamic-libc-start.o -o client/target/graalvm-libs-for-glibc-2.17/Scrt1.o
145+
objcopy --redefine-syms=client/src/main/resources/glibc/glibc.redef.aarch64 client/target/graalvm-libs-for-glibc-2.17/Scrt1.o 2>/dev/null
146+
126147
- name: 'Build native distribution'
127148
run: ./mvnw verify -Pnative -Dmrm=false -V -B -ntp -e -s .mvn/release-settings.xml
128149

129-
- name: 'Verify native binary for only requiring glibc 2.12'
130-
if: ${{ env.OS == 'linux' }}
150+
- name: 'Verify AMD64 native binary for only requiring glibc 2.12'
151+
if: ${{ env.OS == 'linux' && env.ARCH == 'amd64' }}
131152
shell: bash
132153
run: |
133154
(( 4 == "$(ldd client/target/mvnd | awk '{print $1}' | sort -u | grep -c 'lib\(c\|dl\|rt\|pthread\)\.so\.[0-9]')" )) || ( ldd client/target/mvnd && false )
134155
err=0
135156
objdump -T client/target/mvnd | grep GLIBC_ | grep -v 'GLIBC_\([01]\|2\.[0-9]\|2\.1[012]\)[^0-9]' || err=$?
136157
(( err == 1 ))
137158
159+
- name: 'Verify ARM64 native binary for only requiring glibc 2.17'
160+
if: ${{ env.OS == 'linux' && env.ARCH == 'aarch64' }}
161+
shell: bash
162+
run: |
163+
(( 4 == "$(ldd client/target/mvnd | awk '{print $1}' | sort -u | grep -c 'lib\(c\|dl\|rt\|pthread\)\.so\.[0-9]')" )) || ( ldd client/target/mvnd && false )
164+
err=0
165+
objdump -T client/target/mvnd | grep GLIBC_ | grep -v 'GLIBC_\([01]\|2\.[0-9]\|2\.1[017]\)[^0-9]' || err=$?
166+
(( err == 1 ))
167+
138168
- name: 'Upload daemon test logs'
139169
if: always()
140170
uses: actions/upload-artifact@v7

.github/workflows/release.yaml

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ jobs:
3434
strategy:
3535
fail-fast: true
3636
matrix:
37-
# binaries wanted: linux amd64, mac intel, mac M1, windows x86
38-
os: [ ubuntu-24.04, macos-15-intel, macos-15, windows-2025 ]
37+
# binaries wanted: linux amd64, linux arm64, mac intel, mac M1, windows x86
38+
os: [ ubuntu-24.04, ubuntu-24.04-arm, macos-15-intel, macos-15, windows-2025 ]
3939
runs-on: ${{ matrix.os }}
4040

4141
steps:
@@ -74,8 +74,8 @@ jobs:
7474
- name: 'Maven clean'
7575
run: ./mvnw clean -Dmrm=false -B -ntp -e
7676

77-
- name: 'Patch GraalVM libs for only requiring glibc 2.12'
78-
if: ${{ env.OS == 'linux' }}
77+
- name: 'Patch AMD64 GraalVM libs for only requiring glibc 2.12'
78+
if: ${{ env.OS == 'linux' && env.ARCH == 'amd64' }}
7979
shell: bash
8080
run: |
8181
mkdir -p client/target/graalvm-libs-for-glibc-2.12
@@ -95,18 +95,48 @@ jobs:
9595
ld -r /lib/x86_64-linux-gnu/Scrt1.o client/target/dynamic-libc-start.o -o client/target/graalvm-libs-for-glibc-2.12/Scrt1.o
9696
objcopy --redefine-syms=client/src/main/resources/glibc/glibc.redef client/target/graalvm-libs-for-glibc-2.12/Scrt1.o 2>/dev/null
9797
98+
- name: 'Patch ARM64 GraalVM libs for only requiring glibc 2.17'
99+
if: ${{ env.OS == 'linux' && env.ARCH == 'aarch64' }}
100+
shell: bash
101+
run: |
102+
mkdir -p client/target/graalvm-libs-for-glibc-2.17
103+
104+
: patch common libraries
105+
( find "$GRAALVM_HOME/lib/static/linux-aarch64/glibc" -name '*.a'
106+
ls -1 /lib/aarch64-linux-gnu/libz.a
107+
ls -1 "$GRAALVM_HOME/lib/svm/clibraries/linux-aarch64/libjvm.a"
108+
ls -1 "$GRAALVM_HOME/lib/svm/clibraries/linux-aarch64/liblibchelper.a"
109+
) | while IFS= read -r input; do
110+
output="client/target/graalvm-libs-for-glibc-2.17/$(basename -- "$input")"
111+
objcopy --redefine-syms=client/src/main/resources/glibc/glibc.redef.aarch64 -- "$input" "$output" 2>/dev/null
112+
done
113+
114+
: patch gcc startfile
115+
gcc -O3 -Os -Wall -Wextra -Werror -Wconversion -Wsign-conversion -Wcast-qual -pedantic -c -o client/target/dynamic-libc-start.o client/src/main/resources/glibc/dynamic-libc-start.c
116+
ld -r /lib/aarch64-linux-gnu/Scrt1.o client/target/dynamic-libc-start.o -o client/target/graalvm-libs-for-glibc-2.17/Scrt1.o
117+
objcopy --redefine-syms=client/src/main/resources/glibc/glibc.redef.aarch64 client/target/graalvm-libs-for-glibc-2.17/Scrt1.o 2>/dev/null
118+
98119
- name: 'Build native distribution'
99120
run: ./mvnw verify -Pnative -Dmrm=false -B -ntp -e -DskipTests -s .mvn/release-settings.xml
100121

101-
- name: 'Verify native binary for only requiring glibc 2.12'
102-
if: ${{ env.OS == 'linux' }}
122+
- name: 'Verify AMD64 native binary for only requiring glibc 2.12'
123+
if: ${{ env.OS == 'linux' && env.ARCH == 'amd64' }}
103124
shell: bash
104125
run: |
105126
(( 4 == "$(ldd client/target/mvnd | awk '{print $1}' | sort -u | grep -c 'lib\(c\|dl\|rt\|pthread\)\.so\.[0-9]')" )) || ( ldd client/target/mvnd && false )
106127
err=0
107128
objdump -T client/target/mvnd | grep GLIBC_ | grep -v 'GLIBC_\([01]\|2\.[0-9]\|2\.1[012]\)[^0-9]' || err=$?
108129
(( err == 1 ))
109130
131+
- name: 'Verify ARM64 native binary for only requiring glibc 2.17'
132+
if: ${{ env.OS == 'linux' && env.ARCH == 'aarch64' }}
133+
shell: bash
134+
run: |
135+
(( 4 == "$(ldd client/target/mvnd | awk '{print $1}' | sort -u | grep -c 'lib\(c\|dl\|rt\|pthread\)\.so\.[0-9]')" )) || ( ldd client/target/mvnd && false )
136+
err=0
137+
objdump -T client/target/mvnd | grep GLIBC_ | grep -v 'GLIBC_\([01]\|2\.[0-9]\|2\.1[017]\)[^0-9]' || err=$?
138+
(( err == 1 ))
139+
110140
- name: 'Upload artifact'
111141
uses: actions/upload-artifact@v7
112142
with:
@@ -246,6 +276,26 @@ jobs:
246276
asset_name: maven-mvnd-${{ env.VERSION }}-linux-amd64.tar.gz
247277
asset_content_type: application/x-gzip
248278

279+
- name: Deploy maven-mvnd-linux-aarch64.zip
280+
uses: actions/upload-release-asset@v1
281+
env:
282+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
283+
with:
284+
upload_url: ${{ steps.create_release.outputs.upload_url }}
285+
asset_path: mvnd-linux-aarch64/maven-mvnd-${{ env.VERSION }}-linux-aarch64.zip
286+
asset_name: maven-mvnd-${{ env.VERSION }}-linux-aarch64.zip
287+
asset_content_type: application/zip
288+
289+
- name: Deploy maven-mvnd-linux-aarch64.tar.gz
290+
uses: actions/upload-release-asset@v1
291+
env:
292+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
293+
with:
294+
upload_url: ${{ steps.create_release.outputs.upload_url }}
295+
asset_path: mvnd-linux-aarch64/maven-mvnd-${{ env.VERSION }}-linux-aarch64.tar.gz
296+
asset_name: maven-mvnd-${{ env.VERSION }}-linux-aarch64.tar.gz
297+
asset_content_type: application/x-gzip
298+
249299
- name: Deploy maven-mvnd-darwin-amd64.zip
250300
uses: actions/upload-release-asset@v1
251301
env:

client/pom.xml

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@
204204
</profile>
205205

206206
<profile>
207-
<id>linux-image-only-require-glibc-2.12</id>
207+
<id>linux-amd64-image-only-require-glibc-2.12</id>
208208
<activation>
209209
<os>
210210
<family>linux</family>
@@ -233,6 +233,36 @@
233233
</build>
234234
</profile>
235235

236+
<profile>
237+
<id>linux-aarch64-image-only-require-glibc-2.17</id>
238+
<activation>
239+
<os>
240+
<family>linux</family>
241+
</os>
242+
<file>
243+
<exists>target/graalvm-libs-for-glibc-2.17</exists>
244+
</file>
245+
</activation>
246+
<properties>
247+
<patchelf.skip>false</patchelf.skip>
248+
</properties>
249+
<build>
250+
<plugins>
251+
<plugin>
252+
<groupId>org.graalvm.buildtools</groupId>
253+
<artifactId>native-maven-plugin</artifactId>
254+
<configuration>
255+
<buildArgs combine.children="append">
256+
<buildArg>-H:CCompilerPath=${basedir}/src/main/resources/glibc/gcc</buildArg>
257+
<buildArg>-H:CCompilerOption=-B${project.build.directory}/graalvm-libs-for-glibc-2.17</buildArg>
258+
<buildArg>-H:CLibraryPath=${project.build.directory}/graalvm-libs-for-glibc-2.17</buildArg>
259+
</buildArgs>
260+
</configuration>
261+
</plugin>
262+
</plugins>
263+
</build>
264+
</profile>
265+
236266
<profile>
237267
<id>native</id>
238268
<build>

client/src/main/resources/glibc/dynamic-libc-start.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,13 @@
2727
#include <dlfcn.h>
2828
#include <stdint.h>
2929

30+
#if defined(__aarch64__)
31+
__asm__(".symver dlsym,dlsym@GLIBC_2.17");
32+
__asm__(".symver dlvsym,dlvsym@GLIBC_2.17");
33+
#else
3034
__asm__(".symver dlsym,dlsym@GLIBC_2.2.5");
3135
__asm__(".symver dlvsym,dlvsym@GLIBC_2.2.5");
36+
#endif
3237

3338
/* __libc_csu_init is statically linked into each program, and passed to __libc_start_main
3439
* when the program is running with an old glibc (<2.34).

client/src/main/resources/glibc/gcc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,14 @@
2020
set -euf
2121

2222
base=$(dirname -- "$0")
23+
redefine_syms="$base/glibc.redef"
24+
25+
# aarch64 starts with GLIBC_2.17 and cannot consume x86-era GLIBC_2.2.5.
26+
if [ "$(uname -m)" = "aarch64" ] && [ -f "$base/glibc.redef.aarch64" ]; then
27+
redefine_syms="$base/glibc.redef.aarch64"
28+
fi
2329

2430
# fix glibc api version on the fly
25-
find . -name '*.o' -print0 | xargs -0rn 1 objcopy --redefine-syms="$base/glibc.redef"
31+
find . -name '*.o' -print0 | xargs -0rn 1 objcopy --redefine-syms="$redefine_syms"
2632

2733
exec gcc "$@"
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
__libc_start_main __dynamic_libc_start_main
18+
clock_gettime clock_gettime@GLIBC_2.17
19+
dlopen dlopen@GLIBC_2.17
20+
dlsym dlsym@GLIBC_2.17
21+
memcpy memcpy@GLIBC_2.17
22+
posix_spawn posix_spawn@GLIBC_2.17
23+
pthread_attr_getguardsize pthread_attr_getguardsize@GLIBC_2.17
24+
pthread_attr_getstack pthread_attr_getstack@GLIBC_2.17
25+
pthread_attr_setstacksize pthread_attr_setstacksize@GLIBC_2.17
26+
pthread_condattr_setclock pthread_condattr_setclock@GLIBC_2.17
27+
pthread_create pthread_create@GLIBC_2.17
28+
pthread_getattr_np pthread_getattr_np@GLIBC_2.17
29+
pthread_join pthread_join@GLIBC_2.17
30+
pthread_kill pthread_kill@GLIBC_2.17
31+
pthread_mutex_trylock pthread_mutex_trylock@GLIBC_2.17
32+
pthread_setname_np pthread_setname_np@GLIBC_2.17
33+
sem_destroy sem_destroy@GLIBC_2.17
34+
sem_init sem_init@GLIBC_2.17
35+
sem_post sem_post@GLIBC_2.17
36+
sem_wait sem_wait@GLIBC_2.17

0 commit comments

Comments
 (0)