Repository: denoland/deno
Pull request: fix: widen aarch64 linux minimum GLIBC version by improving sysroot build

Fixes the sysroot to make it more reliable on aarch64. The sysroot we download as part of the build process now includes a small script to set up the linker flags required to build in that sysroot.

Fixes #23775 

Before:

```
matt@raspberrypi:~ $ ~/.deno/bin/deno 
/home/matt/.deno/bin/deno: /lib/aarch64-linux-gnu/libm.so.6: version `GLIBC_2.35' not found (required by /home/matt/.deno/bin/deno)
```

After:

```
matt@raspberrypi:/tmp $ ./deno
Deno 1.43.3
exit using ctrl+d, ctrl+c, or close()
REPL is running with all permissions allowed.
To specify permissions, run `deno repl` with allow flags.
```



Changed files:
filename: .github/workflows/ci.generate.ts
patch: @@ -86,7 +86,7 @@ ${installPkgsCommand} || echo 'Failed. Trying again.' && sudo apt-get clean && s
 (yes '' | sudo update-alternatives --force --all) > /dev/null 2> /dev/null || true
 
 echo "Decompressing sysroot..."
-wget -q https://github.com/denoland/deno_sysroot_build/releases/download/sysroot-20240207/sysroot-\`uname -m\`.tar.xz -O /tmp/sysroot.tar.xz
+wget -q https://github.com/denoland/deno_sysroot_build/releases/download/sysroot-20240527/sysroot-\`uname -m\`.tar.xz -O /tmp/sysroot.tar.xz
 cd /
 xzcat /tmp/sysroot.tar.xz | sudo tar -x
 sudo mount --rbind /dev /sysroot/dev
@@ -95,21 +95,23 @@ sudo mount --rbind /home /sysroot/home
 sudo mount -t proc /proc /sysroot/proc
 cd
 
-if [[ \`uname -m\` == "aarch64" ]]; then
-  echo "Copying libdl.a"
-  sudo cp /sysroot/usr/lib/aarch64-linux-gnu/libdl.a /sysroot/lib/aarch64-linux-gnu/libdl.a
-  echo "Copying libdl.so"
-  sudo cp /sysroot/lib/aarch64-linux-gnu/libdl.so.2 /sysroot/lib/aarch64-linux-gnu/libdl.so
-else
-  echo "Copying libdl.a"
-  sudo cp /sysroot/usr/lib/x86_64-linux-gnu/libdl.a /sysroot/lib/x86_64-linux-gnu/libdl.a
-  echo "Copying libdl.so"
-  sudo cp /sysroot/lib/x86_64-linux-gnu/libdl.so.2 /sysroot/lib/x86_64-linux-gnu/libdl.so
-fi
+echo "Done."
 
 # Configure the build environment. Both Rust and Clang will produce
 # llvm bitcode only, so we can use lld's incremental LTO support.
-cat >> $GITHUB_ENV << __0
+
+# Load the sysroot's env vars
+echo "sysroot env:"
+cat /sysroot/.env
+. /sysroot/.env
+
+# Important notes:
+#   1. -ldl seems to be required to avoid a failure in FFI tests. This flag seems
+#      to be in the Rust default flags in the smoketest, so uncertain why we need
+#      to be explicit here.
+#   2. RUSTFLAGS and RUSTDOCFLAGS must be specified, otherwise the doctests fail
+#      to build because the object formats are not compatible.
+echo "
 CARGO_PROFILE_BENCH_INCREMENTAL=false
 CARGO_PROFILE_BENCH_LTO=false
 CARGO_PROFILE_RELEASE_INCREMENTAL=false
@@ -118,28 +120,27 @@ RUSTFLAGS<<__1
   -C linker-plugin-lto=true
   -C linker=clang-${llvmVersion}
   -C link-arg=-fuse-ld=lld-${llvmVersion}
-  -C link-arg=--sysroot=/sysroot
   -C link-arg=-ldl
   -C link-arg=-Wl,--allow-shlib-undefined
   -C link-arg=-Wl,--thinlto-cache-dir=$(pwd)/target/release/lto-cache
   -C link-arg=-Wl,--thinlto-cache-policy,cache_size_bytes=700m
   --cfg tokio_unstable
-  \${{ env.RUSTFLAGS }}
+  $RUSTFLAGS
 __1
 RUSTDOCFLAGS<<__1
   -C linker-plugin-lto=true
   -C linker=clang-${llvmVersion}
   -C link-arg=-fuse-ld=lld-${llvmVersion}
-  -C link-arg=--sysroot=/sysroot
   -C link-arg=-ldl
   -C link-arg=-Wl,--allow-shlib-undefined
   -C link-arg=-Wl,--thinlto-cache-dir=$(pwd)/target/release/lto-cache
   -C link-arg=-Wl,--thinlto-cache-policy,cache_size_bytes=700m
-  \${{ env.RUSTFLAGS }}
+  --cfg tokio_unstable
+  $RUSTFLAGS
 __1
 CC=/usr/bin/clang-${llvmVersion}
-CFLAGS=-flto=thin --sysroot=/sysroot
-__0`,
+CFLAGS=-flto=thin $CFLAGS
+" > $GITHUB_ENV`,
 };
 
 const installBenchTools = "./tools/install_prebuilt.js wrk hyperfine";
@@ -700,6 +701,24 @@ const ci = {
             "df -h",
           ].join("\n"),
         },
+        {
+          // Run a minimal check to ensure that binary is not corrupted, regardless
+          // of our build mode
+          name: "Check deno binary",
+          if: "matrix.job == 'test'",
+          run:
+            'target/${{ matrix.profile }}/deno eval "console.log(1+2)" | grep 3',
+          env: {
+            NO_COLOR: 1,
+          },
+        },
+        {
+          // Verify that the binary actually works in the Ubuntu-16.04 sysroot.
+          name: "Check deno binary (in sysroot)",
+          if: "matrix.job == 'test' && matrix.use_sysroot",
+          run:
+            'sudo chroot /sysroot "$(pwd)/target/${{ matrix.profile }}/deno" --version',
+        },
         {
           name: "Upload PR artifact (linux)",
           if: [
@@ -835,25 +854,6 @@ const ci = {
           ].join("\n"),
           run: "cargo test --release --locked",
         },
-        {
-          // Since all tests are skipped when we're building a tagged commit
-          // this is a minimal check to ensure that binary is not corrupted
-          name: "Check deno binary",
-          if:
-            "matrix.profile == 'release' && startsWith(github.ref, 'refs/tags/')",
-          run: 'target/release/deno eval "console.log(1+2)" | grep 3',
-          env: {
-            NO_COLOR: 1,
-          },
-        },
-        {
-          // Verify that the binary actually works in the Ubuntu-16.04 sysroot.
-          // TODO(mmastrac): make this work for aarch64 as well
-          name: "Check deno binary (in sysroot)",
-          if:
-            "matrix.profile == 'release' && matrix.use_sysroot && matrix.arch != 'aarch64'",
-          run: 'sudo chroot /sysroot "$(pwd)/target/release/deno" --version',
-        },
         {
           name: "Configure hosts file for WPT",
           if: "matrix.wpt",

filename: .github/workflows/ci.yml
patch: @@ -273,7 +273,7 @@ jobs:
           (yes '' | sudo update-alternatives --force --all) > /dev/null 2> /dev/null || true
 
           echo "Decompressing sysroot..."
-          wget -q https://github.com/denoland/deno_sysroot_build/releases/download/sysroot-20240207/sysroot-`uname -m`.tar.xz -O /tmp/sysroot.tar.xz
+          wget -q https://github.com/denoland/deno_sysroot_build/releases/download/sysroot-20240527/sysroot-`uname -m`.tar.xz -O /tmp/sysroot.tar.xz
           cd /
           xzcat /tmp/sysroot.tar.xz | sudo tar -x
           sudo mount --rbind /dev /sysroot/dev
@@ -282,21 +282,23 @@ jobs:
           sudo mount -t proc /proc /sysroot/proc
           cd
 
-          if [[ `uname -m` == "aarch64" ]]; then
-            echo "Copying libdl.a"
-            sudo cp /sysroot/usr/lib/aarch64-linux-gnu/libdl.a /sysroot/lib/aarch64-linux-gnu/libdl.a
-            echo "Copying libdl.so"
-            sudo cp /sysroot/lib/aarch64-linux-gnu/libdl.so.2 /sysroot/lib/aarch64-linux-gnu/libdl.so
-          else
-            echo "Copying libdl.a"
-            sudo cp /sysroot/usr/lib/x86_64-linux-gnu/libdl.a /sysroot/lib/x86_64-linux-gnu/libdl.a
-            echo "Copying libdl.so"
-            sudo cp /sysroot/lib/x86_64-linux-gnu/libdl.so.2 /sysroot/lib/x86_64-linux-gnu/libdl.so
-          fi
+          echo "Done."
 
           # Configure the build environment. Both Rust and Clang will produce
           # llvm bitcode only, so we can use lld's incremental LTO support.
-          cat >> $GITHUB_ENV << __0
+
+          # Load the sysroot's env vars
+          echo "sysroot env:"
+          cat /sysroot/.env
+          . /sysroot/.env
+
+          # Important notes:
+          #   1. -ldl seems to be required to avoid a failure in FFI tests. This flag seems
+          #      to be in the Rust default flags in the smoketest, so uncertain why we need
+          #      to be explicit here.
+          #   2. RUSTFLAGS and RUSTDOCFLAGS must be specified, otherwise the doctests fail
+          #      to build because the object formats are not compatible.
+          echo "
           CARGO_PROFILE_BENCH_INCREMENTAL=false
           CARGO_PROFILE_BENCH_LTO=false
           CARGO_PROFILE_RELEASE_INCREMENTAL=false
@@ -305,28 +307,27 @@ jobs:
             -C linker-plugin-lto=true
             -C linker=clang-17
             -C link-arg=-fuse-ld=lld-17
-            -C link-arg=--sysroot=/sysroot
             -C link-arg=-ldl
             -C link-arg=-Wl,--allow-shlib-undefined
             -C link-arg=-Wl,--thinlto-cache-dir=$(pwd)/target/release/lto-cache
             -C link-arg=-Wl,--thinlto-cache-policy,cache_size_bytes=700m
             --cfg tokio_unstable
-            ${{ env.RUSTFLAGS }}
+            $RUSTFLAGS
           __1
           RUSTDOCFLAGS<<__1
             -C linker-plugin-lto=true
             -C linker=clang-17
             -C link-arg=-fuse-ld=lld-17
-            -C link-arg=--sysroot=/sysroot
             -C link-arg=-ldl
             -C link-arg=-Wl,--allow-shlib-undefined
             -C link-arg=-Wl,--thinlto-cache-dir=$(pwd)/target/release/lto-cache
             -C link-arg=-Wl,--thinlto-cache-policy,cache_size_bytes=700m
-            ${{ env.RUSTFLAGS }}
+            --cfg tokio_unstable
+            $RUSTFLAGS
           __1
           CC=/usr/bin/clang-17
-          CFLAGS=-flto=thin --sysroot=/sysroot
-          __0
+          CFLAGS=-flto=thin $CFLAGS
+          " > $GITHUB_ENV
       - name: Remove macOS cURL --ipv4 flag
         run: |-
           curl --version
@@ -419,6 +420,14 @@ jobs:
           df -h
           cargo build --release --locked --all-targets
           df -h
+      - name: Check deno binary
+        if: '!(matrix.skip) && (matrix.job == ''test'')'
+        run: 'target/${{ matrix.profile }}/deno eval "console.log(1+2)" | grep 3'
+        env:
+          NO_COLOR: 1
+      - name: Check deno binary (in sysroot)
+        if: '!(matrix.skip) && (matrix.job == ''test'' && matrix.use_sysroot)'
+        run: 'sudo chroot /sysroot "$(pwd)/target/${{ matrix.profile }}/deno" --version'
       - name: Upload PR artifact (linux)
         if: |-
           !(matrix.skip) && (matrix.job == 'test' &&
@@ -512,14 +521,6 @@ jobs:
           github.repository == 'denoland/deno' &&
           !startsWith(github.ref, 'refs/tags/'))))
         run: cargo test --release --locked
-      - name: Check deno binary
-        if: '!(matrix.skip) && (matrix.profile == ''release'' && startsWith(github.ref, ''refs/tags/''))'
-        run: target/release/deno eval "console.log(1+2)" | grep 3
-        env:
-          NO_COLOR: 1
-      - name: Check deno binary (in sysroot)
-        if: '!(matrix.skip) && (matrix.profile == ''release'' && matrix.use_sysroot && matrix.arch != ''aarch64'')'
-        run: sudo chroot /sysroot "$(pwd)/target/release/deno" --version
       - name: Configure hosts file for WPT
         if: '!(matrix.skip) && (matrix.wpt)'
         run: ./wpt make-hosts-file | sudo tee -a /etc/hosts