diff --git a/native/linux-clang-cross/build.cake b/native/linux-clang-cross/build.cake index 787077f383..2cde7ee54f 100644 --- a/native/linux-clang-cross/build.cake +++ b/native/linux-clang-cross/build.cake @@ -7,15 +7,20 @@ if (BUILD_ARCH.Length == 0) string GetGnArgs(string arch) { + var (vendor, abi, sysrootarg, linker) = BUILD_VARIANT switch + { + "alpine" or "alpinenodeps" => ("-alpine", "musl", "'--sysroot=/alpine', ", "'-fuse-ld=lld'"), + _ => ("", "gnu", "", ""), + }; var (toolchainArch, targetArch) = arch switch { - "arm" => ("arm-linux-gnueabihf", "armv7a-linux-gnueabihf"), - "arm64" => ("aarch64-linux-gnu", "aarch64-linux-gnu"), - _ => ($"{arch}-linux-gnu", $"{arch}-linux-gnu"), + "arm" => ($"arm{vendor}-linux-{abi}eabihf", $"armv7a{vendor}-linux-{abi}eabihf"), + "arm64" => ($"aarch64{vendor}-linux-{abi}", $"aarch64{vendor}-linux-{abi}"), + _ => ($"{arch}{vendor}-linux-{abi}", $"{arch}{vendor}-linux-{abi}"), }; var sysroot = $"/usr/{toolchainArch}"; - var init = $"'--target={targetArch}'"; + var init = $"{sysrootarg} '--target={targetArch}'"; var bin = $"'-B{sysroot}/bin/' "; var libs = $"'-L{sysroot}/lib/' "; var includes = @@ -26,7 +31,7 @@ string GetGnArgs(string arch) return $"extra_asmflags+=[ {init}, '-no-integrated-as', {bin}, {includes} ] " + $"extra_cflags+=[ {init}, {bin}, {includes} ] " + - $"extra_ldflags+=[ {init}, {bin}, {libs} ] " + + $"extra_ldflags+=[ {init}, {bin}, {libs}, {linker} ] " + ADDITIONAL_GN_ARGS; } @@ -38,6 +43,7 @@ Task("libSkiaSharp") RunCake("../linux/build.cake", "libSkiaSharp", new Dictionary { { "arch", arch }, { "gnArgs", GetGnArgs(arch) }, + { "variant", BUILD_VARIANT }, }); } }); @@ -50,6 +56,7 @@ Task("libHarfBuzzSharp") RunCake("../linux/build.cake", "libHarfBuzzSharp", new Dictionary { { "arch", arch }, { "gnArgs", GetGnArgs(arch) }, + { "variant", BUILD_VARIANT }, }); } }); diff --git a/scripts/Docker/_clang-cross-common.sh b/scripts/Docker/_clang-cross-common.sh new file mode 100755 index 0000000000..ce949db82a --- /dev/null +++ b/scripts/Docker/_clang-cross-common.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +set -ex + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +DOCKER_DIR="$1" + +# the target architecture to build for +ARCH="${2:-arm}" + +# the docker image architecture to use +MACHINE_ARCH="$(uname -m)" +[ "$MACHINE_ARCH" = "arm64" ] && MACHINE_ARCH=aarch64 +IMAGE_ARCH="${3:-$([[ "$MACHINE_ARCH" == "aarch64" ]] && echo "arm64v8" || echo "amd64")}" + +DISTRO_VERSION=$4 +ABI=$5 +VENDOR=$6 + +case $ARCH in + arm) TOOLCHAIN_ARCH=arm$VENDOR-linux-${ABI}eabihf ; TOOLCHAIN_ARCH_SHORT=armhf ; TARGET_MACHINE_ARCH=armhf ;; + arm64) TOOLCHAIN_ARCH=aarch64$VENDOR-linux-$ABI ; TOOLCHAIN_ARCH_SHORT=arm64 ; TARGET_MACHINE_ARCH=aarch64 ;; + riscv64) TOOLCHAIN_ARCH=riscv64$VENDOR-linux-$ABI ; TOOLCHAIN_ARCH_SHORT=riscv64 ; TARGET_MACHINE_ARCH=riscv64 ;; + x86) TOOLCHAIN_ARCH=i686$VENDOR-linux-$ABI ; TOOLCHAIN_ARCH_SHORT=i386 ; TARGET_MACHINE_ARCH=x86 ;; + x64) TOOLCHAIN_ARCH=x86-64$VENDOR-linux-$ABI ; TOOLCHAIN_ARCH_SHORT=amd64 ; TARGET_MACHINE_ARCH=x86_64 ;; + *) echo "Unsupported architecture: $ARCH" && exit 1 ;; +esac + +(cd $DIR && docker build --tag skiasharp-linux-$ABI-cross-$ARCH \ + --build-arg TOOLCHAIN_ARCH=$TOOLCHAIN_ARCH \ + --build-arg TOOLCHAIN_ARCH_SHORT=$TOOLCHAIN_ARCH_SHORT \ + --build-arg IMAGE_ARCH=$IMAGE_ARCH \ + --build-arg MACHINE_ARCH=$MACHINE_ARCH \ + --build-arg TARGET_MACHINE_ARCH=$TARGET_MACHINE_ARCH \ + --build-arg DISTRO_VERSION=$DISTRO_VERSION \ + $DOCKER_DIR) + +if [ "$VENDOR" = "-alpine" ]; then vendor=alpine; fi + +(cd $DIR/../.. && + docker run --rm --name skiasharp-linux-$ABI-cross-$ARCH --volume $(pwd):/work skiasharp-linux-$ABI-cross-$ARCH /bin/bash -c "\ + dotnet tool restore && + dotnet cake --target=externals-linux-clang-cross --configuration=Release --buildarch=$ARCH --variant=$vendor") diff --git a/scripts/Docker/alpine/clang-cross/.dockerignore b/scripts/Docker/alpine/clang-cross/.dockerignore new file mode 100644 index 0000000000..3a09fc21d8 --- /dev/null +++ b/scripts/Docker/alpine/clang-cross/.dockerignore @@ -0,0 +1 @@ +build-local.sh diff --git a/scripts/Docker/alpine/clang-cross/Dockerfile b/scripts/Docker/alpine/clang-cross/Dockerfile new file mode 100644 index 0000000000..198beeb7c3 --- /dev/null +++ b/scripts/Docker/alpine/clang-cross/Dockerfile @@ -0,0 +1,50 @@ +# Arguments: +# IMAGE_ARCH - the architecture of the image [ amd64 | arm64v8 | riscv64 ] +# DOTNET_SDK_VERSION - the version of dotnet for the Cake script [ 8.0 | * ] +# TOOLCHAIN_VERSION - the version of the GCC toolchain [ 9 | * ] +# TOOLCHAIN_ARCH - the architecture of the GCC toolchain [ arm-alpine-linux-musleabihf | aarch64-alpine-linux-musl | riscv64-alpine-linux-musl ] +# TOOLCHAIN_ARCH_SHORT - the short form architecture of the GCC toolchain [ armhf | arm64 ] +# FONTCONFIG_VERSION - the exact version of libfontconfig1 to use [ 2.13.1-2 | * ] + +ARG IMAGE_ARCH=amd64 +FROM ${IMAGE_ARCH}/debian:12 + +# Install the required packages +RUN apt-get update \ + && apt-get install -y \ + curl python3 git clang-19 lld-19 ninja-build xz-utils curl \ + && rm -rf /var/lib/apt/lists/* + +# Install the cross-compilation musl toolchain +ARG DISTRO_VERSION=3.17 +ARG TOOLCHAIN_ARCH_SHORT=armhf +ARG MACHINE_ARCH=x86_64 +ARG TARGET_MACHINE_ARCH=armhf + +# obtain apk.static from gitlab.alpinelinux.org/alpine/apk-tools/-/releases/v2.12.14 +RUN APK_DIR="$(mktemp -d)" && \ + curl -SLO --create-dirs --output-dir "$APK_DIR" "https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v2.12.14/$MACHINE_ARCH/apk.static" && \ + chmod +x "$APK_DIR/apk.static" && \ + "$APK_DIR/apk.static" \ + -X "http://dl-cdn.alpinelinux.org/alpine/v$DISTRO_VERSION/main" \ + -X "http://dl-cdn.alpinelinux.org/alpine/v$DISTRO_VERSION/community" \ + -U --allow-untrusted --root /alpine --arch "$TARGET_MACHINE_ARCH" --initdb add && \ + "$APK_DIR/apk.static" \ + -X "http://dl-cdn.alpinelinux.org/alpine/v$DISTRO_VERSION/main" \ + -X "http://dl-cdn.alpinelinux.org/alpine/v$DISTRO_VERSION/community" \ + -U --allow-untrusted --root /alpine --arch "$TARGET_MACHINE_ARCH" --no-scripts \ + add fontconfig-dev build-base linux-headers + +# Install the .NET SDK +ARG DOTNET_SDK_VERSION=8.0 +ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT 1 +RUN curl https://dot.net/v1/dotnet-install.sh -L -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 + +ENV CC=clang-19 CXX=clang++-19 + +WORKDIR /work diff --git a/scripts/Docker/alpine/clang-cross/build-local.sh b/scripts/Docker/alpine/clang-cross/build-local.sh new file mode 100755 index 0000000000..09e2e3273b --- /dev/null +++ b/scripts/Docker/alpine/clang-cross/build-local.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -ex + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +ARCH=$1 +ALPINE_VERSION=$3 +if [ -z "$ALPINE_VERSION" ]; then + case $ARCH in + riscv64) ALPINE_VERSION=3.20 ;; + *) ALPINE_VERSION=3.17 ;; + esac +fi + +$DIR/../../_clang-cross-common.sh "$DIR" "$ARCH" "$2" "$ALPINE_VERSION" "musl" "-alpine" diff --git a/scripts/Docker/debian/clang-cross/build-local.sh b/scripts/Docker/debian/clang-cross/build-local.sh old mode 100644 new mode 100755 index 157054ead3..c678b60e66 --- a/scripts/Docker/debian/clang-cross/build-local.sh +++ b/scripts/Docker/debian/clang-cross/build-local.sh @@ -3,24 +3,13 @@ set -ex DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -# the target architecture to build for -ARCH="${1:-arm}" -case $ARCH in - arm) BUILD_ARGS="--build-arg TOOLCHAIN_ARCH=arm-linux-gnueabihf --build-arg TOOLCHAIN_ARCH_SHORT=armhf" ;; - arm64) BUILD_ARGS="--build-arg TOOLCHAIN_ARCH=aarch64-linux-gnu --build-arg TOOLCHAIN_ARCH_SHORT=arm64" ;; - riscv64) BUILD_ARGS="--build-arg TOOLCHAIN_ARCH=riscv64-linux-gnu --build-arg TOOLCHAIN_ARCH_SHORT=riscv64" ;; - x86) BUILD_ARGS="--build-arg TOOLCHAIN_ARCH=i686-linux-gnu --build-arg TOOLCHAIN_ARCH_SHORT=i386" ;; - x64) BUILD_ARGS="--build-arg TOOLCHAIN_ARCH=x86-64-linux-gnu --build-arg TOOLCHAIN_ARCH_SHORT=amd64" ;; - *) echo "Unsupported architecture: $ARCH" && exit 1 ;; -esac - -# the docker image architecture to use -IMAGE_ARCH="${2:-$([[ "$(uname -m)" == "arm64" ]] && echo "arm64v8" || echo "amd64")}" - -DEBIAN_VERSION=${3:-11} - -(cd $DIR && docker build --tag skiasharp-linux-cross-$ARCH $BUILD_ARGS --build-arg IMAGE_ARCH=$IMAGE_ARCH $DEBIAN_VERSION) -(cd $DIR/../../../../ && - docker run --rm --name skiasharp-linux-cross-$ARCH --volume $(pwd):/work skiasharp-linux-cross-$ARCH /bin/bash -c "\ - dotnet tool restore ; \ - dotnet cake --target=externals-linux-clang-cross --configuration=Release --buildarch=$ARCH") +ARCH=$1 +DEBIAN_VERSION=$3 +if [ -z "$DEBIAN_VERSION" ]; then + case $ARCH in + riscv64) DEBIAN_VERSION=12 ;; + *) DEBIAN_VERSION=11 ;; + esac +fi + +$DIR/../../_clang-cross-common.sh "$DIR/$DEBIAN_VERSION" "$ARCH" "$2" "$DEBIAN_VERSION" "gnu" diff --git a/scripts/azure-templates-stages.yml b/scripts/azure-templates-stages.yml index 559575a4c3..aba496d9cb 100644 --- a/scripts/azure-templates-stages.yml +++ b/scripts/azure-templates-stages.yml @@ -374,7 +374,17 @@ stages: target: externals-linux-clang-cross - arch: riscv64 docker: scripts/Docker/debian/clang-cross/12 - dockerArgs: --build-arg TOOLCHAIN_ARCH=riscv64-linux-gnu --build-arg TOOLCHAIN_ARCH_SHORT=riscv64 + dockerArgs: --build-arg TOOLCHAIN_ARCH=riscv64-linux-gnu --build-arg TOOLCHAIN_ARCH_SHORT=riscv64 --build-arg DISTRO_VERSION=12 + target: externals-linux-clang-cross + - arch: arm64 + variant: alpine + docker: scripts/Docker/alpine/clang-cross + dockerArgs: --build-arg TOOLCHAIN_ARCH=aarch64-alpine-linux-musl --build-arg TOOLCHAIN_ARCH_SHORT=arm64 --build-arg TARGET_MACHINE_ARCH=aarch64 + target: externals-linux-clang-cross + - arch: riscv64 + variant: alpine + docker: scripts/Docker/alpine/clang-cross + dockerArgs: --build-arg TOOLCHAIN_ARCH=riscv64-alpine-linux-musl --build-arg TOOLCHAIN_ARCH_SHORT=riscv64 --build-arg TARGET_MACHINE_ARCH=riscv64 --build-arg DISTRO_VERSION=3.20 target: externals-linux-clang-cross - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Tizen (Linux) parameters: @@ -518,10 +528,14 @@ stages: # tvOS - name: native_tvos_macos # Linux + - name: native_linux_arm64_alpine_linux + - name: native_linux_arm64_alpine_nodeps_linux - name: native_linux_arm64_linux - name: native_linux_arm64_nodeps_linux - name: native_linux_arm_linux - name: native_linux_arm_nodeps_linux + - name: native_linux_riscv64_alpine_linux + - name: native_linux_riscv64_alpine_nodeps_linux - name: native_linux_riscv64_linux - name: native_linux_riscv64_nodeps_linux - name: native_linux_x64_alpine_linux @@ -561,8 +575,12 @@ stages: # Linux - name: native_linux_arm64_linux - name: native_linux_arm64_nodeps_linux + - name: native_linux_arm64_alpine_linux + - name: native_linux_arm64_alpine_nodeps_linux - name: native_linux_arm_linux - name: native_linux_arm_nodeps_linux + - name: native_linux_riscv64_alpine_linux + - name: native_linux_riscv64_alpine_nodeps_linux - name: native_linux_riscv64_linux - name: native_linux_riscv64_nodeps_linux - name: native_linux_x64_alpine_linux