Skip to content
This repository was archived by the owner on Sep 4, 2025. It is now read-only.

Commit cded84b

Browse files
authored
Ensure version alignment of multi-arch GCC base libraries to prevent libc6:arm64 / libgcc-s1 conflicts during cross-compilation setup (#1019)
* Ensure version alignment of multi-arch GCC base libraries to prevent libc6:arm64 / libgcc-s1 conflicts during cross-compilation setup * enable script invocation from build.tml * regex comment
1 parent 49e2314 commit cded84b

File tree

3 files changed

+83
-19
lines changed

3 files changed

+83
-19
lines changed

‎.vscode/cspell.json‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@
132132
"glsl",
133133
"hotmail",
134134
"kcsb",
135+
"libc",
136+
"libgcc",
135137
"locproj",
136138
"logissue",
137139
"maxdepth",
@@ -155,11 +157,13 @@
155157
"nettrace",
156158
"nonexistentaccount",
157159
"nonexistentrg",
160+
"noninteractive",
158161
"notcontains",
159162
"notlike",
160163
"nslookup",
161164
"otel",
162165
"otlp",
166+
"pipefail",
163167
"privatelink",
164168
"psscriptanalyzer",
165169
"quickstart",

‎eng/pipelines/templates/jobs/build.yml‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,14 @@ jobs:
7878

7979
- task: Powershell@2
8080
displayName: "(Native AOT) Install Linux arm64 cross compile toolchain"
81-
# The arm64 cross-compilation toolchain install on Linux x64 has glitches. This will be re-enabled once resolved.
82-
# condition: and(succeeded(), eq('${{ parameters.OSName }}', 'linux'), eq(variables['Architecture'], 'arm64'))
83-
condition: eq('false', 'true')
81+
condition: and(succeeded(), eq('${{ parameters.OSName }}', 'linux'), eq(variables['Architecture'], 'arm64'))
8482
inputs:
8583
pwsh: true
8684
filePath: $(Build.SourcesDirectory)/eng/scripts/Install-LinuxArm64CrossCompileToolchain.ps1
8785

8886
- task: Powershell@2
8987
displayName: "(Native AOT) Build module"
90-
# Native build runs on all platforms except when targeting arm64 from Linux x64.
91-
condition: and(succeeded(), ne(variables['NoPackagesChanged'],'true'), not(and(eq('${{ parameters.OSName }}', 'linux'), eq(variables['Architecture'], 'arm64'))))
88+
condition: and(succeeded(), ne(variables['NoPackagesChanged'],'true'))
9289
inputs:
9390
pwsh: true
9491
filePath: $(Build.SourcesDirectory)/eng/scripts/Build-Module.ps1

‎eng/scripts/Install-LinuxArm64CrossCompileToolchain.ps1‎

Lines changed: 77 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,92 @@ if ($arch -ne 'x64') {
2121
return
2222
}
2323

24-
# The bash script below follows the official documentation from .NET AOT Team.
25-
# https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/cross-compile#linux
24+
$bashScript = @'
25+
#!/usr/bin/env bash
26+
set -euo pipefail
2627
27-
$bashScript = @"
28-
sudo dpkg --add-architecture arm64
28+
# turning on multi-arch support for arm64 on amd64 host
29+
sudo dpkg --add-architecture arm64 || true
2930
30-
sudo bash -c 'cat > /etc/apt/sources.list.d/arm64.list <<EOF
31-
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy main restricted
32-
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-updates main restricted
31+
# Constrains the existing binary (and optionally source) package repositories to provide only amd64 packages,
32+
# this ensures only amd64 stuffs are pulled from 'archive.ubuntu.com' and 'security.ubuntu.com'
33+
sudo sed -i -E 's/^deb ([^[])/deb [arch=amd64] \1/' /etc/apt/sources.list
34+
sudo sed -i -E 's/^deb-src ([^[])/deb-src [arch=amd64] \1/' /etc/apt/sources.list
35+
36+
# Adds package repositories that provide arm64 packages,
37+
# this ensures the arm64 stuffs are pulled from 'ports.ubuntu.com'.
38+
sudo tee /etc/apt/sources.list.d/arm64.list >/dev/null <<'EOF'
39+
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy main restricted universe multiverse
40+
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-updates main restricted universe multiverse
41+
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-security main restricted universe multiverse
3342
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-backports main restricted universe multiverse
34-
EOF'
43+
EOF
44+
45+
# Refresh package indices for both amd64 and arm64 architectures
46+
sudo apt-get update -qq
47+
48+
# Find the 'gcc base package' name (there is only one 'gcc base package' name per Ubuntu series across all architectures)
49+
GCC_BASE=$(apt-cache search --names-only '^gcc-[0-9]+-base$' | awk '{print $1}' | sort -V | tail -1)
50+
51+
if [[ -z "$GCC_BASE" ]]; then
52+
echo "ERROR: Could not determine gcc base package." >&2
53+
exit 1
54+
fi
55+
56+
# Find 'gcc base package' candidate versions in both architectures
57+
amd64_list=$(apt-cache madison "${GCC_BASE}:amd64" | awk '{print $3}')
58+
arm64_list=$(apt-cache madison "${GCC_BASE}:arm64" | awk '{print $3}')
59+
60+
amd64_gcc_versions=$(printf "%s\n" "$amd64_list" | sort -V)
61+
arm64_gcc_versions=$(printf "%s\n" "$arm64_list" | sort -V)
3562
36-
sudo sed -i -e 's/deb http/deb [arch=amd64] http/g' /etc/apt/sources.list
37-
sudo sed -i -e 's/deb mirror/deb [arch=amd64] mirror/g' /etc/apt/sources.list
63+
# Use the highest common version of 'gcc base package'
64+
gcc_version=$(
65+
comm -12 \
66+
<(printf "%s\n" "$amd64_gcc_versions") \
67+
<(printf "%s\n" "$arm64_gcc_versions") \
68+
| tail -1
69+
)
3870
39-
sudo apt update
40-
sudo apt install -y clang llvm binutils-aarch64-linux-gnu gcc-aarch64-linux-gnu zlib1g-dev:arm64
41-
"@
71+
if [[ -z "$gcc_version" ]]; then
72+
echo "ERROR: No common ${GCC_BASE} version across amd64 and arm64." >&2
73+
echo "amd64 candidates:" >&2; printf "%s\n" "$amd64_gcc_versions" >&2
74+
echo "arm64 candidates:" >&2; printf "%s\n" "$arm64_gcc_versions" >&2
75+
exit 1
76+
fi
77+
78+
echo "Using ${GCC_BASE} version: ${gcc_version} (selected from amd64 and arm64 candidates)"
79+
80+
# Install gcc base libraries for both amd64 and arm64 with versions pinned
81+
# Note: 'libgcc-s1' and 'gcc-*-base' are 'Multi-Arch:same', which means they must be installed at the exact same version across all enabled architectures
82+
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
83+
${GCC_BASE}:amd64=${gcc_version} \
84+
${GCC_BASE}:arm64=${gcc_version} \
85+
libgcc-s1:amd64=${gcc_version} \
86+
libgcc-s1:arm64=${gcc_version}
87+
88+
# Install libc6 and rest of toolchain
89+
# Since we already installed and pinned 'libgcc-s1:arm64' to match the 'libgcc-s1:amd64' version, version alignment is guaranteed and 'libc6:arm64' can now be installed safely.
90+
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
91+
libc6:arm64 \
92+
clang \
93+
llvm \
94+
lld \
95+
binutils-aarch64-linux-gnu \
96+
gcc-aarch64-linux-gnu \
97+
zlib1g-dev:arm64
98+
99+
# Verification step
100+
# output the essential arm64 cross-compilation packages (libc6, libgcc-s1, gcc-*-base) installed on the amd64 host
101+
# Note: In dpkg -l output, the first two characters indicate the package status: the desired state (first i = install requested) and the current state (second i = package is installed)
102+
dpkg -l | grep -E '^(ii)\s+(libc6|libgcc-s1|gcc-[0-9]+-base):arm64' || true
103+
104+
'@
42105

43106
try {
44107
Write-Host "Installing arm64 cross-compilation toolchain..." -ForegroundColor Green
45108
bash -c $bashScript
46-
109+
47110
if ($LASTEXITCODE -eq 0) {
48111
Write-Host "arm64 cross-compilation toolchain installation completed successfully" -ForegroundColor Green
49112
} else {

0 commit comments

Comments
 (0)