This is an automated email from the ASF dual-hosted git repository. gnodet pushed a commit to branch arm64-glibc-master in repository https://gitbox.apache.org/repos/asf/maven-mvnd.git
commit 3c46b1a4d886e76f8decd6d895c3202b3eaa3f14 Author: Guillaume Nodet <[email protected]> AuthorDate: Tue Mar 17 12:13:03 2026 +0100 Add Linux ARM64 (aarch64) native build support Port ARM64 build support from mvnd-1.x PR #1527 to master: - Add ubuntu-24.04-arm runner for Linux ARM64 builds - Fix broken matrix exclude rules (macos-latest→macos-15, windows-latest→windows-2025) - Add glibc.redef.aarch64 pinning all symbols to GLIBC_2.17 - Add #if defined(__aarch64__) conditional in dynamic-libc-start.c - Add uname -m arch detection in gcc wrapper script - Add linux-aarch64-image-only-require-glibc-2.17 profile in client/pom.xml - Add ARM64 glibc patch/verify steps in CI workflows - Add linux-aarch64 release asset upload steps Co-Authored-By: Claude Opus 4.6 <[email protected]> --- .github/workflows/early-access.yaml | 50 +++++++++++++--- .github/workflows/release.yaml | 70 +++++++++++++++++++--- 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, 183 insertions(+), 18 deletions(-) diff --git a/.github/workflows/early-access.yaml b/.github/workflows/early-access.yaml index 10b931fc..9ae31fdd 100644 --- a/.github/workflows/early-access.yaml +++ b/.github/workflows/early-access.yaml @@ -79,15 +79,19 @@ jobs: strategy: 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 ] + # binaries wanted: linux amd64, linux arm64, mac M1, mac intel, windows x86 + os: [ ubuntu-24.04, ubuntu-24.04-arm, macos-15, macos-15-intel, windows-2025 ] arch: [ x64, arm64 ] exclude: - - os: macos-latest + - os: ubuntu-24.04 + arch: arm64 + - os: ubuntu-24.04-arm + arch: x64 + - os: macos-15 arch: x64 - os: macos-15-intel arch: arm64 - - os: windows-latest + - os: windows-2025 arch: arm64 runs-on: ${{ matrix.os }} @@ -143,8 +147,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 @@ -164,11 +168,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 ) @@ -176,6 +201,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[0-7]\)[^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 a39576e4..50e0791c 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -34,15 +34,19 @@ jobs: strategy: fail-fast: true matrix: - # binaries wanted - os: [ ubuntu-24.04, macos-15, macos-15-intel, windows-2025 ] + # binaries wanted: linux amd64, linux arm64, mac M1, mac intel, windows x86 + os: [ ubuntu-24.04, ubuntu-24.04-arm, macos-15, macos-15-intel, windows-2025 ] arch: [ x64, arm64 ] exclude: - - os: macos-latest + - os: ubuntu-24.04 + arch: arm64 + - os: ubuntu-24.04-arm + arch: x64 + - os: macos-15 arch: x64 - os: macos-15-intel arch: arm64 - - os: windows-latest + - os: windows-2025 arch: arm64 runs-on: ${{ matrix.os }} @@ -82,8 +86,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 @@ -103,11 +107,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 ) @@ -115,6 +140,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[0-7]\)[^0-9]' || err=$? + (( err == 1 )) + - name: 'Upload artifact' uses: actions/upload-artifact@v7 with: @@ -254,6 +288,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 0d0d525f..cf46875f 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -160,7 +160,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> @@ -189,6 +189,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
