diff --git a/binding/HarfBuzzSharp.NativeAssets.Linux/HarfBuzzSharp.NativeAssets.Linux.csproj b/binding/HarfBuzzSharp.NativeAssets.Linux/HarfBuzzSharp.NativeAssets.Linux.csproj
index afaeedbfa0..68ede387c7 100644
--- a/binding/HarfBuzzSharp.NativeAssets.Linux/HarfBuzzSharp.NativeAssets.Linux.csproj
+++ b/binding/HarfBuzzSharp.NativeAssets.Linux/HarfBuzzSharp.NativeAssets.Linux.csproj
@@ -19,6 +19,9 @@
+
+
+
diff --git a/binding/HarfBuzzSharp.NativeAssets.Linux/buildTransitive/net4/HarfBuzzSharp.targets b/binding/HarfBuzzSharp.NativeAssets.Linux/buildTransitive/net4/HarfBuzzSharp.targets
index 06826d3c4b..bcde14721b 100644
--- a/binding/HarfBuzzSharp.NativeAssets.Linux/buildTransitive/net4/HarfBuzzSharp.targets
+++ b/binding/HarfBuzzSharp.NativeAssets.Linux/buildTransitive/net4/HarfBuzzSharp.targets
@@ -49,6 +49,14 @@
musl-loongarch64\
+
+ <_NativeHarfBuzzSharpFile Include="$(MSBuildThisFileDirectory)..\..\runtimes\linux-bionic-x64\native\libHarfBuzzSharp*.so">
+ bionic-x64\
+
+ <_NativeHarfBuzzSharpFile Include="$(MSBuildThisFileDirectory)..\..\runtimes\linux-bionic-arm64\native\libHarfBuzzSharp*.so">
+ bionic-arm64\
+
+
%(Dir)%(Filename)%(Extension)
diff --git a/binding/SkiaSharp.NativeAssets.Linux.NoDependencies/SkiaSharp.NativeAssets.Linux.NoDependencies.csproj b/binding/SkiaSharp.NativeAssets.Linux.NoDependencies/SkiaSharp.NativeAssets.Linux.NoDependencies.csproj
index 3de0a3fdde..8e4b6ba82d 100644
--- a/binding/SkiaSharp.NativeAssets.Linux.NoDependencies/SkiaSharp.NativeAssets.Linux.NoDependencies.csproj
+++ b/binding/SkiaSharp.NativeAssets.Linux.NoDependencies/SkiaSharp.NativeAssets.Linux.NoDependencies.csproj
@@ -30,6 +30,9 @@ The excluded dependencies are:
+
+
+
diff --git a/binding/SkiaSharp.NativeAssets.Linux.NoDependencies/buildTransitive/net4/SkiaSharp.targets b/binding/SkiaSharp.NativeAssets.Linux.NoDependencies/buildTransitive/net4/SkiaSharp.targets
index ffe1394d2b..f06e337c21 100644
--- a/binding/SkiaSharp.NativeAssets.Linux.NoDependencies/buildTransitive/net4/SkiaSharp.targets
+++ b/binding/SkiaSharp.NativeAssets.Linux.NoDependencies/buildTransitive/net4/SkiaSharp.targets
@@ -49,6 +49,14 @@
musl-loongarch64\
+
+ <_NativeSkiaSharpFile Include="$(MSBuildThisFileDirectory)..\..\runtimes\linux-bionic-x64\native\libSkiaSharp*.so">
+ bionic-x64\
+
+ <_NativeSkiaSharpFile Include="$(MSBuildThisFileDirectory)..\..\runtimes\linux-bionic-arm64\native\libSkiaSharp*.so">
+ bionic-arm64\
+
+
%(Dir)%(Filename)%(Extension)
diff --git a/binding/SkiaSharp.NativeAssets.Linux/SkiaSharp.NativeAssets.Linux.csproj b/binding/SkiaSharp.NativeAssets.Linux/SkiaSharp.NativeAssets.Linux.csproj
index 1555c37d87..045e0b9f4d 100644
--- a/binding/SkiaSharp.NativeAssets.Linux/SkiaSharp.NativeAssets.Linux.csproj
+++ b/binding/SkiaSharp.NativeAssets.Linux/SkiaSharp.NativeAssets.Linux.csproj
@@ -19,6 +19,9 @@
+
+
+
diff --git a/binding/SkiaSharp.NativeAssets.Linux/buildTransitive/net4/SkiaSharp.targets b/binding/SkiaSharp.NativeAssets.Linux/buildTransitive/net4/SkiaSharp.targets
index ffe1394d2b..f06e337c21 100644
--- a/binding/SkiaSharp.NativeAssets.Linux/buildTransitive/net4/SkiaSharp.targets
+++ b/binding/SkiaSharp.NativeAssets.Linux/buildTransitive/net4/SkiaSharp.targets
@@ -49,6 +49,14 @@
musl-loongarch64\
+
+ <_NativeSkiaSharpFile Include="$(MSBuildThisFileDirectory)..\..\runtimes\linux-bionic-x64\native\libSkiaSharp*.so">
+ bionic-x64\
+
+ <_NativeSkiaSharpFile Include="$(MSBuildThisFileDirectory)..\..\runtimes\linux-bionic-arm64\native\libSkiaSharp*.so">
+ bionic-arm64\
+
+
%(Dir)%(Filename)%(Extension)
diff --git a/scripts/Docker/bionic/amd64/.dockerignore b/scripts/Docker/bionic/amd64/.dockerignore
new file mode 100644
index 0000000000..3a09fc21d8
--- /dev/null
+++ b/scripts/Docker/bionic/amd64/.dockerignore
@@ -0,0 +1 @@
+build-local.sh
diff --git a/scripts/Docker/bionic/amd64/Dockerfile b/scripts/Docker/bionic/amd64/Dockerfile
new file mode 100644
index 0000000000..33c228ee63
--- /dev/null
+++ b/scripts/Docker/bionic/amd64/Dockerfile
@@ -0,0 +1,49 @@
+# Arguments:
+# DOTNET_SDK_VERSION - the version of dotnet for the Cake script [ 8.0 | * ]
+FROM amd64/debian:bookworm
+
+# Install the required packages
+RUN apt-get update && apt-get install -y \
+ build-essential \
+ git \
+ wget \
+ unzip \
+ cmake \
+ ninja-build \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/*
+
+# Configure Android NDK r26b
+RUN wget https://dl.google.com/android/repository/android-ndk-r26b-linux.zip && \
+ unzip android-ndk-r26b-linux.zip -d /opt && \
+ rm android-ndk-r26b-linux.zip
+ENV ANDROID_NDK_HOME /opt/android-ndk-r26b
+ENV PATH $PATH:$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin
+
+# Copy source
+COPY . .
+
+# Install the .NET SDK
+ARG DOTNET_SDK_VERSION=8.0
+ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
+RUN wget https://builds.dotnet.microsoft.com/dotnet/scripts/v1/dotnet-install.sh -O dotnet-install.sh \
+ && bash dotnet-install.sh --channel ${DOTNET_SDK_VERSION} --install-dir /usr/share/dotnet --verbose \
+ && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet \
+ && rm dotnet-install.sh \
+ && dotnet help \
+ && dotnet --info
+
+WORKDIR /work
+
+# Cmake
+RUN cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \
+ -DANDROID_ABI=x86_64 \ # target architecture
+ -DANDROID_NATIVE_API_LEVEL=29 \ # Android 10.0 (API 29)
+ -DANDROID_TOOLCHAIN=clang \ # use clang
+ -DCMAKE_BUILD_TYPE=Release \
+ -B build \
+ .
+RUN cmake --build build --parallel
+
+# Clean build cache
+RUN rm -rf build
diff --git a/scripts/Docker/bionic/amd64/build-local.sh b/scripts/Docker/bionic/amd64/build-local.sh
new file mode 100644
index 0000000000..0b09452bd4
--- /dev/null
+++ b/scripts/Docker/bionic/amd64/build-local.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+set -e
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+
+(cd $DIR && docker build --tag skiasharp-bionic-x64 .)
+(cd $DIR/../../../../ && \
+ docker run --rm --name skiasharp-bionic-x64 --volume $(pwd):/work skiasharp-bionic-x64 /bin/bash -c "\
+ dotnet tool restore ; \
+ dotnet cake --target=externals-linux --configuration=Release --buildarch=x64 --variant=bionic")
diff --git a/scripts/Docker/bionic/arm64v8/.dockerignore b/scripts/Docker/bionic/arm64v8/.dockerignore
new file mode 100644
index 0000000000..3a09fc21d8
--- /dev/null
+++ b/scripts/Docker/bionic/arm64v8/.dockerignore
@@ -0,0 +1 @@
+build-local.sh
diff --git a/scripts/Docker/bionic/arm64v8/Dockerfile b/scripts/Docker/bionic/arm64v8/Dockerfile
new file mode 100644
index 0000000000..84c4509a01
--- /dev/null
+++ b/scripts/Docker/bionic/arm64v8/Dockerfile
@@ -0,0 +1,55 @@
+# Arguments:
+# DOTNET_SDK_VERSION - the version of dotnet for the Cake script [ 8.0 | * ]
+FROM debian:bookworm
+
+# Install the required packages
+RUN apt-get update && apt-get install -y \
+ build-essential \
+ git \
+ wget \
+ unzip \
+ cmake \
+ ninja-build \
+ qemu-user-static \
+ binfmt-support \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/*
+
+# Configure Android NDK r26b
+RUN wget https://dl.google.com/android/repository/android-ndk-r26b-linux.zip && \
+ unzip android-ndk-r26b-linux.zip -d /opt && \
+ rm android-ndk-r26b-linux.zip
+ENV ANDROID_NDK_HOME /opt/android-ndk-r26b
+ENV PATH $PATH:$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin
+
+# AArch64 qemu emulation
+COPY qemu-aarch64-static /usr/bin/qemu-aarch64-static
+RUN chmod +x /usr/bin/qemu-aarch64-static
+
+# Copy source
+COPY . .
+
+# Install the .NET SDK
+ARG DOTNET_SDK_VERSION=8.0
+ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
+RUN wget https://builds.dotnet.microsoft.com/dotnet/scripts/v1/dotnet-install.sh -O dotnet-install.sh \
+ && bash dotnet-install.sh --channel ${DOTNET_SDK_VERSION} --install-dir /usr/share/dotnet --verbose \
+ && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet \
+ && rm dotnet-install.sh \
+ && dotnet help \
+ && dotnet --info
+
+WORKDIR /work
+
+# Cmake
+RUN cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \
+ -DANDROID_ABI=arm64-v8a \ # target architecture
+ -DANDROID_NATIVE_API_LEVEL=29 \ # Android 10.0 (API 29)
+ -DANDROID_TOOLCHAIN=clang \ # use clang
+ -DCMAKE_BUILD_TYPE=Release \
+ -B build \
+ .
+RUN cmake --build build --parallel
+
+# Clean build cache
+RUN rm -rf build
diff --git a/scripts/Docker/bionic/arm64v8/build-local.sh b/scripts/Docker/bionic/arm64v8/build-local.sh
new file mode 100644
index 0000000000..f41b7dc454
--- /dev/null
+++ b/scripts/Docker/bionic/arm64v8/build-local.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+set -e
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+
+(cd $DIR && docker build --tag skiasharp-bionic-arm64 .)
+(cd $DIR/../../../../ && \
+ docker run --rm --name skiasharp-bionic-arm64 --volume $(pwd):/work skiasharp-bionic-arm64 /bin/bash -c "\
+ dotnet tool restore ; \
+ dotnet cake --target=externals-linux --configuration=Release --buildarch=arm64 --variant=bionic")
diff --git a/scripts/azure-templates-stages.yml b/scripts/azure-templates-stages.yml
index 756bc0d75d..ad756eafb5 100644
--- a/scripts/azure-templates-stages.yml
+++ b/scripts/azure-templates-stages.yml
@@ -51,7 +51,6 @@ stages:
- template: /scripts/azure-templates-stages-prepare.yml@self
parameters:
buildAgentHost: ${{ parameters.buildAgentHost }}
-
- ${{ if in(parameters.buildPipelineType, 'native', 'complete') }}:
- template: /scripts/azure-templates-stages-native.yml@self
parameters: