Skip to content

Commit 2b6d12e

Browse files
committed
Refine Linux sysroot and Avalonia host linking
1 parent 96f8b13 commit 2b6d12e

7 files changed

Lines changed: 78 additions & 28 deletions

File tree

.github/actions/sysroot-cache/action.yml

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ inputs:
44
cache-key:
55
description: Cache key for the packed sysroot tarball
66
required: false
7-
default: linux-sysroot-bionic-amd64-minbase
7+
default: linux-sysroot-bionic-amd64
88
sysroot-path:
99
description: Directory to create with debootstrap
1010
required: false
@@ -24,7 +24,7 @@ inputs:
2424
include-packages:
2525
description: Comma-separated package list for debootstrap --include
2626
required: false
27-
default: libfontconfig1-dev,gcc,libstdc++-7-dev
27+
default: build-essential,symlinks,libicu-dev,liblttng-ust-dev,libunwind-dev,libcurl4-openssl-dev,libkrb5-dev,libssl-dev,zlib1g-dev,libbrotli-dev,libfontconfig1-dev,gcc,libstdc++-7-dev
2828
mirror:
2929
description: Ubuntu mirror URL passed to debootstrap
3030
required: false
@@ -42,12 +42,6 @@ outputs:
4242
runs:
4343
using: composite
4444
steps:
45-
- name: Checkout repository
46-
uses: actions/checkout@v6
47-
with:
48-
fetch-depth: 1
49-
submodules: false
50-
5145
- name: Resolve sysroot paths
5246
id: paths
5347
shell: bash
@@ -95,10 +89,12 @@ runs:
9589
--force-check-gpg \
9690
--include='${{ inputs.include-packages }}' \
9791
--arch '${{ inputs.arch }}' \
92+
--components='main,universe' \
93+
--extra-suites='${{ inputs.release }}-updates,${{ inputs.release }}-security,${{ inputs.release }}-backports' \
9894
'${{ inputs.release }}' \
9995
"$sysroot_path" \
10096
'${{ inputs.mirror }}'
10197
102-
sudo chown -R "$(id -u):$(id -g)" "$sysroot_path"
98+
sudo chroot "$sysroot_path" symlinks -cr /usr
10399
104100
bash ./scripts/sysroot-util.sh pack "$sysroot_path"

.github/actions/sysroot-restore/action.yml

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ inputs:
44
cache-key:
55
description: Cache key for the packed sysroot tarball
66
required: false
7-
default: linux-sysroot-bionic-amd64-minbase
7+
default: linux-sysroot-bionic-amd64
88
sysroot-path:
99
description: Directory where the sysroot should be unpacked
1010
required: false
@@ -19,12 +19,6 @@ outputs:
1919
runs:
2020
using: composite
2121
steps:
22-
- name: Checkout repository
23-
uses: actions/checkout@v6
24-
with:
25-
fetch-depth: 1
26-
submodules: false
27-
2822
- name: Resolve sysroot paths
2923
id: paths
3024
shell: bash

.github/workflows/build.yml

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ on:
66
branches:
77
- main
88

9+
env:
10+
LINUX_SYSROOT_CACHE_KEY: linux-sysroot-bionic-amd64
11+
912
# Keep the job graph below in sync with the Mermaid workflow diagram in README.md.
1013
jobs:
1114
windows-hostlibs:
@@ -240,7 +243,7 @@ jobs:
240243
run: python .\scripts\pipeline.py avalonia-test -v --target ${{ matrix.avalonia_target }}
241244

242245
linux-sysroot:
243-
runs-on: ubuntu-22.04
246+
runs-on: ubuntu-latest
244247

245248
steps:
246249
- name: Checkout repository
@@ -251,9 +254,11 @@ jobs:
251254

252255
- name: Build and cache Linux sysroot
253256
uses: ./.github/actions/sysroot-cache
257+
with:
258+
cache-key: ${{ env.LINUX_SYSROOT_CACHE_KEY }}
254259

255260
linux-hostlibs:
256-
runs-on: ubuntu-22.04
261+
runs-on: ubuntu-latest
257262
needs:
258263
- linux-sysroot
259264

@@ -267,6 +272,8 @@ jobs:
267272
- name: Restore Linux sysroot
268273
id: restore_sysroot
269274
uses: ./.github/actions/sysroot-restore
275+
with:
276+
cache-key: ${{ env.LINUX_SYSROOT_CACHE_KEY }}
270277

271278
- name: Compute hostlibs cache key
272279
id: hostlibs_key
@@ -306,7 +313,7 @@ jobs:
306313
if-no-files-found: error
307314

308315
linux-matrix-test:
309-
runs-on: ubuntu-22.04
316+
runs-on: ubuntu-latest
310317
needs:
311318
- linux-sysroot
312319
- linux-hostlibs
@@ -320,6 +327,8 @@ jobs:
320327

321328
- name: Restore Linux sysroot
322329
uses: ./.github/actions/sysroot-restore
330+
with:
331+
cache-key: ${{ env.LINUX_SYSROOT_CACHE_KEY }}
323332

324333
- name: Install LLVM
325334
run: |
@@ -343,7 +352,7 @@ jobs:
343352
run: python ./scripts/pipeline.py matrix -v
344353

345354
linux-skia:
346-
runs-on: ubuntu-22.04
355+
runs-on: ubuntu-latest
347356
needs:
348357
- linux-sysroot
349358
strategy:
@@ -366,6 +375,8 @@ jobs:
366375
- name: Restore Linux sysroot
367376
id: restore_sysroot
368377
uses: ./.github/actions/sysroot-restore
378+
with:
379+
cache-key: ${{ env.LINUX_SYSROOT_CACHE_KEY }}
369380

370381
- name: Compute skia cache key
371382
id: skia_key
@@ -402,7 +413,7 @@ jobs:
402413
if-no-files-found: error
403414

404415
linux-link-avalonia:
405-
runs-on: ubuntu-22.04
416+
runs-on: ubuntu-latest
406417
needs:
407418
- linux-sysroot
408419
- linux-hostlibs
@@ -425,6 +436,8 @@ jobs:
425436
- name: Restore Linux sysroot
426437
id: restore_sysroot
427438
uses: ./.github/actions/sysroot-restore
439+
with:
440+
cache-key: ${{ env.LINUX_SYSROOT_CACHE_KEY }}
428441

429442
- name: Compute hostlibs cache key
430443
id: hostlibs_key
@@ -456,7 +469,7 @@ jobs:
456469
run: python ./scripts/pipeline.py link-avalonia -v --target ${{ matrix.avalonia_target }} --os linux --sysroot "${{ steps.restore_sysroot.outputs.sysroot-path }}"
457470

458471
- name: Run Avalonia App Host package tests
459-
run: python ./scripts/pipeline.py avalonia-test -v --target ${{ matrix.avalonia_target }}
472+
run: python ./scripts/pipeline.py avalonia-test -v --target ${{ matrix.avalonia_target }} --sysroot "${{ steps.restore_sysroot.outputs.sysroot-path }}"
460473

461474
- name: Upload Linux Avalonia apphost artifact
462475
uses: actions/upload-artifact@v6

scripts/pipeline.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ def run_avalonia_test():
132132
header("Run avalonia apphost test")
133133
env = dict(os.environ)
134134
env["TargetAvaloniaVersion"] = args.target
135+
if args.sysroot:
136+
env["ROOTFS_DIR"] = args.sysroot
135137
cmd = ["dotnet", "test", "--project", AVALONIA_TEST_CSPROJ, "-c", "Release"]
136138
cmd.extend([f"-v:{dotnet_verbosity()}"])
137139
execv(cmd, env=env)
@@ -211,6 +213,10 @@ def parse_args():
211213
default="11.0",
212214
help="Target Avalonia version. This decides skiasharp version and changes output package version",
213215
)
216+
avalonia_test_parser.add_argument(
217+
"--sysroot",
218+
help="optional sysroot path exposed to tests as ROOTFS_DIR",
219+
)
214220
avalonia_test_parser.add_argument(
215221
"-v", "--verbose", action="count", default=0, help="verbose output"
216222
)

src/package-avalonia-apphost/AvaloniaAppHost.Link.proj

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
<AvaloniaTemplateTfm Condition="'$(AvaloniaTemplateTfm)' == ''">net10.0</AvaloniaTemplateTfm>
2828
<AvaloniaAppHostArtifactRoot>$([MSBuild]::NormalizePath('$(RepoRoot)', 'artifacts/avalonia-host/$(TargetAvaloniaVersion)'))</AvaloniaAppHostArtifactRoot>
2929
<_ResolvedSysroot Condition="'$(Sysroot)' != ''">$([MSBuild]::NormalizePath('$(RepoRoot)', '$(Sysroot)'))</_ResolvedSysroot>
30+
<_AvaloniaAppHostExportsFile>$([MSBuild]::NormalizePath('$(MSBuildProjectDirectory)', 'apphost.exports'))</_AvaloniaAppHostExportsFile>
31+
<_AvaloniaSingleFileHostExportsFile>$([MSBuild]::NormalizePath('$(MSBuildProjectDirectory)', 'singlefilehost.exports'))</_AvaloniaSingleFileHostExportsFile>
3032

3133
<StaticHostRid>$(AvaloniaHostRid)</StaticHostRid>
3234
<ComputeNETCoreBuildOutputFiles>true</ComputeNETCoreBuildOutputFiles>
@@ -92,19 +94,28 @@
9294
Condition="'$(_AvaloniaHostRidIsWindows)' == 'True'" />
9395
<LinkerArg Include="--sysroot=&quot;$(_ResolvedSysroot)&quot;"
9496
Condition="'$(_AvaloniaHostRidIsWindows)' != 'True' and '$(_ResolvedSysroot)' != ''" />
95-
<LinkerArg Include="-lfontconfig -Wl,--version-script=$([MSBuild]::NormalizePath('singlefilehost.exports'))"
97+
<LinkerArg Include="-lfontconfig"
9698
Condition="'$(_AvaloniaHostRidIsWindows)' != 'True'" />
99+
<LinkerArg Include="-Wl,--version-script=$(AvaloniaExportsFile)"
100+
Condition="'$(_AvaloniaHostRidIsWindows)' != 'True' and '$(AvaloniaExportsFile)' != ''" />
97101
</ItemGroup>
98102
</Target>
99103

100-
<Target Name="_LinkAvaloniaHostsForRid"
101-
DependsOnTargets="_ResolveAvaloniaLinkInputs;LinkAppHost;LinkSingleFileHost" />
104+
<Target Name="_LinkAvaloniaAppHostForRid"
105+
DependsOnTargets="_ResolveAvaloniaLinkInputs;LinkAppHost" />
106+
107+
<Target Name="_LinkAvaloniaSingleFileHostForRid"
108+
DependsOnTargets="_ResolveAvaloniaLinkInputs;LinkSingleFileHost" />
102109

103110
<Target Name="LinkAvaloniaHosts"
104111
DependsOnTargets="_ResolveAvaloniaTargetRids">
105112
<MSBuild Projects="$(MSBuildProjectFullPath)"
106-
Targets="_LinkAvaloniaHostsForRid"
113+
Targets="_LinkAvaloniaAppHostForRid"
114+
BuildInParallel="false"
115+
Properties="Configuration=$(Configuration);TargetAvaloniaVersion=$(TargetAvaloniaVersion);HostLibsRoot=$(HostLibsRoot);AvaloniaNativeLibsRoot=$(AvaloniaNativeLibsRoot);AvaloniaAppHostArtifactRoot=$(AvaloniaAppHostArtifactRoot);AvaloniaTemplateTfm=$(AvaloniaTemplateTfm);AvaloniaHostRid=%(_AvaloniaTargetRid.Identity);Sysroot=$(_ResolvedSysroot);AvaloniaExportsFile=$(_AvaloniaAppHostExportsFile)" />
116+
<MSBuild Projects="$(MSBuildProjectFullPath)"
117+
Targets="_LinkAvaloniaSingleFileHostForRid"
107118
BuildInParallel="false"
108-
Properties="Configuration=$(Configuration);TargetAvaloniaVersion=$(TargetAvaloniaVersion);HostLibsRoot=$(HostLibsRoot);AvaloniaNativeLibsRoot=$(AvaloniaNativeLibsRoot);AvaloniaAppHostArtifactRoot=$(AvaloniaAppHostArtifactRoot);AvaloniaTemplateTfm=$(AvaloniaTemplateTfm);AvaloniaHostRid=%(_AvaloniaTargetRid.Identity);Sysroot=$(_ResolvedSysroot)" />
119+
Properties="Configuration=$(Configuration);TargetAvaloniaVersion=$(TargetAvaloniaVersion);HostLibsRoot=$(HostLibsRoot);AvaloniaNativeLibsRoot=$(AvaloniaNativeLibsRoot);AvaloniaAppHostArtifactRoot=$(AvaloniaAppHostArtifactRoot);AvaloniaTemplateTfm=$(AvaloniaTemplateTfm);AvaloniaHostRid=%(_AvaloniaTargetRid.Identity);Sysroot=$(_ResolvedSysroot);AvaloniaExportsFile=$(_AvaloniaSingleFileHostExportsFile)" />
109120
</Target>
110121
</Project>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
libSkiaSharp {
2+
global:
3+
sk_*;
4+
gr_*;
5+
skottie_*;
6+
sksg_*;
7+
skresources_*;
8+
local:
9+
*;
10+
};
11+
12+
libHarfBuzzSharp {
13+
global:
14+
hb_*;
15+
local:
16+
*;
17+
};

tests/HostForge.TestInfra/AvaloniaPackageBuilder.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ public static class AvaloniaPackageBuilder
44
{
55
private static readonly SemaphoreSlim Lock = new(1, 1);
66
private static readonly HashSet<string> PackedModes = new(StringComparer.Ordinal);
7+
private const string RootfsDirEnvironmentVariableName = "ROOTFS_DIR";
78

89
public static async Task EnsurePackedAsync(
910
string packageMode = "windows",
@@ -42,7 +43,8 @@ public static async Task EnsurePackedAsync(
4243

4344
CommandResult result = await CommandRunner.RunAsync(
4445
"dotnet",
45-
RepoContext.AppendTargetAvaloniaVersionProperty($"pack \"{project}\" -c Release -v:minimal -p:AvaloniaAppHostPackageMode={packageMode}"),
46+
RepoContext.AppendTargetAvaloniaVersionProperty(
47+
$"pack \"{project}\" -c Release -v:minimal -p:AvaloniaAppHostPackageMode={packageMode}{BuildSysrootPropertyArgument()}"),
4648
RepoContext.RepoRoot,
4749
cancellationToken);
4850

@@ -59,4 +61,15 @@ public static async Task EnsurePackedAsync(
5961
Lock.Release();
6062
}
6163
}
64+
65+
private static string BuildSysrootPropertyArgument()
66+
{
67+
string? rootfsDir = Environment.GetEnvironmentVariable(RootfsDirEnvironmentVariableName);
68+
if (string.IsNullOrWhiteSpace(rootfsDir))
69+
{
70+
return string.Empty;
71+
}
72+
73+
return $" -p:Sysroot=\"{rootfsDir.Trim()}\"";
74+
}
6275
}

0 commit comments

Comments
 (0)