This is an automated email from the ASF dual-hosted git repository.
cstamas pushed a commit to branch mvnd-1.x
in repository https://gitbox.apache.org/repos/asf/maven-mvnd.git
The following commit(s) were added to refs/heads/mvnd-1.x by this push:
new bfa45f1e (feat): Add Linux ARM64 Builds (#1527)
bfa45f1e is described below
commit bfa45f1e7c2dfbb4ab6dad70e6031fb1238f533f
Author: Kris <[email protected]>
AuthorDate: Tue Mar 17 21:11:10 2026 +1000
(feat): Add Linux ARM64 Builds (#1527)
* :construction_worker: (feat): Add ARM64 Builds
---
.github/workflows/early-access.yaml | 40 ++++++++++++--
.github/workflows/release.yaml | 62 +++++++++++++++++++---
client/pom.xml | 32 ++++++++++-
.../src/main/resources/glibc/dynamic-libc-start.c | 5 ++
client/src/main/resources/glibc/gcc | 8 ++-
.../src/main/resources/glibc/glibc.redef.aarch64 | 36 +++++++++++++
6 files changed, 170 insertions(+), 13 deletions(-)
diff --git a/.github/workflows/early-access.yaml
b/.github/workflows/early-access.yaml
index f1a6d14f..7a81b274 100644
--- a/.github/workflows/early-access.yaml
+++ b/.github/workflows/early-access.yaml
@@ -63,7 +63,7 @@ jobs:
fail-fast: false
matrix:
# binaries wanted: linux amd64, mac M1, mac intel, windows x86
- os: [ ubuntu-24.04, macos-15, macos-15-intel, windows-2025 ]
+ os: [ ubuntu-24.04, ubuntu-24.04-arm, macos-15, macos-15-intel,
windows-2025 ]
runs-on: ${{ matrix.os }}
steps:
@@ -102,8 +102,8 @@ jobs:
- name: 'Maven clean'
run: ./mvnw clean -Dmrm=false -V -B -ntp -e
- - name: 'Patch GraalVM libs for only requiring glibc 2.12'
- if: ${{ env.OS == 'linux' }}
+ - name: 'Patch AMD64 GraalVM libs for only requiring glibc 2.12'
+ if: ${{ env.OS == 'linux' && env.ARCH == 'amd64' }}
shell: bash
run: |
mkdir -p client/target/graalvm-libs-for-glibc-2.12
@@ -123,11 +123,32 @@ jobs:
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
objcopy --redefine-syms=client/src/main/resources/glibc/glibc.redef
client/target/graalvm-libs-for-glibc-2.12/Scrt1.o 2>/dev/null
+ - name: 'Patch ARM64 GraalVM libs for only requiring glibc 2.17'
+ if: ${{ env.OS == 'linux' && env.ARCH == 'aarch64' }}
+ shell: bash
+ run: |
+ mkdir -p client/target/graalvm-libs-for-glibc-2.17
+
+ : patch common libraries
+ ( find "$GRAALVM_HOME/lib/static/linux-aarch64/glibc" -name '*.a'
+ ls -1 /lib/aarch64-linux-gnu/libz.a
+ ls -1 "$GRAALVM_HOME/lib/svm/clibraries/linux-aarch64/libjvm.a"
+ ls -1
"$GRAALVM_HOME/lib/svm/clibraries/linux-aarch64/liblibchelper.a"
+ ) | while IFS= read -r input; do
+ output="client/target/graalvm-libs-for-glibc-2.17/$(basename
-- "$input")"
+ objcopy
--redefine-syms=client/src/main/resources/glibc/glibc.redef.aarch64 -- "$input"
"$output" 2>/dev/null
+ done
+
+ : patch gcc startfile
+ 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
+ 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
+ objcopy
--redefine-syms=client/src/main/resources/glibc/glibc.redef.aarch64
client/target/graalvm-libs-for-glibc-2.17/Scrt1.o 2>/dev/null
+
- name: 'Build native distribution'
run: ./mvnw verify -Pnative -Dmrm=false -V -B -ntp -e -s
.mvn/release-settings.xml
- - name: 'Verify native binary for only requiring glibc 2.12'
- if: ${{ env.OS == 'linux' }}
+ - name: 'Verify AMD64 native binary for only requiring glibc 2.12'
+ if: ${{ env.OS == 'linux' && env.ARCH == 'amd64' }}
shell: bash
run: |
(( 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 )
@@ -135,6 +156,15 @@ jobs:
objdump -T client/target/mvnd | grep GLIBC_ | grep -v
'GLIBC_\([01]\|2\.[0-9]\|2\.1[012]\)[^0-9]' || err=$?
(( err == 1 ))
+ - name: 'Verify ARM64 native binary for only requiring glibc 2.17'
+ if: ${{ env.OS == 'linux' && env.ARCH == 'aarch64' }}
+ shell: bash
+ run: |
+ (( 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 )
+ err=0
+ objdump -T client/target/mvnd | grep GLIBC_ | grep -v
'GLIBC_\([01]\|2\.[0-9]\|2\.1[017]\)[^0-9]' || err=$?
+ (( err == 1 ))
+
- name: 'Upload daemon test logs'
if: always()
uses: actions/upload-artifact@v7
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 6dca2e4d..eb190229 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -34,8 +34,8 @@ jobs:
strategy:
fail-fast: true
matrix:
- # binaries wanted: linux amd64, mac intel, mac M1, windows x86
- os: [ ubuntu-24.04, macos-15-intel, macos-15, windows-2025 ]
+ # binaries wanted: linux amd64, linux arm64, mac intel, mac M1,
windows x86
+ os: [ ubuntu-24.04, ubuntu-24.04-arm, macos-15-intel, macos-15,
windows-2025 ]
runs-on: ${{ matrix.os }}
steps:
@@ -74,8 +74,8 @@ jobs:
- name: 'Maven clean'
run: ./mvnw clean -Dmrm=false -B -ntp -e
- - name: 'Patch GraalVM libs for only requiring glibc 2.12'
- if: ${{ env.OS == 'linux' }}
+ - name: 'Patch AMD64 GraalVM libs for only requiring glibc 2.12'
+ if: ${{ env.OS == 'linux' && env.ARCH == 'amd64' }}
shell: bash
run: |
mkdir -p client/target/graalvm-libs-for-glibc-2.12
@@ -95,11 +95,32 @@ jobs:
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
objcopy --redefine-syms=client/src/main/resources/glibc/glibc.redef
client/target/graalvm-libs-for-glibc-2.12/Scrt1.o 2>/dev/null
+ - name: 'Patch ARM64 GraalVM libs for only requiring glibc 2.17'
+ if: ${{ env.OS == 'linux' && env.ARCH == 'aarch64' }}
+ shell: bash
+ run: |
+ mkdir -p client/target/graalvm-libs-for-glibc-2.17
+
+ : patch common libraries
+ ( find "$GRAALVM_HOME/lib/static/linux-aarch64/glibc" -name '*.a'
+ ls -1 /lib/aarch64-linux-gnu/libz.a
+ ls -1 "$GRAALVM_HOME/lib/svm/clibraries/linux-aarch64/libjvm.a"
+ ls -1
"$GRAALVM_HOME/lib/svm/clibraries/linux-aarch64/liblibchelper.a"
+ ) | while IFS= read -r input; do
+ output="client/target/graalvm-libs-for-glibc-2.17/$(basename
-- "$input")"
+ objcopy
--redefine-syms=client/src/main/resources/glibc/glibc.redef.aarch64 -- "$input"
"$output" 2>/dev/null
+ done
+
+ : patch gcc startfile
+ 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
+ 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
+ objcopy
--redefine-syms=client/src/main/resources/glibc/glibc.redef.aarch64
client/target/graalvm-libs-for-glibc-2.17/Scrt1.o 2>/dev/null
+
- name: 'Build native distribution'
run: ./mvnw verify -Pnative -Dmrm=false -B -ntp -e -DskipTests -s
.mvn/release-settings.xml
- - name: 'Verify native binary for only requiring glibc 2.12'
- if: ${{ env.OS == 'linux' }}
+ - name: 'Verify AMD64 native binary for only requiring glibc 2.12'
+ if: ${{ env.OS == 'linux' && env.ARCH == 'amd64' }}
shell: bash
run: |
(( 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 )
@@ -107,6 +128,15 @@ jobs:
objdump -T client/target/mvnd | grep GLIBC_ | grep -v
'GLIBC_\([01]\|2\.[0-9]\|2\.1[012]\)[^0-9]' || err=$?
(( err == 1 ))
+ - name: 'Verify ARM64 native binary for only requiring glibc 2.17'
+ if: ${{ env.OS == 'linux' && env.ARCH == 'aarch64' }}
+ shell: bash
+ run: |
+ (( 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 )
+ err=0
+ objdump -T client/target/mvnd | grep GLIBC_ | grep -v
'GLIBC_\([01]\|2\.[0-9]\|2\.1[017]\)[^0-9]' || err=$?
+ (( err == 1 ))
+
- name: 'Upload artifact'
uses: actions/upload-artifact@v7
with:
@@ -246,6 +276,26 @@ jobs:
asset_name: maven-mvnd-${{ env.VERSION }}-linux-amd64.tar.gz
asset_content_type: application/x-gzip
+ - name: Deploy maven-mvnd-linux-aarch64.zip
+ uses: actions/upload-release-asset@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+ asset_path: mvnd-linux-aarch64/maven-mvnd-${{ env.VERSION
}}-linux-aarch64.zip
+ asset_name: maven-mvnd-${{ env.VERSION }}-linux-aarch64.zip
+ asset_content_type: application/zip
+
+ - name: Deploy maven-mvnd-linux-aarch64.tar.gz
+ uses: actions/upload-release-asset@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+ asset_path: mvnd-linux-aarch64/maven-mvnd-${{ env.VERSION
}}-linux-aarch64.tar.gz
+ asset_name: maven-mvnd-${{ env.VERSION }}-linux-aarch64.tar.gz
+ asset_content_type: application/x-gzip
+
- name: Deploy maven-mvnd-darwin-amd64.zip
uses: actions/upload-release-asset@v1
env:
diff --git a/client/pom.xml b/client/pom.xml
index d3bbbeac..5a924354 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -204,7 +204,7 @@
</profile>
<profile>
- <id>linux-image-only-require-glibc-2.12</id>
+ <id>linux-amd64-image-only-require-glibc-2.12</id>
<activation>
<os>
<family>linux</family>
@@ -233,6 +233,36 @@
</build>
</profile>
+ <profile>
+ <id>linux-aarch64-image-only-require-glibc-2.17</id>
+ <activation>
+ <os>
+ <family>linux</family>
+ </os>
+ <file>
+ <exists>target/graalvm-libs-for-glibc-2.17</exists>
+ </file>
+ </activation>
+ <properties>
+ <patchelf.skip>false</patchelf.skip>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.graalvm.buildtools</groupId>
+ <artifactId>native-maven-plugin</artifactId>
+ <configuration>
+ <buildArgs combine.children="append">
+
<buildArg>-H:CCompilerPath=${basedir}/src/main/resources/glibc/gcc</buildArg>
+
<buildArg>-H:CCompilerOption=-B${project.build.directory}/graalvm-libs-for-glibc-2.17</buildArg>
+
<buildArg>-H:CLibraryPath=${project.build.directory}/graalvm-libs-for-glibc-2.17</buildArg>
+ </buildArgs>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
<profile>
<id>native</id>
<build>
diff --git a/client/src/main/resources/glibc/dynamic-libc-start.c
b/client/src/main/resources/glibc/dynamic-libc-start.c
index 2272b255..74ebffd3 100644
--- a/client/src/main/resources/glibc/dynamic-libc-start.c
+++ b/client/src/main/resources/glibc/dynamic-libc-start.c
@@ -27,8 +27,13 @@
#include <dlfcn.h>
#include <stdint.h>
+#if defined(__aarch64__)
+__asm__(".symver dlsym,dlsym@GLIBC_2.17");
+__asm__(".symver dlvsym,dlvsym@GLIBC_2.17");
+#else
__asm__(".symver dlsym,dlsym@GLIBC_2.2.5");
__asm__(".symver dlvsym,dlvsym@GLIBC_2.2.5");
+#endif
/* __libc_csu_init is statically linked into each program, and passed to
__libc_start_main
* when the program is running with an old glibc (<2.34).
diff --git a/client/src/main/resources/glibc/gcc
b/client/src/main/resources/glibc/gcc
index 6b147c66..b80a6ebe 100755
--- a/client/src/main/resources/glibc/gcc
+++ b/client/src/main/resources/glibc/gcc
@@ -20,8 +20,14 @@
set -euf
base=$(dirname -- "$0")
+redefine_syms="$base/glibc.redef"
+
+# aarch64 starts with GLIBC_2.17 and cannot consume x86-era GLIBC_2.2.5.
+if [ "$(uname -m)" = "aarch64" ] && [ -f "$base/glibc.redef.aarch64" ]; then
+ redefine_syms="$base/glibc.redef.aarch64"
+fi
# fix glibc api version on the fly
-find . -name '*.o' -print0 | xargs -0rn 1 objcopy
--redefine-syms="$base/glibc.redef"
+find . -name '*.o' -print0 | xargs -0rn 1 objcopy
--redefine-syms="$redefine_syms"
exec gcc "$@"
diff --git a/client/src/main/resources/glibc/glibc.redef.aarch64
b/client/src/main/resources/glibc/glibc.redef.aarch64
new file mode 100644
index 00000000..7c845d2b
--- /dev/null
+++ b/client/src/main/resources/glibc/glibc.redef.aarch64
@@ -0,0 +1,36 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+__libc_start_main __dynamic_libc_start_main
+clock_gettime clock_gettime@GLIBC_2.17
+dlopen dlopen@GLIBC_2.17
+dlsym dlsym@GLIBC_2.17
+memcpy memcpy@GLIBC_2.17
+posix_spawn posix_spawn@GLIBC_2.17
+pthread_attr_getguardsize pthread_attr_getguardsize@GLIBC_2.17
+pthread_attr_getstack pthread_attr_getstack@GLIBC_2.17
+pthread_attr_setstacksize pthread_attr_setstacksize@GLIBC_2.17
+pthread_condattr_setclock pthread_condattr_setclock@GLIBC_2.17
+pthread_create pthread_create@GLIBC_2.17
+pthread_getattr_np pthread_getattr_np@GLIBC_2.17
+pthread_join pthread_join@GLIBC_2.17
+pthread_kill pthread_kill@GLIBC_2.17
+pthread_mutex_trylock pthread_mutex_trylock@GLIBC_2.17
+pthread_setname_np pthread_setname_np@GLIBC_2.17
+sem_destroy sem_destroy@GLIBC_2.17
+sem_init sem_init@GLIBC_2.17
+sem_post sem_post@GLIBC_2.17
+sem_wait sem_wait@GLIBC_2.17