Skip to content

Commit f9d11b3

Browse files
authored
Increase Linux support (#3209)
Use Debian 10 and cross-compile for more architectures.
1 parent 5bf7f9c commit f9d11b3

File tree

22 files changed

+344
-236
lines changed

22 files changed

+344
-236
lines changed

externals/depot_tools

Submodule depot_tools updated from ecad42c to 8fecc59

native/linux-clang-cross/build.cake

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,33 @@ DirectoryPath ROOT_PATH = MakeAbsolute(Directory("../.."));
22

33
#load "../../scripts/cake/shared.cake"
44

5+
string TOOLCHAIN_ARCH = Argument("toolchainArch", EnvironmentVariable("TOOLCHAIN_ARCH"));
6+
string TOOLCHAIN_ARCH_SHORT = Argument("toolchainArchShort", EnvironmentVariable("TOOLCHAIN_ARCH_SHORT"));
7+
string TOOLCHAIN_ARCH_TARGET = Argument("toolchainArchTarget", EnvironmentVariable("TOOLCHAIN_ARCH_TARGET"));
8+
9+
Information("Toolchain:");
10+
Information($" Arch: {TOOLCHAIN_ARCH} ({TOOLCHAIN_ARCH_SHORT})");
11+
Information($" Target {TOOLCHAIN_ARCH_TARGET}");
12+
513
if (BUILD_ARCH.Length == 0)
614
BUILD_ARCH = new [] { "arm" };
715

816
string GetGnArgs(string arch)
917
{
10-
var (vendor, abi, sysrootarg, linker) = BUILD_VARIANT switch
11-
{
12-
"alpine" or "alpinenodeps" => ("-alpine", "musl", "'--sysroot=/alpine', ", "'-fuse-ld=lld'"),
13-
_ => ("", "gnu", "", ""),
14-
};
15-
var (toolchainArch, targetArch) = arch switch
18+
var (sysrootArg, linker) = BUILD_VARIANT switch
1619
{
17-
"arm" => ($"arm{vendor}-linux-{abi}eabihf", $"armv7a{vendor}-linux-{abi}eabihf"),
18-
"arm64" => ($"aarch64{vendor}-linux-{abi}", $"aarch64{vendor}-linux-{abi}"),
19-
_ => ($"{arch}{vendor}-linux-{abi}", $"{arch}{vendor}-linux-{abi}"),
20+
"alpine" or "alpinenodeps" => ("'--sysroot=/alpine', ", "'-fuse-ld=lld'"),
21+
_ => ("", ""),
2022
};
2123

22-
var sysroot = $"/usr/{toolchainArch}";
23-
var init = $"{sysrootarg} '--target={targetArch}'";
24+
var sysroot = $"/usr/{TOOLCHAIN_ARCH}";
25+
var init = $"{sysrootArg} '--target={TOOLCHAIN_ARCH_TARGET}'";
2426
var bin = $"'-B{sysroot}/bin/' ";
2527
var libs = $"'-L{sysroot}/lib/' ";
2628
var includes =
2729
$"'-I{sysroot}/include', " +
2830
$"'-I{sysroot}/include/c++/current', " +
29-
$"'-I{sysroot}/include/c++/current/{toolchainArch}' ";
31+
$"'-I{sysroot}/include/c++/current/{TOOLCHAIN_ARCH}' ";
3032

3133
return
3234
$"extra_asmflags+=[ {init}, '-no-integrated-as', {bin}, {includes} ] " +
@@ -43,7 +45,6 @@ Task("libSkiaSharp")
4345
RunCake("../linux/build.cake", "libSkiaSharp", new Dictionary<string, string> {
4446
{ "arch", arch },
4547
{ "gnArgs", GetGnArgs(arch) },
46-
{ "variant", BUILD_VARIANT },
4748
});
4849
}
4950
});
@@ -56,7 +57,6 @@ Task("libHarfBuzzSharp")
5657
RunCake("../linux/build.cake", "libHarfBuzzSharp", new Dictionary<string, string> {
5758
{ "arch", arch },
5859
{ "gnArgs", GetGnArgs(arch) },
59-
{ "variant", BUILD_VARIANT },
6060
});
6161
}
6262
});

native/linux/build.cake

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ bool SUPPORT_VULKAN = SUPPORT_VULKAN_VAR == "1" || SUPPORT_VULKAN_VAR.ToLower()
1212
var VERIFY_EXCLUDED = Argument("verifyExcluded", Argument("verifyexcluded", ""))
1313
.ToLower().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
1414

15+
var VERIFY_GLIBC_MAX_VAR = Argument("verifyGlibcMax", Argument("verifyglibcmax", "2.28"));
16+
var VERIFY_GLIBC_MAX = string.IsNullOrEmpty(VERIFY_GLIBC_MAX_VAR) ? null : System.Version.Parse(VERIFY_GLIBC_MAX_VAR);
17+
1518
string CC = Argument("cc", EnvironmentVariable("CC"));
1619
string CXX = Argument("cxx", EnvironmentVariable("CXX"));
1720
string AR = Argument("ar", EnvironmentVariable("AR"));
@@ -31,29 +34,56 @@ if (!string.IsNullOrEmpty(AR))
3134

3235
void CheckDeps(FilePath so)
3336
{
34-
if (VERIFY_EXCLUDED == null || VERIFY_EXCLUDED.Length == 0)
35-
return;
36-
3737
Information($"Making sure that there are no dependencies on: {string.Join(", ", VERIFY_EXCLUDED)}");
3838

39-
RunProcess("readelf", $"-d {so}", out var stdout);
40-
Information(String.Join(Environment.NewLine + " ", stdout));
39+
RunProcess("readelf", $"-dV {so}", out var stdoutEnum);
40+
var stdout = stdoutEnum.ToArray();
4141

42-
var needed = stdout
43-
.Where(l => l.Contains("(NEEDED)"))
44-
.ToList();
42+
var needed = MatchRegex(@"\(NEEDED\).+\[(.+)\]", stdout).ToList();
43+
44+
Information("Dependencies:");
45+
foreach (var need in needed) {
46+
Information($" {need}");
47+
}
4548

4649
foreach (var exclude in VERIFY_EXCLUDED) {
4750
if (needed.Any(o => o.Contains(exclude.Trim(), StringComparison.OrdinalIgnoreCase)))
4851
throw new Exception($"{so} contained a dependency on {exclude}.");
4952
}
53+
54+
var glibcs = MatchRegex(@"GLIBC_([\w\.\d]+)", stdout).Distinct().ToList();
55+
glibcs.Sort();
56+
57+
Information("GLIBC:");
58+
foreach (var glibc in glibcs) {
59+
Information($" {glibc}");
60+
}
61+
62+
if (VERIFY_GLIBC_MAX != null) {
63+
foreach (var glibc in glibcs) {
64+
var version = System.Version.Parse(glibc);
65+
if (version > VERIFY_GLIBC_MAX)
66+
throw new Exception($"{so} contained a dependency on GLIBC {glibc} which is greater than the expected GLIBC {VERIFY_GLIBC_MAX}.");
67+
}
68+
}
5069
}
5170

5271
Task("libSkiaSharp")
5372
.IsDependentOn("git-sync-deps")
5473
.WithCriteria(IsRunningOnLinux())
5574
.Does(() =>
5675
{
76+
// patch the gclient_paths.py for Python 3.7
77+
{
78+
var gclient = DEPOT_PATH.CombineWithFilePath("gclient_paths.py");
79+
var contents = System.IO.File.ReadAllText(gclient.FullPath);
80+
var newContents = contents
81+
.Replace("@functools.lru_cache", "@functools.lru_cache()")
82+
.Replace("@functools.lru_cache()()", "@functools.lru_cache()");
83+
if (contents != newContents)
84+
System.IO.File.WriteAllText(gclient.FullPath, newContents);
85+
}
86+
5787
foreach (var arch in BUILD_ARCH) {
5888
if (Skip(arch)) return;
5989

scripts/Docker/_clang-cross-common.sh

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,43 @@
11
#!/usr/bin/env bash
22
set -ex
33

4+
# Parameters:
5+
# $1 - The directory containing the Dockerfile [ clang-cross/10 | clang-cross ]
6+
# $2 - The target architecture to build for [ arm | arm64 | riscv64 | x86 | x64 ]
7+
# $3 - The ABI [ gnu | musl ]
8+
# $4 - The variant [ "" | alpine ]
9+
410
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
11+
12+
# the directory containing the Dockerfile
513
DOCKER_DIR="$1"
614

715
# the target architecture to build for
8-
ARCH="${2:-arm}"
16+
ARCH="$2"
917

1018
# the docker image architecture to use
1119
MACHINE_ARCH="$(uname -m)"
12-
[ "$MACHINE_ARCH" = "arm64" ] && MACHINE_ARCH=aarch64
13-
IMAGE_ARCH="${3:-$([[ "$MACHINE_ARCH" == "aarch64" ]] && echo "arm64v8" || echo "amd64")}"
14-
15-
DISTRO_VERSION=$4
16-
ABI=$5
17-
VENDOR=$6
18-
19-
case $ARCH in
20-
arm) TOOLCHAIN_ARCH=arm$VENDOR-linux-${ABI}eabihf ; TOOLCHAIN_ARCH_SHORT=armhf ; TARGET_MACHINE_ARCH=armhf ;;
21-
arm64) TOOLCHAIN_ARCH=aarch64$VENDOR-linux-$ABI ; TOOLCHAIN_ARCH_SHORT=arm64 ; TARGET_MACHINE_ARCH=aarch64 ;;
22-
riscv64) TOOLCHAIN_ARCH=riscv64$VENDOR-linux-$ABI ; TOOLCHAIN_ARCH_SHORT=riscv64 ; TARGET_MACHINE_ARCH=riscv64 ;;
23-
x86) TOOLCHAIN_ARCH=i686$VENDOR-linux-$ABI ; TOOLCHAIN_ARCH_SHORT=i386 ; TARGET_MACHINE_ARCH=x86 ;;
24-
x64) TOOLCHAIN_ARCH=x86-64$VENDOR-linux-$ABI ; TOOLCHAIN_ARCH_SHORT=amd64 ; TARGET_MACHINE_ARCH=x86_64 ;;
25-
*) echo "Unsupported architecture: $ARCH" && exit 1 ;;
20+
case $MACHINE_ARCH in
21+
arm64) IMAGE_ARCH=arm64v8 ; MACHINE_ARCH=aarch64 ;;
22+
*) IMAGE_ARCH=amd64 ;;
2623
esac
2724

28-
(cd $DIR && docker build --tag skiasharp-linux-$ABI-cross-$ARCH \
29-
--build-arg TOOLCHAIN_ARCH=$TOOLCHAIN_ARCH \
30-
--build-arg TOOLCHAIN_ARCH_SHORT=$TOOLCHAIN_ARCH_SHORT \
31-
--build-arg IMAGE_ARCH=$IMAGE_ARCH \
32-
--build-arg MACHINE_ARCH=$MACHINE_ARCH \
33-
--build-arg TARGET_MACHINE_ARCH=$TARGET_MACHINE_ARCH \
34-
--build-arg DISTRO_VERSION=$DISTRO_VERSION \
25+
# the ABI
26+
ABI=$3
27+
28+
# the variant
29+
VARIANT=$4
30+
31+
(cd $DIR &&
32+
docker build --tag skiasharp-linux-$ABI-cross-$ARCH \
33+
--build-arg BUILD_ARCH=$ARCH \
34+
--build-arg IMAGE_ARCH=$IMAGE_ARCH \
35+
--build-arg MACHINE_ARCH=$MACHINE_ARCH \
3536
$DOCKER_DIR)
3637

37-
if [ "$VENDOR" = "-alpine" ]; then vendor=alpine; fi
38+
[ -n "$VARIANT" ] && VARIANT="--variant=$VARIANT"
3839

3940
(cd $DIR/../.. &&
40-
docker run --rm --name skiasharp-linux-$ABI-cross-$ARCH --volume $(pwd):/work skiasharp-linux-$ABI-cross-$ARCH /bin/bash -c "\
41-
dotnet tool restore &&
42-
dotnet cake --target=externals-linux-clang-cross --configuration=Release --buildarch=$ARCH --variant=$vendor")
41+
docker run --rm --name skiasharp-linux-$ABI-cross-$ARCH --volume $(pwd):/work skiasharp-linux-$ABI-cross-$ARCH /bin/bash -c " \
42+
dotnet tool restore ; \
43+
dotnet cake --target=externals-linux-clang-cross --configuration=Release --buildarch=$ARCH $VARIANT ")

scripts/Docker/alpine/amd64/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ RUN apk add --no-cache \
1010

1111
# Install the .NET SDK
1212
ARG DOTNET_SDK_VERSION=8.0
13-
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT 1
13+
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
1414
RUN wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh \
1515
&& bash dotnet-install.sh --channel ${DOTNET_SDK_VERSION} --install-dir /usr/share/dotnet --verbose \
1616
&& ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet \

scripts/Docker/alpine/arm64v8/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ RUN apk add --no-cache \
1010

1111
# Install the .NET SDK
1212
ARG DOTNET_SDK_VERSION=8.0
13-
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT 1
13+
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
1414
RUN wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh \
1515
&& bash dotnet-install.sh --channel ${DOTNET_SDK_VERSION} --install-dir /usr/share/dotnet --verbose \
1616
&& ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet \
Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,76 @@
11
# Arguments:
22
# IMAGE_ARCH - the architecture of the image [ amd64 | arm64v8 | riscv64 ]
33
# DOTNET_SDK_VERSION - the version of dotnet for the Cake script [ 8.0 | * ]
4+
# LLVM_VERSION - the version of the LLVM compiler [ 13 | * ]
45
# TOOLCHAIN_VERSION - the version of the GCC toolchain [ 9 | * ]
56
# TOOLCHAIN_ARCH - the architecture of the GCC toolchain [ arm-alpine-linux-musleabihf | aarch64-alpine-linux-musl | riscv64-alpine-linux-musl ]
6-
# TOOLCHAIN_ARCH_SHORT - the short form architecture of the GCC toolchain [ armhf | arm64 ]
7-
# FONTCONFIG_VERSION - the exact version of libfontconfig1 to use [ 2.13.1-2 | * ]
87

98
ARG IMAGE_ARCH=amd64
109
FROM ${IMAGE_ARCH}/debian:12
1110

11+
# Set the architecture-specific variables based on the value of the BUILD_ARCH argument
12+
ARG BUILD_ARCH=arm64
13+
RUN case ${BUILD_ARCH} in \
14+
arm) TOOLCHAIN_ARCH=armv7-alpine-linux-musleabihf ; TOOLCHAIN_ARCH_TARGET=armv7-alpine-linux-musleabihf ;; \
15+
arm64) TOOLCHAIN_ARCH=aarch64-alpine-linux-musl ; TOOLCHAIN_ARCH_TARGET=aarch64-alpine-linux-musl ;; \
16+
riscv64) TOOLCHAIN_ARCH=riscv64-alpine-linux-musl ; TOOLCHAIN_ARCH_TARGET=riscv64-alpine-linux-musl ;; \
17+
x86) TOOLCHAIN_ARCH=i586-alpine-linux-musl ; TOOLCHAIN_ARCH_TARGET=i586-alpine-linux-musl ;; \
18+
x64) TOOLCHAIN_ARCH=x86_64-alpine-linux-musl ; TOOLCHAIN_ARCH_TARGET=x86_64-alpine-linux-musl ;; \
19+
*) echo "Unsupported architecture: ${BUILD_ARCH}" && exit 1 ;; \
20+
esac \
21+
&& echo "export TOOLCHAIN_ARCH=${TOOLCHAIN_ARCH}" > /etc/skia-env \
22+
&& echo "export TOOLCHAIN_ARCH_TARGET=${TOOLCHAIN_ARCH_TARGET}" >> /etc/skia-env
23+
1224
# Install the required packages
25+
ARG LLVM_VERSION=19
1326
RUN apt-get update \
1427
&& apt-get install -y \
15-
curl python3 git clang-19 lld-19 ninja-build xz-utils curl \
28+
curl python3 git clang-${LLVM_VERSION} lld-${LLVM_VERSION} ninja-build xz-utils \
1629
&& rm -rf /var/lib/apt/lists/*
1730

1831
# Install the cross-compilation musl toolchain
19-
ARG DISTRO_VERSION=3.17
20-
ARG TOOLCHAIN_ARCH_SHORT=armhf
32+
# First, obtain apk.static from https://gitlab.alpinelinux.org/alpine/apk-tools/-/releases/v2.12.14
2133
ARG MACHINE_ARCH=x86_64
22-
ARG TARGET_MACHINE_ARCH=armhf
23-
24-
# obtain apk.static from gitlab.alpinelinux.org/alpine/apk-tools/-/releases/v2.12.14
25-
RUN APK_DIR="$(mktemp -d)" && \
26-
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" && \
27-
chmod +x "$APK_DIR/apk.static" && \
28-
"$APK_DIR/apk.static" \
34+
RUN . /etc/skia-env \
35+
&& case "${BUILD_ARCH}" in \
36+
arm) APK_ARCH=armv7 ;; \
37+
arm64) APK_ARCH=aarch64 ;; \
38+
riscv64) APK_ARCH=riscv64 ;; \
39+
x86) APK_ARCH=x86 ;; \
40+
x64) APK_ARCH=x86_64 ;; \
41+
*) echo "Unsupported architecture: ${BUILD_ARCH}" && exit 1 ;; \
42+
esac \
43+
&& case "${BUILD_ARCH}" in \
44+
riscv64) DISTRO_VERSION=3.20 ;; \
45+
*) DISTRO_VERSION=3.17 ;; \
46+
esac \
47+
&& APK_DIR="$(mktemp -d)" \
48+
&& 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" \
49+
&& chmod +x "$APK_DIR/apk.static" \
50+
&& "$APK_DIR/apk.static" \
2951
-X "http://dl-cdn.alpinelinux.org/alpine/v$DISTRO_VERSION/main" \
3052
-X "http://dl-cdn.alpinelinux.org/alpine/v$DISTRO_VERSION/community" \
31-
-U --allow-untrusted --root /alpine --arch "$TARGET_MACHINE_ARCH" --initdb add && \
32-
"$APK_DIR/apk.static" \
53+
-U --allow-untrusted --root /alpine --arch "$APK_ARCH" --initdb add \
54+
&& "$APK_DIR/apk.static" \
3355
-X "http://dl-cdn.alpinelinux.org/alpine/v$DISTRO_VERSION/main" \
3456
-X "http://dl-cdn.alpinelinux.org/alpine/v$DISTRO_VERSION/community" \
35-
-U --allow-untrusted --root /alpine --arch "$TARGET_MACHINE_ARCH" --no-scripts \
57+
-U --allow-untrusted --root /alpine --arch "$APK_ARCH" --no-scripts \
3658
add fontconfig-dev build-base linux-headers
3759

3860
# Install the .NET SDK
3961
ARG DOTNET_SDK_VERSION=8.0
40-
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT 1
62+
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
4163
RUN curl https://dot.net/v1/dotnet-install.sh -L -o dotnet-install.sh \
4264
&& bash dotnet-install.sh --channel ${DOTNET_SDK_VERSION} --install-dir /usr/share/dotnet --verbose \
4365
&& ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet \
4466
&& rm dotnet-install.sh \
4567
&& dotnet help \
4668
&& dotnet --info
4769

48-
ENV CC=clang-19 CXX=clang++-19
70+
ENV CC=clang-${LLVM_VERSION} CXX=clang++-${LLVM_VERSION}
4971

5072
WORKDIR /work
73+
74+
COPY ./startup.sh /
75+
RUN chmod +x /startup.sh
76+
ENTRYPOINT [ "/startup.sh" ]
Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
#!/usr/bin/env bash
22
set -ex
33

4+
# Parameters:
5+
# $1 - The target architecture to build for [ arm | arm64 | riscv64 | x86 | x64 ]
6+
47
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
58

6-
ARCH=$1
7-
ALPINE_VERSION=$3
8-
if [ -z "$ALPINE_VERSION" ]; then
9-
case $ARCH in
10-
riscv64) ALPINE_VERSION=3.20 ;;
11-
*) ALPINE_VERSION=3.17 ;;
12-
esac
13-
fi
9+
ARCH="${1:-arm}"
1410

15-
$DIR/../../_clang-cross-common.sh "$DIR" "$ARCH" "$2" "$ALPINE_VERSION" "musl" "-alpine"
11+
$DIR/../../_clang-cross-common.sh "$DIR" "$ARCH" "musl" "alpine"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/usr/bin/env bash
2+
set -e
3+
4+
source /etc/skia-env
5+
6+
exec "$@"

scripts/Docker/debian/amd64/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Arguments:
22
# DOTNET_SDK_VERSION - the version of dotnet for the Cake script [ 8.0 | * ]
33

4-
FROM amd64/debian:11
4+
FROM amd64/debian:10
55

66
# Install the required packages
77
RUN apt-get update \
@@ -12,7 +12,7 @@ RUN apt-get update \
1212

1313
# Install the .NET SDK
1414
ARG DOTNET_SDK_VERSION=8.0
15-
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT 1
15+
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
1616
RUN curl https://dot.net/v1/dotnet-install.sh -L -o dotnet-install.sh \
1717
&& bash dotnet-install.sh --channel ${DOTNET_SDK_VERSION} --install-dir /usr/share/dotnet --verbose \
1818
&& ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet \

0 commit comments

Comments
 (0)