Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af373cd174 | ||
|
|
2550092870 | ||
|
|
c58a4f3573 | ||
|
|
70a76384e6 | ||
|
|
d02f1f0b55 |
No files matched your search
@@ -1,298 +0,0 @@
|
||||
name: staticlink-avalonia-native
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "17 3 * * *"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
avalonia_version:
|
||||
description: Avalonia version to build; empty checks the latest stable 11.x and 12.x versions
|
||||
required: false
|
||||
type: string
|
||||
force_build:
|
||||
description: Build even when this StaticLink.Avalonia.Native version already exists
|
||||
required: true
|
||||
default: false
|
||||
type: boolean
|
||||
publish_to_nuget:
|
||||
description: Publish with NuGet Trusted Publishing after smoke tests
|
||||
required: true
|
||||
default: true
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
detect:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
versions: ${{ steps.version.outputs.versions }}
|
||||
should_build: ${{ steps.version.outputs.should_build }}
|
||||
steps:
|
||||
- name: Detect unpublished Avalonia version
|
||||
id: version
|
||||
shell: bash
|
||||
env:
|
||||
REQUESTED_VERSION: ${{ inputs.avalonia_version }}
|
||||
FORCE_BUILD: ${{ inputs.force_build }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
if [ -n "$REQUESTED_VERSION" ]; then
|
||||
candidate_versions=("$REQUESTED_VERSION")
|
||||
else
|
||||
nuget_versions="$(curl --fail --silent --show-error --location \
|
||||
https://api.nuget.org/v3-flatcontainer/avalonia/index.json)"
|
||||
candidate_versions=()
|
||||
for major in 11 12; do
|
||||
candidate_versions+=("$(jq -r --arg major "$major" \
|
||||
'[.versions[] | select(startswith($major + ".") and (contains("-") | not))] | last' \
|
||||
<<< "$nuget_versions")")
|
||||
done
|
||||
fi
|
||||
|
||||
versions='[]'
|
||||
for avalonia_version in "${candidate_versions[@]}"; do
|
||||
if [ -z "$avalonia_version" ] || [ "$avalonia_version" = "null" ]; then
|
||||
echo "Could not determine a stable Avalonia version." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
package_version="$avalonia_version.1"
|
||||
package_url="https://api.nuget.org/v3-flatcontainer/staticlink.avalonia.native/$package_version/staticlink.avalonia.native.$package_version.nupkg"
|
||||
if [ "$FORCE_BUILD" != "true" ] && curl --fail --silent --location --output /dev/null "$package_url"; then
|
||||
echo "Already published: $package_version"
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "Build required: $package_version"
|
||||
versions="$(jq -cn --argjson versions "$versions" \
|
||||
--arg avalonia_version "$avalonia_version" \
|
||||
--arg package_version "$package_version" \
|
||||
'$versions + [{avalonia_version: $avalonia_version, package_version: $package_version}]')"
|
||||
done
|
||||
|
||||
echo "versions=$versions" >> "$GITHUB_OUTPUT"
|
||||
if [ "$versions" = '[]' ]; then
|
||||
echo 'should_build=false' >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo 'should_build=true' >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
build:
|
||||
needs: detect
|
||||
if: ${{ needs.detect.outputs.should_build == 'true' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: ${{ fromJSON(needs.detect.outputs.versions) }}
|
||||
rid: [osx-x64, osx-arm64]
|
||||
include:
|
||||
- rid: osx-x64
|
||||
runner: macos-14
|
||||
- rid: osx-arm64
|
||||
runner: macos-15
|
||||
runs-on: ${{ matrix.runner }}
|
||||
permissions:
|
||||
contents: read
|
||||
env:
|
||||
RID: ${{ matrix.rid }}
|
||||
AVALONIA_VERSION: ${{ matrix.version.avalonia_version }}
|
||||
WORK_DIR: ${{ github.workspace }}/External/AvaloniaNative/.work
|
||||
OUTPUT_DIR: ${{ github.workspace }}/External/AvaloniaNative/${{ matrix.rid }}/native
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup .NET for Avalonia header generation
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: |
|
||||
8.0.x
|
||||
10.0.x
|
||||
|
||||
- name: Build static AvaloniaNative
|
||||
run: bash scripts/build-macos-avalonia-native-static.sh
|
||||
|
||||
- name: Build macOS font preinit object
|
||||
run: bash scripts/build-macos-font-preinit.sh
|
||||
|
||||
- name: Upload static AvaloniaNative
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: native-avalonia-${{ matrix.version.avalonia_version }}-${{ matrix.rid }}
|
||||
path: |
|
||||
External/AvaloniaNative/${{ matrix.rid }}/native/libAvaloniaNative.a
|
||||
External/AvaloniaNative/${{ matrix.rid }}/native/macos_font_preinit.o
|
||||
if-no-files-found: error
|
||||
|
||||
pack:
|
||||
needs:
|
||||
- detect
|
||||
- build
|
||||
if: ${{ needs.detect.outputs.should_build == 'true' }}
|
||||
strategy:
|
||||
matrix:
|
||||
version: ${{ fromJSON(needs.detect.outputs.versions) }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: "10.0.x"
|
||||
|
||||
- name: Download static AvaloniaNative archives
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: native-avalonia-${{ matrix.version.avalonia_version }}-*
|
||||
path: artifacts/native
|
||||
merge-multiple: false
|
||||
|
||||
- name: Prepare package inputs
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
for rid in osx-x64 osx-arm64; do
|
||||
mkdir -p "External/AvaloniaNative/$rid/native"
|
||||
cp "artifacts/native/native-avalonia-${{ matrix.version.avalonia_version }}-$rid/libAvaloniaNative.a" "External/AvaloniaNative/$rid/native/"
|
||||
cp "artifacts/native/native-avalonia-${{ matrix.version.avalonia_version }}-$rid/macos_font_preinit.o" "External/AvaloniaNative/$rid/native/"
|
||||
done
|
||||
|
||||
- name: Pack StaticLink.Avalonia.Native
|
||||
run: |
|
||||
dotnet pack NuGet/AvaloniaNative/StaticLink.Avalonia.Native.csproj \
|
||||
-c Release \
|
||||
-o artifacts/nuget \
|
||||
/p:PackageVersion=${{ matrix.version.package_version }} \
|
||||
/p:Version=${{ matrix.version.package_version }}
|
||||
|
||||
- name: Upload NuGet package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: staticlink-avalonia-native-${{ matrix.version.package_version }}
|
||||
path: artifacts/nuget/*.nupkg
|
||||
if-no-files-found: error
|
||||
|
||||
smoke:
|
||||
needs:
|
||||
- detect
|
||||
- pack
|
||||
if: ${{ needs.detect.outputs.should_build == 'true' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: ${{ fromJSON(needs.detect.outputs.versions) }}
|
||||
rid: [osx-x64, osx-arm64]
|
||||
include:
|
||||
- rid: osx-x64
|
||||
runner: macos-14
|
||||
- rid: osx-arm64
|
||||
runner: macos-15
|
||||
runs-on: ${{ matrix.runner }}
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: "10.0.x"
|
||||
|
||||
- name: Download NuGet package
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: staticlink-avalonia-native-${{ matrix.version.package_version }}
|
||||
path: artifacts/nuget
|
||||
|
||||
- name: Publish Avalonia NativeAOT smoke app
|
||||
shell: pwsh
|
||||
run: |
|
||||
$projectDir = Join-Path $PWD "artifacts/avalonia-native-smoke-src"
|
||||
pwsh ./scripts/create-avalonia-smoke.ps1 `
|
||||
-ProjectDir $projectDir `
|
||||
-NuGetSource (Resolve-Path "artifacts/nuget") `
|
||||
-AvaloniaVersion "${{ matrix.version.avalonia_version }}" `
|
||||
-StaticLinkNativeVersion "${{ matrix.version.package_version }}"
|
||||
dotnet publish (Join-Path $projectDir "AvaloniaStaticLinkSmoke.csproj") `
|
||||
-c Release `
|
||||
-r "${{ matrix.rid }}" `
|
||||
--configfile (Join-Path $projectDir "NuGet.config") `
|
||||
/p:PublishDir="$PWD/artifacts/smoke-${{ matrix.rid }}/"
|
||||
|
||||
- name: Verify AvaloniaNative is statically linked
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
test ! -f "artifacts/smoke-${{ matrix.rid }}/libAvaloniaNative.dylib"
|
||||
test -x "artifacts/smoke-${{ matrix.rid }}/AvaloniaStaticLinkSmoke"
|
||||
|
||||
- name: Run Avalonia smoke app
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cd "artifacts/smoke-${{ matrix.rid }}"
|
||||
python3 - <<'PY'
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
proc = subprocess.Popen(
|
||||
["./AvaloniaStaticLinkSmoke"],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
text=True,
|
||||
)
|
||||
try:
|
||||
output, _ = proc.communicate(timeout=15)
|
||||
except subprocess.TimeoutExpired:
|
||||
proc.kill()
|
||||
output, _ = proc.communicate()
|
||||
print(output or "")
|
||||
print("Avalonia smoke app stayed alive for 15 seconds.")
|
||||
sys.exit(0)
|
||||
|
||||
print(output or "")
|
||||
if proc.returncode == 0:
|
||||
sys.exit(0)
|
||||
sys.exit(proc.returncode if proc.returncode > 0 else 1)
|
||||
PY
|
||||
|
||||
publish:
|
||||
needs:
|
||||
- detect
|
||||
- smoke
|
||||
if: ${{ needs.detect.outputs.should_build == 'true' && (github.event_name == 'schedule' || inputs.publish_to_nuget == true) }}
|
||||
strategy:
|
||||
matrix:
|
||||
version: ${{ fromJSON(needs.detect.outputs.versions) }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Download NuGet package
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: staticlink-avalonia-native-${{ matrix.version.package_version }}
|
||||
path: artifacts/nuget
|
||||
|
||||
- name: Validate Trusted Publishing configuration
|
||||
env:
|
||||
NUGET_USER: ${{ vars.NUGET_USER }}
|
||||
run: test -n "$NUGET_USER"
|
||||
|
||||
- name: NuGet login
|
||||
id: login
|
||||
uses: NuGet/login@v1
|
||||
with:
|
||||
user: ${{ vars.NUGET_USER }}
|
||||
|
||||
- name: Publish to nuget.org
|
||||
run: |
|
||||
dotnet nuget push artifacts/nuget/*.nupkg \
|
||||
--source https://www.nuget.org/api/v2/package \
|
||||
--api-key "${{ steps.login.outputs.NUGET_API_KEY }}" \
|
||||
--skip-duplicate
|
||||
@@ -3,6 +3,18 @@ name: staticlink-avalonia
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
environment_only:
|
||||
description: Validate the complete toolchain container without building release libraries
|
||||
type: boolean
|
||||
default: false
|
||||
skiasharp_version:
|
||||
description: Stable SkiaSharp version from this branch major; empty uses the branch version
|
||||
type: string
|
||||
default: ''
|
||||
native_package_revision:
|
||||
description: Published AvaloniaNative revision for independent graphics smoke tests
|
||||
type: string
|
||||
default: '1'
|
||||
publish_to_nuget:
|
||||
description: Publish package to nuget.org
|
||||
required: true
|
||||
@@ -11,7 +23,7 @@ on:
|
||||
publish_to_release:
|
||||
description: Publish NuGet package and smoke apps to GitHub Release
|
||||
required: true
|
||||
default: true
|
||||
default: false
|
||||
type: boolean
|
||||
push:
|
||||
tags:
|
||||
@@ -20,46 +32,39 @@ on:
|
||||
env:
|
||||
DOTNET_ALPINE_IMAGE: mcr.microsoft.com/dotnet/sdk:10.0.302-alpine3.23
|
||||
|
||||
concurrency:
|
||||
group: graphics-${{ github.ref }}-${{ inputs.skiasharp_version }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
environment:
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
uses: ./.github/workflows/zig-toolchain-image.yml
|
||||
|
||||
preflight:
|
||||
if: ${{ inputs.environment_only != true }}
|
||||
uses: ./.github/workflows/static-graphics-preflight.yml
|
||||
with:
|
||||
skiasharp_version: ${{ inputs.skiasharp_version }}
|
||||
|
||||
build-linux:
|
||||
needs: preflight
|
||||
uses: ./.github/workflows/static-graphics-linux.yml
|
||||
build-zig:
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
needs: [preflight, environment]
|
||||
uses: ./.github/workflows/static-graphics-zig-cross.yml
|
||||
with:
|
||||
skiasharp_version: ${{ needs.preflight.outputs.skiasharp_version }}
|
||||
angle_branch: ${{ needs.preflight.outputs.angle_branch }}
|
||||
|
||||
build-musl:
|
||||
needs: preflight
|
||||
uses: ./.github/workflows/static-graphics-musl.yml
|
||||
with:
|
||||
skiasharp_version: ${{ needs.preflight.outputs.skiasharp_version }}
|
||||
angle_branch: ${{ needs.preflight.outputs.angle_branch }}
|
||||
dotnet_alpine_image: mcr.microsoft.com/dotnet/sdk:10.0.302-alpine3.23
|
||||
|
||||
build-windows:
|
||||
needs: preflight
|
||||
uses: ./.github/workflows/static-graphics-windows.yml
|
||||
with:
|
||||
skiasharp_version: ${{ needs.preflight.outputs.skiasharp_version }}
|
||||
angle_branch: ${{ needs.preflight.outputs.angle_branch }}
|
||||
|
||||
build-macos:
|
||||
needs: preflight
|
||||
uses: ./.github/workflows/static-graphics-macos.yml
|
||||
with:
|
||||
skiasharp_version: ${{ needs.preflight.outputs.skiasharp_version }}
|
||||
angle_branch: ${{ needs.preflight.outputs.angle_branch }}
|
||||
source_lock: ${{ needs.preflight.outputs.source_lock }}
|
||||
toolchain_image: ${{ needs.environment.outputs.image }}
|
||||
|
||||
pack:
|
||||
runs-on: ubuntu-24.04
|
||||
needs:
|
||||
- build-linux
|
||||
- build-musl
|
||||
- build-windows
|
||||
- build-macos
|
||||
- preflight
|
||||
- build-zig
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
@@ -109,7 +114,13 @@ jobs:
|
||||
test -f External/NativeStatic/win-x86/native/skia_x86_stdcall_thunks.lib
|
||||
|
||||
- name: Pack NuGet package
|
||||
run: dotnet pack NuGet/StaticGraphics/StaticLink.Avalonia.csproj -c Release -o artifacts/nuget
|
||||
env:
|
||||
SOURCE_LOCK_JSON: ${{ needs.preflight.outputs.source_lock }}
|
||||
PACKAGE_VERSION: ${{ needs.preflight.outputs.package_version }}
|
||||
SKIASHARP_VERSION: ${{ needs.preflight.outputs.skiasharp_version }}
|
||||
run: |
|
||||
python3 scripts/apply-release-version.py
|
||||
dotnet pack NuGet/StaticGraphics/StaticLink.Avalonia.csproj -c Release -o artifacts/nuget
|
||||
|
||||
- name: Verify portable NuGet paths
|
||||
shell: bash
|
||||
@@ -123,6 +134,13 @@ jobs:
|
||||
unzip -Z1 "$package" | grep -Fx 'buildTransitive/StaticLink.Avalonia.props'
|
||||
unzip -Z1 "$package" | grep -Fx 'buildTransitive/StaticLink.Avalonia.targets'
|
||||
|
||||
- name: Upload release source lock
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: graphics-release-source-lock
|
||||
path: build/linux-toolchain/release.lock.json
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload NuGet artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@@ -171,11 +189,16 @@ jobs:
|
||||
with:
|
||||
arch: ${{ matrix.msvc_arch }}
|
||||
|
||||
- name: Install LLVM linker for Zig Windows archives
|
||||
if: ${{ startsWith(matrix.rid, 'win-') }}
|
||||
shell: pwsh
|
||||
run: choco install llvm -y
|
||||
|
||||
- name: Install Linux publish dependencies
|
||||
if: ${{ startsWith(matrix.rid, 'linux-') && !startsWith(matrix.rid, 'linux-musl-') }}
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y clang lld xvfb zlib1g-dev libfontconfig1-dev libfreetype6 libgl1 libice6 libsm6 libx11-6 libxcb1 libxcursor1 libxext6 libxfixes3 libxinerama1 libxrandr2 libxrender1 libxi6
|
||||
sudo apt-get install -y clang lld xvfb zlib1g-dev libfontconfig1-dev libffi-dev libwayland-dev libx11-dev libxext-dev libxcb1-dev libfreetype6 libgl1 libice6 libsm6 libx11-6 libxcb1 libxcursor1 libxext6 libxfixes3 libxinerama1 libxrandr2 libxrender1 libxi6
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
@@ -200,7 +223,9 @@ jobs:
|
||||
$avaloniaVersion = "${{ matrix.avalonia_version }}"
|
||||
if (-not $avaloniaVersion) { $avaloniaVersion = "11.3.14" }
|
||||
$projectDir = Join-Path $PWD "artifacts/avalonia-smoke-src"
|
||||
pwsh ./scripts/create-avalonia-smoke.ps1 -ProjectDir $projectDir -NuGetSource (Resolve-Path "artifacts/nuget") -StaticLinkVersion $version -AvaloniaVersion $avaloniaVersion
|
||||
$nativeVersion = ""
|
||||
if ("${{ matrix.rid }}".StartsWith("osx-")) { $nativeVersion = "$avaloniaVersion.${{ inputs.native_package_revision || '1' }}" }
|
||||
pwsh ./scripts/create-avalonia-smoke.ps1 -ProjectDir $projectDir -NuGetSource (Resolve-Path "artifacts/nuget") -StaticLinkVersion $version -AvaloniaVersion $avaloniaVersion -StaticLinkNativeVersion $nativeVersion
|
||||
dotnet publish (Join-Path $projectDir "AvaloniaStaticLinkSmoke.csproj") `
|
||||
-c Release `
|
||||
-r "${{ matrix.rid }}" `
|
||||
@@ -226,7 +251,7 @@ jobs:
|
||||
-v "${{ github.workspace }}:/workspace" `
|
||||
-w /workspace `
|
||||
"${{ env.DOTNET_ALPINE_IMAGE }}" `
|
||||
sh -c "apk add --no-cache clang lld build-base zlib-dev fontconfig-dev && dotnet publish /workspace/artifacts/avalonia-smoke-src/AvaloniaStaticLinkSmoke.csproj -c Release -r ${{ matrix.rid }} --configfile /workspace/artifacts/avalonia-smoke-src/NuGet.config /p:PublishAot=true /p:SelfContained=true /p:PublishSingleFile=true /p:StripSymbols=true /p:PublishDir=/workspace/artifacts/smoke-${{ matrix.rid }}/"
|
||||
sh -c "apk add --no-cache clang lld build-base zlib-dev fontconfig-dev libffi-dev wayland-dev libx11-dev libxext-dev libxcb-dev && dotnet publish /workspace/artifacts/avalonia-smoke-src/AvaloniaStaticLinkSmoke.csproj -c Release -r ${{ matrix.rid }} --configfile /workspace/artifacts/avalonia-smoke-src/NuGet.config /p:PublishAot=true /p:SelfContained=true /p:PublishSingleFile=true /p:StripSymbols=true /p:PublishDir=/workspace/artifacts/smoke-${{ matrix.rid }}/"
|
||||
|
||||
- name: Verify no dynamic graphics libraries remain
|
||||
shell: pwsh
|
||||
@@ -354,11 +379,12 @@ jobs:
|
||||
PY
|
||||
|
||||
- name: Upload Avalonia smoke app
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: avalonia-smoke-${{ matrix.rid }}
|
||||
path: artifacts/smoke-${{ matrix.rid }}/**
|
||||
if-no-files-found: error
|
||||
if-no-files-found: warn
|
||||
|
||||
smoke-macos-metal:
|
||||
runs-on: macos-15
|
||||
@@ -392,7 +418,7 @@ jobs:
|
||||
-NuGetSource (Resolve-Path "artifacts/nuget") `
|
||||
-StaticLinkVersion $Matches[1] `
|
||||
-AvaloniaVersion "12.1.0" `
|
||||
-StaticLinkNativeVersion "12.1.0.1"
|
||||
-StaticLinkNativeVersion "12.1.0.${{ inputs.native_package_revision || '1' }}"
|
||||
dotnet publish (Join-Path $projectDir "AvaloniaStaticLinkSmoke.csproj") `
|
||||
-c Release `
|
||||
-r osx-arm64 `
|
||||
@@ -451,7 +477,18 @@ jobs:
|
||||
raise SystemExit(f"Avalonia {renderer} smoke app failed with exit code {result.returncode}.")
|
||||
PY
|
||||
|
||||
- name: Upload macOS Metal smoke app
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: avalonia-smoke-osx-arm64-metal
|
||||
path: artifacts/smoke-osx-arm64-metal/**
|
||||
if-no-files-found: warn
|
||||
|
||||
publish-nuget:
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
runs-on: ubuntu-24.04
|
||||
needs:
|
||||
- pack
|
||||
@@ -469,14 +506,21 @@ jobs:
|
||||
name: staticlink-avalonia-nuget
|
||||
path: artifacts/nuget
|
||||
|
||||
- name: NuGet Trusted Publishing login
|
||||
id: login
|
||||
if: ${{ vars.NUGET_USER != '' && (startsWith(github.ref, 'refs/tags/staticlink-avalonia-v') || inputs.publish_to_nuget == true) }}
|
||||
uses: NuGet/login@v1
|
||||
with:
|
||||
user: ${{ vars.NUGET_USER }}
|
||||
|
||||
- name: Publish to nuget.org
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/staticlink-avalonia-v') || (github.event_name == 'workflow_dispatch' && inputs.publish_to_nuget == true) }}
|
||||
env:
|
||||
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
|
||||
NUGET_API_KEY: ${{ steps.login.outputs.NUGET_API_KEY || secrets.NUGET_API_KEY }}
|
||||
run: |
|
||||
if [ -z "$NUGET_API_KEY" ]; then
|
||||
echo "NUGET_API_KEY secret is not configured. Skipping publish."
|
||||
exit 0
|
||||
echo "NUGET_API_KEY secret is not configured." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for package in artifacts/nuget/*.nupkg; do
|
||||
@@ -506,6 +550,12 @@ jobs:
|
||||
name: staticlink-avalonia-nuget
|
||||
path: release-artifacts/staticlink-avalonia-nuget
|
||||
|
||||
- name: Download release source lock
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: graphics-release-source-lock
|
||||
path: release-artifacts/source-lock
|
||||
|
||||
- name: Download smoke artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
@@ -516,6 +566,7 @@ jobs:
|
||||
- name: Prepare release files
|
||||
run: |
|
||||
mkdir -p release-files
|
||||
cp release-artifacts/source-lock/release.lock.json release-files/
|
||||
find release-artifacts/staticlink-avalonia-nuget -type f \( -name '*.nupkg' -o -name '*.snupkg' \) -exec cp {} release-files/ \;
|
||||
for dir in release-artifacts/avalonia-smoke-*; do
|
||||
[ -d "$dir" ] || continue
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
name: static-graphics-linux-debian-zig
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
skiasharp_version:
|
||||
required: true
|
||||
type: string
|
||||
source_lock:
|
||||
type: string
|
||||
default: ''
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
skiasharp_version:
|
||||
type: string
|
||||
default: '4.150.1'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
uses: ./.github/workflows/static-graphics-zig-cross.yml
|
||||
with:
|
||||
skiasharp_version: ${{ inputs.skiasharp_version }}
|
||||
source_lock: ${{ inputs.source_lock || '' }}
|
||||
rids: '["linux-x64","linux-arm64","linux-musl-x64","linux-musl-arm64"]'
|
||||
@@ -1,4 +1,4 @@
|
||||
name: static-graphics-linux
|
||||
name: static-graphics-linux-zig
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
@@ -6,59 +6,23 @@ on:
|
||||
skiasharp_version:
|
||||
required: true
|
||||
type: string
|
||||
angle_branch:
|
||||
required: true
|
||||
source_lock:
|
||||
type: string
|
||||
default: ''
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
skiasharp_version:
|
||||
required: true
|
||||
default: "4.150.1"
|
||||
type: string
|
||||
angle_branch:
|
||||
required: true
|
||||
default: "7922"
|
||||
type: string
|
||||
default: '4.150.1'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- rid: linux-x64
|
||||
target_cpu: x64
|
||||
runner: ubuntu-24.04
|
||||
- rid: linux-arm64
|
||||
target_cpu: arm64
|
||||
runner: ubuntu-24.04-arm
|
||||
runs-on: ${{ matrix.runner }}
|
||||
env:
|
||||
SKIASHARP_VERSION: ${{ inputs.skiasharp_version }}
|
||||
ANGLE_BRANCH: ${{ inputs.angle_branch }}
|
||||
RID: ${{ matrix.rid }}
|
||||
TARGET_CPU: ${{ matrix.target_cpu }}
|
||||
LLVM_AR: llvm-ar
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Restore native build cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: External/NativeStatic/.work
|
||||
key: native-work-linux-${{ matrix.rid }}-${{ inputs.skiasharp_version }}-${{ inputs.angle_branch }}-${{ hashFiles('External/NativeStatic/patches/*.patch', 'scripts/build-linux-static-graphics.sh') }}
|
||||
|
||||
- name: Install native build dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y clang lld llvm g++ ninja-build pkg-config libfontconfig1-dev libglib2.0-dev libgl1-mesa-dev libpci-dev libx11-dev libxcb1-dev libxext-dev
|
||||
|
||||
- name: Build Linux static graphics libraries
|
||||
run: scripts/build-linux-static-graphics.sh all
|
||||
|
||||
- name: Upload Linux static archives
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: native-static-${{ matrix.rid }}
|
||||
path: External/NativeStatic/${{ matrix.rid }}/*
|
||||
if-no-files-found: error
|
||||
uses: ./.github/workflows/static-graphics-zig-cross.yml
|
||||
with:
|
||||
skiasharp_version: ${{ inputs.skiasharp_version }}
|
||||
source_lock: ${{ inputs.source_lock || '' }}
|
||||
rids: '["linux-x64","linux-arm64"]'
|
||||
@@ -1,4 +1,4 @@
|
||||
name: static-graphics-macos
|
||||
name: static-graphics-macos-zig
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
@@ -6,69 +6,23 @@ on:
|
||||
skiasharp_version:
|
||||
required: true
|
||||
type: string
|
||||
angle_branch:
|
||||
required: true
|
||||
source_lock:
|
||||
type: string
|
||||
default: ''
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
skiasharp_version:
|
||||
required: true
|
||||
default: "4.150.1"
|
||||
type: string
|
||||
angle_branch:
|
||||
required: true
|
||||
default: "7922"
|
||||
type: string
|
||||
default: '4.150.1'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- rid: osx-x64
|
||||
target_cpu: x64
|
||||
- rid: osx-arm64
|
||||
target_cpu: arm64
|
||||
runs-on: macos-15
|
||||
env:
|
||||
SKIASHARP_VERSION: ${{ inputs.skiasharp_version }}
|
||||
ANGLE_BRANCH: ${{ inputs.angle_branch }}
|
||||
RID: ${{ matrix.rid }}
|
||||
TARGET_CPU: ${{ matrix.target_cpu }}
|
||||
WORK_DIR: ${{ github.workspace }}/External/NativeStatic/.work
|
||||
OUTPUT_DIR: ${{ github.workspace }}/External/NativeStatic/${{ matrix.rid }}/native
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Restore native build cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: External/NativeStatic/.work
|
||||
key: native-work-macos-${{ matrix.rid }}-${{ inputs.skiasharp_version }}-${{ inputs.angle_branch }}-${{ hashFiles('External/NativeStatic/patches/*.patch', 'scripts/build-macos-static-graphics.sh') }}
|
||||
|
||||
- name: Install native build dependencies
|
||||
run: brew install ninja
|
||||
|
||||
- name: Install Xcode Metal toolchain
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cat > /tmp/staticlink-metal-check.metal <<'EOF'
|
||||
#include <metal_stdlib>
|
||||
using namespace metal;
|
||||
kernel void staticlink_metal_check(device float* values [[buffer(0)]], uint id [[thread_position_in_grid]]) { values[id] = 0; }
|
||||
EOF
|
||||
if ! xcrun metal -c /tmp/staticlink-metal-check.metal -o /tmp/staticlink-metal-check.air >/dev/null 2>&1; then
|
||||
sudo xcodebuild -downloadComponent MetalToolchain
|
||||
fi
|
||||
xcrun metal -c /tmp/staticlink-metal-check.metal -o /tmp/staticlink-metal-check.air >/dev/null
|
||||
|
||||
- name: Build macOS static graphics libraries
|
||||
run: bash ./scripts/build-macos-static-graphics.sh all
|
||||
|
||||
- name: Upload macOS static archives
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: native-static-${{ matrix.rid }}
|
||||
path: External/NativeStatic/${{ matrix.rid }}/*
|
||||
if-no-files-found: error
|
||||
uses: ./.github/workflows/static-graphics-zig-cross.yml
|
||||
with:
|
||||
skiasharp_version: ${{ inputs.skiasharp_version }}
|
||||
source_lock: ${{ inputs.source_lock || '' }}
|
||||
rids: '["osx-x64","osx-arm64"]'
|
||||
@@ -1,4 +1,4 @@
|
||||
name: static-graphics-musl
|
||||
name: static-graphics-musl-zig
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
@@ -6,88 +6,23 @@ on:
|
||||
skiasharp_version:
|
||||
required: true
|
||||
type: string
|
||||
angle_branch:
|
||||
required: true
|
||||
type: string
|
||||
dotnet_alpine_image:
|
||||
required: true
|
||||
source_lock:
|
||||
type: string
|
||||
default: ''
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
skiasharp_version:
|
||||
required: true
|
||||
default: "4.150.1"
|
||||
type: string
|
||||
angle_branch:
|
||||
required: true
|
||||
default: "7922"
|
||||
type: string
|
||||
dotnet_alpine_image:
|
||||
required: true
|
||||
default: mcr.microsoft.com/dotnet/sdk:10.0.302-alpine3.23
|
||||
type: string
|
||||
default: '4.150.1'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- rid: linux-musl-x64
|
||||
target_cpu: x64
|
||||
runner: ubuntu-24.04
|
||||
- rid: linux-musl-arm64
|
||||
target_cpu: arm64
|
||||
runner: ubuntu-24.04-arm
|
||||
runs-on: ${{ matrix.runner }}
|
||||
env:
|
||||
SKIASHARP_VERSION: ${{ inputs.skiasharp_version }}
|
||||
ANGLE_BRANCH: ${{ inputs.angle_branch }}
|
||||
DOTNET_ALPINE_IMAGE: ${{ inputs.dotnet_alpine_image }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Restore native build cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: External/NativeStatic/.work
|
||||
key: native-work-musl-${{ matrix.rid }}-${{ inputs.skiasharp_version }}-${{ inputs.angle_branch }}-${{ hashFiles('External/NativeStatic/patches/*.patch', 'scripts/build-linux-static-graphics.sh') }}
|
||||
|
||||
- name: Build Linux musl static graphics libraries
|
||||
run: |
|
||||
docker run --rm \
|
||||
-v "$PWD:/workspace" \
|
||||
-w /workspace \
|
||||
-e RID="${{ matrix.rid }}" \
|
||||
-e TARGET_CPU="${{ matrix.target_cpu }}" \
|
||||
-e OUTPUT_DIR="/workspace/External/NativeStatic/${{ matrix.rid }}/native" \
|
||||
-e SKIASHARP_VERSION="$SKIASHARP_VERSION" \
|
||||
-e ANGLE_BRANCH="$ANGLE_BRANCH" \
|
||||
-e LLVM_AR=llvm-ar \
|
||||
-e DEPOT_TOOLS_BOOTSTRAP_PYTHON3=0 \
|
||||
-e VPYTHON_BYPASS="manually managed python not supported by chrome operations" \
|
||||
"$DOTNET_ALPINE_IMAGE" \
|
||||
sh -lc '
|
||||
set -e
|
||||
apk add --no-cache bash ca-certificates git python3 py3-httplib2 py3-pysocks py3-six clang compiler-rt lld llvm g++ ninja pkgconf fontconfig-dev glib-dev mesa-dev libx11-dev libxcb-dev libxext-dev pciutils-dev linux-headers perl curl tar xz patch gcompat libc6-compat
|
||||
git config --global --add safe.directory "*"
|
||||
python3 - <<'"'"'PY'"'"'
|
||||
import pathlib
|
||||
import httplib2
|
||||
|
||||
path = pathlib.Path(httplib2.__file__).with_name("socks.py")
|
||||
if not path.exists():
|
||||
path.write_text("from socks import *\n")
|
||||
PY
|
||||
bash scripts/build-linux-static-graphics.sh all
|
||||
'
|
||||
|
||||
- name: Normalize native build cache ownership
|
||||
run: sudo chown -R "$(id -u):$(id -g)" External/NativeStatic/.work
|
||||
|
||||
- name: Upload Linux musl static archives
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: native-static-${{ matrix.rid }}
|
||||
path: External/NativeStatic/${{ matrix.rid }}/*
|
||||
if-no-files-found: error
|
||||
uses: ./.github/workflows/static-graphics-zig-cross.yml
|
||||
with:
|
||||
skiasharp_version: ${{ inputs.skiasharp_version }}
|
||||
source_lock: ${{ inputs.source_lock || '' }}
|
||||
rids: '["linux-musl-x64","linux-musl-arm64"]'
|
||||
@@ -2,7 +2,13 @@ name: static-graphics-preflight
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
skiasharp_version:
|
||||
type: string
|
||||
default: ''
|
||||
outputs:
|
||||
source_lock:
|
||||
value: ${{ jobs.validate.outputs.source_lock }}
|
||||
package_version:
|
||||
value: ${{ jobs.validate.outputs.package_version }}
|
||||
skiasharp_version:
|
||||
@@ -15,6 +21,7 @@ jobs:
|
||||
validate:
|
||||
runs-on: ubuntu-24.04
|
||||
outputs:
|
||||
source_lock: ${{ steps.versions.outputs.source_lock }}
|
||||
package_version: ${{ steps.versions.outputs.package_version }}
|
||||
skiasharp_version: ${{ steps.versions.outputs.skiasharp_version }}
|
||||
angle_branch: ${{ steps.versions.outputs.angle_branch }}
|
||||
@@ -29,7 +36,14 @@ jobs:
|
||||
- name: Read and validate versions
|
||||
id: versions
|
||||
shell: bash
|
||||
env:
|
||||
REQUESTED_VERSION: ${{ inputs.skiasharp_version }}
|
||||
run: |
|
||||
if [ "${GITHUB_REF_TYPE:-}" = tag ] && [ -z "$REQUESTED_VERSION" ]; then
|
||||
tag_version="${GITHUB_REF_NAME#staticlink-avalonia-v}"
|
||||
REQUESTED_VERSION="${tag_version%%-*}"
|
||||
fi
|
||||
python3 scripts/resolve-release-lock.py --version "$REQUESTED_VERSION"
|
||||
python3 - <<'PY'
|
||||
import os
|
||||
import pathlib
|
||||
@@ -37,7 +51,10 @@ jobs:
|
||||
|
||||
project = pathlib.Path("NuGet/StaticGraphics/StaticLink.Avalonia.csproj")
|
||||
root = ET.parse(project).getroot()
|
||||
import json
|
||||
lock = json.loads(pathlib.Path("build/linux-toolchain/release.lock.json").read_text())
|
||||
package_version = root.findtext(".//Version")
|
||||
package_version = lock["skiasharp_version"] + "-" + package_version.split("-", 1)[1]
|
||||
skia_reference = next(
|
||||
item.attrib["Version"]
|
||||
for item in root.findall(".//PackageReference")
|
||||
@@ -45,7 +62,7 @@ jobs:
|
||||
)
|
||||
version_base, revision = package_version.rsplit(".", 1)
|
||||
skiasharp_version, angle_branch = version_base.split("-", 1)
|
||||
if not revision.isdigit() or skiasharp_version != skia_reference:
|
||||
if not revision.isdigit() or skiasharp_version != lock["skiasharp_version"]:
|
||||
raise SystemExit(f"Inconsistent package version: {package_version}, SkiaSharp: {skia_reference}")
|
||||
if os.environ.get("GITHUB_REF_TYPE") == "tag":
|
||||
expected_tag = f"staticlink-avalonia-v{package_version}"
|
||||
@@ -53,6 +70,7 @@ jobs:
|
||||
raise SystemExit(f"Release tag must be {expected_tag}")
|
||||
|
||||
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output:
|
||||
output.write("source_lock=" + json.dumps(lock, separators=(",", ":")) + "\n")
|
||||
output.write(f"package_version={package_version}\n")
|
||||
output.write(f"skiasharp_version={skiasharp_version}\n")
|
||||
output.write(f"angle_branch={angle_branch}\n")
|
||||
@@ -65,7 +83,7 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
git ls-remote --exit-code --heads https://github.com/mono/SkiaSharp.git "refs/heads/release/${SKIASHARP_VERSION}"
|
||||
git ls-remote --exit-code --tags https://github.com/mono/SkiaSharp.git "refs/tags/v${SKIASHARP_VERSION}"
|
||||
git clone --depth 1 --branch "chromium/${ANGLE_BRANCH}" https://github.com/google/angle.git /tmp/staticlink-angle
|
||||
git -C /tmp/staticlink-angle apply --check "$GITHUB_WORKSPACE/External/NativeStatic/patches/angle-chromium-${ANGLE_BRANCH}.patch"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: static-graphics-windows
|
||||
name: static-graphics-windows-zig
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
@@ -6,87 +6,23 @@ on:
|
||||
skiasharp_version:
|
||||
required: true
|
||||
type: string
|
||||
angle_branch:
|
||||
required: true
|
||||
source_lock:
|
||||
type: string
|
||||
default: ''
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
skiasharp_version:
|
||||
required: true
|
||||
default: "4.150.1"
|
||||
type: string
|
||||
angle_branch:
|
||||
required: true
|
||||
default: "7922"
|
||||
type: string
|
||||
default: '4.150.1'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- rid: win-x64
|
||||
target_cpu: x64
|
||||
msvc_arch: x64
|
||||
- rid: win-x86
|
||||
target_cpu: x86
|
||||
msvc_arch: x86
|
||||
- rid: win-arm64
|
||||
target_cpu: arm64
|
||||
msvc_arch: amd64_arm64
|
||||
runs-on: windows-2022
|
||||
env:
|
||||
SKIASHARP_VERSION: ${{ inputs.skiasharp_version }}
|
||||
ANGLE_BRANCH: ${{ inputs.angle_branch }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Restore native build cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: External/NativeStatic/.work
|
||||
key: native-work-windows-${{ matrix.rid }}-${{ inputs.skiasharp_version }}-${{ inputs.angle_branch }}-${{ hashFiles('External/NativeStatic/patches/*.patch', 'scripts/build-windows-static-graphics.ps1') }}
|
||||
|
||||
- name: Setup MSVC environment
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: ${{ matrix.msvc_arch }}
|
||||
|
||||
- name: Configure Chromium Visual Studio environment
|
||||
shell: pwsh
|
||||
run: |
|
||||
"DEPOT_TOOLS_WIN_TOOLCHAIN=0" >> $env:GITHUB_ENV
|
||||
"GYP_MSVS_VERSION=17.0" >> $env:GITHUB_ENV
|
||||
"GYP_MSVS_OVERRIDE_PATH=$($env:VSINSTALLDIR.TrimEnd('\', '/'))" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Install native build dependencies
|
||||
shell: pwsh
|
||||
run: |
|
||||
git config --global core.longpaths true
|
||||
choco install ninja llvm -y
|
||||
|
||||
- name: Validate Windows ANGLE inputs
|
||||
shell: pwsh
|
||||
env:
|
||||
RID: ${{ matrix.rid }}
|
||||
TARGET_CPU: ${{ matrix.target_cpu }}
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN: 0
|
||||
GYP_MSVS_VERSION: 17.0
|
||||
run: .\scripts\build-windows-static-graphics.ps1 angle-preflight
|
||||
|
||||
- name: Build Windows static graphics libraries
|
||||
shell: pwsh
|
||||
env:
|
||||
RID: ${{ matrix.rid }}
|
||||
TARGET_CPU: ${{ matrix.target_cpu }}
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN: 0
|
||||
GYP_MSVS_VERSION: 17.0
|
||||
run: .\scripts\build-windows-static-graphics.ps1 all
|
||||
|
||||
- name: Upload Windows static archives
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: native-static-${{ matrix.rid }}
|
||||
path: External/NativeStatic/${{ matrix.rid }}/*
|
||||
if-no-files-found: error
|
||||
uses: ./.github/workflows/static-graphics-zig-cross.yml
|
||||
with:
|
||||
skiasharp_version: ${{ inputs.skiasharp_version }}
|
||||
source_lock: ${{ inputs.source_lock || '' }}
|
||||
rids: '["win-x64","win-x86","win-arm64"]'
|
||||
@@ -0,0 +1,111 @@
|
||||
name: static-graphics-zig-cross-debian12
|
||||
|
||||
# All native archives are compiled with Zig on Linux; platform runners validate consumer apps.
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
skiasharp_version:
|
||||
type: string
|
||||
required: true
|
||||
toolchain_image:
|
||||
type: string
|
||||
default: ''
|
||||
rids:
|
||||
type: string
|
||||
default: '["linux-x64","linux-arm64","linux-musl-x64","linux-musl-arm64","win-x64","win-x86","win-arm64","osx-x64","osx-arm64"]'
|
||||
artifact_prefix:
|
||||
type: string
|
||||
default: native-static
|
||||
source_lock:
|
||||
type: string
|
||||
required: true
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
skiasharp_version:
|
||||
description: Locked SkiaSharp release profile
|
||||
type: string
|
||||
default: '4.150.1'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
image:
|
||||
if: ${{ inputs.toolchain_image == '' }}
|
||||
uses: ./.github/workflows/zig-toolchain-image.yml
|
||||
|
||||
build:
|
||||
needs: image
|
||||
if: ${{ always() && (needs.image.result == 'success' || inputs.toolchain_image != '') }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: read
|
||||
env:
|
||||
TOOLCHAIN_IMAGE: ${{ inputs.toolchain_image || needs.image.outputs.image }}
|
||||
timeout-minutes: 180
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
rid: ${{ fromJSON(inputs.rids || '["linux-x64","linux-arm64","linux-musl-x64","linux-musl-arm64","win-x64","win-x86","win-arm64","osx-x64","osx-arm64"]') }}
|
||||
steps:
|
||||
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
||||
- name: Resolve immutable build inputs
|
||||
env:
|
||||
SOURCE_LOCK_JSON: ${{ inputs.source_lock }}
|
||||
REQUESTED_VERSION: ${{ inputs.skiasharp_version }}
|
||||
run: |
|
||||
if [ -n "$SOURCE_LOCK_JSON" ]; then
|
||||
python3 - <<'PY'
|
||||
import json, os, pathlib
|
||||
lock = json.loads(os.environ['SOURCE_LOCK_JSON'])
|
||||
if lock['skiasharp_version'] != os.environ['REQUESTED_VERSION']:
|
||||
raise SystemExit('Source lock does not match requested version')
|
||||
pathlib.Path('build/linux-toolchain/release.lock.json').write_text(json.dumps(lock, indent=2) + '\n')
|
||||
PY
|
||||
else
|
||||
python3 scripts/resolve-release-lock.py --version "$REQUESTED_VERSION"
|
||||
fi
|
||||
- name: Restore exact target cache
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
|
||||
with:
|
||||
path: External/NativeStatic/.work
|
||||
key: zig-debian12-v3-${{ inputs.skiasharp_version }}-${{ matrix.rid }}-${{ hashFiles('build/linux-toolchain/**', 'scripts/prepare-cross-sources.sh', 'scripts/build-linux-static-graphics.sh', 'External/NativeStatic/patches/*.patch') }}
|
||||
- name: Pull immutable toolchain image
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
ACTOR: ${{ github.actor }}
|
||||
run: |
|
||||
printf '%s' "$GH_TOKEN" | docker login ghcr.io -u "$ACTOR" --password-stdin
|
||||
docker pull "$TOOLCHAIN_IMAGE"
|
||||
- name: Prepare locked sources and build native libraries
|
||||
env:
|
||||
CROSS_RID: ${{ matrix.rid }}
|
||||
SKIASHARP_PROFILE: ${{ inputs.skiasharp_version }}
|
||||
run: |
|
||||
mkdir -p External/NativeStatic/.work/home
|
||||
docker run --rm --user "$(id -u):$(id -g)" \
|
||||
-e HOME=/src/External/NativeStatic/.work/home -e CROSS_RID -e SKIASHARP_PROFILE \
|
||||
-e CCACHE_DIR=/src/External/NativeStatic/.work/ccache -e CCACHE_MAXSIZE=1G \
|
||||
-e ZIG_GLOBAL_CACHE_DIR=/src/External/NativeStatic/.work/zig-global \
|
||||
-v "$PWD:/src" -w /src --entrypoint bash "$TOOLCHAIN_IMAGE" -c '
|
||||
set -euo pipefail
|
||||
export SOURCE_LOCK="/src/build/linux-toolchain/release.lock.json"
|
||||
source scripts/prepare-cross-sources.sh
|
||||
python3 build/linux-toolchain/build-cross.py \
|
||||
--target "$CROSS_RID" \
|
||||
--sources-manifest "$WORK_DIR/cross-sources.json" \
|
||||
--work /src/External/NativeStatic/.work/toolchains \
|
||||
--output "/src/External/NativeStatic/zig-cross/$SKIASHARP_PROFILE/$CROSS_RID" --jobs 4
|
||||
python3 build/linux-toolchain/package-zig.py \
|
||||
--rid "$CROSS_RID" \
|
||||
--input "/src/External/NativeStatic/zig-cross/$SKIASHARP_PROFILE/$CROSS_RID" \
|
||||
--output "/src/External/NativeStatic/$CROSS_RID/native"
|
||||
'
|
||||
- name: Upload archives, link tests and input manifest
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: ${{ inputs.artifact_prefix || 'native-static' }}-${{ matrix.rid }}
|
||||
path: External/NativeStatic/${{ matrix.rid }}/**
|
||||
if-no-files-found: error
|
||||
@@ -0,0 +1,55 @@
|
||||
name: zig-recent-release-regression
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
versions:
|
||||
description: JSON array of stable SkiaSharp versions from this branch major
|
||||
type: string
|
||||
default: '["4.150.3","4.150.5","4.153.1"]'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
resolve:
|
||||
runs-on: ubuntu-24.04
|
||||
outputs:
|
||||
releases: ${{ steps.locks.outputs.releases }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- id: locks
|
||||
env:
|
||||
VERSIONS: ${{ inputs.versions }}
|
||||
run: |
|
||||
python3 - <<'PY'
|
||||
import json, os, pathlib, subprocess
|
||||
versions = json.loads(os.environ['VERSIONS'])
|
||||
if not isinstance(versions, list) or not 1 <= len(versions) <= 5:
|
||||
raise SystemExit('Expected one to five stable versions')
|
||||
releases = []
|
||||
for version in versions:
|
||||
subprocess.run(['python3', 'scripts/resolve-release-lock.py', '--version', version], check=True)
|
||||
lock = json.loads(pathlib.Path('build/linux-toolchain/release.lock.json').read_text())
|
||||
releases.append({'version': version, 'lock': json.dumps(lock)})
|
||||
with open(os.environ['GITHUB_OUTPUT'], 'a') as output:
|
||||
output.write('releases=' + json.dumps(releases, separators=(',', ':')) + '\n')
|
||||
PY
|
||||
|
||||
toolchain:
|
||||
needs: resolve
|
||||
uses: ./.github/workflows/zig-toolchain-image.yml
|
||||
|
||||
build:
|
||||
needs: [resolve, toolchain]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
release: ${{ fromJSON(needs.resolve.outputs.releases) }}
|
||||
uses: ./.github/workflows/static-graphics-zig-cross.yml
|
||||
with:
|
||||
skiasharp_version: ${{ matrix.release.version }}
|
||||
source_lock: ${{ matrix.release.lock }}
|
||||
toolchain_image: ${{ needs.toolchain.outputs.image }}
|
||||
artifact_prefix: regression-${{ matrix.release.version }}
|
||||
@@ -0,0 +1,78 @@
|
||||
name: pinned-zig-toolchain-image
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
validation_rids:
|
||||
type: string
|
||||
default: '[]'
|
||||
outputs:
|
||||
image:
|
||||
description: Immutable Debian 12 Zig toolchain image reference
|
||||
value: ${{ jobs.image.outputs.image }}
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
image:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 60
|
||||
outputs:
|
||||
image: ${{ steps.publish.outputs.image }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Publish or reuse exact toolchain image
|
||||
id: publish
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
ACTOR: ${{ github.actor }}
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
VALIDATION_RIDS: ${{ inputs.validation_rids || '[]' }}
|
||||
BASE_HASH: ${{ hashFiles('build/linux-toolchain/Dockerfile') }}
|
||||
RECIPE_HASH: ${{ hashFiles('build/linux-toolchain/Dockerfile*', 'build/linux-toolchain/*.py', 'build/linux-toolchain/*.c', 'build/linux-toolchain/*.gn.in', 'build/linux-toolchain/*lock.json', 'build/linux-toolchain/versions/*.json', 'build/linux-toolchain/patches/**') }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
printf '%s' "$GH_TOKEN" | docker login ghcr.io -u "$ACTOR" --password-stdin
|
||||
repository="ghcr.io/${REPOSITORY,,}-zig"
|
||||
image="$repository:recipe-$RECIPE_HASH"
|
||||
base="$repository:debian12-$BASE_HASH"
|
||||
built_image=false
|
||||
if ! docker pull "$image"; then
|
||||
if ! docker pull "$base"; then
|
||||
docker build --platform linux/amd64 \
|
||||
--label "org.opencontainers.image.source=https://github.com/$REPOSITORY" \
|
||||
-t "$base" build/linux-toolchain
|
||||
docker push "$base"
|
||||
docker pull "$base"
|
||||
fi
|
||||
base_digest="$(docker image inspect --format '{{index .RepoDigests 0}}' "$base")"
|
||||
docker build --platform linux/amd64 \
|
||||
--build-arg "TOOLCHAIN_IMAGE=$base_digest" \
|
||||
--label "org.opencontainers.image.source=https://github.com/$REPOSITORY" \
|
||||
-f build/linux-toolchain/Dockerfile.cross-probe \
|
||||
-t "$image" build/linux-toolchain
|
||||
built_image=true
|
||||
fi
|
||||
mkdir -p artifacts/toolchain-environment
|
||||
docker run --rm --user "$(id -u):$(id -g)" \
|
||||
-e HOME=/tmp -e DOTNET_CLI_HOME=/tmp -e ZIG_GLOBAL_CACHE_DIR=/tmp/zig-cache \
|
||||
-v "$PWD/artifacts/toolchain-environment:/validation" \
|
||||
--entrypoint python3 "$image" /opt/staticlink/validate-toolchain.py --output /validation --rids "$VALIDATION_RIDS"
|
||||
if [ "$built_image" = true ]; then
|
||||
docker push "$image"
|
||||
docker pull "$image"
|
||||
fi
|
||||
digest="$(docker image inspect --format '{{index .RepoDigests 0}}' "$image")"
|
||||
case "$digest" in "$repository"@sha256:*) ;; *) echo 'No immutable image digest' >&2; exit 1 ;; esac
|
||||
echo "image=$digest" >> "$GITHUB_OUTPUT"
|
||||
echo "Toolchain: $digest" >> "$GITHUB_STEP_SUMMARY"
|
||||
- name: Upload environment validation report
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: toolchain-environment-validation
|
||||
path: artifacts/toolchain-environment/
|
||||
if-no-files-found: warn
|
||||
@@ -0,0 +1,38 @@
|
||||
# Manual artifact validation
|
||||
|
||||
Daily schedules are disabled during validation. No NuGet.org publication or
|
||||
GitHub Release is requested by the manual dispatcher on main.
|
||||
|
||||
Before release builds, run nuget-static-graphics.yml on skia4 with
|
||||
environment_only=true. This checks the actual container's Python/depot_tools,
|
||||
.NET 8/10, SDKs, sysroots, and C/C++ compilation plus C executable linking for
|
||||
all nine RIDs. Download toolchain-environment-validation to inspect the report.
|
||||
The same environment gate runs before every graphics and native build and
|
||||
must pass before the toolchain image is published for release compilation.
|
||||
|
||||
- skia3: nuget-static-graphics.yml; latest stable SkiaSharp 3.
|
||||
- skia4: nuget-static-graphics.yml; latest stable SkiaSharp 4.
|
||||
- avalonia-native: nuget-avalonia-native.yml; latest stable Avalonia 11 and 12.
|
||||
|
||||
Download staticlink-avalonia-nuget and avalonia-smoke-<RID> from each graphics run.
|
||||
Download staticlink-avalonia-native-<version> and
|
||||
avalonia-native-smoke-<AvaloniaVersion>-<RID> from the native run.
|
||||
Native archives and source locks are also retained as Actions artifacts.
|
||||
|
||||
Graphics macOS smoke tests use the already published AvaloniaNative revision 1
|
||||
by default, so the graphics builds do not require the experimental native
|
||||
revision 2 to be published. The native branch validates its own local revision 2
|
||||
package separately. To test both experimental packages together, put both
|
||||
downloaded packages in a local NuGet feed and reference their exact versions.
|
||||
|
||||
Smoke executables are retained even if a later runtime validation fails.
|
||||
An artifact is not evidence that all validation gates passed; check job results.
|
||||
|
||||
The daily-native-release workflow on main currently supports manual dispatch
|
||||
only. Its three matrix jobs check out their own branch and dispatch independently.
|
||||
Use force_build=true to rebuild published versions for testing.
|
||||
After validation, enable the schedule on main only; non-default branches cannot
|
||||
run their own GitHub cron schedules. Publication remains an explicit opt-in.
|
||||
While publication is disabled, an unpublished package may be rebuilt on every
|
||||
check; add successful-run tracking before enabling artifact-only daily builds
|
||||
if avoiding repeated builds is required.
|
||||
@@ -0,0 +1,9 @@
|
||||
# Daily releases (not enabled)
|
||||
|
||||
This branch currently runs manual artifact validation only. The independent
|
||||
three-branch dispatcher is on main and has no schedule yet. NuGet.org and
|
||||
GitHub Release publication are disabled for the initial runs.
|
||||
|
||||
See [ACTION-TESTING.md](ACTION-TESTING.md) for artifact names, the macOS native
|
||||
package used by graphics smoke tests, and the steps required before daily
|
||||
builds are enabled.
|
||||
@@ -19,6 +19,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="../../External/AvaloniaNative/osx-x64/native/avalonia-native-build.json" Pack="true" PackagePath="buildMetadata/osx-x64.json" />
|
||||
<None Include="../../External/AvaloniaNative/osx-arm64/native/avalonia-native-build.json" Pack="true" PackagePath="buildMetadata/osx-arm64.json" />
|
||||
<None Include="README.md" Pack="true" PackagePath="README.md" />
|
||||
<None Include="lib/net8.0/_._" Pack="true" PackagePath="lib/net8.0/_._" />
|
||||
<None Include="buildTransitive/StaticLink.Avalonia.Native.props" Pack="true" PackagePath="buildTransitive/$(PackageId).props" />
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<IncludeBuildOutput>false</IncludeBuildOutput>
|
||||
<SuppressDependenciesWhenPacking>false</SuppressDependenciesWhenPacking>
|
||||
<PackageId>StaticLink.Avalonia</PackageId>
|
||||
<Version>4.150.1-7922.1</Version>
|
||||
<Version>4.150.1-7922.2</Version>
|
||||
<Authors>greepar</Authors>
|
||||
<Company>greepar</Company>
|
||||
<Description>Static SkiaSharp, HarfBuzzSharp, and ANGLE libraries for Avalonia NativeAOT single-file publishing.</Description>
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="README.md" Pack="true" PackagePath="" />
|
||||
<None Include="../../build/linux-toolchain/release.lock.json" Condition="Exists('../../build/linux-toolchain/release.lock.json')" Pack="true" PackagePath="buildMetadata/sources.lock.json" />
|
||||
<None Include="lib/net8.0/_._" Pack="true" PackagePath="lib/net8.0/_._" />
|
||||
<None Include="buildTransitive/StaticLink.Avalonia.props" Pack="true" PackagePath="buildTransitive/$(PackageId).props" />
|
||||
<None Include="buildTransitive/StaticLink.Avalonia.targets" Pack="true" PackagePath="buildTransitive/$(PackageId).targets" />
|
||||
|
||||
@@ -163,4 +163,19 @@
|
||||
</ItemGroup>
|
||||
<Delete Files="@(_StaticLinkAvaloniaFilesToDelete)" TreatErrorsAsWarnings="true" />
|
||||
</Target>
|
||||
<Target Name="StaticLinkAvaloniaAddZigRuntime"
|
||||
BeforeTargets="LinkNative"
|
||||
Condition="'$(PublishAot)' == 'true' and Exists('$(_StaticLinkAvaloniaNativeRoot)/zig-build.json')">
|
||||
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith('win-'))">
|
||||
<CppLinker>lld-link</CppLinker>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/zig-runtime/*.lib" Condition="$(RuntimeIdentifier.StartsWith('win-'))" />
|
||||
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/zig-runtime/*.a" Condition="!$(RuntimeIdentifier.StartsWith('win-'))" />
|
||||
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/libEGL_static.lib" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libEGL_static.lib')" />
|
||||
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/libEGL_static.a" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libEGL_static.a')" />
|
||||
<NativeSystemLibrary Include="X11;Xext;xcb;wayland-client;wayland-egl;ffi" Condition="$(RuntimeIdentifier.StartsWith('linux-'))" />
|
||||
<LinkerArg Include="/lldmingw" Condition="$(RuntimeIdentifier.StartsWith('win-'))" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,3 +1,5 @@
|
||||
> 3/4 分支构建更新:原生图形库与 macOS AvaloniaNative 已统一为 Linux 上的 Zig 入口;Windows/macOS runner 用于消费者运行验收。配置与真实编译的验证范围见 [CROSS-COMPILE.md](build/linux-toolchain/CROSS-COMPILE.md),每日发布说明见 [DAILY-RELEASE.md](DAILY-RELEASE.md)。完整九平台回归与 Docker 镜像尚待 Action 实跑,不能视为已全部通过。
|
||||
|
||||
# StaticLink.Avalonia
|
||||
|
||||
Static native libraries for Avalonia single-file NativeAOT publishing.
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"checked_at_utc": "2026-10-04",
|
||||
"live_plan": [
|
||||
{
|
||||
"ref": "4.150.1-7922.1",
|
||||
"skiasharp_version": "4.153.1",
|
||||
"package_version": "4.153.1-7922.1"
|
||||
}
|
||||
],
|
||||
"source_lock_checks": {
|
||||
"3.119.2": {
|
||||
"skiasharp_version": "3.119.2",
|
||||
"skiasharp_revision": "2888c737ad016d584c74525e2d35db5097ea8576",
|
||||
"angle_branch": "7922",
|
||||
"angle_revision": "7e08726e32026a0bbabd6ec8a1a90f5ab533ed66",
|
||||
"skia_revision": "927041a58f130e0dd0562ba86cb4170989ad39e9"
|
||||
},
|
||||
"3.119.4": {
|
||||
"skiasharp_version": "3.119.4",
|
||||
"skiasharp_revision": "f568ac94dd768ef9a2f593537cfde2dd0d348ef5",
|
||||
"angle_branch": "7922",
|
||||
"angle_revision": "7e08726e32026a0bbabd6ec8a1a90f5ab533ed66",
|
||||
"skia_revision": "7dbfc07dd33181f84e0958afb7ee805c6c769f0b"
|
||||
},
|
||||
"4.150.2": {
|
||||
"skiasharp_version": "4.150.2",
|
||||
"skiasharp_revision": "fd1fdd5239f826514651a4ada5d7bb3dcec2fb43",
|
||||
"angle_branch": "7922",
|
||||
"angle_revision": "7e08726e32026a0bbabd6ec8a1a90f5ab533ed66",
|
||||
"skia_revision": "b70519562e2d26d3cf56286d3a13ca25152cfae4"
|
||||
},
|
||||
"4.150.3": {
|
||||
"skiasharp_version": "4.150.3",
|
||||
"skiasharp_revision": "f8a404ff3375872d042404a29189ceb8e3001a41",
|
||||
"angle_branch": "7922",
|
||||
"angle_revision": "7e08726e32026a0bbabd6ec8a1a90f5ab533ed66",
|
||||
"skia_revision": "eb86e4b3ee034085b62d3980b3d94629862441e6"
|
||||
},
|
||||
"4.150.5": {
|
||||
"skiasharp_version": "4.150.5",
|
||||
"skiasharp_revision": "16f82682f756217654eb1a152cdb639e358b8976",
|
||||
"angle_branch": "7922",
|
||||
"angle_revision": "7e08726e32026a0bbabd6ec8a1a90f5ab533ed66",
|
||||
"skia_revision": "579fa81eeed6906732e27b7d95149538584dd20b"
|
||||
},
|
||||
"4.153.1": {
|
||||
"skiasharp_version": "4.153.1",
|
||||
"skiasharp_revision": "4783f51448f9b070dda4f87b83e941c9599e466e",
|
||||
"angle_branch": "7922",
|
||||
"angle_revision": "7e08726e32026a0bbabd6ec8a1a90f5ab533ed66",
|
||||
"skia_revision": "45afab4f1f0921f3feb97f58cf89b136fffa85e6"
|
||||
}
|
||||
},
|
||||
"checks_passed": [
|
||||
"actionlint",
|
||||
"python-json-yaml-bash-syntax",
|
||||
"numeric-stable-version-selection",
|
||||
"skip-published-version",
|
||||
"freeze-skia2",
|
||||
"real-nuget-discovery",
|
||||
"immutable-tag-and-skia-gitlink-resolution",
|
||||
"generated-package-version-and-exact-dependency"
|
||||
],
|
||||
"not_run": [
|
||||
"full-build-of-the-six-new-versions",
|
||||
"github-actions",
|
||||
"docker-cold-build",
|
||||
"windows-macos-runtime",
|
||||
"dotnet-pack",
|
||||
"nuget-publish"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
# Zig cross compilation for SkiaSharp 3 / 4
|
||||
|
||||
All nine native targets use Zig 0.14.1 from Linux: linux-x64, linux-arm64,
|
||||
linux-musl-x64, linux-musl-arm64, win-x64, win-x86, win-arm64, osx-x64, osx-arm64.
|
||||
Windows uses the GNU ABI, without MSVC. macOS uses a checksum-pinned real SDK,
|
||||
without Xcode. AvaloniaNative 11/12 also compiles with Zig on Linux.
|
||||
|
||||
## Local evidence (2026-10-04)
|
||||
|
||||
| Check | Result |
|
||||
| --- | --- |
|
||||
| 3.119.2, 3.119.4, 4.150.3, 4.150.5, 4.153.1 × nine GN configurations | 45 passed; these are configuration checks |
|
||||
| All five versions, Windows x64 Skia/SkiaSharp/HarfBuzz compilation and executable link | Passed |
|
||||
| 3.119.4 Windows x86 Skia and stdcall thunks | Compilation and raster/EGL links passed; fixed ANGLE archives reused |
|
||||
| 3.119.4 Linux x64 | All six archives and both links passed; raster/UTF-8 execution passed |
|
||||
| 3.119.4 Linux ARM64 | Three Skia archives and raster link passed; raster/UTF-8 execution passed under QEMU |
|
||||
| 4.153.1 macOS ARM64 | Three Skia archives and raster executable link passed |
|
||||
| AvaloniaNative 11.3.14 / 12.1.0, both macOS architectures | Four full compilations and SDK libc++ executable links passed |
|
||||
|
||||
Exact scope is recorded in `recent-version-validation.json`. Earlier baseline
|
||||
results are retained separately. The raster probe checks 64 pixels and UTF-8
|
||||
buffer ingestion; it does not prove complete font shaping or GPU operation.
|
||||
|
||||
There is no local Docker daemon or Windows/macOS runtime. The complete Debian
|
||||
image, five releases × nine full builds, NativeAOT consumer applications and
|
||||
actual Actions/NuGet publication have not been verified locally. Local builds
|
||||
used the Linux host and pinned cross tools, not a running Debian container.
|
||||
|
||||
## Repeatable inputs and failure policy
|
||||
|
||||
`Dockerfile` pins Debian 12 by digest, apt by snapshot and depot_tools by commit.
|
||||
`Dockerfile.cross-probe` is the production cross image despite its historical
|
||||
name. It pins Zig, the macOS SDK, WinRT headers, availability runtime and Linux
|
||||
sysroot packages by checksum. SDK extraction supports pinned Debian Python 3.11.
|
||||
|
||||
`zig-toolchain-image.yml` builds/reuses GHCR images by recipe digest and passes
|
||||
an immutable image digest to downstream builds. Repository package write
|
||||
permission is required. Source profiles pin SkiaSharp, Skia and ANGLE commits.
|
||||
The existing exact per-target source/build cache has no fallback restores;
|
||||
ccache additionally checks compiler contents. Cold downloads remain necessary.
|
||||
|
||||
`build-cross.py` adapts declared GN capabilities, rejects unknown compiler flags,
|
||||
checks static targets, builds six archives and links raster and EGL/GLES probes.
|
||||
`package-zig.py` requires archive hashes and successful links before packaging.
|
||||
Windows x86 gets generated stdcall thunks. Captured Zig runtime libraries are
|
||||
included for consumer linking. A successful C link does not establish NativeAOT
|
||||
compatibility; the release workflow gates publication on consumer OS tests.
|
||||
|
||||
## Run
|
||||
|
||||
Use the `zig-recent-regression` manual Action for recent-version full matrices.
|
||||
Use `static-graphics-zig-cross-debian12` for one pinned release and nine RIDs.
|
||||
For already synced sources, run `build/linux-toolchain/build-cross.py --help`;
|
||||
`--configure-only` configures without compiling, while `--component skia` checks
|
||||
only the three Skia libraries and their executable link.
|
||||
|
||||
This common driver supports the tested source revisions. Future compiler,
|
||||
SDK, GN or source changes can still require deliberate updates. Daily releases
|
||||
fail closed and publish only after all required jobs pass. SkiaSharp 2 is frozen
|
||||
and excluded from the new regression/release tracks.
|
||||
@@ -0,0 +1,38 @@
|
||||
# Multi-architecture index; deliberately update together with the snapshot/cache key.
|
||||
FROM debian:bookworm-slim@sha256:3783cc01769c7b2b1b83a5c5ad96c815348e28ed7da68e2e3687004faa906251
|
||||
|
||||
ARG DEBIAN_SNAPSHOT=20260901T000000Z
|
||||
ARG DEPOT_TOOLS_REVISION=8a5434051036b32412a2ecb10c213a72e3f3ccb9
|
||||
ENV DEBIAN_FRONTEND=noninteractive \
|
||||
DEPOT_TOOLS_UPDATE=0 \
|
||||
DEPOT_TOOLS_REVISION=${DEPOT_TOOLS_REVISION} \
|
||||
LLVM_AR=llvm-ar-16 \
|
||||
BUILD_JOBS=4
|
||||
|
||||
# HTTP bootstrap uses Debian's signed Release metadata. Do not disable signature checks.
|
||||
RUN rm -f /etc/apt/sources.list.d/debian.sources \
|
||||
&& printf 'deb [check-valid-until=no] http://snapshot.debian.org/archive/debian/%s bookworm main\ndeb [check-valid-until=no] http://snapshot.debian.org/archive/debian-security/%s bookworm-security main\n' "$DEBIAN_SNAPSHOT" "$DEBIAN_SNAPSHOT" > /etc/apt/sources.list \
|
||||
&& apt-get update \
|
||||
&& printf 'Package: *\nPin: origin "snapshot.debian.org"\nPin-Priority: 1001\n' > /etc/apt/preferences.d/staticlink-snapshot \
|
||||
&& apt-get dist-upgrade -y --allow-downgrades \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
ca-certificates git curl python3 python3-six python3-requests python3-httplib2 \
|
||||
build-essential ccache clang-16 lld-16 llvm-16 libclang-rt-16-dev ninja-build \
|
||||
pkg-config cmake binutils file unzip xz-utils bzip2 patch \
|
||||
libfontconfig1-dev libglib2.0-dev libgl1-mesa-dev libpci-dev \
|
||||
libx11-dev libxcb1-dev libxext-dev libwayland-dev libexpat1-dev libicu72 libssl3 \
|
||||
&& for tool in clang clang++ llvm-ar llvm-ranlib llvm-nm lld ld.lld lld-link ld64.lld; do \
|
||||
ln -s "/usr/bin/$tool-16" "/usr/local/bin/$tool"; \
|
||||
done \
|
||||
&& mkdir -p /opt/staticlink \
|
||||
&& dpkg-query -W > /opt/staticlink/packages.lock \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Store the pinned checkout inside the image so the runner never selects depot_tools HEAD.
|
||||
RUN git init /opt/depot_tools \
|
||||
&& git -C /opt/depot_tools remote add origin https://chromium.googlesource.com/chromium/tools/depot_tools.git \
|
||||
&& git -C /opt/depot_tools fetch --depth 1 origin "$DEPOT_TOOLS_REVISION" \
|
||||
&& git -C /opt/depot_tools checkout --detach FETCH_HEAD
|
||||
ENV DEPOT_TOOLS_DIR=/opt/depot_tools
|
||||
WORKDIR /src
|
||||
CMD ["bash"]
|
||||
@@ -0,0 +1,61 @@
|
||||
# Build this local base from Dockerfile first; it contains the pinned Debian toolchain.
|
||||
ARG TOOLCHAIN_IMAGE=staticlink-debian12:probe-base
|
||||
FROM mcr.microsoft.com/dotnet/sdk:10.0.302@sha256:72dd743782f2ae7e5476fd64f6a460045e3998dc862218b80e6944cba79a01b0 AS dotnet10
|
||||
FROM mcr.microsoft.com/dotnet/sdk:8.0.416@sha256:8b5eece40d8a8050c09332eab1e65563fd4c928c5881e9e72bca7a4b0339f881 AS dotnet8
|
||||
FROM python:3.12.12-slim-bookworm@sha256:593bd06efe90efa80dc4eee3948be7c0fde4134606dd40d8dd8dbcade98e669c AS python312
|
||||
FROM ${TOOLCHAIN_IMAGE}
|
||||
COPY --from=python312 /usr/local/ /usr/local/
|
||||
ENV PYTHONPATH=/usr/lib/python3/dist-packages
|
||||
RUN ldconfig && python3 -c 'import inspect, tarfile, six, requests, httplib2; assert "filter" in inspect.signature(tarfile.TarFile.extractall).parameters'
|
||||
|
||||
ARG TARGETARCH
|
||||
RUN case "$TARGETARCH" in \
|
||||
amd64) zig_arch=x86_64; zig_sha=24aeeec8af16c381934a6cd7d95c807a8cb2cf7df9fa40d359aa884195c4716c ;; \
|
||||
arm64) zig_arch=aarch64; zig_sha=f7a654acc967864f7a050ddacfaa778c7504a0eca8d2b678839c21eea47c992b ;; \
|
||||
*) echo "Unsupported host architecture: $TARGETARCH" >&2; exit 1 ;; \
|
||||
esac \
|
||||
&& curl --fail --location --retry 3 \
|
||||
"https://ziglang.org/download/0.14.1/zig-$zig_arch-linux-0.14.1.tar.xz" -o /tmp/zig.tar.xz \
|
||||
&& printf '%s /tmp/zig.tar.xz\n' "$zig_sha" | sha256sum --check \
|
||||
&& mkdir /opt/zig \
|
||||
&& tar -xJf /tmp/zig.tar.xz -C /opt/zig --strip-components=1 \
|
||||
&& ln -s /opt/zig/zig /usr/local/bin/zig \
|
||||
&& rm /tmp/zig.tar.xz
|
||||
|
||||
ARG MACOS_SDK_SHA256=c15cf0f3f17d714d1aa5a642da8e118db53d79429eb015771ba816aa7c6c1cbd
|
||||
# Architecture-independent MinGW WinRT headers supplement Zig's SDK. Extract
|
||||
# files only: do not install Ubuntu binaries or change Debian package resolution.
|
||||
RUN curl --fail --location --retry 3 \
|
||||
https://snapshot.ubuntu.com/ubuntu/20260828T000000Z/pool/universe/m/mingw-w64/mingw-w64-common_11.0.1-3build1_all.deb \
|
||||
-o /tmp/mingw.deb \
|
||||
&& printf '%s /tmp/mingw.deb\n' \
|
||||
4a42fd30fbc3838c58c929d8a4882682fc12408bb7a0e6cafa913c0f0a57c187 | sha256sum --check \
|
||||
&& mkdir /opt/mingw && dpkg-deb --extract /tmp/mingw.deb /opt/mingw \
|
||||
&& rm /tmp/mingw.deb
|
||||
|
||||
RUN curl --fail --location --retry 3 \
|
||||
https://github.com/joseluisq/macosx-sdks/releases/download/15.5/MacOSX15.5.sdk.tar.xz \
|
||||
-o /tmp/macos-sdk.tar.xz \
|
||||
&& printf '%s /tmp/macos-sdk.tar.xz\n' "$MACOS_SDK_SHA256" | sha256sum --check \
|
||||
&& mkdir /opt/macos-sdk \
|
||||
&& tar -xJf /tmp/macos-sdk.tar.xz -C /opt/macos-sdk \
|
||||
&& rm /tmp/macos-sdk.tar.xz
|
||||
|
||||
RUN mkdir -p /opt/staticlink \
|
||||
&& curl --fail --location --retry 3 \
|
||||
https://raw.githubusercontent.com/llvm/llvm-project/llvmorg-19.1.7/compiler-rt/lib/builtins/os_version_check.c \
|
||||
-o /opt/staticlink/os_version_check.c \
|
||||
&& printf '%s /opt/staticlink/os_version_check.c\n' \
|
||||
bc0b9f10e8d1a1ac5905d710f1c9fead23878e31233748d580393edc4e3bfc18 | sha256sum --check
|
||||
|
||||
ENTRYPOINT ["python3", "/opt/staticlink/probe-cross.py"]
|
||||
|
||||
COPY --from=dotnet8 /usr/share/dotnet /opt/dotnet
|
||||
COPY --from=dotnet10 /usr/share/dotnet /opt/dotnet
|
||||
ENV DOTNET_ROOT=/opt/dotnet PATH=/opt/dotnet:${PATH}
|
||||
COPY fetch-linux-sysroots.py linux-sysroots*.lock.json /opt/staticlink/
|
||||
RUN python3 /opt/staticlink/fetch-linux-sysroots.py --output /opt/sysroots \
|
||||
--locks /opt/staticlink/linux-sysroots.lock.json /opt/staticlink/linux-sysroots-musl.lock.json
|
||||
COPY *.py smoke-*.c sources.lock.json cross-toolchain.lock.json *.gn.in /opt/staticlink/
|
||||
COPY patches/ /opt/staticlink/patches/
|
||||
COPY versions/ /opt/staticlink/versions/
|
||||
@@ -0,0 +1,20 @@
|
||||
# Debian 12 Zig cross toolchain
|
||||
|
||||
The production native-build path is the pinned Debian 12 image plus Zig 0.14.1,
|
||||
covering all nine GNU Linux, musl Linux, Windows and macOS targets. musl uses
|
||||
checksum-locked target sysroots inside the same Debian image.
|
||||
|
||||
Read [CROSS-COMPILE.md](CROSS-COMPILE.md) for current build commands, exact local
|
||||
validation scope and remaining Docker/runtime/NativeAOT verification. Read
|
||||
[DAILY-RELEASE.md](../../DAILY-RELEASE.md) for daily 3/4 release configuration.
|
||||
|
||||
`Dockerfile` pins the base digest, apt snapshot and source-preparation tools.
|
||||
`Dockerfile.cross-probe` adds Zig, macOS SDK, Windows headers, target Linux SDKs
|
||||
and .NET SDKs. The historical filename is retained for existing references.
|
||||
`zig-toolchain-image.yml` reuses recipe-tagged GHCR images and downstream jobs
|
||||
pull their immutable digest. Source locks and archive/link manifests provide
|
||||
traceability. No complete local Docker image build has been run.
|
||||
|
||||
Legacy platform helper scripts are retained for reference; production graphics
|
||||
Actions now delegate to the common Zig cross-build workflow. SkiaSharp 2 remains
|
||||
outside the new daily tracks.
|
||||
@@ -0,0 +1,23 @@
|
||||
target_os = "linux"
|
||||
target_cpu = "@CPU@"
|
||||
is_debug = false
|
||||
is_component_build = false
|
||||
is_clang = true
|
||||
treat_warnings_as_errors = false
|
||||
use_custom_libcxx = false
|
||||
use_custom_libcxx_for_host = false
|
||||
use_sysroot = false
|
||||
use_lld = false
|
||||
use_thin_lto = false
|
||||
symbol_level = 0
|
||||
angle_build_tests = false
|
||||
build_angle_deqp_tests = false
|
||||
angle_enable_swiftshader = false
|
||||
angle_enable_vulkan = false
|
||||
angle_enable_wgpu = false
|
||||
clang_use_chrome_plugins = false
|
||||
enable_rust = false
|
||||
clang_version = "19"
|
||||
|
||||
# Chromium UI/ATK is not part of the standalone ANGLE library targets.
|
||||
use_glib = false
|
||||
@@ -0,0 +1,21 @@
|
||||
target_os = "mac"
|
||||
target_cpu = "@CPU@"
|
||||
is_debug = false
|
||||
is_component_build = false
|
||||
is_clang = true
|
||||
treat_warnings_as_errors = false
|
||||
use_custom_libcxx = false
|
||||
use_custom_libcxx_for_host = false
|
||||
use_sysroot = false
|
||||
use_lld = false
|
||||
use_thin_lto = false
|
||||
symbol_level = 0
|
||||
angle_build_tests = false
|
||||
build_angle_deqp_tests = false
|
||||
angle_enable_swiftshader = false
|
||||
angle_enable_vulkan = false
|
||||
angle_enable_wgpu = false
|
||||
clang_use_chrome_plugins = false
|
||||
enable_rust = false
|
||||
use_system_xcode = true
|
||||
clang_version = "19"
|
||||
@@ -0,0 +1,25 @@
|
||||
target_os = "win"
|
||||
target_cpu = "@CPU@"
|
||||
is_debug = false
|
||||
is_component_build = false
|
||||
is_clang = true
|
||||
treat_warnings_as_errors = false
|
||||
use_custom_libcxx = false
|
||||
use_custom_libcxx_for_host = false
|
||||
use_sysroot = false
|
||||
use_lld = false
|
||||
use_thin_lto = false
|
||||
symbol_level = 0
|
||||
angle_build_tests = false
|
||||
build_angle_deqp_tests = false
|
||||
angle_enable_swiftshader = false
|
||||
angle_enable_vulkan = false
|
||||
angle_enable_wgpu = false
|
||||
clang_use_chrome_plugins = false
|
||||
enable_rust = false
|
||||
|
||||
visual_studio_version = "2022"
|
||||
windows_sdk_version = "10.0.22621.0"
|
||||
clang_version = "19"
|
||||
use_clang_modules = false
|
||||
angle_copy_compiler_dll = false
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build Avalonia's pinned macOS native sources with Zig on Linux."""
|
||||
import argparse,subprocess,re,json,os,hashlib
|
||||
from pathlib import Path
|
||||
p=argparse.ArgumentParser();p.add_argument('--source',type=Path,required=True);p.add_argument('--rid',choices=['osx-x64','osx-arm64'],required=True);p.add_argument('--sdk',type=Path,required=True);p.add_argument('--zig',default='zig');p.add_argument('--output',type=Path,required=True);p.add_argument('--work',type=Path,required=True);a=p.parse_args()
|
||||
a.source=a.source.resolve();a.output=a.output.resolve();a.work=a.work.resolve();a.output.mkdir(parents=True,exist_ok=True);a.work.mkdir(parents=True,exist_ok=True)
|
||||
repo=Path(__file__).resolve().parents[2]
|
||||
tools=a.work/'tools'
|
||||
subprocess.run(['python3',str(repo/'build/linux-toolchain/zig-cross.py'),'--zig',a.zig,'--target',a.rid,'--sdk',str(a.sdk),'--output',str(tools)],check=True)
|
||||
descriptor=tools/'toolchain.json'
|
||||
config=json.loads(descriptor.read_text());config['target']=config['target'].split('-macos.')[0]+'-macos.12.0.0';descriptor.write_text(json.dumps(config,indent=2)+'\n')
|
||||
native=a.source/'native/Avalonia.Native';project=native/'src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj'
|
||||
headers=native/'inc'
|
||||
if not (headers/'avalonia-native.h').is_file():
|
||||
header_project=native/'Avalonia.Native.macOS.proj'
|
||||
if header_project.is_file():
|
||||
subprocess.run(['dotnet','build',str(header_project),'-t:GenerateMicroComItems'],cwd=a.source,check=True)
|
||||
else:
|
||||
subprocess.run(['bash',str(native/'generate-headers.sh')],cwd=a.source,check=True)
|
||||
# Match the authoritative Xcode Sources build phases, rather than guessing every .mm in the repo.
|
||||
project_text=project.read_text()
|
||||
names=set(re.findall(r'/\* (.+?\.(?:mm|m|cpp|cc|c)) in Sources \*/',project_text))
|
||||
file_flags={}
|
||||
for name,flags in re.findall(r'/\* (.+?\.(?:mm|m|cpp|cc|c)) in Sources \*/[^\n]*COMPILER_FLAGS = \"([^\"]+)\"',project_text):
|
||||
import shlex
|
||||
file_flags[name]=shlex.split(flags)
|
||||
if not names:raise SystemExit('No authoritative Xcode source list found')
|
||||
objects=[];source_hashes={}
|
||||
for name in sorted(names):
|
||||
matches=list(native.rglob(name))
|
||||
if len(matches)!=1:raise SystemExit('Ambiguous or missing Xcode source '+name+': '+str(matches))
|
||||
source=matches[0];obj=a.work/(hashlib.sha256(str(source.relative_to(native)).encode()).hexdigest()+'.o')
|
||||
command=[str(tools/('cc' if source.suffix in ('.c','.m') else 'cxx')),'-O2','-fPIC','-fblocks','-mmacosx-version-min=12.0','-I'+str(headers),'-I'+str(native/'src/OSX'),'-I'+str(native/'src'),'-c',str(source),'-o',str(obj)]
|
||||
if source.suffix in ('.mm','.m'):command+=['-fobjc-arc']
|
||||
if source.suffix in ('.mm','.cpp','.cc'):command+=['-std=c++17']
|
||||
command+=file_flags.get(name,[])
|
||||
subprocess.run(command,check=True);objects.append(obj);source_hashes[str(source.relative_to(native))]=hashlib.sha256(source.read_bytes()).hexdigest()
|
||||
subprocess.run([str(tools/'ar'),'rcs',str(a.output/'libAvaloniaNative.a'),*map(str,objects)],check=True)
|
||||
# The macOS font pre-initializer is compiled by the same cross compiler.
|
||||
env=dict(os.environ,RID=a.rid,OUTPUT_DIR=str(a.output),CC=str(tools/'cc'),STATICLINK_ZIG_CROSS='1')
|
||||
subprocess.run(['bash',str(repo/'scripts/build-macos-font-preinit.sh')],env=env,check=True)
|
||||
commit=subprocess.check_output(['git','-C',str(a.source),'rev-parse','HEAD'],text=True).strip()
|
||||
(a.output/'avalonia-native-build.json').write_text(json.dumps({'source_commit':commit,'rid':a.rid,'toolchain':json.loads((tools/'toolchain.json').read_text()),'sources':source_hashes,'validation':'compiled archive; macOS AOT/runtime validation runs separately'},indent=2)+'\n')
|
||||
@@ -0,0 +1,242 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build pinned, already dependency-synced SkiaSharp/ANGLE sources from Linux."""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import platform
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from skia_compat import archive, configure, parse_args, repair_xps, repair_skcms
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
|
||||
|
||||
def run(args, cwd=None, env=None):
|
||||
print('+', ' '.join(map(str, args)), flush=True)
|
||||
subprocess.run(list(map(str, args)), cwd=cwd, env=env, check=True)
|
||||
|
||||
|
||||
def patch(source, filename):
|
||||
path = HERE / 'patches' / filename
|
||||
cmd = ['git', '-C', str(source), 'apply']
|
||||
if subprocess.run(cmd + ['--reverse', '--check', str(path)], capture_output=True).returncode == 0:
|
||||
return
|
||||
run(cmd + ['--check', path])
|
||||
run(cmd + [path])
|
||||
|
||||
|
||||
def main():
|
||||
p = argparse.ArgumentParser(description=__doc__)
|
||||
p.add_argument('--target', choices=['linux-x64', 'linux-arm64', 'linux-musl-x64', 'linux-musl-arm64', 'win-x64', 'win-x86', 'win-arm64', 'osx-x64', 'osx-arm64'], required=True)
|
||||
p.add_argument('--sources-manifest', type=Path, help='cross-sources.json from prepare-cross-sources.sh')
|
||||
p.add_argument('--source-lock', type=Path, help='Exact version profile; defaults to sources.lock.json')
|
||||
p.add_argument('--skia', type=Path, help='SkiaSharp externals/skia, with its pinned dependencies synced')
|
||||
p.add_argument('--angle', type=Path, help='ANGLE source with pinned DEPS synced, including tools/win')
|
||||
p.add_argument('--angle-gn', type=Path, help='GN from the pinned ANGLE DEPS')
|
||||
p.add_argument('--zig', default='zig')
|
||||
p.add_argument('--sdk', type=Path, default=Path('/opt/macos-sdk/MacOSX15.5.sdk'))
|
||||
p.add_argument('--mingw-headers', type=Path, default=Path('/opt/mingw/usr/share/mingw-w64/include'))
|
||||
p.add_argument('--availability-source', type=Path, default=Path('/opt/staticlink/os_version_check.c'))
|
||||
p.add_argument('--linux-sysroots', type=Path, default=Path('/opt/sysroots'))
|
||||
p.add_argument('--linux-headers', type=Path, default=Path('/opt/staticlink/linux-headers'))
|
||||
p.add_argument('--work', type=Path, required=True)
|
||||
p.add_argument('--output', type=Path, required=True)
|
||||
p.add_argument('--jobs', type=int, default=4)
|
||||
p.add_argument('--configure-only', action='store_true')
|
||||
p.add_argument('--component', choices=['all', 'skia'], default='all', help='Build Skia alone when validating a new SkiaSharp release')
|
||||
a = p.parse_args()
|
||||
if a.sources_manifest:
|
||||
sources = json.loads(a.sources_manifest.read_text())
|
||||
if a.source_lock is None and sources.get('source_lock'):
|
||||
a.source_lock = Path(sources['source_lock'])
|
||||
for name in ('skia', 'angle', 'angle_gn'):
|
||||
if getattr(a, name) is None:
|
||||
setattr(a, name, Path(sources[name]))
|
||||
if any(getattr(a, name) is None for name in ('skia', 'angle', 'angle_gn')):
|
||||
p.error('Provide --sources-manifest or all of --skia, --angle and --angle-gn')
|
||||
if platform.system() != 'Linux' or a.jobs < 1:
|
||||
p.error('Requires Linux and positive --jobs')
|
||||
for name in ('skia', 'angle', 'angle_gn', 'sdk', 'work', 'output', 'availability_source', 'mingw_headers'):
|
||||
setattr(a, name, getattr(a, name).resolve())
|
||||
lock = json.loads((a.source_lock or HERE / 'sources.lock.json').read_text())
|
||||
for src, key in ((a.skia, 'skia_revision'), (a.angle, 'angle_revision')):
|
||||
revision = subprocess.check_output(['git', '-C', str(src), 'rev-parse', 'HEAD'], text=True).strip()
|
||||
if revision != lock[key]:
|
||||
raise SystemExit(f'{src}: expected {lock[key]}, got {revision}; update the lock and revalidate first')
|
||||
if 'skiasharp_build("SkiaSharp")' not in (a.skia / 'BUILD.gn').read_text():
|
||||
raise SystemExit('--skia must be the SkiaSharp-patched Skia source, not vanilla Google Skia')
|
||||
a.work.mkdir(parents=True, exist_ok=True)
|
||||
a.output.mkdir(parents=True, exist_ok=True)
|
||||
windows = a.target.startswith('win')
|
||||
mac = a.target.startswith('osx')
|
||||
linux = a.target.startswith('linux')
|
||||
cpu = a.target.rsplit('-', 1)[1]
|
||||
os_name = 'win' if windows else ('mac' if mac else 'linux')
|
||||
if windows and not (a.mingw_headers / 'windows.ui.composition.h').is_file():
|
||||
raise SystemExit('Windows ANGLE requires --mingw-headers containing the pinned WinRT headers')
|
||||
recipe = hashlib.sha256()
|
||||
for path in sorted(HERE.rglob('*')):
|
||||
if path.is_file() and (path.suffix in ('.py', '.in', '.patch', '.c') or path.name in ('cross-toolchain.lock.json', 'linux-sysroots.lock.json', 'linux-sysroots-musl.lock.json')):
|
||||
recipe.update(str(path.relative_to(HERE)).encode())
|
||||
recipe.update(path.read_bytes())
|
||||
variant = hashlib.sha256((json.dumps(lock, sort_keys=True) + recipe.hexdigest()).encode()).hexdigest()[:16]
|
||||
shared = {'angle_revision': lock['angle_revision'], 'recipe': recipe.hexdigest(), 'toolchain': json.loads((HERE / 'cross-toolchain.lock.json').read_text())}
|
||||
angle_variant = hashlib.sha256(json.dumps(shared, sort_keys=True).encode()).hexdigest()[:16]
|
||||
tools = a.work / angle_variant / a.target
|
||||
host_cpu = 'arm64' if platform.machine() == 'aarch64' else 'x64'
|
||||
host_tools = a.work / angle_variant / ('linux-' + host_cpu)
|
||||
for target, output in ((a.target, tools), ('linux-' + host_cpu, host_tools)):
|
||||
command = [sys.executable, HERE / 'zig-cross.py', '--zig', a.zig, '--target', target,
|
||||
'--output', output, '--sdk', a.sdk, '--mingw-headers', a.mingw_headers]
|
||||
if target.startswith('linux'):
|
||||
command += ['--linux-sysroot', a.linux_sysroots / target, '--linux-headers', a.linux_headers]
|
||||
run(command)
|
||||
config = json.loads((tools / 'toolchain.json').read_text())
|
||||
zig = config['zig']
|
||||
zig_lib = Path(json.loads(subprocess.check_output([zig, 'env'], text=True))['lib_dir'])
|
||||
print('skcms Clang compatibility:', repair_skcms(a.skia), flush=True)
|
||||
if windows:
|
||||
print('XPS compatibility:', repair_xps(a.skia), flush=True)
|
||||
# First apply the project's static ANGLE target patch if necessary.
|
||||
if 'angle_static_library("libANGLE_static")' not in (a.angle / 'BUILD.gn').read_text():
|
||||
patch(a.angle, 'angle-static-targets.patch')
|
||||
for filename in ('BUILDCONFIG.gn-zig.patch', 'BUILD.gn-zig.patch',
|
||||
'sdk_info-linux.patch', 'find_sdk-linux.patch', 'gcc-toolchain-objc.patch'):
|
||||
patch(a.angle, filename)
|
||||
run([sys.executable, a.angle / 'build/util/lastchange.py', '-o', a.angle / 'build/util/LASTCHANGE'], cwd=a.angle)
|
||||
# Separate runtime paths prevent architectures from sharing an incompatible cache.
|
||||
clang = tools / 'clang'
|
||||
runtime = clang / 'lib/clang/19/lib' / ('windows' if windows else ('darwin' if mac else 'linux')) / (
|
||||
'clang_rt.builtins-' + {'x64': 'x86_64', 'x86': 'i386', 'arm64': 'aarch64'}[cpu] + '.lib'
|
||||
if windows else ('libclang_rt.osx.a' if mac else 'libclang_rt.builtins-' + ('x86_64' if cpu == 'x64' else 'aarch64') + '.a'))
|
||||
runtime.parent.mkdir(parents=True, exist_ok=True)
|
||||
run([zig, 'build-lib', zig_lib / 'compiler_rt.zig', '-target', config['target'],
|
||||
'-O', 'ReleaseFast', '-fPIC', '-femit-bin=' + str(runtime)])
|
||||
if linux:
|
||||
for runtime_cpu, runtime_target in ((cpu, config['target']), (host_cpu, json.loads((host_tools / 'toolchain.json').read_text())['target'])):
|
||||
triple = 'x86_64-unknown-linux-gnu' if runtime_cpu == 'x64' else 'aarch64-unknown-linux-gnu'
|
||||
alias = clang / 'lib/clang/19/lib' / triple / 'libclang_rt.builtins.a'
|
||||
alias.parent.mkdir(parents=True, exist_ok=True)
|
||||
run([zig, 'build-lib', zig_lib / 'compiler_rt.zig', '-target', runtime_target,
|
||||
'-O', 'ReleaseFast', '-fPIC', '-femit-bin=' + str(alias)])
|
||||
availability = None
|
||||
if mac:
|
||||
if hashlib.sha256(a.availability_source.read_bytes()).hexdigest() != 'bc0b9f10e8d1a1ac5905d710f1c9fead23878e31233748d580393edc4e3bfc18':
|
||||
raise SystemExit('LLVM availability source checksum mismatch')
|
||||
availability = tools / 'os_version_check.o'
|
||||
run([tools / 'cc', '-c', a.availability_source, '-o', availability])
|
||||
run([tools / 'ar', 'rcs', runtime, availability])
|
||||
env = os.environ.copy()
|
||||
env['PATH'] = str(tools) + os.pathsep + env['PATH']
|
||||
env['CCACHE_BASEDIR'] = str(a.skia)
|
||||
env['CCACHE_NOHASHDIR'] = 'true'
|
||||
env['CCACHE_COMPILERCHECK'] = 'content'
|
||||
env['STATICLINK_MACOS_SDK'] = str(a.sdk)
|
||||
env['STATICLINK_DARWIN_TOOLS'] = str(tools)
|
||||
skia_out = a.skia / 'out' / ('staticlink-zig-' + a.target + '-' + variant)
|
||||
angle_out = a.angle / 'out' / ('staticlink-zig-' + a.target + '-' + angle_variant)
|
||||
for out in (skia_out, angle_out):
|
||||
out.mkdir(parents=True, exist_ok=True)
|
||||
skia_args = (HERE / ('skia-' + os_name + '.gn.in')).read_text().replace('@CPU@', cpu)
|
||||
if mac:
|
||||
skia_args += f'min_macos_version = "{"11.0" if cpu == "arm64" else "10.13"}"\n'
|
||||
skia_args += f'xcode_sysroot = {json.dumps(str(a.sdk))}\n'
|
||||
for name in ('cc', 'cxx', 'ar'):
|
||||
skia_args += name + ' = ' + json.dumps(str(tools / name)) + '\n'
|
||||
if linux:
|
||||
for key in ('cc', 'cxx', 'ar'):
|
||||
skia_args = skia_args.replace('@' + key.upper() + '@', str(tools / key))
|
||||
capabilities = configure(a.skia, skia_out, parse_args(skia_args), a.skia / 'bin/gn', env)
|
||||
for target in ('skia', 'SkiaSharp', 'HarfBuzzSharp'):
|
||||
description = json.loads(subprocess.check_output([str(a.skia / 'bin/gn'), 'desc', str(skia_out.relative_to(a.skia)),
|
||||
'//:' + target, '--format=json'], cwd=a.skia, env=env, text=True))
|
||||
kind = next(iter(description.values()))['type']
|
||||
if kind != 'static_library':
|
||||
raise SystemExit(f'{target} is {kind}; expected static_library')
|
||||
if windows:
|
||||
# Upstream Skia fixes Windows to the MSVC rules; retain its graph and
|
||||
# replace compiler/archive commands explicitly with the GNU adapters.
|
||||
path = skia_out / 'toolchain.ninja'
|
||||
body = path.read_text()
|
||||
index = body.index('subninja ')
|
||||
rules = ''
|
||||
for name, flags in (('cc', 'cflags_c'), ('cxx', 'cflags_cc')):
|
||||
rules += f'rule {name}\n command = {tools / name} -MD -MF ${{out}}.d ${{defines}} ${{include_dirs}} ${{cflags}} ${{{flags}}} -c ${{in}} -o ${{out}}\n depfile = ${{out}}.d\n deps = gcc\n'
|
||||
rules += f'rule alink\n command = {tools / "ar"} rcs ${{out}} @${{out}}.rsp\n rspfile = ${{out}}.rsp\n rspfile_content = ${{in_newline}}\n'
|
||||
rules += 'rule stamp\n command = touch ${out}\nrule copy\n command = cp ${in} ${out}\nrule asm\n command = false\n'
|
||||
path.write_text(rules + '\n' + body[index:])
|
||||
sdk_link = angle_out / 'sdk/xcode_links/MacOSX15.5.sdk'
|
||||
if mac:
|
||||
sdk_link.parent.mkdir(parents=True, exist_ok=True)
|
||||
if sdk_link.is_symlink():
|
||||
sdk_link.unlink()
|
||||
sdk_link.symlink_to(a.sdk)
|
||||
# Each architecture gets an independent toolchain file; concurrent builds
|
||||
# do not rewrite another target's generated GN toolchain.
|
||||
toolchain_dir = a.angle / ('staticlink_zig_' + a.target.replace('-', '_') + '_' + angle_variant)
|
||||
toolchain_dir.mkdir(exist_ok=True)
|
||||
text = 'import("//build/toolchain/gcc_toolchain.gni")\n'
|
||||
for name, folder, target_os, target_cpu in (('target', tools, os_name, cpu), ('host', host_tools, 'linux', host_cpu)):
|
||||
text += f'gcc_toolchain("{name}") {{\n'
|
||||
for var in ('cc', 'cxx', 'ar'):
|
||||
text += ' ' + var + ' = ' + json.dumps(str(folder / var)) + '\n'
|
||||
text += f' ld = cxx\n nm = "nm"\n readelf = "readelf"\n toolchain_args = {{ current_os = "{target_os}" current_cpu = "{target_cpu}" is_clang = true use_remoteexec = false }}\n}}\n'
|
||||
(toolchain_dir / 'BUILD.gn').write_text(text)
|
||||
angle_args = (HERE / ('angle-' + os_name + '.gn.in')).read_text().replace('@CPU@', cpu)
|
||||
angle_args += f'custom_toolchain = "//{toolchain_dir.name}:target"\nhost_toolchain = "//{toolchain_dir.name}:host"\n'
|
||||
angle_args += 'clang_base_path = ' + json.dumps(str(clang)) + '\n'
|
||||
if linux:
|
||||
angle_args += 'pkg_config = ' + json.dumps(str(tools / 'pkg-config')) + '\n'
|
||||
angle_args += 'host_pkg_config = ' + json.dumps(str(host_tools / 'pkg-config')) + '\n'
|
||||
if windows:
|
||||
# These mandatory GN metadata paths refer to the real MinGW headers.
|
||||
# The SDK/version strings satisfy GN; MSVC/Windows SDK are not used.
|
||||
for name, path in (('visual_studio_path', Path(zig).parent), ('wdk_path', Path(zig).parent),
|
||||
('windows_sdk_path', zig_lib / 'libc/include/any-windows-any')):
|
||||
angle_args += name + ' = ' + json.dumps(str(path)) + '\n'
|
||||
(angle_out / 'args.gn').write_text(angle_args)
|
||||
run([a.angle_gn, 'gen', angle_out.relative_to(a.angle)], cwd=a.angle, env=env)
|
||||
if a.configure_only:
|
||||
print(f'Configured {lock["skiasharp_version"]} {a.target}: all three Skia targets are static libraries')
|
||||
return
|
||||
run(['ninja', '-C', skia_out, '-j', a.jobs, 'skia', 'SkiaSharp', 'HarfBuzzSharp'], env=env)
|
||||
if a.component == 'all':
|
||||
run(['ninja', '-C', angle_out, '-j', a.jobs, 'libANGLE_static', 'libGLESv2_static', 'libEGL_static'], env=env)
|
||||
if availability:
|
||||
run([tools / 'ar', 'rcs', archive(skia_out, 'skia'), availability])
|
||||
files = [(archive(skia_out, name), name)
|
||||
for name in ('skia', 'SkiaSharp', 'HarfBuzzSharp')]
|
||||
if a.component == 'all':
|
||||
files += [(angle_out / ('obj/lib' + name + '_static.a'), name) for name in ('ANGLE', 'GLESv2', 'EGL')]
|
||||
manifest = dict(target=a.target, sources=lock, toolchain=config, archives={})
|
||||
manifest['build_variant'] = variant
|
||||
manifest['skia_capabilities'] = capabilities
|
||||
if linux:
|
||||
manifest['linux_sdk_packages'] = json.loads((HERE / ('linux-sysroots-musl.lock.json' if 'musl' in a.target else 'linux-sysroots.lock.json')).read_text())[a.target]
|
||||
manifest['toolchain_inputs'] = json.loads((HERE / 'cross-toolchain.lock.json').read_text())
|
||||
manifest['gn_sha256'] = {str(path): hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
for path in (a.skia / 'bin/gn', a.angle_gn)}
|
||||
manifest['recipe_sha256'] = {str(path.relative_to(HERE)): hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
for path in sorted(HERE.rglob('*')) if path.is_file() and (path.suffix in ('.py', '.in', '.patch', '.c') or path.name in ('cross-toolchain.lock.json', 'linux-sysroots.lock.json', 'linux-sysroots-musl.lock.json'))}
|
||||
packages = Path('/opt/staticlink/packages.lock')
|
||||
if packages.is_file():
|
||||
shutil.copy2(packages, a.output / 'toolchain-packages.lock')
|
||||
manifest['packages_sha256'] = hashlib.sha256(packages.read_bytes()).hexdigest()
|
||||
for source, name in files:
|
||||
dest = a.output / ('lib' + name + '.a')
|
||||
shutil.copy2(source, dest)
|
||||
manifest['archives'][dest.name] = hashlib.sha256(dest.read_bytes()).hexdigest()
|
||||
run([sys.executable, HERE / 'link-cross.py', '--toolchain', tools, '--skia', a.skia,
|
||||
'--angle', a.angle, '--libraries', a.output, '--output', a.output / 'link-tests', '--component', a.component])
|
||||
if a.target == 'win-x86':
|
||||
run([sys.executable, HERE / 'x86-thunks.py', '--source', a.skia.parent.parent,
|
||||
'--toolchain', tools, '--libraries', a.output])
|
||||
manifest['link_tests'] = 'passed; target runtime tests still required'
|
||||
(a.output / 'cross-build.json').write_text(json.dumps(manifest, indent=2) + '\n')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"zig_version": "0.14.1",
|
||||
"macos_sdk_version": "15.5",
|
||||
"macos_sdk_sha256": "c15cf0f3f17d714d1aa5a642da8e118db53d79429eb015771ba816aa7c6c1cbd",
|
||||
"mingw_headers_version": "11.0.1-3build1",
|
||||
"mingw_package_sha256": "4a42fd30fbc3838c58c929d8a4882682fc12408bb7a0e6cafa913c0f0a57c187",
|
||||
"llvm_availability_revision": "llvmorg-19.1.7",
|
||||
"llvm_availability_sha256": "bc0b9f10e8d1a1ac5905d710f1c9fead23878e31233748d580393edc4e3bfc18",
|
||||
"angle_gn_revision": "e331ddb6e93389abfc75c611690bb82f5274029e"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Materialize target SDK libraries from immutable, checksum-locked packages."""
|
||||
import argparse,json,hashlib,urllib.request,tarfile,subprocess
|
||||
from pathlib import Path
|
||||
p=argparse.ArgumentParser();p.add_argument('--output',type=Path,required=True);p.add_argument('--locks',type=Path,nargs='+',required=True);a=p.parse_args()
|
||||
for lock in a.locks:
|
||||
for rid,packages in json.loads(lock.read_text()).items():
|
||||
dest=a.output/rid;dest.mkdir(parents=True,exist_ok=True)
|
||||
for package in packages:
|
||||
with urllib.request.urlopen(package['url'],timeout=90) as response:data=response.read()
|
||||
if hashlib.sha256(data).hexdigest()!=package['sha256']:raise SystemExit('SDK checksum mismatch: '+package['name'])
|
||||
path=a.output/(rid+'-'+Path(package['url']).name);path.write_bytes(data)
|
||||
if path.suffix=='.deb':subprocess.run(['dpkg-deb','--extract',str(path),str(dest)],check=True)
|
||||
else:
|
||||
with tarfile.open(path,mode='r:gz',ignore_zeros=True) as tar:
|
||||
members=[m for m in tar.getmembers() if m.name.startswith(('lib/','usr/lib/','usr/include/','etc/fonts/'))]
|
||||
for m in members:
|
||||
if m.issym() and m.linkname.startswith('/'):
|
||||
import posixpath
|
||||
m.linkname=posixpath.relpath(m.linkname.lstrip('/'),posixpath.dirname(m.name))
|
||||
# Debian 12's pinned Python 3.11 has no extraction-filter API.
|
||||
# Validate paths and links explicitly before extracting locked APK files.
|
||||
root=dest.resolve()
|
||||
for m in members:
|
||||
target=(root/m.name).resolve()
|
||||
if not target.is_relative_to(root):raise SystemExit('Unsafe SDK archive path: '+m.name)
|
||||
if not (m.isfile() or m.isdir() or m.issym() or m.islnk()):raise SystemExit('Unsupported SDK archive entry: '+m.name)
|
||||
if m.issym() or m.islnk():
|
||||
link=(target.parent/m.linkname if m.issym() else root/m.linkname).resolve()
|
||||
if not link.is_relative_to(root):raise SystemExit('Unsafe SDK archive link: '+m.name)
|
||||
tar.extractall(dest,members=members)
|
||||
path.unlink()
|
||||
print(rid,package['name'],package['version'],flush=True)
|
||||
# Copy only platform headers; never replace Zig's target libc headers with the host's.
|
||||
import shutil
|
||||
headers=a.output.parent/'staticlink/linux-headers';headers.mkdir(parents=True,exist_ok=True)
|
||||
for name in ('fontconfig','X11','xcb','GL','KHR','EGL','freetype2','libdrm'):
|
||||
src=a.output/'linux-x64/usr/include'/name
|
||||
if src.is_dir():shutil.copytree(src,headers/name,dirs_exist_ok=True,symlinks=True)
|
||||
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Link raster/HarfBuzz and EGL/GLES executables against cross-built archives."""
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
|
||||
|
||||
def main():
|
||||
p = argparse.ArgumentParser(description=__doc__)
|
||||
p.add_argument('--toolchain', type=Path, required=True)
|
||||
p.add_argument('--skia', type=Path, required=True)
|
||||
p.add_argument('--angle', type=Path, required=True)
|
||||
p.add_argument('--libraries', type=Path, required=True)
|
||||
p.add_argument('--output', type=Path, required=True)
|
||||
p.add_argument('--component', choices=['all', 'skia'], default='all')
|
||||
a = p.parse_args()
|
||||
config = json.loads((a.toolchain / 'toolchain.json').read_text())
|
||||
windows = 'windows' in config['target']
|
||||
a.output.mkdir(parents=True, exist_ok=True)
|
||||
target = config['target']
|
||||
flags = []
|
||||
mac = 'macos' in target
|
||||
linux = 'linux' in target
|
||||
if mac:
|
||||
# ANGLE's pinned Chromium build has a macOS 13 deployment minimum.
|
||||
target = target.split('-macos.')[0] + '-macos.13.0'
|
||||
sdk = config['sdk']
|
||||
flags = ['-isysroot', sdk, '-L' + sdk + '/usr/lib', '-F' + sdk + '/System/Library/Frameworks']
|
||||
for name in (('raster', 'angle') if a.component == 'all' else ('raster',)):
|
||||
obj = a.output / ('smoke-' + name + '.o')
|
||||
includes = [a.skia, a.skia / 'third_party/externals/harfbuzz/src', a.angle / 'include']
|
||||
command = [str(a.toolchain / 'cc')]
|
||||
if name == 'angle':
|
||||
command.extend(('-DANGLE_STATIC=1', '-DKHRONOS_STATIC'))
|
||||
else:
|
||||
header = (a.skia / 'include/core/SkMilestone.h').read_text()
|
||||
match = re.search(r'^\s*#define\s+SK_MILESTONE\s+(\d+)', header, re.MULTILINE)
|
||||
if not match:
|
||||
raise SystemExit('Cannot discover the Skia milestone; inspect the new source layout')
|
||||
command.append('-DSTATICLINK_EXPECTED_MILESTONE=' + match[1])
|
||||
command += ['-I' + str(path) for path in includes]
|
||||
command += ['-c', str(HERE / ('smoke-' + name + '.c')), '-o', str(obj)]
|
||||
subprocess.run(command, check=True)
|
||||
libs = ('SkiaSharp', 'skia', 'HarfBuzzSharp') if name == 'raster' else ('EGL', 'GLESv2', 'ANGLE')
|
||||
command = [config['zig'], 'c++', '-target', target, '-O2', *flags, str(obj)]
|
||||
command += [str(a.libraries / ('lib' + library + '.a')) for library in libs]
|
||||
if windows:
|
||||
command += ['-l' + lib for lib in ('dwrite', 'gdi32', 'ole32', 'oleaut32', 'user32', 'uuid',
|
||||
'windowscodecs', 'dxguid', 'dxgi', 'd3d11', 'd3d9', 'dwmapi', 'shlwapi', 'setupapi', 'version', 'advapi32', 'api-ms-win-core-synch-l1-2-0')]
|
||||
elif mac:
|
||||
for framework in ('CoreFoundation', 'CoreGraphics', 'CoreText', 'Foundation', 'AppKit',
|
||||
'Metal', 'QuartzCore', 'OpenGL', 'IOKit', 'IOSurface'):
|
||||
command += ['-framework', framework]
|
||||
command += ['-lobjc']
|
||||
availability = a.toolchain / 'os_version_check.o'
|
||||
if availability.is_file():
|
||||
command.append(str(availability))
|
||||
elif linux:
|
||||
sysroot = Path(config.get('linux_sysroot') or '/')
|
||||
for path in (sysroot / 'usr/lib', sysroot / 'lib', sysroot / 'usr/lib' / ('x86_64-linux-gnu' if target.startswith('x86_64') else 'aarch64-linux-gnu')):
|
||||
if path.is_dir():
|
||||
command += ['-L' + str(path)]
|
||||
command += ['-lfontconfig', '-ldl', '-lm', '-lpthread'] if name == 'raster' else ['-lX11', '-lXext', '-lxcb', '-lwayland-client', '-lwayland-egl', '-lffi', '-ldl', '-lm', '-lpthread']
|
||||
command += ['-v']
|
||||
command += ['-o', str(a.output / ('smoke-' + name + ('.exe' if windows else '')))]
|
||||
result = subprocess.run(command, capture_output=True, text=True)
|
||||
print(result.stdout, end='')
|
||||
print(result.stderr, end='')
|
||||
result.check_returncode()
|
||||
# Keep the exact runtime archives chosen by this Zig target. AOT consumes
|
||||
# these without substituting the consumer machine's C++ toolchain.
|
||||
import shlex, shutil
|
||||
runtimes = {}
|
||||
project_archives = {path.resolve() for path in a.libraries.glob('lib*.a')}
|
||||
for line in (result.stdout + '\n' + result.stderr).splitlines():
|
||||
try:
|
||||
tokens = shlex.split(line)
|
||||
except ValueError:
|
||||
continue
|
||||
for token in tokens:
|
||||
path = Path(token)
|
||||
if path.suffix in ('.a', '.lib') and path.is_file() and path.resolve() not in project_archives and not path.resolve().is_relative_to(a.libraries.resolve()):
|
||||
dest = a.libraries / 'zig-runtime' / path.name
|
||||
dest.parent.mkdir(exist_ok=True)
|
||||
shutil.copy2(path, dest)
|
||||
runtimes[path.name] = str(path)
|
||||
descriptor = a.libraries / 'zig-runtime' / 'inputs.json'
|
||||
if descriptor.exists():
|
||||
runtimes = dict(json.loads(descriptor.read_text()), **runtimes)
|
||||
descriptor.parent.mkdir(exist_ok=True)
|
||||
descriptor.write_text(json.dumps(runtimes, indent=2) + '\n')
|
||||
print('Executable link tests passed. Run them on the target OS to validate behavior.')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,474 @@
|
||||
{
|
||||
"linux-musl-x64": [
|
||||
{
|
||||
"name": "brotli-dev",
|
||||
"version": "1.2.0-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/brotli-dev-1.2.0-r0.apk",
|
||||
"sha256": "f61bd37140c76a22e97ad9d7461becda5d41526bbee1a8bc2523edad5ae6f35e"
|
||||
},
|
||||
{
|
||||
"name": "brotli-libs",
|
||||
"version": "1.2.0-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/brotli-libs-1.2.0-r0.apk",
|
||||
"sha256": "09fbf1ddf0c71c6c4ab7bc12aef3452d8ace5adeab10c4c30214fc70f5e0e087"
|
||||
},
|
||||
{
|
||||
"name": "bzip2-dev",
|
||||
"version": "1.0.8-r6",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/bzip2-dev-1.0.8-r6.apk",
|
||||
"sha256": "59a73f8712a9c0c16553a759149ee5ecf87a6160ef021aeb922ddb0c0b3a695b"
|
||||
},
|
||||
{
|
||||
"name": "expat",
|
||||
"version": "2.8.5-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/expat-2.8.5-r0.apk",
|
||||
"sha256": "19f3d19d7deb82e357a70cb30b38dd81fa1cbecdb7e0a834071e993d5df18246"
|
||||
},
|
||||
{
|
||||
"name": "expat-dev",
|
||||
"version": "2.8.5-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/expat-dev-2.8.5-r0.apk",
|
||||
"sha256": "5a31977673fbdacf195d372114501c06b18eb1f24553c99b92e47e0e24478f9e"
|
||||
},
|
||||
{
|
||||
"name": "fontconfig",
|
||||
"version": "2.17.1-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/fontconfig-2.17.1-r0.apk",
|
||||
"sha256": "f44cea53076f18428dad0c27c75ca717ebfc3d2f0f4c8d4428ce70b62e25adf1"
|
||||
},
|
||||
{
|
||||
"name": "fontconfig-dev",
|
||||
"version": "2.17.1-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/fontconfig-dev-2.17.1-r0.apk",
|
||||
"sha256": "e819dd0eb3f2a2a4f802a16911959e1232b323c4e2db9ce020c3d52e9bfd5053"
|
||||
},
|
||||
{
|
||||
"name": "freetype",
|
||||
"version": "2.14.3-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/freetype-2.14.3-r0.apk",
|
||||
"sha256": "670c9922ab4eb9df65c0e4ad7839bbe3f486016fc1fb637c46d657b74d99a24f"
|
||||
},
|
||||
{
|
||||
"name": "freetype-dev",
|
||||
"version": "2.14.3-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/freetype-dev-2.14.3-r0.apk",
|
||||
"sha256": "85a90244c039722c409996e5e5e65d4751664984ed1843a00c5d751577627972"
|
||||
},
|
||||
{
|
||||
"name": "libbsd",
|
||||
"version": "0.12.2-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libbsd-0.12.2-r0.apk",
|
||||
"sha256": "1252092dea853063252bbdaf9fa604819055b004ba3114b88b842fbfe44659e9"
|
||||
},
|
||||
{
|
||||
"name": "libbz2",
|
||||
"version": "1.0.8-r6",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libbz2-1.0.8-r6.apk",
|
||||
"sha256": "9995840a76ac97ec006259391b7a81b73b73c5cf2f462bf12bb2250afbf665b9"
|
||||
},
|
||||
{
|
||||
"name": "libexpat",
|
||||
"version": "2.8.5-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libexpat-2.8.5-r0.apk",
|
||||
"sha256": "5216046085b92da88a6b107dbbb558f69d49c347a6335291fcf199ebd1670a8f"
|
||||
},
|
||||
{
|
||||
"name": "libffi",
|
||||
"version": "3.5.2-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libffi-3.5.2-r0.apk",
|
||||
"sha256": "0b3473a1468bed5fbb913a1ffa121e253080b21b013fe47e0300bd7e85224e76"
|
||||
},
|
||||
{
|
||||
"name": "libffi-dev",
|
||||
"version": "3.5.2-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libffi-dev-3.5.2-r0.apk",
|
||||
"sha256": "737a9109fc4a763465cc117ca20edd18d4ea3fe9ed6f717251aa744b8ebbaba6"
|
||||
},
|
||||
{
|
||||
"name": "libmd",
|
||||
"version": "1.1.0-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libmd-1.1.0-r0.apk",
|
||||
"sha256": "704446100fb39f2699d848d97f09463dd6fdd35f3a1acb038483712e1e37f766"
|
||||
},
|
||||
{
|
||||
"name": "libpng",
|
||||
"version": "1.6.59-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libpng-1.6.59-r0.apk",
|
||||
"sha256": "148a10e3d6419f787b16edbc2d0bb19d12a2a078225baaa416c895c14f47fc1e"
|
||||
},
|
||||
{
|
||||
"name": "libpng-dev",
|
||||
"version": "1.6.59-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libpng-dev-1.6.59-r0.apk",
|
||||
"sha256": "01b89d3cea124fed78359b71f77e4d545de6e3163077167947e6adf84bdcb595"
|
||||
},
|
||||
{
|
||||
"name": "libx11",
|
||||
"version": "1.8.12-r1",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libx11-1.8.12-r1.apk",
|
||||
"sha256": "cbc478a642226812ab13688bfe9ec69c86cf0e8e037dba7cfd055e8d7741f30c"
|
||||
},
|
||||
{
|
||||
"name": "libx11-dev",
|
||||
"version": "1.8.12-r1",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libx11-dev-1.8.12-r1.apk",
|
||||
"sha256": "91eac12015dffbeb06b2755eae52722b1740018d775db33fbe68abc353b951df"
|
||||
},
|
||||
{
|
||||
"name": "libxau",
|
||||
"version": "1.0.12-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libxau-1.0.12-r0.apk",
|
||||
"sha256": "61ee983ec9d47821cae9b3e1c8245a5b0b228361839be9b596a42c817b691a9f"
|
||||
},
|
||||
{
|
||||
"name": "libxau-dev",
|
||||
"version": "1.0.12-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libxau-dev-1.0.12-r0.apk",
|
||||
"sha256": "2af8a78f1deaf398e96964f17d5640e3448fc5e935392e3550283e8d7c54a6cc"
|
||||
},
|
||||
{
|
||||
"name": "libxcb",
|
||||
"version": "1.17.0-r1",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libxcb-1.17.0-r1.apk",
|
||||
"sha256": "f73934506edfdcb6895f04e313481ca48592ac4cec59cdb8fc073a7681bfbd31"
|
||||
},
|
||||
{
|
||||
"name": "libxcb-dev",
|
||||
"version": "1.17.0-r1",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libxcb-dev-1.17.0-r1.apk",
|
||||
"sha256": "8735d97a346eae3999a599e49eb533481478d0ef9466e6e5a5453dd1e3ae8f3d"
|
||||
},
|
||||
{
|
||||
"name": "libxdmcp",
|
||||
"version": "1.1.5-r1",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libxdmcp-1.1.5-r1.apk",
|
||||
"sha256": "f134d28babb070834066aa716c303768ed0ede32ac086f3dfbd8cbbac62380ee"
|
||||
},
|
||||
{
|
||||
"name": "libxdmcp-dev",
|
||||
"version": "1.1.5-r1",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libxdmcp-dev-1.1.5-r1.apk",
|
||||
"sha256": "d8a304762ea4295287ef1adf9d93d64f04bdfc4e845b453698b3276b12e8fc10"
|
||||
},
|
||||
{
|
||||
"name": "libxext",
|
||||
"version": "1.3.6-r2",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libxext-1.3.6-r2.apk",
|
||||
"sha256": "404beb855daf09fdb8d15f177a3608da62825a44497a805675a186171c04eb6c"
|
||||
},
|
||||
{
|
||||
"name": "libxext-dev",
|
||||
"version": "1.3.6-r2",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libxext-dev-1.3.6-r2.apk",
|
||||
"sha256": "ebb6262372a918a6bee4ff2137dacdb1fa13be78d0e3544a082d6530ce8e05b6"
|
||||
},
|
||||
{
|
||||
"name": "libxml2",
|
||||
"version": "2.13.9-r1",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/libxml2-2.13.9-r1.apk",
|
||||
"sha256": "1af363248efb54914993bbd516c89878c2b5b0c53be0c78bb43d5a3e9a8ceda6"
|
||||
},
|
||||
{
|
||||
"name": "mesa-dev",
|
||||
"version": "25.2.7-r1",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/mesa-dev-25.2.7-r1.apk",
|
||||
"sha256": "da17f767ae27fc8ff9a958ff82d217ee3a890d888b43e6a62171a402b48156a1"
|
||||
},
|
||||
{
|
||||
"name": "musl",
|
||||
"version": "1.2.5-r23",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/musl-1.2.5-r23.apk",
|
||||
"sha256": "4f3c4a7bf9f51d2c91007e333b17459362ffd881b4a343e8da07b6c50c4f4a0d"
|
||||
},
|
||||
{
|
||||
"name": "wayland-dev",
|
||||
"version": "1.24.0-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/wayland-dev-1.24.0-r0.apk",
|
||||
"sha256": "5afcb3e3c414d2c0e602bc9ef1b4868fd7df9e53aec55f3f722ce4897019f014"
|
||||
},
|
||||
{
|
||||
"name": "wayland-libs-client",
|
||||
"version": "1.24.0-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/wayland-libs-client-1.24.0-r0.apk",
|
||||
"sha256": "020313c601f85a9e91d1ae0d01e9f1e9905d1127b78dce9c278a75cfd52416d2"
|
||||
},
|
||||
{
|
||||
"name": "wayland-libs-cursor",
|
||||
"version": "1.24.0-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/wayland-libs-cursor-1.24.0-r0.apk",
|
||||
"sha256": "e87fb03656132b550182b019b7f3218f336ff9637dc574ef0f22a0ad148f8577"
|
||||
},
|
||||
{
|
||||
"name": "wayland-libs-egl",
|
||||
"version": "1.24.0-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/wayland-libs-egl-1.24.0-r0.apk",
|
||||
"sha256": "2d9165a79e7e779b52dd203959f64eb8f7caad460f3e6d76097efc432e115936"
|
||||
},
|
||||
{
|
||||
"name": "wayland-libs-server",
|
||||
"version": "1.24.0-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/wayland-libs-server-1.24.0-r0.apk",
|
||||
"sha256": "c30fd5c6f081732670e7dd69316df73cb3939b8c53237314ca1ec3f991b2a1f7"
|
||||
},
|
||||
{
|
||||
"name": "xorgproto",
|
||||
"version": "2024.1-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/xorgproto-2024.1-r0.apk",
|
||||
"sha256": "96e2b99a0227d301170ae840c37693d65c767dd0a15a1243ced45325850ad424"
|
||||
},
|
||||
{
|
||||
"name": "xz-libs",
|
||||
"version": "5.8.4-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/xz-libs-5.8.4-r0.apk",
|
||||
"sha256": "3c8cc415e88c2a097543d9ee828081ec1905e7d0f57a319c8896269b0e00a672"
|
||||
},
|
||||
{
|
||||
"name": "zlib",
|
||||
"version": "1.3.2-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/zlib-1.3.2-r0.apk",
|
||||
"sha256": "f56dea63692059bd65854bb179b7551971a441000b0d98c5b031291ca0450b56"
|
||||
},
|
||||
{
|
||||
"name": "zlib-dev",
|
||||
"version": "1.3.2-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/x86_64/zlib-dev-1.3.2-r0.apk",
|
||||
"sha256": "c811e48ea401e05479a74d93f8ac820bbb6af44b2adf0335769316e5cc2b72c4"
|
||||
}
|
||||
],
|
||||
"linux-musl-arm64": [
|
||||
{
|
||||
"name": "brotli-dev",
|
||||
"version": "1.2.0-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/brotli-dev-1.2.0-r0.apk",
|
||||
"sha256": "012c9917e3a3f37efbb255fdff240d4fe0ee83a2e4e5d7511eddcce57a2daa30"
|
||||
},
|
||||
{
|
||||
"name": "brotli-libs",
|
||||
"version": "1.2.0-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/brotli-libs-1.2.0-r0.apk",
|
||||
"sha256": "c8a9113b0007d40291e55cfc196744b64004253707e37b3c07e188166fb2d0a0"
|
||||
},
|
||||
{
|
||||
"name": "bzip2-dev",
|
||||
"version": "1.0.8-r6",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/bzip2-dev-1.0.8-r6.apk",
|
||||
"sha256": "69d79bb497c25e81fce8695653f448666c08bc8b28fa51506b74b38946a0a03a"
|
||||
},
|
||||
{
|
||||
"name": "expat",
|
||||
"version": "2.8.5-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/expat-2.8.5-r0.apk",
|
||||
"sha256": "b5b520d2bd7a89e8fbad6a59667f70d4656326dd8a4df84c3e5ef4b5c0056243"
|
||||
},
|
||||
{
|
||||
"name": "expat-dev",
|
||||
"version": "2.8.5-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/expat-dev-2.8.5-r0.apk",
|
||||
"sha256": "2aad86f9f50aeb5b3c7a0e4022693dd810f51ec9c7a28037f3d2e71dbd9ecb1e"
|
||||
},
|
||||
{
|
||||
"name": "fontconfig",
|
||||
"version": "2.17.1-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/fontconfig-2.17.1-r0.apk",
|
||||
"sha256": "38e815b8f898482e3c8111ac158208ba0a6a9aa13dbef49ccc36b36df77c793e"
|
||||
},
|
||||
{
|
||||
"name": "fontconfig-dev",
|
||||
"version": "2.17.1-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/fontconfig-dev-2.17.1-r0.apk",
|
||||
"sha256": "5661ba91c9da743151b333a69b05f467f5c4145395f3d54567e7e9999aa8d842"
|
||||
},
|
||||
{
|
||||
"name": "freetype",
|
||||
"version": "2.14.3-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/freetype-2.14.3-r0.apk",
|
||||
"sha256": "b1012afa50bdebe872fab255b1c6db8c2c05b0dc4fc274c48d714e1887401b4e"
|
||||
},
|
||||
{
|
||||
"name": "freetype-dev",
|
||||
"version": "2.14.3-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/freetype-dev-2.14.3-r0.apk",
|
||||
"sha256": "cd8d91f81c9477f0f76fd8db8158237fa99b1e0f73f6ec6e929bfc46b076b51d"
|
||||
},
|
||||
{
|
||||
"name": "libbsd",
|
||||
"version": "0.12.2-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libbsd-0.12.2-r0.apk",
|
||||
"sha256": "358715f27bfe492dcb11f3589c8f106c37071780f55adafc52b2c5cfd3771e4d"
|
||||
},
|
||||
{
|
||||
"name": "libbz2",
|
||||
"version": "1.0.8-r6",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libbz2-1.0.8-r6.apk",
|
||||
"sha256": "ccd478f4d5346a25911d4ee977690e2695e0ca3acf3e6b1a8c1300b2f4311e2f"
|
||||
},
|
||||
{
|
||||
"name": "libexpat",
|
||||
"version": "2.8.5-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libexpat-2.8.5-r0.apk",
|
||||
"sha256": "18e5a4f1715dd9fee420d250d14be9e59936352929085939f33da01c3fbde28d"
|
||||
},
|
||||
{
|
||||
"name": "libffi",
|
||||
"version": "3.5.2-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libffi-3.5.2-r0.apk",
|
||||
"sha256": "ebf430b246a6b1167350431e2af59a09f4edbc42dc3e03f3b9d74800ba5f9e7f"
|
||||
},
|
||||
{
|
||||
"name": "libffi-dev",
|
||||
"version": "3.5.2-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libffi-dev-3.5.2-r0.apk",
|
||||
"sha256": "96830dcf534e196258838122fcaae6582ea02c957413a31e53a86ae403db0478"
|
||||
},
|
||||
{
|
||||
"name": "libmd",
|
||||
"version": "1.1.0-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libmd-1.1.0-r0.apk",
|
||||
"sha256": "8818536cdc38dd3c252d6c6915f65ddd49390aa209cc7f70b87c446adedf820c"
|
||||
},
|
||||
{
|
||||
"name": "libpng",
|
||||
"version": "1.6.59-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libpng-1.6.59-r0.apk",
|
||||
"sha256": "087102199da459dd8985c118a67d6d6c463de6798f243424feb239d1087b1064"
|
||||
},
|
||||
{
|
||||
"name": "libpng-dev",
|
||||
"version": "1.6.59-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libpng-dev-1.6.59-r0.apk",
|
||||
"sha256": "9f7a8ceb60638786dd675ccc526668516a8ca4df4b54daa05f526df12f76c7bd"
|
||||
},
|
||||
{
|
||||
"name": "libx11",
|
||||
"version": "1.8.12-r1",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libx11-1.8.12-r1.apk",
|
||||
"sha256": "7f53f6f26293abac468b9563f2a90bc9a34306ec8a677af23d01d7455e3db943"
|
||||
},
|
||||
{
|
||||
"name": "libx11-dev",
|
||||
"version": "1.8.12-r1",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libx11-dev-1.8.12-r1.apk",
|
||||
"sha256": "114785b13b6df10d7997e9e8e12bf95fd5f0e6644fd420fa84dcfc0956cdecb9"
|
||||
},
|
||||
{
|
||||
"name": "libxau",
|
||||
"version": "1.0.12-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libxau-1.0.12-r0.apk",
|
||||
"sha256": "ddfad479041b53e5f57a2fdfac12454993ae3937f6f893d67cd98cbd63abfcf0"
|
||||
},
|
||||
{
|
||||
"name": "libxau-dev",
|
||||
"version": "1.0.12-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libxau-dev-1.0.12-r0.apk",
|
||||
"sha256": "bed89cb8971efccf37f0a77d6cddcd31f122a322d04fc75117cddb48804c2290"
|
||||
},
|
||||
{
|
||||
"name": "libxcb",
|
||||
"version": "1.17.0-r1",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libxcb-1.17.0-r1.apk",
|
||||
"sha256": "8609cadcd7af03c1aade3663fdf3bbe27e4180fe0edbe98d3f12f0ae6e95aedc"
|
||||
},
|
||||
{
|
||||
"name": "libxcb-dev",
|
||||
"version": "1.17.0-r1",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libxcb-dev-1.17.0-r1.apk",
|
||||
"sha256": "f6d1488df536002017c10a435caa32f9527ec9ad5aa86cbab639cde4258a2b67"
|
||||
},
|
||||
{
|
||||
"name": "libxdmcp",
|
||||
"version": "1.1.5-r1",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libxdmcp-1.1.5-r1.apk",
|
||||
"sha256": "f95a668a5b8888aadbee24e8ffb30f60e4d40cdf8ef61b35383e7ecf49182c66"
|
||||
},
|
||||
{
|
||||
"name": "libxdmcp-dev",
|
||||
"version": "1.1.5-r1",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libxdmcp-dev-1.1.5-r1.apk",
|
||||
"sha256": "fa1dd28326caf9e3299bf36a94fa5d62c6f448588044fcf95ddcf2bcaabd9aff"
|
||||
},
|
||||
{
|
||||
"name": "libxext",
|
||||
"version": "1.3.6-r2",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libxext-1.3.6-r2.apk",
|
||||
"sha256": "bb7e84c1d38e5dcdfdb56e543394469f9c884cb13e09f5e07986863a9bea62e7"
|
||||
},
|
||||
{
|
||||
"name": "libxext-dev",
|
||||
"version": "1.3.6-r2",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libxext-dev-1.3.6-r2.apk",
|
||||
"sha256": "9b70dc8e575dbc28feed289a4336bc181cc7327886364aefe4bb3bb81a98c49b"
|
||||
},
|
||||
{
|
||||
"name": "libxml2",
|
||||
"version": "2.13.9-r1",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/libxml2-2.13.9-r1.apk",
|
||||
"sha256": "91d3e730edbd5214c501696725e7af9a93e12a9dd6a296e719dca2f3de0697d5"
|
||||
},
|
||||
{
|
||||
"name": "mesa-dev",
|
||||
"version": "25.2.7-r1",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/mesa-dev-25.2.7-r1.apk",
|
||||
"sha256": "a9759357562a1365b35b01a2be05cc33ec3ab0f3a1c1bd079a0b68e4c29ef129"
|
||||
},
|
||||
{
|
||||
"name": "musl",
|
||||
"version": "1.2.5-r23",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/musl-1.2.5-r23.apk",
|
||||
"sha256": "6a3edd924ead1fad88a69e28c5775809af3026b322f58428001cd02fedc5299e"
|
||||
},
|
||||
{
|
||||
"name": "wayland-dev",
|
||||
"version": "1.24.0-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/wayland-dev-1.24.0-r0.apk",
|
||||
"sha256": "681397cc91e05bb6cc63af4b37a59aa510aaab37539c9e6629d7fbfbcb1f0e57"
|
||||
},
|
||||
{
|
||||
"name": "wayland-libs-client",
|
||||
"version": "1.24.0-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/wayland-libs-client-1.24.0-r0.apk",
|
||||
"sha256": "47634dcc2befcae378f9f60681d2af1864db85e57f65e11a3557a43f77911073"
|
||||
},
|
||||
{
|
||||
"name": "wayland-libs-cursor",
|
||||
"version": "1.24.0-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/wayland-libs-cursor-1.24.0-r0.apk",
|
||||
"sha256": "a6f8e01ec409b183693169af006d1edc8b673af801bd540820fdb7808cb5e27b"
|
||||
},
|
||||
{
|
||||
"name": "wayland-libs-egl",
|
||||
"version": "1.24.0-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/wayland-libs-egl-1.24.0-r0.apk",
|
||||
"sha256": "4f2ae7b94f0b6c95dae885c0c24ac59eea5fd2b7a4680cec43dd8366c86564d2"
|
||||
},
|
||||
{
|
||||
"name": "wayland-libs-server",
|
||||
"version": "1.24.0-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/wayland-libs-server-1.24.0-r0.apk",
|
||||
"sha256": "c6bc1243dd337ba638834cd1e7a5ccfd10b6e2315e63af02f441bff581c35c66"
|
||||
},
|
||||
{
|
||||
"name": "xorgproto",
|
||||
"version": "2024.1-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/xorgproto-2024.1-r0.apk",
|
||||
"sha256": "8d53e4b89f3067a4d24f7645127b100a4d46a567eccb82428fe5256c17316b0d"
|
||||
},
|
||||
{
|
||||
"name": "xz-libs",
|
||||
"version": "5.8.4-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/xz-libs-5.8.4-r0.apk",
|
||||
"sha256": "55cec0880e1d06049147cd295a7c8a2909a668fc58a00c187741f3a16c25c55d"
|
||||
},
|
||||
{
|
||||
"name": "zlib",
|
||||
"version": "1.3.2-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/zlib-1.3.2-r0.apk",
|
||||
"sha256": "ecda4cc94fd18f90182f1d3a615889df5e0db9cf78926d11627dd23e06d2e6e8"
|
||||
},
|
||||
{
|
||||
"name": "zlib-dev",
|
||||
"version": "1.3.2-r0",
|
||||
"url": "https://dl-cdn.alpinelinux.org/alpine/v3.23/main/aarch64/zlib-dev-1.3.2-r0.apk",
|
||||
"sha256": "18a7f594ad7439629cb5889e4f0ad71075dd9f0cd4729a0461ba1501e21bc583"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,594 @@
|
||||
{
|
||||
"linux-x64": [
|
||||
{
|
||||
"name": "libbrotli-dev",
|
||||
"version": "1.0.9-2+b6",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/b/brotli/libbrotli-dev_1.0.9-2+b6_amd64.deb",
|
||||
"sha256": "932de11d4d9caee3300319b2fdf6ca505ca739706be48737df5e40ee90ccb6ca"
|
||||
},
|
||||
{
|
||||
"name": "libbrotli1",
|
||||
"version": "1.0.9-2+b6",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/b/brotli/libbrotli1_1.0.9-2+b6_amd64.deb",
|
||||
"sha256": "563b4caec1aa5e876bd3355b36e7a38e1484baf5a293b48d1e8bd22db786e4d7"
|
||||
},
|
||||
{
|
||||
"name": "libbsd0",
|
||||
"version": "0.11.7-2",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libb/libbsd/libbsd0_0.11.7-2_amd64.deb",
|
||||
"sha256": "bb31cc8b40f962a85b2cec970f7f79cc704a1ae4bad24257a822055404b2c60b"
|
||||
},
|
||||
{
|
||||
"name": "libbz2-1.0",
|
||||
"version": "1.0.8-5+b1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/b/bzip2/libbz2-1.0_1.0.8-5+b1_amd64.deb",
|
||||
"sha256": "54149da3f44b22d523b26b692033b84503d822cc5122fed606ea69cc83ca5aeb"
|
||||
},
|
||||
{
|
||||
"name": "libbz2-dev",
|
||||
"version": "1.0.8-5+b1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/b/bzip2/libbz2-dev_1.0.8-5+b1_amd64.deb",
|
||||
"sha256": "df7204e188f7514ceae9c6f57c6c8b25ce8a642746fe284c6e89122ef26b7e57"
|
||||
},
|
||||
{
|
||||
"name": "libc6",
|
||||
"version": "2.36-9+deb12u14",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/g/glibc/libc6_2.36-9+deb12u14_amd64.deb",
|
||||
"sha256": "ba4f88f73dbc3ae9055f3c20f4523bfdbaf1ad13ff95e258924f77d20b4fbedf"
|
||||
},
|
||||
{
|
||||
"name": "libegl-dev",
|
||||
"version": "1.6.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libg/libglvnd/libegl-dev_1.6.0-1_amd64.deb",
|
||||
"sha256": "0ec9bffb024527dfb61eaeae44966e2b5b3114b3dc315b4117b0df95b1c96ef8"
|
||||
},
|
||||
{
|
||||
"name": "libegl1",
|
||||
"version": "1.6.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libg/libglvnd/libegl1_1.6.0-1_amd64.deb",
|
||||
"sha256": "fe4d8b39f6e6fe1a32ab1efd85893553eaa9cf3866aa668ccf355f585b37d523"
|
||||
},
|
||||
{
|
||||
"name": "libexpat1",
|
||||
"version": "2.5.0-1+deb12u2",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/e/expat/libexpat1_2.5.0-1+deb12u2_amd64.deb",
|
||||
"sha256": "2255e62fc22a86d2c544b8a3f516da9aee19383ad5742722ab4ce7f66a30dbc8"
|
||||
},
|
||||
{
|
||||
"name": "libexpat1-dev",
|
||||
"version": "2.5.0-1+deb12u2",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/e/expat/libexpat1-dev_2.5.0-1+deb12u2_amd64.deb",
|
||||
"sha256": "757279c1ce56ca88ca519e4c01cffd94e8480ce936f53fe9b0d61dc1bab20394"
|
||||
},
|
||||
{
|
||||
"name": "libffi-dev",
|
||||
"version": "3.4.4-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libf/libffi/libffi-dev_3.4.4-1_amd64.deb",
|
||||
"sha256": "89fb890aee5148f4d308a46cd8980a54fd44135f068f05b38a6ad06800bf6df3"
|
||||
},
|
||||
{
|
||||
"name": "libffi8",
|
||||
"version": "3.4.4-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libf/libffi/libffi8_3.4.4-1_amd64.deb",
|
||||
"sha256": "6d9f6c25c30efccce6d4bceaa48ea86c329a3432abb360a141f76ac223a4c34a"
|
||||
},
|
||||
{
|
||||
"name": "libfontconfig-dev",
|
||||
"version": "2.14.1-4",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/f/fontconfig/libfontconfig-dev_2.14.1-4_amd64.deb",
|
||||
"sha256": "74f4bbde5795e4fb4c453308bd0eb8ef45d7ade3cf11b3c18394f9e2c15d28df"
|
||||
},
|
||||
{
|
||||
"name": "libfontconfig1",
|
||||
"version": "2.14.1-4",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/f/fontconfig/libfontconfig1_2.14.1-4_amd64.deb",
|
||||
"sha256": "16ee38d374e064f534116dc442b086ef26f9831f1c0af7e5fb4fe4512e700649"
|
||||
},
|
||||
{
|
||||
"name": "libfreetype-dev",
|
||||
"version": "2.12.1+dfsg-5+deb12u4",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/f/freetype/libfreetype-dev_2.12.1+dfsg-5+deb12u4_amd64.deb",
|
||||
"sha256": "5fa327ae78e645cff5a2aadad92ca3640abc5cee7ad5368d7551bea8930202af"
|
||||
},
|
||||
{
|
||||
"name": "libfreetype6",
|
||||
"version": "2.12.1+dfsg-5+deb12u4",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/f/freetype/libfreetype6_2.12.1+dfsg-5+deb12u4_amd64.deb",
|
||||
"sha256": "8043e479f73f29992d652e3f9dfe8b17f9780c7ea6330afe379ec5f9f188ac44"
|
||||
},
|
||||
{
|
||||
"name": "libgl-dev",
|
||||
"version": "1.6.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libg/libglvnd/libgl-dev_1.6.0-1_amd64.deb",
|
||||
"sha256": "ebc12df48ae53924e114d9358ef3da4306d7ef8f7179300af52f1faef8b5db3e"
|
||||
},
|
||||
{
|
||||
"name": "libgl1",
|
||||
"version": "1.6.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libg/libglvnd/libgl1_1.6.0-1_amd64.deb",
|
||||
"sha256": "6f89b1702c48e9a2437bb3c1ffac8e1ab2d828fc28b3d14b2eecd4cc19b2c790"
|
||||
},
|
||||
{
|
||||
"name": "libglvnd0",
|
||||
"version": "1.6.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libg/libglvnd/libglvnd0_1.6.0-1_amd64.deb",
|
||||
"sha256": "b6da5b153dd62d8b5e5fbe25242db1fc05c068707c365db49abda8c2427c75f8"
|
||||
},
|
||||
{
|
||||
"name": "libglx0",
|
||||
"version": "1.6.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libg/libglvnd/libglx0_1.6.0-1_amd64.deb",
|
||||
"sha256": "95f568df73dedf43ae66834a75502112e0d4f3ad7124f3dbfa790b739383b896"
|
||||
},
|
||||
{
|
||||
"name": "libmd0",
|
||||
"version": "1.0.4-2",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libm/libmd/libmd0_1.0.4-2_amd64.deb",
|
||||
"sha256": "03539fd30c509e27101d13a56e52eda9062bdf1aefe337c07ab56def25a13eab"
|
||||
},
|
||||
{
|
||||
"name": "libpng-dev",
|
||||
"version": "1.6.39-2+deb12u5",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libp/libpng1.6/libpng-dev_1.6.39-2+deb12u5_amd64.deb",
|
||||
"sha256": "25649c413d02092ae7b1093a3c3ee54cbd2d4fdb0a0494787e434ccf0905903f"
|
||||
},
|
||||
{
|
||||
"name": "libpng16-16",
|
||||
"version": "1.6.39-2+deb12u5",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libp/libpng1.6/libpng16-16_1.6.39-2+deb12u5_amd64.deb",
|
||||
"sha256": "a56d64bfaa9da12aafb83347909e62e6fd5fd251e6b34c194065911a30359978"
|
||||
},
|
||||
{
|
||||
"name": "libpthread-stubs0-dev",
|
||||
"version": "0.4-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libp/libpthread-stubs/libpthread-stubs0-dev_0.4-1_amd64.deb",
|
||||
"sha256": "54632f160e1e8a43656a87195a547391038c4ca0f53291b849cd4457ba5dfde9"
|
||||
},
|
||||
{
|
||||
"name": "libuuid1",
|
||||
"version": "2.38.1-5+deb12u3",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/u/util-linux/libuuid1_2.38.1-5+deb12u3_amd64.deb",
|
||||
"sha256": "5fff398321da62d28a842bcbabd193d72ae21724962c029dc32b1dc6b2deaeaf"
|
||||
},
|
||||
{
|
||||
"name": "libwayland-client0",
|
||||
"version": "1.21.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/w/wayland/libwayland-client0_1.21.0-1_amd64.deb",
|
||||
"sha256": "1f002d028b8b79eec9847c636d8886d10dfe8c884cc2bebe18086b1391c5a28d"
|
||||
},
|
||||
{
|
||||
"name": "libwayland-cursor0",
|
||||
"version": "1.21.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/w/wayland/libwayland-cursor0_1.21.0-1_amd64.deb",
|
||||
"sha256": "0b684467ec795024fcaae99ea4384959cc4052b2da5adec38c9b76dfed9bcf41"
|
||||
},
|
||||
{
|
||||
"name": "libwayland-dev",
|
||||
"version": "1.21.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/w/wayland/libwayland-dev_1.21.0-1_amd64.deb",
|
||||
"sha256": "063ac40e71069a1a92c2be32799f4a2d234f3d361ba98cea2e3137a7ab6804d1"
|
||||
},
|
||||
{
|
||||
"name": "libwayland-egl1",
|
||||
"version": "1.21.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/w/wayland/libwayland-egl1_1.21.0-1_amd64.deb",
|
||||
"sha256": "cb4225f0e15e00a3570d4cbc288c87ff477d73e741c3f1c5a6d47cf350d45378"
|
||||
},
|
||||
{
|
||||
"name": "libwayland-server0",
|
||||
"version": "1.21.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/w/wayland/libwayland-server0_1.21.0-1_amd64.deb",
|
||||
"sha256": "df0396221d7b794496a687ec61fae82b6465648bc0ab6501ba0a5ed7f56eb8d6"
|
||||
},
|
||||
{
|
||||
"name": "libx11-6",
|
||||
"version": "2:1.8.4-2+deb12u2",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libx11/libx11-6_1.8.4-2+deb12u2_amd64.deb",
|
||||
"sha256": "d88c973e79fd9b65838d77624142952757e47a6eb1a58602acf0911cf35989f4"
|
||||
},
|
||||
{
|
||||
"name": "libx11-dev",
|
||||
"version": "2:1.8.4-2+deb12u2",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libx11/libx11-dev_1.8.4-2+deb12u2_amd64.deb",
|
||||
"sha256": "8493220d4309af1907a1f2f6eeb204c8103dafcc368394fbc4a0858c28612ff9"
|
||||
},
|
||||
{
|
||||
"name": "libx11-xcb1",
|
||||
"version": "2:1.8.4-2+deb12u2",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libx11/libx11-xcb1_1.8.4-2+deb12u2_amd64.deb",
|
||||
"sha256": "f5da45e1d881a793250a96613f28c471a248877f1a0f18a5c90e2a620a76c898"
|
||||
},
|
||||
{
|
||||
"name": "libxau-dev",
|
||||
"version": "1:1.0.9-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxau/libxau-dev_1.0.9-1_amd64.deb",
|
||||
"sha256": "d1a7f5d484e0879b3b2e8d512894744505e53d078712ce65903fef2ecfd824bb"
|
||||
},
|
||||
{
|
||||
"name": "libxau6",
|
||||
"version": "1:1.0.9-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxau/libxau6_1.0.9-1_amd64.deb",
|
||||
"sha256": "679db1c4579ec7c61079adeaae8528adeb2e4bf5465baa6c56233b995d714750"
|
||||
},
|
||||
{
|
||||
"name": "libxcb1",
|
||||
"version": "1.15-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxcb/libxcb1_1.15-1_amd64.deb",
|
||||
"sha256": "fdc61332a3892168f3cc9cfa1fe9cf11a91dc3e0acacbc47cbc50ebaa234cc71"
|
||||
},
|
||||
{
|
||||
"name": "libxcb1-dev",
|
||||
"version": "1.15-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxcb/libxcb1-dev_1.15-1_amd64.deb",
|
||||
"sha256": "c078c024114fdada06d3158af1771d7ed8763ab434cfbcbe6a334aa8a9cae358"
|
||||
},
|
||||
{
|
||||
"name": "libxdmcp-dev",
|
||||
"version": "1:1.1.2-3",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxdmcp/libxdmcp-dev_1.1.2-3_amd64.deb",
|
||||
"sha256": "c6733e5f6463afd261998e408be6eb37f24ce0a64b63bed50a87ddb18ebc1699"
|
||||
},
|
||||
{
|
||||
"name": "libxdmcp6",
|
||||
"version": "1:1.1.2-3",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxdmcp/libxdmcp6_1.1.2-3_amd64.deb",
|
||||
"sha256": "ecb8536f5fb34543b55bb9dc5f5b14c9dbb4150a7bddb3f2287b7cab6e9d25ef"
|
||||
},
|
||||
{
|
||||
"name": "libxext-dev",
|
||||
"version": "2:1.3.4-1+b1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxext/libxext-dev_1.3.4-1+b1_amd64.deb",
|
||||
"sha256": "591456aba90eeed7a1c1b044d469fd7704bf7d83af9dc574bbe2efc4a2fd1dba"
|
||||
},
|
||||
{
|
||||
"name": "libxext6",
|
||||
"version": "2:1.3.4-1+b1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxext/libxext6_1.3.4-1+b1_amd64.deb",
|
||||
"sha256": "504b7be9d7df4f6f4519e8dd4d6f9d03a9fb911a78530fa23a692fba3058cba6"
|
||||
},
|
||||
{
|
||||
"name": "libxfixes3",
|
||||
"version": "1:6.0.0-2",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxfixes/libxfixes3_6.0.0-2_amd64.deb",
|
||||
"sha256": "1cd616396ff2ecae77e6e8b5b7695d414f0146de2d147837a2a02165f99e1a2c"
|
||||
},
|
||||
{
|
||||
"name": "libxi6",
|
||||
"version": "2:1.8-1+b1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxi/libxi6_1.8-1+b1_amd64.deb",
|
||||
"sha256": "6c2fb5f241b311788990122c6e693915867cd8ed9d6da2e3524aec7ed3cdb4c0"
|
||||
},
|
||||
{
|
||||
"name": "libxrandr2",
|
||||
"version": "2:1.5.2-2+b1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxrandr/libxrandr2_1.5.2-2+b1_amd64.deb",
|
||||
"sha256": "e2e10b672085ddf1d294cd689ed21bde5899325fd13626c2614b7d7b2d49a808"
|
||||
},
|
||||
{
|
||||
"name": "libxrender1",
|
||||
"version": "1:0.9.10-1.1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxrender/libxrender1_0.9.10-1.1_amd64.deb",
|
||||
"sha256": "b2a6d160578f359220101947c8d67059b44704a251e688de1d0b744fefedfd1a"
|
||||
},
|
||||
{
|
||||
"name": "x11proto-dev",
|
||||
"version": "2022.1-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/x/xorgproto/x11proto-dev_2022.1-1_all.deb",
|
||||
"sha256": "3cab66a6591774188a568f9b54c4e7956f18da76e0e0fc4a779db5f6bcc3f148"
|
||||
},
|
||||
{
|
||||
"name": "xtrans-dev",
|
||||
"version": "1.4.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/x/xtrans/xtrans-dev_1.4.0-1_all.deb",
|
||||
"sha256": "9ce1af9464faee0c679348dd11cdf63934c12e734a64e0903692b0cb5af38e06"
|
||||
},
|
||||
{
|
||||
"name": "zlib1g",
|
||||
"version": "1:1.2.13.dfsg-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/z/zlib/zlib1g_1.2.13.dfsg-1_amd64.deb",
|
||||
"sha256": "d7dd1d1411fedf27f5e27650a6eff20ef294077b568f4c8c5e51466dc7c08ce4"
|
||||
},
|
||||
{
|
||||
"name": "zlib1g-dev",
|
||||
"version": "1:1.2.13.dfsg-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/z/zlib/zlib1g-dev_1.2.13.dfsg-1_amd64.deb",
|
||||
"sha256": "f9ce531f60cbd5df37996af9370e0171be96902a17ec2bdbd8d62038c354094f"
|
||||
}
|
||||
],
|
||||
"linux-arm64": [
|
||||
{
|
||||
"name": "libbrotli-dev",
|
||||
"version": "1.0.9-2+b6",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/b/brotli/libbrotli-dev_1.0.9-2+b6_arm64.deb",
|
||||
"sha256": "68f334eb61694c2e5ca756174d111109f72193d1e3c14a25a65833c6dfcd98b7"
|
||||
},
|
||||
{
|
||||
"name": "libbrotli1",
|
||||
"version": "1.0.9-2+b6",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/b/brotli/libbrotli1_1.0.9-2+b6_arm64.deb",
|
||||
"sha256": "3137de7f71952e710ee9f0df05026b3c6f463be9369a502d57c7696732f1ed22"
|
||||
},
|
||||
{
|
||||
"name": "libbsd0",
|
||||
"version": "0.11.7-2",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libb/libbsd/libbsd0_0.11.7-2_arm64.deb",
|
||||
"sha256": "ef00f132ddd268ee67d756998723ee18543db27ab34930c0a9f1cff75cf55382"
|
||||
},
|
||||
{
|
||||
"name": "libbz2-1.0",
|
||||
"version": "1.0.8-5+b1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/b/bzip2/libbz2-1.0_1.0.8-5+b1_arm64.deb",
|
||||
"sha256": "d3a96ece03326498b39ff093a76800dfcbcb1d4049d6ae6e9f6fa1aa7a590ad6"
|
||||
},
|
||||
{
|
||||
"name": "libbz2-dev",
|
||||
"version": "1.0.8-5+b1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/b/bzip2/libbz2-dev_1.0.8-5+b1_arm64.deb",
|
||||
"sha256": "c9827ab40420f1259b1a10983978ec8de87c11fc1a6b3c192adea1c4c490754f"
|
||||
},
|
||||
{
|
||||
"name": "libc6",
|
||||
"version": "2.36-9+deb12u14",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/g/glibc/libc6_2.36-9+deb12u14_arm64.deb",
|
||||
"sha256": "01f4330719fd4f65580e16ea5a0527f372fca750e8f588d26deaf09f2d3b1cf4"
|
||||
},
|
||||
{
|
||||
"name": "libegl-dev",
|
||||
"version": "1.6.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libg/libglvnd/libegl-dev_1.6.0-1_arm64.deb",
|
||||
"sha256": "8a3004f892785a5fa4c9f969c116f567a36d1c8e9b3d5fd0403055151e36c7d3"
|
||||
},
|
||||
{
|
||||
"name": "libegl1",
|
||||
"version": "1.6.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libg/libglvnd/libegl1_1.6.0-1_arm64.deb",
|
||||
"sha256": "707097a275155c600e2e9251c4ee7cdfdb2d8f50a678a850a2526a7bc9664166"
|
||||
},
|
||||
{
|
||||
"name": "libexpat1",
|
||||
"version": "2.5.0-1+deb12u2",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/e/expat/libexpat1_2.5.0-1+deb12u2_arm64.deb",
|
||||
"sha256": "8dc1976735acf825e3a922d82f171e20feec7394da2b8c616091983e38706275"
|
||||
},
|
||||
{
|
||||
"name": "libexpat1-dev",
|
||||
"version": "2.5.0-1+deb12u2",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/e/expat/libexpat1-dev_2.5.0-1+deb12u2_arm64.deb",
|
||||
"sha256": "9987e4aa214b0ec23fc2ba6a99b8f10d2dc68f2de347722215ae3f960802e3d3"
|
||||
},
|
||||
{
|
||||
"name": "libffi-dev",
|
||||
"version": "3.4.4-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libf/libffi/libffi-dev_3.4.4-1_arm64.deb",
|
||||
"sha256": "8ff6335f76752ef8659762435d0d88129ef0090a587520853238809bd10ef392"
|
||||
},
|
||||
{
|
||||
"name": "libffi8",
|
||||
"version": "3.4.4-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libf/libffi/libffi8_3.4.4-1_arm64.deb",
|
||||
"sha256": "80b5c36177dc0e29d531c7eddbed3cc7355cb490e49f8cfa5959572d161f27b3"
|
||||
},
|
||||
{
|
||||
"name": "libfontconfig-dev",
|
||||
"version": "2.14.1-4",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/f/fontconfig/libfontconfig-dev_2.14.1-4_arm64.deb",
|
||||
"sha256": "7da35e69d4f43b337aa9508da8e9089de80e75285141be3d7bec1055a0501aa4"
|
||||
},
|
||||
{
|
||||
"name": "libfontconfig1",
|
||||
"version": "2.14.1-4",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/f/fontconfig/libfontconfig1_2.14.1-4_arm64.deb",
|
||||
"sha256": "4836d9deca824883f0de33d4f8f3718ba776c6e7c80cd7c418b5a0f86c009b9e"
|
||||
},
|
||||
{
|
||||
"name": "libfreetype-dev",
|
||||
"version": "2.12.1+dfsg-5+deb12u4",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/f/freetype/libfreetype-dev_2.12.1+dfsg-5+deb12u4_arm64.deb",
|
||||
"sha256": "4e5057ac9107c69c0f49f4a8989056a7c37184c94c73ee48ba7023c5fb118db7"
|
||||
},
|
||||
{
|
||||
"name": "libfreetype6",
|
||||
"version": "2.12.1+dfsg-5+deb12u4",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/f/freetype/libfreetype6_2.12.1+dfsg-5+deb12u4_arm64.deb",
|
||||
"sha256": "b8d32e54ebc9020637f8fa16b6afa64a5731e40845a6e01880d38d6f632237c9"
|
||||
},
|
||||
{
|
||||
"name": "libgl-dev",
|
||||
"version": "1.6.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libg/libglvnd/libgl-dev_1.6.0-1_arm64.deb",
|
||||
"sha256": "56add9e710c072cf56504beed50a639f9f7c64f4e31e66958fa65a566084888c"
|
||||
},
|
||||
{
|
||||
"name": "libgl1",
|
||||
"version": "1.6.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libg/libglvnd/libgl1_1.6.0-1_arm64.deb",
|
||||
"sha256": "f4043ab47f52325973d2b608514b3469b055b65c744861c7f378755a32e799d6"
|
||||
},
|
||||
{
|
||||
"name": "libglvnd0",
|
||||
"version": "1.6.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libg/libglvnd/libglvnd0_1.6.0-1_arm64.deb",
|
||||
"sha256": "d5063205fab5322ee686f33f87c6315b3fcd1335ea4e7bc8202b48ed4f9c9e83"
|
||||
},
|
||||
{
|
||||
"name": "libglx0",
|
||||
"version": "1.6.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libg/libglvnd/libglx0_1.6.0-1_arm64.deb",
|
||||
"sha256": "523f9b71f75e48ae605d8ef298a4b03ade26ade9a808a85329a3bd82a54b9b0d"
|
||||
},
|
||||
{
|
||||
"name": "libmd0",
|
||||
"version": "1.0.4-2",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libm/libmd/libmd0_1.0.4-2_arm64.deb",
|
||||
"sha256": "99a8c7dd591fae9fb37d8bf8dfdffa850e207fa405b3198c5b24711a5f972381"
|
||||
},
|
||||
{
|
||||
"name": "libpng-dev",
|
||||
"version": "1.6.39-2+deb12u5",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libp/libpng1.6/libpng-dev_1.6.39-2+deb12u5_arm64.deb",
|
||||
"sha256": "f02dc017801713dfd11aaa7e72d705f747570e029fd242c29af072d64474ddfc"
|
||||
},
|
||||
{
|
||||
"name": "libpng16-16",
|
||||
"version": "1.6.39-2+deb12u5",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libp/libpng1.6/libpng16-16_1.6.39-2+deb12u5_arm64.deb",
|
||||
"sha256": "69aba3963ddfb11b98e5bf4b0d022f76b797436568884b10f2da32e0f4b8c2dd"
|
||||
},
|
||||
{
|
||||
"name": "libpthread-stubs0-dev",
|
||||
"version": "0.4-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libp/libpthread-stubs/libpthread-stubs0-dev_0.4-1_arm64.deb",
|
||||
"sha256": "acd58ed5d26d3f4d4b0856ebec6bc43f9c4357601a532eee0d2de839a8b8952e"
|
||||
},
|
||||
{
|
||||
"name": "libuuid1",
|
||||
"version": "2.38.1-5+deb12u3",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/u/util-linux/libuuid1_2.38.1-5+deb12u3_arm64.deb",
|
||||
"sha256": "3b2d19df0f3190108cf54228c4cfc822226c06d8f3615a5ab16a7dffb1f58aed"
|
||||
},
|
||||
{
|
||||
"name": "libwayland-client0",
|
||||
"version": "1.21.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/w/wayland/libwayland-client0_1.21.0-1_arm64.deb",
|
||||
"sha256": "ae390cc04c2eb1de90b9a6373505b22c730ada5e72daa50c507b7f99c12faf06"
|
||||
},
|
||||
{
|
||||
"name": "libwayland-cursor0",
|
||||
"version": "1.21.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/w/wayland/libwayland-cursor0_1.21.0-1_arm64.deb",
|
||||
"sha256": "8c8d1a3942bc3fc9dd3ea7c679c1a314e59cdaaa700883d54d1bb3ec89db256b"
|
||||
},
|
||||
{
|
||||
"name": "libwayland-dev",
|
||||
"version": "1.21.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/w/wayland/libwayland-dev_1.21.0-1_arm64.deb",
|
||||
"sha256": "932405c58195d299495230792e374ad304adadf3d3ffdc07eda3466b756adc33"
|
||||
},
|
||||
{
|
||||
"name": "libwayland-egl1",
|
||||
"version": "1.21.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/w/wayland/libwayland-egl1_1.21.0-1_arm64.deb",
|
||||
"sha256": "c08124a4d9af24f058b45c88867a84697882e755ea94965795d152fe26fe57c9"
|
||||
},
|
||||
{
|
||||
"name": "libwayland-server0",
|
||||
"version": "1.21.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/w/wayland/libwayland-server0_1.21.0-1_arm64.deb",
|
||||
"sha256": "4d99e7e0503fdaa999e67d47d8612c0465e775eafa47819573da50bdb09064f2"
|
||||
},
|
||||
{
|
||||
"name": "libx11-6",
|
||||
"version": "2:1.8.4-2+deb12u2",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libx11/libx11-6_1.8.4-2+deb12u2_arm64.deb",
|
||||
"sha256": "d1d533e983582282a9ea82c87ac5ce715a9b67bd6d1acbd2439a11c63c36549b"
|
||||
},
|
||||
{
|
||||
"name": "libx11-dev",
|
||||
"version": "2:1.8.4-2+deb12u2",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libx11/libx11-dev_1.8.4-2+deb12u2_arm64.deb",
|
||||
"sha256": "34bfc833561de983cfb4475523fedc13abb4faee14a876300de659591779add8"
|
||||
},
|
||||
{
|
||||
"name": "libx11-xcb1",
|
||||
"version": "2:1.8.4-2+deb12u2",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libx11/libx11-xcb1_1.8.4-2+deb12u2_arm64.deb",
|
||||
"sha256": "21c7e6f19909bb1e02bb3c2089789791858c54d37e86cef9d7872782c1cb711e"
|
||||
},
|
||||
{
|
||||
"name": "libxau-dev",
|
||||
"version": "1:1.0.9-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxau/libxau-dev_1.0.9-1_arm64.deb",
|
||||
"sha256": "21db3761a8f388fc83707c00fac645d4332737a859dd727571e1e6ede003b048"
|
||||
},
|
||||
{
|
||||
"name": "libxau6",
|
||||
"version": "1:1.0.9-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxau/libxau6_1.0.9-1_arm64.deb",
|
||||
"sha256": "36c2bf400641a80521093771dc2562c903df4065f9eb03add50d90564337ea6c"
|
||||
},
|
||||
{
|
||||
"name": "libxcb1",
|
||||
"version": "1.15-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxcb/libxcb1_1.15-1_arm64.deb",
|
||||
"sha256": "041d9a68415c3ccf3ce8f4f8b88e4bbfb5dc1f0d97013c6ef8423e620ea50f84"
|
||||
},
|
||||
{
|
||||
"name": "libxcb1-dev",
|
||||
"version": "1.15-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxcb/libxcb1-dev_1.15-1_arm64.deb",
|
||||
"sha256": "87b5c3f1bb130727df68295ecfaadc305ee10c150afeb1a183e95b9150e18db5"
|
||||
},
|
||||
{
|
||||
"name": "libxdmcp-dev",
|
||||
"version": "1:1.1.2-3",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxdmcp/libxdmcp-dev_1.1.2-3_arm64.deb",
|
||||
"sha256": "6fd0bc51f3a4e6b7f944f24f15524a4c4ba68a4b0aa136c18bdb96a2d36988f2"
|
||||
},
|
||||
{
|
||||
"name": "libxdmcp6",
|
||||
"version": "1:1.1.2-3",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxdmcp/libxdmcp6_1.1.2-3_arm64.deb",
|
||||
"sha256": "e92569ac33247261aa09adfadc34ced3994ac301cf8b58de415a2d5dbf15ccfc"
|
||||
},
|
||||
{
|
||||
"name": "libxext-dev",
|
||||
"version": "2:1.3.4-1+b1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxext/libxext-dev_1.3.4-1+b1_arm64.deb",
|
||||
"sha256": "07f5e3efeba9564071885b2d0d2ba277692fa309a9f05ef862688af0022b1fcf"
|
||||
},
|
||||
{
|
||||
"name": "libxext6",
|
||||
"version": "2:1.3.4-1+b1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxext/libxext6_1.3.4-1+b1_arm64.deb",
|
||||
"sha256": "5e9c0ad606eb4674c645fe8e0e64330c47d2729f7a59ed569848610efd5d5b62"
|
||||
},
|
||||
{
|
||||
"name": "libxfixes3",
|
||||
"version": "1:6.0.0-2",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxfixes/libxfixes3_6.0.0-2_arm64.deb",
|
||||
"sha256": "d47bda8fed01b19b41d503e2df05d9166c58e30e2376f2f8784ceb7a834befe6"
|
||||
},
|
||||
{
|
||||
"name": "libxi6",
|
||||
"version": "2:1.8-1+b1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxi/libxi6_1.8-1+b1_arm64.deb",
|
||||
"sha256": "b26383c9929d8bfba051eee22301e064d17039ed022bbf31990feb0d7a03b36c"
|
||||
},
|
||||
{
|
||||
"name": "libxrandr2",
|
||||
"version": "2:1.5.2-2+b1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxrandr/libxrandr2_1.5.2-2+b1_arm64.deb",
|
||||
"sha256": "f0bc7f79fee182caae176652fdb1bf349d13b9591b10ad4dc1c896521da8e49f"
|
||||
},
|
||||
{
|
||||
"name": "libxrender1",
|
||||
"version": "1:0.9.10-1.1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/libx/libxrender/libxrender1_0.9.10-1.1_arm64.deb",
|
||||
"sha256": "f260193deb4eaf0b410a1c61e1f84804366ee3372b8bad9f38005f7dbcd89aae"
|
||||
},
|
||||
{
|
||||
"name": "x11proto-dev",
|
||||
"version": "2022.1-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/x/xorgproto/x11proto-dev_2022.1-1_all.deb",
|
||||
"sha256": "3cab66a6591774188a568f9b54c4e7956f18da76e0e0fc4a779db5f6bcc3f148"
|
||||
},
|
||||
{
|
||||
"name": "xtrans-dev",
|
||||
"version": "1.4.0-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/x/xtrans/xtrans-dev_1.4.0-1_all.deb",
|
||||
"sha256": "9ce1af9464faee0c679348dd11cdf63934c12e734a64e0903692b0cb5af38e06"
|
||||
},
|
||||
{
|
||||
"name": "zlib1g",
|
||||
"version": "1:1.2.13.dfsg-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/z/zlib/zlib1g_1.2.13.dfsg-1_arm64.deb",
|
||||
"sha256": "52b8b8a145bbe1956bba82034f77022cbef0c3d0885c9e32d9817a7932fe1913"
|
||||
},
|
||||
{
|
||||
"name": "zlib1g-dev",
|
||||
"version": "1:1.2.13.dfsg-1",
|
||||
"url": "https://snapshot.debian.org/archive/debian/20260901T000000Z/pool/main/z/zlib/zlib1g-dev_1.2.13.dfsg-1_arm64.deb",
|
||||
"sha256": "afb60f0bae432f2f0edfe2d674e99c1a13a147c9aa2b52f2f23e3df19ece76f5"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
{
|
||||
"tested_date_utc": "2026-10-04",
|
||||
"host": "Ubuntu 24.04 Linux x64",
|
||||
"zig_version": "0.14.1",
|
||||
"sources": {
|
||||
"skiasharp_version": "4.150.1",
|
||||
"skiasharp_revision": "c3e4f4c20e1f23ab74d31a8838a5bd6dc55365f2",
|
||||
"angle_branch": "7922",
|
||||
"angle_revision": "7e08726e32026a0bbabd6ec8a1a90f5ab533ed66",
|
||||
"skia_revision": "0aa2d542e833ffd1d4d1b68a5152375e7f65ce11"
|
||||
},
|
||||
"target_runtime_tested": false,
|
||||
"docker_build_tested": false,
|
||||
"cold_source_preparation_tested": false,
|
||||
"avalonia_nativeaot_tested": false,
|
||||
"targets": {
|
||||
"win-x64": {
|
||||
"six_archives_compiled": true,
|
||||
"raster_harfbuzz_link": "passed",
|
||||
"egl_gles_link": "passed",
|
||||
"archives_sha256": {
|
||||
"libANGLE.a": "9b4af0208fef7773dc91f684cdf676b156f48eb40821c99eb55b531f4b262214",
|
||||
"libEGL.a": "dc1d8568d8d3bab0d5e6956f97db88a1d3c5887a5f2437dfd29fa5abb2a48c97",
|
||||
"libGLESv2.a": "a78c019c732a356691b849d8f632dab9f1c3254452ef98fc3ed963fd33e7049c",
|
||||
"libHarfBuzzSharp.a": "71602aa223348bc34f754438bd2f9b90ba025547c8305b0ad45e23fbd4d0a882",
|
||||
"libSkiaSharp.a": "3aa2b79953dfcd3b8dde7996701c3a29878e61fb589a6398f0cccacd1c33f4f2",
|
||||
"libskia.a": "40418692d55d26e55f1882f8386ce341410a0712ae1691d47a26b3033bd7e9a8"
|
||||
},
|
||||
"executables_sha256": {
|
||||
"smoke-angle.exe": "bc54570c5f9cdca0a28e2f9ceb2bdb1a118cabfdf6516557d1d31fd777a7d4c5",
|
||||
"smoke-raster.exe": "289f963e2180bd12cdca298b931451ebc7698bef71930318899adc4505fbccef"
|
||||
}
|
||||
},
|
||||
"win-x86": {
|
||||
"six_archives_compiled": true,
|
||||
"raster_harfbuzz_link": "passed",
|
||||
"egl_gles_link": "passed",
|
||||
"archives_sha256": {
|
||||
"libANGLE.a": "27f715956b9625ffca27ebb10e4135d173ed03970745c257fe6437fd8db23daf",
|
||||
"libEGL.a": "ddab449877aa244333f43c4a79705d3c1347c5cfae778c46ca707cd78e9ed8ed",
|
||||
"libGLESv2.a": "adf90968b2a8984c9bceefbbce1edacb1a06038fdc9b2bfc962e9227a9c947bd",
|
||||
"libHarfBuzzSharp.a": "8483f2e5cc92561884163f317f496a2e4b6b61242774176fe8b6370bbc54c695",
|
||||
"libSkiaSharp.a": "565c25b03b4f574a7db5dca98327b5f7b8eea07c1f0dab5e09d6c731ad71fd29",
|
||||
"libskia.a": "97e086493216fef2d372f555c62c2fbaf28e4d6a61398ec37334164408bcc31f"
|
||||
},
|
||||
"executables_sha256": {
|
||||
"smoke-angle.exe": "5e3a6a7951f038fa1e1a9889e8f3212de285a9464b4b722700da259b1bb9e7bb",
|
||||
"smoke-raster.exe": "9b1b4dbc3686caa89ae03cb19c5d29b3cde16ab8c0381f7c1c8b339a8f5169e5"
|
||||
}
|
||||
},
|
||||
"win-arm64": {
|
||||
"six_archives_compiled": true,
|
||||
"raster_harfbuzz_link": "passed",
|
||||
"egl_gles_link": "passed",
|
||||
"archives_sha256": {
|
||||
"libANGLE.a": "d496f595573d62e64ad1fad9339f64249ddd3904d37146ad3d1e1c58b032d797",
|
||||
"libEGL.a": "8f87692e53a3843eb8131e51f0cbc03c7eef02039d22cc25348ecacbc12028d7",
|
||||
"libGLESv2.a": "cea510c2d0bbed66bd67d0070953408da23a39a0e5a3be959ed4cec6069973cb",
|
||||
"libHarfBuzzSharp.a": "662f4174d0bc0ee0760fdeacebb7ce8f187118b524239a745058547d4c25ca10",
|
||||
"libSkiaSharp.a": "17d4ed43351f0b97b6c816de41a3e2469dd42d4df42acc6201fd30a75b8e25df",
|
||||
"libskia.a": "52d4b8ec673881d4beb729580eac867696ca5fda4ad4c2a498f33cd8b915c76b"
|
||||
},
|
||||
"executables_sha256": {
|
||||
"smoke-angle.exe": "68367ceba8053f75b841d0e2b7ab6bc8f613836b91ebd13e463fe6d261b245a9",
|
||||
"smoke-raster.exe": "ce758159e371ae94504ae1502dbe26034ea1c3789f33f71a0f65640991578dfb"
|
||||
}
|
||||
},
|
||||
"osx-x64": {
|
||||
"six_archives_compiled": true,
|
||||
"raster_harfbuzz_link": "passed",
|
||||
"egl_gles_link": "passed",
|
||||
"archives_sha256": {
|
||||
"libANGLE.a": "353b6ad07961f94cdbde8f7901fc924fbb50600156da8194ec7dd5d9c9d96115",
|
||||
"libEGL.a": "6ea3c6d73e1f6a3785fdd941c37e50c7d00f3f5c136edf648f27243e5698d517",
|
||||
"libGLESv2.a": "e3bbb289e2be771c498eae0c4037e3d9058a0a52e100dd5b6622de42f00ecb7c",
|
||||
"libHarfBuzzSharp.a": "c80b4156937b0a63ff649d7ef9ee520e342ee6f6d556a65a42e37095e91e1157",
|
||||
"libSkiaSharp.a": "2a1e5d7d7737921cdb6a9679630fb3068ce1d2eecd7300ec7747898bb8132d39",
|
||||
"libskia.a": "8062a85f7f5ded8f67c19db06b42c6792a526d5856c4bae467fb46d182992315"
|
||||
},
|
||||
"executables_sha256": {
|
||||
"smoke-angle": "1930720daf83d6a63268427b5c1a700a46fa6cf8edd93821133224fb1d456522",
|
||||
"smoke-raster": "6cb98cb854b52f94339eb225422d511b6e11abc9e5299658b455352f332139c4"
|
||||
}
|
||||
},
|
||||
"osx-arm64": {
|
||||
"six_archives_compiled": true,
|
||||
"raster_harfbuzz_link": "passed",
|
||||
"egl_gles_link": "passed",
|
||||
"archives_sha256": {
|
||||
"libANGLE.a": "3459ece2b66c8cbb096bf20016a40d4d463224ff7a0b4e29cab44c578daf1665",
|
||||
"libEGL.a": "6011625f7ac8bf467e3135588a9a30e472f55fec6de3834b1b472deed4627d15",
|
||||
"libGLESv2.a": "2c4e990ddc67f98abcc09401fa5541386cbe80458581c6fd621fd379a8541835",
|
||||
"libHarfBuzzSharp.a": "3802662600cca36985997d24187c3bc06e1a20c258fc260778eecd34a5d791f9",
|
||||
"libSkiaSharp.a": "e5bf6468713228ab9386d6f31f6556aed98a9cbc307b4be1fbbd61644f97658b",
|
||||
"libskia.a": "44e3515fdf0f09c8621b35c37c23d4441d34a831d42b88391811ad8fdff710da"
|
||||
},
|
||||
"executables_sha256": {
|
||||
"smoke-angle": "f19386a0d04af9a89f8ec70df6f3a1205747cfc2761efd86c4e781bcf0818018",
|
||||
"smoke-raster": "954dde21bf79234fa0abc30b6e5307c88558996b7777f0d459693a3588b1cc43"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"date_utc": "2026-10-04",
|
||||
"compiler": "Zig 0.14.1 / Clang 19",
|
||||
"cross_configuration_checks": {
|
||||
"2.88.9/win-x64": 0,
|
||||
"2.88.9/win-x86": 0,
|
||||
"2.88.9/win-arm64": 0,
|
||||
"2.88.9/osx-x64": 0,
|
||||
"2.88.9/osx-arm64": 0,
|
||||
"3.119.1/win-x64": 0,
|
||||
"3.119.1/win-x86": 0,
|
||||
"3.119.1/win-arm64": 0,
|
||||
"3.119.1/osx-x64": 0,
|
||||
"3.119.1/osx-arm64": 0,
|
||||
"4.150.1/win-x64": 0,
|
||||
"4.150.1/win-x86": 0,
|
||||
"4.150.1/win-arm64": 0,
|
||||
"4.150.1/osx-x64": 0,
|
||||
"4.150.1/osx-arm64": 0
|
||||
},
|
||||
"native_linux_configuration_checks": {
|
||||
"2.88.9/x64": "passed",
|
||||
"2.88.9/arm64": "passed",
|
||||
"3.119.1/x64": "passed",
|
||||
"3.119.1/arm64": "passed",
|
||||
"4.150.1/x64": "passed",
|
||||
"4.150.1/arm64": "passed"
|
||||
},
|
||||
"new_full_build_checks": {
|
||||
"2.88.9": {
|
||||
"target": "win-x64",
|
||||
"three_archives": "passed",
|
||||
"raster_harfbuzz_executable_link": "passed",
|
||||
"sha256": {
|
||||
"libskia.a": "d972f868e4910cee774d592b09e3e52f65657ec3b10a1c38c26e6625e998196e",
|
||||
"libSkiaSharp.a": "e7f22c39ce570fa74988e13a288e00646cf1b08e0be82e60a6b589bab149a8fd",
|
||||
"libHarfBuzzSharp.a": "e7e117c25a16f9770f0953a260441d920b5a1e27b8c52457429f03ddacbe8855",
|
||||
"smoke-raster.exe": "6a8ab77adc1444933757f702aa4dab10716a60a284ffa4777745493443909f9d"
|
||||
}
|
||||
},
|
||||
"3.119.1": {
|
||||
"target": "win-x64",
|
||||
"three_archives": "passed",
|
||||
"raster_harfbuzz_executable_link": "passed",
|
||||
"sha256": {
|
||||
"libskia.a": "d895266910b2fc8a6a72d56715ddd0b50e1e9752b184d3b99a31b8ca6614451a",
|
||||
"libSkiaSharp.a": "544685511adf5b29eac2df771ef5088ba271fb570614671d0bde68e841ac3b32",
|
||||
"libHarfBuzzSharp.a": "6ac05af0bb31b42af86f003e4eb70db4c4eeb021b5a438282bbd182db0dba100",
|
||||
"smoke-raster.exe": "80cfda94712bd1df0671ce96fb27a174053451557d99ab542f148ac45a951532"
|
||||
}
|
||||
}
|
||||
},
|
||||
"runtime_tests": false,
|
||||
"docker_cold_build_tested": false,
|
||||
"4.150.1": "Previous five-target full archive/link checks are in local-cross-validation.json; updated win-x64 link test also passed."
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Export verified Zig archives in the layout consumed by the NuGet package."""
|
||||
import argparse,json,shutil,hashlib
|
||||
from pathlib import Path
|
||||
p=argparse.ArgumentParser();p.add_argument('--input',type=Path,required=True);p.add_argument('--output',type=Path,required=True);p.add_argument('--rid',required=True)
|
||||
a=p.parse_args();manifest=json.loads((a.input/'cross-build.json').read_text())
|
||||
if manifest['target']!=a.rid or not manifest.get('link_tests','').startswith('passed'):
|
||||
raise SystemExit('Only successfully linked target archives may be packaged')
|
||||
names={'libskia.a':'skia.lib','libSkiaSharp.a':'SkiaSharp.lib','libHarfBuzzSharp.a':'libHarfBuzzSharp.lib','libANGLE.a':'libANGLE_static.lib','libGLESv2.a':'libGLESv2_static.lib','libEGL.a':'libEGL_static.lib'} if a.rid.startswith('win') else {'libskia.a':'libskia.a','libSkiaSharp.a':'libSkiaSharp.a','libHarfBuzzSharp.a':'libHarfBuzzSharp.a','libANGLE.a':'libANGLE_static.a','libGLESv2.a':'libGLESv2_static.a','libEGL.a':'libEGL_static.a'}
|
||||
a.output.mkdir(parents=True,exist_ok=True)
|
||||
for source,destination in names.items():
|
||||
path=a.input/source
|
||||
if hashlib.sha256(path.read_bytes()).hexdigest()!=manifest['archives'][source]:raise SystemExit('Archive checksum mismatch: '+source)
|
||||
shutil.copy2(path,a.output/destination)
|
||||
runtime=a.input/'zig-runtime'
|
||||
if not runtime.is_dir() or not [p for p in runtime.iterdir() if p.suffix in ('.a','.lib')]:raise SystemExit('Zig C++/compiler runtime archives were not captured')
|
||||
(a.output/'zig-runtime').mkdir(exist_ok=True)
|
||||
for path in runtime.iterdir():
|
||||
if path.suffix not in ('.a','.lib'):continue
|
||||
dest=path.stem+'.lib' if a.rid.startswith('win') else path.name
|
||||
shutil.copy2(path,a.output/'zig-runtime'/dest)
|
||||
if a.rid=='win-x86':
|
||||
path=a.input/'skia_x86_stdcall_thunks.lib'
|
||||
if not path.is_file():raise SystemExit('x86 stdcall thunks are required')
|
||||
shutil.copy2(path,a.output/path.name)
|
||||
shutil.copy2(a.input/'cross-build.json',a.output/'zig-build.json')
|
||||
print('Packaged',a.rid)
|
||||
@@ -0,0 +1,2 @@
|
||||
# Unified diffs contain space-prefixed empty context lines.
|
||||
*.patch -whitespace
|
||||
@@ -0,0 +1,28 @@
|
||||
--- a/BUILD.gn
|
||||
+++ b/BUILD.gn
|
||||
@@ -427,7 +427,8 @@
|
||||
ldflags = [ "-Wl,--build-id" ]
|
||||
}
|
||||
|
||||
-_use_copy_compiler_dll = angle_has_build && is_win
|
||||
+declare_args() { angle_copy_compiler_dll = true }
|
||||
+_use_copy_compiler_dll = angle_has_build && is_win && angle_copy_compiler_dll
|
||||
|
||||
if (_use_copy_compiler_dll) {
|
||||
copy("copy_compiler_dll") {
|
||||
@@ -1534,6 +1535,7 @@
|
||||
}
|
||||
|
||||
angle_static_library("libGLESv2_static") {
|
||||
+ complete_static_lib = true
|
||||
|
||||
sources = libglesv2_sources
|
||||
public_deps = [ ":libGLESv2_thin_static" ]
|
||||
@@ -1652,6 +1654,7 @@
|
||||
}
|
||||
|
||||
libEGL_template("libEGL_static") {
|
||||
+ complete_static_lib = true
|
||||
target_type = "angle_static_library"
|
||||
public_configs = [ ":angle_static_config" ]
|
||||
deps = [ ":libGLESv2_static" ]
|
||||
@@ -0,0 +1,20 @@
|
||||
--- a/build/config/BUILDCONFIG.gn
|
||||
+++ b/build/config/BUILDCONFIG.gn
|
||||
@@ -584,7 +584,7 @@
|
||||
}
|
||||
|
||||
if (!defined(use_libcxx_modules)) {
|
||||
- use_libcxx_modules = is_clang
|
||||
+ use_libcxx_modules = is_clang && !(is_win && host_os == "linux")
|
||||
}
|
||||
|
||||
if (filter_include(
|
||||
@@ -715,7 +715,7 @@
|
||||
}
|
||||
|
||||
if (!defined(use_libcxx_modules)) {
|
||||
- use_libcxx_modules = is_clang
|
||||
+ use_libcxx_modules = is_clang && !(is_win && host_os == "linux")
|
||||
}
|
||||
|
||||
if (filter_include(
|
||||
@@ -0,0 +1,64 @@
|
||||
diff --git a/DEPS b/DEPS
|
||||
index 8ba99a6..1a5e1a5 100644
|
||||
--- a/DEPS
|
||||
+++ b/DEPS
|
||||
@@ -768,9 +768,4 @@ deps = {
|
||||
},
|
||||
|
||||
- 'third_party/catapult': {
|
||||
- 'url': Var('chromium_git') + '/catapult.git' + '@' + Var('catapult_revision'),
|
||||
- 'condition': 'not build_with_chromium',
|
||||
- },
|
||||
-
|
||||
# Cherry is a dEQP/VK-GL-CTS management GUI written in Go. We use it for viewing test results.
|
||||
'third_party/cherry': {
|
||||
@@ -795,9 +790,4 @@ deps = {
|
||||
|
||||
|
||||
- 'third_party/dawn': {
|
||||
- 'url': Var('dawn_git') + '/dawn.git' + '@' + Var('dawn_revision'),
|
||||
- 'condition': 'checkout_angle_dawn_deps and not build_with_chromium'
|
||||
- },
|
||||
-
|
||||
'third_party/depot_tools': {
|
||||
'url': Var('chromium_git') + '/chromium/tools/depot_tools.git@94e89b10b92cc9d6e58fc8d1b6474b7d29e8a114',
|
||||
@@ -875,9 +865,4 @@ deps = {
|
||||
},
|
||||
|
||||
- 'third_party/llvm/src': {
|
||||
- 'url': Var('chromium_git') + '/external/github.com/llvm/llvm-project@67790d3fb06b184b7be9c4d3e36ab01f0ac4198e',
|
||||
- 'condition': 'checkout_angle_cl_deps and not build_with_chromium',
|
||||
- },
|
||||
-
|
||||
'third_party/llvm-build/Release+Asserts': {
|
||||
'dep_type': 'gcs',
|
||||
@@ -1217,9 +1202,4 @@ deps = {
|
||||
},
|
||||
|
||||
- 'third_party/SwiftShader': {
|
||||
- 'url': Var('swiftshader_git') + '/SwiftShader@f3e464b1e56795940f826a972b39e19bd9f6ac6c',
|
||||
- 'condition': 'not build_with_chromium',
|
||||
- },
|
||||
-
|
||||
'third_party/turbine/cipd': {
|
||||
'packages': [
|
||||
@@ -1233,8 +1213,4 @@ deps = {
|
||||
},
|
||||
|
||||
- 'third_party/VK-GL-CTS/src': {
|
||||
- 'url': Var('chromium_git') + '/external/github.com/KhronosGroup/VK-GL-CTS' + '@' + Var('vk_gl_cts_revision'),
|
||||
- },
|
||||
-
|
||||
'third_party/vulkan-deps': {
|
||||
'url': Var('chromium_git') + '/vulkan-deps@f2b9fece7c6772c09379b3a6938dbcd2573f2a3e',
|
||||
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
|
||||
index 710bba9..33d4a64 100644
|
||||
--- a/src/compiler/translator/IntermNode.cpp
|
||||
+++ b/src/compiler/translator/IntermNode.cpp
|
||||
@@ -881,5 +881,5 @@ const TConstantUnion *TIntermAggregate::getConstantValue() const
|
||||
angle::base::CheckedNumeric<size_t> checkedArraySize = elementSize;
|
||||
checkedArraySize *= getOutermostArraySize();
|
||||
- constArray = new TConstantUnion[checkedArraySize.ValueOrDie()];
|
||||
+ constArray = new TConstantUnion[static_cast<size_t>(checkedArraySize.ValueOrDie())];
|
||||
|
||||
size_t elementOffset = 0u;
|
||||
@@ -0,0 +1,21 @@
|
||||
--- a/BUILD.gn
|
||||
+++ b/BUILD.gn
|
||||
@@ -1523,7 +1523,18 @@
|
||||
public_deps = [ ":libANGLE" ]
|
||||
}
|
||||
|
||||
+angle_static_library("libANGLE_static") {
|
||||
+ complete_static_lib = true
|
||||
+ public_deps = [ ":libANGLE" ]
|
||||
+}
|
||||
+
|
||||
+angle_static_library("libANGLE_with_capture_static") {
|
||||
+ complete_static_lib = true
|
||||
+ public_deps = [ ":libANGLE_with_capture" ]
|
||||
+}
|
||||
+
|
||||
angle_static_library("libGLESv2_static") {
|
||||
+
|
||||
sources = libglesv2_sources
|
||||
public_deps = [ ":libGLESv2_thin_static" ]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
--- a/build/mac/find_sdk.py
|
||||
+++ b/build/mac/find_sdk.py
|
||||
@@ -1,3 +1,12 @@
|
||||
+import os,sys,json
|
||||
+if sys.platform == 'linux' and os.environ.get('STATICLINK_MACOS_SDK'):
|
||||
+ sdk=os.environ['STATICLINK_MACOS_SDK']
|
||||
+ if '--print_sdk_path' in sys.argv:print('//'+str(__import__('pathlib').Path.cwd().relative_to(__import__('pathlib').Path(__file__).resolve().parents[2]))+'/sdk/xcode_links/MacOSX15.5.sdk')
|
||||
+ if '--print_bin_path' in sys.argv:print(os.environ['STATICLINK_DARWIN_TOOLS'])
|
||||
+ if '--print_sdk_build' in sys.argv:print('24F74')
|
||||
+ print('15.5')
|
||||
+ sys.exit(0)
|
||||
+
|
||||
#!/usr/bin/env python3
|
||||
# Copyright 2012 The Chromium Authors
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
@@ -0,0 +1,38 @@
|
||||
--- a/build/toolchain/gcc_toolchain.gni
|
||||
+++ b/build/toolchain/gcc_toolchain.gni
|
||||
@@ -369,6 +369,35 @@
|
||||
outputs = [ output ]
|
||||
}
|
||||
|
||||
+ if (current_os == "mac") {
|
||||
+ tool("objc") {
|
||||
+ output = "$object_subdir/{{source_name_part}}.o"
|
||||
+ depfile = "$output.d"
|
||||
+ precompiled_header_type = "gcc"
|
||||
+
|
||||
+ # {{output}} may contain .dwo file, so use $output instead of {{output}}
|
||||
+ # in command.
|
||||
+ command = "$coverage_wrapper$cc $md -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_objc}}${extra_cppflags}${extra_cflags}${module_name_flag} -c {{source}} -o $output"
|
||||
+ depsformat = "gcc"
|
||||
+ description = "OBJC {{output}}"
|
||||
+ outputs = [ output ]
|
||||
+ }
|
||||
+
|
||||
+ tool("objcxx") {
|
||||
+ output = "$object_subdir/{{source_name_part}}.o"
|
||||
+ depfile = "$output.d"
|
||||
+ precompiled_header_type = "gcc"
|
||||
+
|
||||
+ # {{output}} may contain .dwo file, so use $output instead of {{output}}
|
||||
+ # in command.
|
||||
+ command = "$coverage_wrapper$cxx $md -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_objcc}}${extra_cppflags}${extra_cxxflags} {{module_deps}}${module_name_flag} -c {{source}} -o $output"
|
||||
+ depsformat = "gcc"
|
||||
+ description = "OBJCXX {{output}}"
|
||||
+ outputs = [ output ]
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
tool("cxx_module") {
|
||||
depfile = "{{output}}.d"
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
--- a/build/config/apple/sdk_info.py
|
||||
+++ b/build/config/apple/sdk_info.py
|
||||
@@ -1,3 +1,11 @@
|
||||
+import os,sys,json
|
||||
+if sys.platform == 'linux' and os.environ.get('STATICLINK_MACOS_SDK'):
|
||||
+ sdk=os.environ['STATICLINK_MACOS_SDK']
|
||||
+ sdk='//'+str(__import__('pathlib').Path.cwd().relative_to(__import__('pathlib').Path(__file__).resolve().parents[3]))+'/sdk/xcode_links/MacOSX15.5.sdk'
|
||||
+ values={'xcode_version':'1640','xcode_version_int':1640,'xcode_build':'16F6','sdk_path':sdk,'sdk_version':'15.5','sdk_build':'24F74','sdk_platform_path':sdk,'toolchains_path':os.environ['STATICLINK_DARWIN_TOOLS']}
|
||||
+ for k,v in values.items():print(k+'='+json.dumps(v))
|
||||
+ sys.exit(0)
|
||||
+
|
||||
#!/usr/bin/env python3
|
||||
# Copyright 2014 The Chromium Authors
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
@@ -0,0 +1,11 @@
|
||||
--- a/src/xps/SkXPSDevice.cpp
|
||||
+++ b/src/xps/SkXPSDevice.cpp
|
||||
@@ -337,7 +337,7 @@
|
||||
return true;
|
||||
}
|
||||
|
||||
-static HRESULT subset_typeface(const SkXPSDevice::TypefaceUse& current) {
|
||||
+HRESULT subset_typeface(const SkXPSDevice::TypefaceUse& current) {
|
||||
//The CreateFontPackage API is only supported on desktop, not in UWP
|
||||
#if defined(SK_WINUWP) || defined(SK_BUILD_FOR_WINRT) || defined(SK_BUILD_FOR_NANOSERVER)
|
||||
return E_NOTIMPL;
|
||||
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Compile target objects and SDK API probes; this does not build release libraries."""
|
||||
import argparse
|
||||
import json
|
||||
import pathlib
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
TARGETS = (
|
||||
"x86-windows-gnu", "x86_64-windows-gnu", "aarch64-windows-gnu",
|
||||
"x86-windows-msvc", "x86_64-windows-msvc", "aarch64-windows-msvc",
|
||||
"x86_64-macos", "aarch64-macos",
|
||||
)
|
||||
SOURCES = {
|
||||
"plain": "int answer(void) { return 42; }\n",
|
||||
"cpp": '#include <string>\nextern "C" int answer(void) { std::string s="test"; return int(s.size()); }\n',
|
||||
"windows": '''#include <windows.h>
|
||||
#include <dwrite_3.h>
|
||||
#include <xpsobjectmodel.h>
|
||||
// These call shapes are required by Skia 4.150.1's DirectWrite paint backend.
|
||||
HRESULT paint_child(IDWritePaintReader* reader, DWRITE_PAINT_ELEMENT* element) {
|
||||
return reader->MoveToFirstChild(element);
|
||||
}
|
||||
void paint_color(IDWritePaintReader* reader, DWRITE_COLOR_F color) {
|
||||
reader->SetTextColor(color);
|
||||
}
|
||||
''',
|
||||
"macos": '''#include <ApplicationServices/ApplicationServices.h>
|
||||
#import <Metal/Metal.h>
|
||||
int answer(void) { return sizeof(CFIndex); }
|
||||
''',
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--zig", default="zig")
|
||||
parser.add_argument("--output", type=pathlib.Path, required=True)
|
||||
parser.add_argument("--target", choices=TARGETS, action="append")
|
||||
parser.add_argument("--macos-sdk", type=pathlib.Path)
|
||||
parser.add_argument("--windows-sdk", type=pathlib.Path,
|
||||
help="An xwin splat containing crt/include and sdk/include")
|
||||
args = parser.parse_args()
|
||||
output = args.output.resolve()
|
||||
output.mkdir(parents=True, exist_ok=True)
|
||||
version = subprocess.check_output([args.zig, "version"], text=True).strip()
|
||||
results = {"zig_version": version, "targets": {}}
|
||||
with tempfile.TemporaryDirectory(prefix="staticlink-probe-") as temporary:
|
||||
source_dir = pathlib.Path(temporary)
|
||||
for name, source in SOURCES.items():
|
||||
suffix = ".mm" if name == "macos" else ".cpp"
|
||||
(source_dir / (name + suffix)).write_text(source)
|
||||
for target in args.target or TARGETS:
|
||||
destination = output / target
|
||||
destination.mkdir(exist_ok=True)
|
||||
flags = []
|
||||
if "macos" in target and args.macos_sdk:
|
||||
sdk = args.macos_sdk.resolve()
|
||||
flags += ["-isysroot", str(sdk), "-F", str(sdk / "System/Library/Frameworks")]
|
||||
if target.endswith("windows-msvc") and args.windows_sdk:
|
||||
sdk = args.windows_sdk.resolve()
|
||||
for include in ("crt/include", "sdk/include/ucrt", "sdk/include/shared", "sdk/include/um"):
|
||||
flags += ["-isystem", str(sdk / include)]
|
||||
target_results = {}
|
||||
for name in ("plain", "cpp", "windows" if "windows" in target else "macos"):
|
||||
suffix = ".mm" if name == "macos" else ".cpp"
|
||||
command = [args.zig, "c++", "-target", target, "-std=c++20", *flags,
|
||||
"-c", str(source_dir / (name + suffix)),
|
||||
"-o", str(destination / (name + ".o"))]
|
||||
result = subprocess.run(command, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT, text=True)
|
||||
(destination / (name + ".log")).write_text(result.stdout)
|
||||
target_results[name] = {"exit_code": result.returncode, "command": command}
|
||||
print(target, name, "PASS" if result.returncode == 0 else "FAIL", flush=True)
|
||||
results["targets"][target] = target_results
|
||||
(output / "results.json").write_text(json.dumps(results, indent=2) + "\n")
|
||||
return int(any(test["exit_code"] for tests in results["targets"].values() for test in tests.values()))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"date": "2026-10-04",
|
||||
"zig": "0.14.1",
|
||||
"versions": [
|
||||
"3.119.2",
|
||||
"3.119.4",
|
||||
"4.150.3",
|
||||
"4.150.5",
|
||||
"4.153.1"
|
||||
],
|
||||
"configuration": {
|
||||
"passed": 45,
|
||||
"targets_per_version": 9,
|
||||
"full_build": false
|
||||
},
|
||||
"full_skia_build_and_executable_link": {
|
||||
"win-x64": [
|
||||
"3.119.2",
|
||||
"3.119.4",
|
||||
"4.150.3",
|
||||
"4.150.5",
|
||||
"4.153.1"
|
||||
],
|
||||
"win-x86": [
|
||||
"3.119.4"
|
||||
],
|
||||
"linux-x64": [
|
||||
"3.119.4"
|
||||
],
|
||||
"linux-arm64": [
|
||||
"3.119.4"
|
||||
],
|
||||
"osx-arm64": [
|
||||
"4.153.1"
|
||||
]
|
||||
},
|
||||
"angle": {
|
||||
"linux-x64": "3.119.4: six archives compiled and both executable links passed",
|
||||
"win-x86": "3.119.4: fixed ANGLE archives reused; both executable links passed"
|
||||
},
|
||||
"execution": {
|
||||
"linux-x64": "64 raster pixels and 2 UTF-8 codepoints passed",
|
||||
"linux-arm64": "same raster/UTF-8 test passed under QEMU",
|
||||
"gpu": "not validated; Linux ANGLE probe lacked a display"
|
||||
},
|
||||
"avalonia_native": {
|
||||
"versions": [
|
||||
"11.3.14",
|
||||
"12.1.0"
|
||||
],
|
||||
"targets": [
|
||||
"osx-x64",
|
||||
"osx-arm64"
|
||||
],
|
||||
"compilation": "all four passed",
|
||||
"executable_link": "all four passed against macOS SDK system libc++",
|
||||
"execution": "not run"
|
||||
},
|
||||
"not_validated": [
|
||||
"complete Debian Docker image build",
|
||||
"all five releases full nine-RID build",
|
||||
"Windows/macOS runtime",
|
||||
"full NativeAOT application",
|
||||
"GitHub Actions execution",
|
||||
"NuGet publication"
|
||||
],
|
||||
"environment_note": "Local builds ran on the Linux host with pinned cross tools, not inside Docker. Disk exhaustion required resumptions; it is not recorded as source incompatibility."
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
target_os = "linux"
|
||||
target_cpu = "@CPU@"
|
||||
is_official_build = true
|
||||
is_static_skiasharp = true
|
||||
skia_enable_tools = false
|
||||
skia_enable_ganesh = true
|
||||
skia_enable_pdf = false
|
||||
skia_enable_skottie = false
|
||||
skia_use_dng_sdk = false
|
||||
skia_use_fontconfig = true
|
||||
skia_use_freetype = true
|
||||
skia_use_harfbuzz = false
|
||||
skia_use_icu = false
|
||||
skia_use_piex = false
|
||||
skia_use_sfntly = false
|
||||
skia_use_system_expat = false
|
||||
skia_use_system_freetype2 = false
|
||||
skia_use_system_libjpeg_turbo = false
|
||||
skia_use_system_libpng = false
|
||||
skia_use_system_libwebp = false
|
||||
skia_use_system_zlib = false
|
||||
skia_use_vulkan = false
|
||||
skia_use_xps = false
|
||||
extra_cflags_cc = [ "-frtti", "-pthread" ]
|
||||
cc = "@CC@"
|
||||
cxx = "@CXX@"
|
||||
ar = "@AR@"
|
||||
extra_cflags = [ "-DSKIA_C_DLL", "-DHAVE_SYSCALL_GETRANDOM", "-DXML_DEV_URANDOM" ]
|
||||
# Standalone SkiaSharp excludes the Chromium PartitionAlloc dependency.
|
||||
skia_use_partition_alloc = false
|
||||
@@ -0,0 +1,27 @@
|
||||
target_os = "mac"
|
||||
target_cpu = "@CPU@"
|
||||
is_official_build = true
|
||||
is_static_skiasharp = true
|
||||
skia_enable_tools = false
|
||||
skia_enable_ganesh = true
|
||||
skia_use_metal = true
|
||||
skia_enable_pdf = false
|
||||
skia_enable_skottie = false
|
||||
skia_use_dng_sdk = false
|
||||
skia_use_fontconfig = false
|
||||
skia_use_freetype = false
|
||||
skia_use_harfbuzz = false
|
||||
skia_use_icu = false
|
||||
skia_use_piex = false
|
||||
skia_use_sfntly = false
|
||||
skia_use_system_expat = false
|
||||
skia_use_system_libjpeg_turbo = false
|
||||
skia_use_system_libpng = false
|
||||
skia_use_system_libwebp = false
|
||||
skia_use_system_zlib = false
|
||||
skia_use_vulkan = false
|
||||
skia_use_xps = false
|
||||
extra_cflags = [ "-DSKIA_C_DLL" ]
|
||||
extra_cflags_cc = [ "-frtti" ]
|
||||
# Standalone SkiaSharp excludes the Chromium PartitionAlloc dependency.
|
||||
skia_use_partition_alloc = false
|
||||
@@ -0,0 +1,28 @@
|
||||
target_os = "win"
|
||||
target_cpu = "@CPU@"
|
||||
is_official_build = true
|
||||
is_static_skiasharp = true
|
||||
is_clang = true
|
||||
skia_enable_tools = false
|
||||
skia_enable_ganesh = true
|
||||
skia_enable_pdf = false
|
||||
skia_enable_skottie = false
|
||||
skia_use_dng_sdk = false
|
||||
skia_use_fontconfig = false
|
||||
skia_use_freetype = false
|
||||
skia_use_harfbuzz = false
|
||||
skia_use_icu = false
|
||||
skia_use_piex = false
|
||||
skia_use_sfntly = false
|
||||
skia_use_system_expat = false
|
||||
skia_use_system_freetype2 = false
|
||||
skia_use_system_libjpeg_turbo = false
|
||||
skia_use_system_libpng = false
|
||||
skia_use_system_libwebp = false
|
||||
skia_use_system_zlib = false
|
||||
skia_use_vulkan = false
|
||||
skia_use_xps = true
|
||||
extra_cflags = [ "-DSKIA_C_DLL" ]
|
||||
extra_cflags_cc = [ "/GR" ]
|
||||
# Standalone SkiaSharp excludes the Chromium PartitionAlloc dependency.
|
||||
skia_use_partition_alloc = false
|
||||
@@ -0,0 +1,123 @@
|
||||
"""Discover Skia GN capabilities; keep version policy out of the build driver."""
|
||||
import json
|
||||
from pathlib import Path
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
|
||||
def repair_xps(source):
|
||||
path = source / 'src/xps/SkXPSDevice.cpp'
|
||||
header = source / 'src/xps/SkXPSDevice.h'
|
||||
if not path.exists() or not header.exists():
|
||||
return 'absent'
|
||||
text = path.read_text()
|
||||
if not re.search(r'friend\s+HRESULT\s+subset_typeface\s*\(', header.read_text()):
|
||||
return 'not-needed'
|
||||
text, count = re.subn(r'(?m)^static HRESULT (subset_typeface\s*\()', r'HRESULT \1', text)
|
||||
if count > 1:
|
||||
raise RuntimeError('Ambiguous XPS helper declarations; inspect the new source layout')
|
||||
if count:
|
||||
path.write_text(text)
|
||||
return 'repaired' if count else 'already-compatible'
|
||||
|
||||
|
||||
def repair_skcms(source):
|
||||
repaired = []
|
||||
for relative in ('third_party/skcms/skcms.cc', 'modules/skcms/skcms.cc'):
|
||||
path = source / relative
|
||||
if not path.is_file():
|
||||
continue
|
||||
text = path.read_text()
|
||||
def replace(match):
|
||||
features = match[2]
|
||||
if 'avx512f' in features.split(',') and 'evex512' not in features.split(','):
|
||||
return match[1] + features + ',evex512' + match[3]
|
||||
return match[0]
|
||||
updated = re.sub(r'(#pragma clang attribute push\(__attribute__\(\(target\(")([^"]+)("\)\)\))', replace, text)
|
||||
if updated != text:
|
||||
path.write_text(updated)
|
||||
repaired.append(relative)
|
||||
# This changes only the AVX512-dispatched functions' Clang target attribute;
|
||||
# the baseline CPU path and runtime dispatch remain unchanged.
|
||||
return repaired
|
||||
|
||||
|
||||
def configure(source, out, desired, gn, env):
|
||||
# GN itself resolves imports, defaults and conditional declarations. Text
|
||||
# searches alone can incorrectly report an option from an inactive branch.
|
||||
# Apply the feature policy during discovery too: Skia's default tools build
|
||||
# can otherwise demand test-only dependencies before we can list options.
|
||||
bootstrap = dict(desired)
|
||||
out.mkdir(parents=True, exist_ok=True)
|
||||
def write(values):
|
||||
(out / 'args.gn').write_text(''.join(f'{key} = {value}\n' for key, value in values.items()))
|
||||
write(bootstrap)
|
||||
subprocess.run([str(gn), 'gen', str(out.relative_to(source))],
|
||||
cwd=source, env=env, check=True)
|
||||
command = [str(gn), 'args', str(out.relative_to(source)), '--list', '--json']
|
||||
result = subprocess.run(command, cwd=source, env=env, capture_output=True, text=True)
|
||||
if result.returncode:
|
||||
raise RuntimeError('Cannot discover Skia build arguments:\n' + result.stdout + result.stderr)
|
||||
# Older GN emits warnings before the JSON array for unsupported bootstrap args.
|
||||
match = re.search(r'(?m)^\[\s*\{', result.stdout)
|
||||
if not match:
|
||||
raise RuntimeError('GN did not return an argument list:\n' + result.stdout)
|
||||
arguments = json.loads(result.stdout[match.start():])
|
||||
available = {entry['name'] for entry in arguments}
|
||||
values = {key: value for key, value in desired.items() if key in available}
|
||||
if 'skia_enable_ganesh' in available:
|
||||
values['skia_enable_ganesh'] = 'true'
|
||||
elif 'skia_enable_gpu' in available:
|
||||
values['skia_enable_gpu'] = 'true'
|
||||
else:
|
||||
raise RuntimeError('No known Skia GPU switch; refusing to silently change the graphics feature set')
|
||||
required = {'target_os', 'target_cpu', 'is_static_skiasharp', 'extra_cflags', 'extra_cflags_cc'}
|
||||
required |= {key for key in ('skia_use_metal', 'skia_use_xps') if desired.get(key) == 'true'}
|
||||
missing = required - available
|
||||
if missing:
|
||||
raise RuntimeError('Skia source lacks required build capabilities: ' + ', '.join(sorted(missing)))
|
||||
write(values)
|
||||
subprocess.run([str(gn), 'gen', str(out.relative_to(source)), '--fail-on-unused-args'],
|
||||
cwd=source, env=env, check=True)
|
||||
report = {'available_arguments': sorted(available), 'selected_arguments': values,
|
||||
'omitted_obsolete_arguments': sorted(set(desired) - available)}
|
||||
(out / 'skia-capabilities.json').write_text(json.dumps(report, indent=2) + '\n')
|
||||
return report
|
||||
|
||||
|
||||
def parse_args(text):
|
||||
# Values can include multiline lists, as used by the native Linux recipe.
|
||||
assignments = list(re.finditer(r'(?m)^[ \t]*([A-Za-z_]\w*)[ \t]*=', text))
|
||||
if not assignments:
|
||||
raise ValueError('No GN assignments in build recipe')
|
||||
return {match[1]: text[match.end():assignments[index + 1].start()
|
||||
if index + 1 < len(assignments) else len(text)].strip()
|
||||
for index, match in enumerate(assignments)}
|
||||
|
||||
|
||||
def archive(source, name):
|
||||
candidates = [source / (name + '.lib'), source / ('lib' + name + '.a'),
|
||||
source / 'obj' / (name + '.lib'), source / 'obj' / ('lib' + name + '.a')]
|
||||
matches = [path for path in candidates if path.is_file()]
|
||||
if len(matches) != 1:
|
||||
raise RuntimeError(f'Expected one archive for {name}; found {matches}')
|
||||
return matches[0]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import argparse
|
||||
import os
|
||||
p = argparse.ArgumentParser(description='Configure native or cross Skia using its actual GN capabilities')
|
||||
p.add_argument('--source', type=Path, required=True)
|
||||
p.add_argument('--out', type=Path, required=True)
|
||||
a = p.parse_args()
|
||||
source, out = a.source.resolve(), a.out.resolve()
|
||||
gn = source / ('bin/gn.exe' if os.name == 'nt' else 'bin/gn')
|
||||
repair_xps(source)
|
||||
desired = parse_args((out / 'args.gn').read_text())
|
||||
compiler = desired.get('cc', 'clang-cl' if os.name == 'nt' else 'clang').strip('"')
|
||||
version = subprocess.run([compiler, '--version'], capture_output=True, text=True, check=True)
|
||||
match = re.search(r'clang version (\d+)', version.stdout)
|
||||
if match and int(match[1]) >= 19:
|
||||
repair_skcms(source)
|
||||
configure(source, out, desired, gn, os.environ.copy())
|
||||
@@ -0,0 +1,3 @@
|
||||
#include <EGL/egl.h>
|
||||
#include <GLES2/gl2.h>
|
||||
int main(void) { EGLDisplay d = eglGetDisplay(EGL_DEFAULT_DISPLAY); EGLint a,b; if (!eglInitialize(d,&a,&b)) return 1; glClear(GL_COLOR_BUFFER_BIT); return eglTerminate(d) ? 0 : 2; }
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "include/c/sk_general.h"
|
||||
#include "include/c/sk_surface.h"
|
||||
#include "include/c/sk_canvas.h"
|
||||
#include "hb.h"
|
||||
#ifndef STATICLINK_EXPECTED_MILESTONE
|
||||
#error "Pass the milestone detected from this source tree"
|
||||
#endif
|
||||
int main(void) {
|
||||
if (sk_version_get_milestone() != STATICLINK_EXPECTED_MILESTONE) return 1;
|
||||
sk_imageinfo_t info = {NULL, 8, 8, RGBA_8888_SK_COLORTYPE, PREMUL_SK_ALPHATYPE};
|
||||
sk_surface_t *surface = sk_surface_new_raster(&info, 0, NULL);
|
||||
if (!surface) return 2;
|
||||
sk_canvas_clear(sk_surface_get_canvas(surface), 0xff336699u);
|
||||
uint8_t pixels[8*8*4];
|
||||
if (!sk_surface_read_pixels(surface, &info, pixels, 8*4, 0, 0)) return 3;
|
||||
for (int i=0; i<8*8; i++) {
|
||||
if (pixels[i*4] != 0x33 || pixels[i*4+1] != 0x66 || pixels[i*4+2] != 0x99 || pixels[i*4+3] != 0xff) return 4;
|
||||
}
|
||||
sk_surface_unref(surface);
|
||||
hb_buffer_t *buffer = hb_buffer_create();
|
||||
hb_buffer_add_utf8(buffer, "A\xe4\xb8\xad", 4, 0, -1);
|
||||
hb_buffer_guess_segment_properties(buffer);
|
||||
unsigned length = 0;
|
||||
hb_glyph_info_t *glyphs = hb_buffer_get_glyph_infos(buffer, &length);
|
||||
if (length != 2 || glyphs[0].codepoint != 65 || glyphs[1].codepoint != 0x4e2d) return 5;
|
||||
hb_buffer_destroy(buffer);
|
||||
printf("PASS Skia=%s HarfBuzz=%s raster=64 pixels UTF8=2 codepoints\n", sk_version_get_string(), hb_version_string());
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"skiasharp_version": "4.150.1",
|
||||
"skiasharp_revision": "c3e4f4c20e1f23ab74d31a8838a5bd6dc55365f2",
|
||||
"angle_branch": "7922",
|
||||
"angle_revision": "7e08726e32026a0bbabd6ec8a1a90f5ab533ed66",
|
||||
"skia_revision": "0aa2d542e833ffd1d4d1b68a5152375e7f65ce11"
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Fetch pinned native cross-build dependencies without cloning Git history."""
|
||||
import argparse
|
||||
import ast
|
||||
import json
|
||||
import hashlib
|
||||
from pathlib import Path
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
# These dependencies correspond to features explicitly disabled by this recipe.
|
||||
# Unknown/new dependencies stay enabled; do not infer a skip from their names.
|
||||
DISABLED = {'dng_sdk', 'icu', 'dawn', 'angle2', 'swiftshader', 'emsdk'}
|
||||
|
||||
|
||||
def evaluate(node, variables):
|
||||
if isinstance(node, ast.Constant):
|
||||
return node.value
|
||||
if isinstance(node, ast.Dict):
|
||||
return {evaluate(k, variables): evaluate(v, variables) for k, v in zip(node.keys, node.values)}
|
||||
if isinstance(node, (ast.List, ast.Tuple)):
|
||||
return [evaluate(n, variables) for n in node.elts]
|
||||
if isinstance(node, ast.BinOp) and isinstance(node.op, ast.Add):
|
||||
return evaluate(node.left, variables) + evaluate(node.right, variables)
|
||||
if isinstance(node, ast.Call) and isinstance(node.func, ast.Name) and node.func.id == 'Var' and len(node.args) == 1:
|
||||
return variables[evaluate(node.args[0], variables)]
|
||||
raise ValueError('Unsupported DEPS expression: ' + ast.dump(node))
|
||||
|
||||
|
||||
def dependencies(source):
|
||||
values = {}
|
||||
for node in ast.parse((source / 'DEPS').read_text()).body:
|
||||
if isinstance(node, ast.Assign):
|
||||
for name in node.targets:
|
||||
if isinstance(name, ast.Name) and name.id in ('vars', 'deps'):
|
||||
values[name.id] = evaluate(node.value, values.get('vars', {}))
|
||||
if not values.get('deps'):
|
||||
raise ValueError('No dependency map in DEPS')
|
||||
return values['deps']
|
||||
|
||||
|
||||
def main():
|
||||
p = argparse.ArgumentParser(description=__doc__)
|
||||
p.add_argument('--source', type=Path, required=True)
|
||||
p.add_argument('--cache', type=Path, help='Immutable dependency checkouts shared across version profiles')
|
||||
p.add_argument('--no-fetch-gn', action='store_true', help='Use an existing verified GN for a local test')
|
||||
a = p.parse_args()
|
||||
source = a.source.resolve()
|
||||
records = {}
|
||||
for relative, value in dependencies(source).items():
|
||||
if not isinstance(value, str):
|
||||
continue # GN/Ninja CIPD packages are handled by upstream fetch-gn.
|
||||
if Path(relative).name in DISABLED:
|
||||
continue
|
||||
if '..' in Path(relative).parts:
|
||||
raise ValueError('Dependency path escapes source: ' + relative)
|
||||
link = source / relative
|
||||
path = link.absolute()
|
||||
if not path.is_relative_to(source):
|
||||
raise ValueError('Dependency path escapes source: ' + relative)
|
||||
url, revision = value.rsplit('@', 1)
|
||||
if not re.fullmatch(r'[0-9a-f]{40}', revision):
|
||||
raise ValueError('Dependency is not commit-pinned: ' + value)
|
||||
if a.cache:
|
||||
key = hashlib.sha256((url + '@' + revision).encode()).hexdigest()
|
||||
cached = a.cache.resolve() / key
|
||||
if link.is_symlink():
|
||||
link.unlink()
|
||||
if not link.exists():
|
||||
link.parent.mkdir(parents=True, exist_ok=True)
|
||||
link.symlink_to(cached, target_is_directory=True)
|
||||
path = cached
|
||||
if not (path / '.git').exists():
|
||||
subprocess.run(['git', 'init', '-q', str(path)], check=True)
|
||||
subprocess.run(['git', '-C', str(path), 'remote', 'add', 'origin', url], check=True)
|
||||
current = subprocess.run(['git', '-C', str(path), 'rev-parse', 'HEAD'], capture_output=True, text=True)
|
||||
if current.stdout.strip() != revision:
|
||||
subprocess.run(['git', '-C', str(path), 'remote', 'set-url', 'origin', url], check=True)
|
||||
subprocess.run(['git', '-C', str(path), 'fetch', '--depth=1', 'origin', revision], check=True)
|
||||
subprocess.run(['git', '-C', str(path), 'checkout', '--detach', revision], check=True)
|
||||
records[relative] = revision
|
||||
if not a.no_fetch_gn:
|
||||
subprocess.run([sys.executable, str(source / 'bin/fetch-gn')], cwd=source, check=True)
|
||||
(source / 'native-cross-deps.json').write_text(json.dumps(records, indent=2) + '\n')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Validate the actual release container before compiling native libraries."""
|
||||
import argparse
|
||||
import inspect
|
||||
import json
|
||||
from pathlib import Path
|
||||
import runpy
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tarfile
|
||||
import tempfile
|
||||
|
||||
|
||||
def run(command):
|
||||
print("+", " ".join(map(str, command)), flush=True)
|
||||
return subprocess.check_output(list(map(str, command)), text=True, stderr=subprocess.STDOUT)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--output", type=Path, required=True)
|
||||
parser.add_argument("--rids", default="[]")
|
||||
args = parser.parse_args()
|
||||
args.output.mkdir(parents=True, exist_ok=True)
|
||||
report = {"python": sys.version, "targets": {}, "passed": False}
|
||||
try:
|
||||
if "filter" not in inspect.signature(tarfile.TarFile.extractall).parameters:
|
||||
raise RuntimeError("depot_tools requires tarfile extraction filters")
|
||||
for module in ("six", "requests", "httplib2"):
|
||||
__import__(module)
|
||||
run([sys.executable, "/opt/depot_tools/gclient.py", "help"])
|
||||
for tool in ("git", "ninja", "clang", "llvm-ar", "lld", "pkg-config", "cmake", "patch", "file", "dotnet", "zig"):
|
||||
if not shutil.which(tool):
|
||||
raise RuntimeError("Missing tool: " + tool)
|
||||
report["zig"] = run(["zig", "version"]).strip()
|
||||
if report["zig"] != "0.14.1":
|
||||
raise RuntimeError("Unexpected Zig version")
|
||||
report["dotnet_sdks"] = run(["dotnet", "--list-sdks"]).splitlines()
|
||||
for major in ("8.", "10."):
|
||||
if not any(version.startswith(major) for version in report["dotnet_sdks"]):
|
||||
raise RuntimeError("Missing .NET SDK " + major)
|
||||
adapter = Path(__file__).with_name("zig-cross.py")
|
||||
targets = runpy.run_path(str(adapter))["TARGETS"]
|
||||
requested = json.loads(args.rids)
|
||||
if not isinstance(requested, list) or any(rid not in targets for rid in requested):
|
||||
raise ValueError("Expected a JSON array of supported RIDs")
|
||||
if requested:
|
||||
targets = {rid: targets[rid] for rid in requested}
|
||||
sdk = Path("/opt/macos-sdk/MacOSX15.5.sdk")
|
||||
if json.loads((sdk / "SDKSettings.json").read_text())["Version"] != "15.5":
|
||||
raise RuntimeError("Unexpected macOS SDK version")
|
||||
with tempfile.TemporaryDirectory(prefix="staticlink-environment-") as temporary:
|
||||
work = Path(temporary)
|
||||
plain = work / "main.c"
|
||||
plain.write_text("int main(void) { return 0; }\n")
|
||||
cpp = work / "probe.cpp"
|
||||
for rid in targets:
|
||||
target_work = work / rid
|
||||
command = [sys.executable, adapter, "--target", rid, "--output", target_work,
|
||||
"--sdk", sdk, "--mingw-headers", "/opt/mingw/usr/share/mingw-w64/include"]
|
||||
source = "#include <string>\nint value() { return int(std::string(\\\"ok\\\").size()); }\n".replace('\\\"', '"')
|
||||
if rid.startswith("linux"):
|
||||
sysroot = Path("/opt/sysroots") / rid
|
||||
if not (sysroot / "usr/include").is_dir():
|
||||
raise RuntimeError("Missing sysroot: " + rid)
|
||||
if not (sysroot / "usr/include/wayland-client.h").is_file():
|
||||
raise RuntimeError("Missing Wayland headers: " + rid)
|
||||
command += ["--linux-sysroot", sysroot, "--linux-headers", "/opt/staticlink/linux-headers"]
|
||||
source += "#include <fontconfig/fontconfig.h>\n#include <ffi.h>\n#include <ft2build.h>\n#include FT_FREETYPE_H\n"
|
||||
elif rid.startswith("win"):
|
||||
source += "#include <windows.h>\n#include <dwrite_3.h>\n#include <XpsObjectModel.h>\n#include <windows.ui.composition.h>\n"
|
||||
cpp.write_text(source)
|
||||
run(command)
|
||||
run([target_work / "cxx", "-std=c++17", "-c", cpp, "-o", target_work / "cpp.o"])
|
||||
run([target_work / "cc", "-c", plain, "-o", target_work / "main.o"])
|
||||
run([target_work / "ar", "rcs", target_work / "probe.a", target_work / "main.o"])
|
||||
executable = target_work / ("probe.exe" if rid.startswith("win") else "probe")
|
||||
run([target_work / "cc", plain, "-o", executable])
|
||||
if rid.startswith("osx"):
|
||||
objc = work / "probe.mm"
|
||||
objc.write_text("#import <Cocoa/Cocoa.h>\n#import <Metal/Metal.h>\nint value() { return sizeof(CFIndex); }\n")
|
||||
run([target_work / "cxx", "-fobjc-arc", "-fblocks", "-c", objc, "-o", target_work / "objc.o"])
|
||||
report["targets"][rid] = {
|
||||
"passed": True,
|
||||
"object": run(["file", target_work / "main.o"]).strip(),
|
||||
"executable": run(["file", executable]).strip(),
|
||||
}
|
||||
print(rid + ": C/C++ compile, archive and executable link PASS", flush=True)
|
||||
report["passed"] = True
|
||||
except Exception as error:
|
||||
report["error"] = str(error)
|
||||
if isinstance(error, subprocess.CalledProcessError):
|
||||
report["error_output"] = error.output
|
||||
print(error.output, flush=True)
|
||||
raise
|
||||
finally:
|
||||
(args.output / "environment-validation.json").write_text(json.dumps(report, indent=2) + "\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"skiasharp_version": "2.88.9",
|
||||
"skiasharp_revision": "9699cdf046a989423a5e5eca68e7fd813486d81c",
|
||||
"angle_branch": "7922",
|
||||
"angle_revision": "7e08726e32026a0bbabd6ec8a1a90f5ab533ed66",
|
||||
"skia_revision": "4bed689c9c9eb77a120c6a9d54af6a572c85d1c2"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"skiasharp_version": "3.119.1",
|
||||
"skiasharp_revision": "cc78b5933d23e6383db5d246e70db915770d55d6",
|
||||
"angle_branch": "7922",
|
||||
"angle_revision": "7e08726e32026a0bbabd6ec8a1a90f5ab533ed66",
|
||||
"skia_revision": "40f75dc0051d141913c07c20d4c19590c7da0cb7"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"skiasharp_version": "3.119.2",
|
||||
"skiasharp_revision": "2888c737ad016d584c74525e2d35db5097ea8576",
|
||||
"angle_branch": "7922",
|
||||
"angle_revision": "7e08726e32026a0bbabd6ec8a1a90f5ab533ed66",
|
||||
"skia_revision": "927041a58f130e0dd0562ba86cb4170989ad39e9"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"skiasharp_version": "3.119.4",
|
||||
"skiasharp_revision": "f568ac94dd768ef9a2f593537cfde2dd0d348ef5",
|
||||
"angle_branch": "7922",
|
||||
"angle_revision": "7e08726e32026a0bbabd6ec8a1a90f5ab533ed66",
|
||||
"skia_revision": "7dbfc07dd33181f84e0958afb7ee805c6c769f0b"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"skiasharp_version": "4.150.1",
|
||||
"skiasharp_revision": "c3e4f4c20e1f23ab74d31a8838a5bd6dc55365f2",
|
||||
"angle_branch": "7922",
|
||||
"angle_revision": "7e08726e32026a0bbabd6ec8a1a90f5ab533ed66",
|
||||
"skia_revision": "0aa2d542e833ffd1d4d1b68a5152375e7f65ce11"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"skiasharp_version": "4.150.2",
|
||||
"skiasharp_revision": "fd1fdd5239f826514651a4ada5d7bb3dcec2fb43",
|
||||
"angle_branch": "7922",
|
||||
"angle_revision": "7e08726e32026a0bbabd6ec8a1a90f5ab533ed66",
|
||||
"skia_revision": "b70519562e2d26d3cf56286d3a13ca25152cfae4"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"skiasharp_version": "4.150.3",
|
||||
"skiasharp_revision": "f8a404ff3375872d042404a29189ceb8e3001a41",
|
||||
"angle_branch": "7922",
|
||||
"angle_revision": "7e08726e32026a0bbabd6ec8a1a90f5ab533ed66",
|
||||
"skia_revision": "eb86e4b3ee034085b62d3980b3d94629862441e6"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"skiasharp_version": "4.150.5",
|
||||
"skiasharp_revision": "16f82682f756217654eb1a152cdb639e358b8976",
|
||||
"angle_branch": "7922",
|
||||
"angle_revision": "7e08726e32026a0bbabd6ec8a1a90f5ab533ed66",
|
||||
"skia_revision": "579fa81eeed6906732e27b7d95149538584dd20b"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"skiasharp_version": "4.153.1",
|
||||
"skiasharp_revision": "4783f51448f9b070dda4f87b83e941c9599e466e",
|
||||
"angle_branch": "7922",
|
||||
"angle_revision": "7e08726e32026a0bbabd6ec8a1a90f5ab533ed66",
|
||||
"skia_revision": "45afab4f1f0921f3feb97f58cf89b136fffa85e6"
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate cdecl -> stdcall adapters using the pinned managed P/Invoke ABI."""
|
||||
import argparse,re,subprocess,json
|
||||
from pathlib import Path
|
||||
p=argparse.ArgumentParser();p.add_argument('--source',type=Path,required=True);p.add_argument('--toolchain',type=Path,required=True);p.add_argument('--libraries',type=Path,required=True);a=p.parse_args()
|
||||
files=[a.source/'binding/SkiaSharp/SkiaApi.generated.cs',a.source/'binding/HarfBuzzSharp/HarfBuzzApi.generated.cs']
|
||||
text='\n'.join(x.read_text() if x.is_file() else subprocess.check_output(['git','-C',str(a.source),'show','HEAD:'+str(x.relative_to(a.source))],text=True) for x in files)
|
||||
structs={}
|
||||
# Generated structs use public fields; omit properties and methods.
|
||||
for match in re.finditer(r'\bstruct\s+(\w+)\s*\{',text):
|
||||
pos=match.end();depth=1;end=pos
|
||||
while depth:
|
||||
if text[end]=='{':depth+=1
|
||||
if text[end]=='}':depth-=1
|
||||
end+=1
|
||||
block=text[pos:end-1]
|
||||
structs[match[1]]=[m[1].strip() for m in re.finditer(r'^\s*public\s+(.+?)\s+\w+;\s*$',block,re.M)]
|
||||
sizes={}
|
||||
def layout(t):
|
||||
t=re.sub(r'\b(?:ref|out|in|readonly)\b','',t).strip()
|
||||
if '*' in t or t.endswith(('[]','Delegate')):return 4,4
|
||||
if t in sizes:return sizes[t],4
|
||||
if t in structs:raise KeyError(t)
|
||||
if t in ['Int64','UInt64','long','ulong','Double','double']:return 8,4
|
||||
if t in ['Int16','UInt16','short','ushort']:return 2,2
|
||||
if t in ['Byte','SByte','byte','sbyte','Boolean','bool']:return 1,1
|
||||
return 4,4 # enums and generated opaque pointer aliases
|
||||
pending=set(structs)
|
||||
while pending:
|
||||
done=set()
|
||||
for name in sorted(pending):
|
||||
offset=0;align=1
|
||||
try:
|
||||
for t in structs[name]:
|
||||
n,k=layout(t);offset=(offset+k-1)//k*k+n;align=max(align,k)
|
||||
except KeyError:continue
|
||||
sizes[name]=(offset+align-1)//align*align;done.add(name)
|
||||
if not done:raise SystemExit('Unresolved managed struct layout: '+str(pending))
|
||||
pending-=done
|
||||
symbols=set()
|
||||
for path in a.libraries.glob('lib*.a'):
|
||||
result=subprocess.run(['nm','--defined-only',str(path)],capture_output=True,text=True,check=True)
|
||||
symbols.update(re.findall(r'\bT\s+(_(?:sk|gr|hb)_\w+)\s*$',result.stdout,re.M))
|
||||
thunks={}
|
||||
def parameters(s):
|
||||
result=[];depth=0;start=0
|
||||
for i,c in enumerate(s):
|
||||
if c in '[<(':depth+=1
|
||||
elif c in ']> )'.replace(' ',''):depth-=1
|
||||
elif c==',' and depth==0:result.append(s[start:i]);start=i+1
|
||||
result.append(s[start:]);return [v.strip() for v in result if v.strip()]
|
||||
for m in re.finditer(r'internal static (?:extern|partial)\s+.+?\s+((?:sk|gr|hb)_\w+)\s*\((.*?)\);',text,re.S):
|
||||
symbol='_'+m[1]
|
||||
if symbol not in symbols:continue
|
||||
count=0
|
||||
for param in parameters(m[2]):
|
||||
param=re.sub(r'/\*.*?\*/|\[[^\]]+\]','',param).strip();typ=param.rsplit(' ',1)[0]
|
||||
n,_=layout(typ);count+=(n+3)//4*4
|
||||
thunks[symbol+'@'+str(count)]=(symbol,count)
|
||||
if not thunks:raise SystemExit('No x86 exported APIs matched pinned managed bindings')
|
||||
assembly=['.text','.set "@feat.00", 1']
|
||||
for name,(symbol,count) in sorted(thunks.items()):
|
||||
assembly+=['.globl "'+name+'"','"'+name+'":']+['pushl '+str(count)+'(%esp)']*(count//4)
|
||||
assembly+=['calll '+symbol,'addl $'+str(count)+', %esp','retl $'+str(count)]
|
||||
path=a.libraries/'skia_x86_stdcall_thunks.s';path.write_text('\n'.join(assembly)+'\n');obj=path.with_suffix('.o')
|
||||
subprocess.run([str(a.toolchain/'cc'),'-c',str(path),'-o',str(obj)],check=True)
|
||||
subprocess.run([str(a.toolchain/'ar'),'rcs',str(a.libraries/'skia_x86_stdcall_thunks.lib'),str(obj)],check=True)
|
||||
(a.libraries/'x86-thunks.json').write_text(json.dumps({'count':len(thunks),'layouts':sizes,'thunks':thunks},indent=2)+'\n')
|
||||
print('Generated',len(thunks),'x86 stdcall thunks')
|
||||
@@ -0,0 +1,293 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Pinned Zig compiler adapters for static-library cross-builds on Linux."""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import re
|
||||
|
||||
TARGETS = {
|
||||
"linux-x64": "x86_64-linux-gnu.2.36.0", "linux-arm64": "aarch64-linux-gnu.2.36.0",
|
||||
"linux-musl-x64": "x86_64-linux-musl", "linux-musl-arm64": "aarch64-linux-musl",
|
||||
"win-x64": "x86_64-windows-gnu", "win-x86": "x86-windows-gnu",
|
||||
"win-arm64": "aarch64-windows-gnu", "osx-x64": "x86_64-macos.10.13.0",
|
||||
"osx-arm64": "aarch64-macos.11.0.0",
|
||||
}
|
||||
|
||||
|
||||
def mingw_overlay(zig_lib, output):
|
||||
source = zig_lib / "libc/include/any-windows-any/dwrite_3.h"
|
||||
text = source.read_text()
|
||||
# Add only non-virtual overloads/default arguments. Keep IID, virtual order,
|
||||
# virtual parameter types and C vtables exactly as supplied by MinGW.
|
||||
for name in ("IDWritePaintReader", "IDWriteFontFace4"):
|
||||
start = text.index(name + " : public")
|
||||
end = text.index("#ifdef __CRT_UUID_DECL", start)
|
||||
block = text[start:end]
|
||||
if name == "IDWritePaintReader":
|
||||
block = block.replace("UINT32 struct_size) = 0;",
|
||||
"UINT32 struct_size = sizeof(DWRITE_PAINT_ELEMENT)) = 0;")
|
||||
extra = """ HRESULT SetCurrentGlyph(UINT32 glyph, DWRITE_PAINT_ELEMENT *element,
|
||||
D2D_RECT_F *clip, DWRITE_PAINT_ATTRIBUTES *attributes = 0) {
|
||||
return SetCurrentGlyph(glyph, element, sizeof(DWRITE_PAINT_ELEMENT), clip, attributes);
|
||||
}
|
||||
HRESULT SetTextColor(const DWRITE_COLOR_F &color) { return SetTextColor(&color); }
|
||||
"""
|
||||
else:
|
||||
extra = """ HRESULT GetGlyphImageFormats(UINT16 glyph, UINT32 first, UINT32 last,
|
||||
DWRITE_GLYPH_IMAGE_FORMATS *formats) {
|
||||
return GetGlyphImageFormats_(glyph, first, last, formats);
|
||||
}
|
||||
"""
|
||||
index = block.rindex("};")
|
||||
block = block[:index] + extra + block[index:]
|
||||
text = text[:start] + block + text[end:]
|
||||
output.mkdir(parents=True, exist_ok=True)
|
||||
(output / "dwrite_3.h").write_text(text)
|
||||
for name in ("XpsObjectModel.h", "ObjBase.h", "DispatcherQueue.h", "VersionHelpers.h", "T2EmbApi.h", "FontSub.h"):
|
||||
alias = output / name
|
||||
if alias.is_symlink():
|
||||
alias.unlink()
|
||||
alias.symlink_to(source.parent / name.lower())
|
||||
return hashlib.sha256(source.read_bytes()).hexdigest()
|
||||
|
||||
|
||||
def compiler(config, tool, incoming):
|
||||
target = config["target"]
|
||||
if "--version" in incoming and "linux-gnu." in target:
|
||||
target = target.split("linux-gnu.")[0] + "linux-gnu"
|
||||
windows = "windows" in target
|
||||
args = ["-I" + config["include"]] if windows else [
|
||||
"-isysroot", config["sdk"], "-idirafter", config["sdk"] + "/usr/include",
|
||||
"-F", config["sdk"] + "/System/Library/Frameworks", "-Wno-elaborated-enum-base",
|
||||
] if "macos" in target else []
|
||||
if config.get('linux_abi_headers'):
|
||||
args += ['-I' + config['linux_abi_headers']]
|
||||
if config.get('linux_headers'):
|
||||
args += ['-I' + config['linux_headers'], '-I' + config['linux_headers'] + '/freetype2']
|
||||
if config.get('linux_sysroot') and '-c' not in incoming and '-o' in incoming:
|
||||
root = Path(config['linux_sysroot'])
|
||||
cpu = 'x86_64' if target.startswith('x86_64') else 'aarch64'
|
||||
for path in (root / 'usr/lib' / (cpu + '-linux-gnu'), root / 'lib' / (cpu + '-linux-gnu'), root / 'usr/lib', root / 'lib'):
|
||||
args += ['-L' + str(path)]
|
||||
if 'linux' in target and '-c' not in incoming and '-o' in incoming:
|
||||
args.append('-fuse-ld=lld')
|
||||
if windows:
|
||||
# Accept Windows header/Skia spellings such as __forceinline while
|
||||
# retaining the GNU target ABI and leaving _MSC_VER undefined.
|
||||
args.append("-fms-extensions")
|
||||
if windows and config.get("mingw_headers"):
|
||||
args.extend(("-idirafter", config["mingw_headers"]))
|
||||
mapping = {
|
||||
"/O2": "-O2", "/fp:precise": "-ffp-model=precise", "/std:c++20": "-std=c++20",
|
||||
"/std:c11": "-std=c11", "/GR": "-frtti", "/GR-": "-fno-rtti", "/w": "-w",
|
||||
"/Ob2": "-finline-functions", "/arch:AVX2": "-mcpu=x86_64_v3",
|
||||
"/arch:AVX512": "-mcpu=x86_64_v4+evex512", "/TC": "-xc", "/TP": "-xc++",
|
||||
"/Gy": "-ffunction-sections", "/Gw": "-fdata-sections",
|
||||
"/Oy-": "-fno-omit-frame-pointer", "/guard:cf": "-mguard=cf",
|
||||
"/W3": "-Wall",
|
||||
"-march=x86-64-v3": "-mcpu=x86_64_v3", "-march=x86-64-v4": "-mcpu=x86_64_v4+evex512",
|
||||
"-march=armv8-a+crc+crypto": "-mcpu=generic+crc+aes+sha2",
|
||||
}
|
||||
iterator = iter(incoming)
|
||||
for flag in iterator:
|
||||
if flag in ("-Wl,--fatal-warnings", "-Wl,--disable-new-dtags"):
|
||||
continue
|
||||
if flag in ("-o", "-MF", "-MT", "-MQ", "-I", "-isystem", "-isysroot", "-F", "-idirafter", "-include"):
|
||||
args.extend((flag, next(iterator)))
|
||||
continue
|
||||
if flag in ("-target", "--target"):
|
||||
next(iterator)
|
||||
continue
|
||||
if flag.startswith("--target="):
|
||||
continue
|
||||
if flag.startswith("/clang:"):
|
||||
flag = flag[7:]
|
||||
if flag.startswith(("-fdiagnostics-show-inlining-chain", "-fno-lifetime-dse",
|
||||
"-fsanitize-ignore-for-ubsan-feature=", "-fmsc-version=")):
|
||||
continue
|
||||
if flag.startswith("/D"):
|
||||
flag = "-D" + flag[2:]
|
||||
if re.fullmatch(r"/std:(c\+\+\d+|c\d+)", flag):
|
||||
flag = "-std=" + flag[5:]
|
||||
if flag in ("/arch:SSE", "/arch:SSE2", "/arch:AVX"):
|
||||
flag = {"/arch:SSE": "-msse", "/arch:SSE2": "-msse2", "/arch:AVX": "-mavx"}[flag]
|
||||
if flag == "/W4":
|
||||
args.extend(("-Wall", "-Wextra"))
|
||||
continue
|
||||
if flag in ("/bigobj", "/utf-8", "/Zc:inline", "/Zc:lambda", "/Zc:twoPhase", "/FS", "/MT"):
|
||||
continue
|
||||
if flag.startswith(("/wd", "/we")):
|
||||
continue # MSVC diagnostic numbers have no GNU Clang equivalent.
|
||||
if windows and flag.startswith("/") and flag not in mapping and not Path(flag).exists():
|
||||
raise SystemExit("Unsupported MSVC option: " + flag)
|
||||
if flag == '-stdlib=libstdc++':
|
||||
flag = '-stdlib=libc++'
|
||||
args.append(mapping.get(flag, flag))
|
||||
if any(flag.startswith("-mavx512") for flag in args):
|
||||
args.append("-mevex512")
|
||||
if windows:
|
||||
if "-DCRC32_SIMD_SSE42_PCLMUL" in args:
|
||||
args.extend(("-msse4.2", "-mpclmul"))
|
||||
if "-DADLER32_SIMD_SSSE3" in args:
|
||||
args.append("-mssse3")
|
||||
# Older MSVC GN rules express SSE dispatch through a macro: Clang needs
|
||||
# matching CPU features on those units, never on ordinary baseline units.
|
||||
if target.startswith(("x86", "i386")):
|
||||
levels = {"SSE2": ["-msse2"], "SSE3": ["-msse3"], "SSSE3": ["-mssse3"],
|
||||
"SSE41": ["-msse4.1"], "SSE42": ["-msse4.2", "-mcrc32"]}
|
||||
for level, features in levels.items():
|
||||
if "-DSK_CPU_SSE_LEVEL=SK_CPU_SSE_LEVEL_" + level in args:
|
||||
args.extend(features)
|
||||
return [config["zig"], "cc" if tool == "cc" else "c++", "-target", target, *args]
|
||||
|
||||
|
||||
def execute(config, tool, incoming):
|
||||
if tool in ("cc", "cxx"):
|
||||
command = compiler(config, tool, incoming)
|
||||
elif tool == "ar":
|
||||
flags = [x.replace("rcsT", "rcs") for x in incoming if x not in ("/WX", "/ignore:4221", "-T", "--thin")]
|
||||
command = [config["zig"], "ar"]
|
||||
if "macos" in config["target"]:
|
||||
command.append("--format=darwin")
|
||||
command += flags
|
||||
else:
|
||||
output = None
|
||||
inputs = []
|
||||
iterator = iter(incoming)
|
||||
for flag in iterator:
|
||||
if flag in ("-static", "-no_warning_for_no_symbols"):
|
||||
continue
|
||||
if flag == "-o":
|
||||
output = next(iterator)
|
||||
elif flag == "-filelist":
|
||||
inputs.extend(Path(next(iterator)).read_text().splitlines())
|
||||
elif flag.startswith("@"):
|
||||
inputs.extend(shlex.split(Path(flag[1:]).read_text()))
|
||||
else:
|
||||
inputs.append(flag)
|
||||
if not output:
|
||||
raise SystemExit("Darwin libtool adapter needs -o")
|
||||
command = [config["zig"], "ar", "--format=darwin", "rcs", output, *inputs]
|
||||
if tool in ('ar', 'libtool'):
|
||||
# Never leave a truncated archive behind when disk/network/job failures
|
||||
# interrupt archiving. GN response files contain a complete member list.
|
||||
index = next((i for i, arg in enumerate(command[2:], 2)
|
||||
if not arg.startswith('@') and Path(arg).suffix in ('.a', '.lib')), None)
|
||||
if index is None:
|
||||
raise SystemExit('Cannot identify archive output: ' + str(command))
|
||||
dest = Path(command[index])
|
||||
temporary = dest.with_name(dest.name + '.tmp-' + str(os.getpid()))
|
||||
temporary.unlink(missing_ok=True)
|
||||
objects = [x for x in command[index + 1:] if not x.startswith('-')]
|
||||
if tool == 'ar' and dest.exists() and len(objects) == 1 and not objects[0].startswith('@'):
|
||||
shutil.copy2(dest, temporary) # Explicit runtime/availability append.
|
||||
command[index] = str(temporary)
|
||||
try:
|
||||
subprocess.run(command, check=True)
|
||||
os.replace(temporary, dest)
|
||||
finally:
|
||||
temporary.unlink(missing_ok=True)
|
||||
return
|
||||
cache = shutil.which('ccache')
|
||||
if tool in ('cc', 'cxx') and cache and os.environ.get('CCACHE_DIR') and '-c' in incoming:
|
||||
os.environ['CCACHE_COMPILERTYPE'] = 'clang'
|
||||
raw = str(Path(config['output']) / ('_cached-' + tool))
|
||||
os.execv(cache, [cache, raw, *command[4:]])
|
||||
os.execv(config["zig"], command)
|
||||
|
||||
|
||||
def prepare(args):
|
||||
zig = str(Path(shutil.which(args.zig) or args.zig).resolve())
|
||||
version = subprocess.check_output([zig, "version"], text=True).strip()
|
||||
if version != "0.14.1":
|
||||
raise SystemExit("This adapter is verified with Zig 0.14.1; got " + version)
|
||||
lib = Path(json.loads(subprocess.check_output([zig, "env"], text=True))["lib_dir"])
|
||||
output = args.output.resolve()
|
||||
output.mkdir(parents=True, exist_ok=True)
|
||||
config = {"zig": zig, "target": TARGETS[args.target], "version": version}
|
||||
if args.target.startswith("win"):
|
||||
include = output / "include"
|
||||
# Regeneration is idempotent; remove only the generated SDK case alias.
|
||||
alias = include / "XpsObjectModel.h"
|
||||
if alias.is_symlink():
|
||||
alias.unlink()
|
||||
config["mingw_header_sha256"] = mingw_overlay(lib, include)
|
||||
config["include"] = str(include)
|
||||
if args.mingw_headers:
|
||||
config["mingw_headers"] = str(args.mingw_headers.resolve())
|
||||
header = args.mingw_headers / "windows.ui.composition.h"
|
||||
if header.is_file():
|
||||
original = header.read_text()
|
||||
text = original
|
||||
# WIDL 11 omitted namespace qualification on these imported
|
||||
# types. Use the real declarations already imported by the
|
||||
# header; preserve interface UUIDs and method/vtable order.
|
||||
for name in ("DirectXAlphaMode", "DirectXPixelFormat"):
|
||||
text = text.replace("enum " + name, "enum ABI::Windows::Graphics::DirectX::" + name)
|
||||
text = text.replace("struct Size", "struct ABI::Windows::Foundation::Size")
|
||||
for name in ("Vector2", "Vector3", "Vector4", "Matrix3x2", "Matrix4x4", "Quaternion"):
|
||||
text = text.replace("struct " + name, "struct ABI::Windows::Foundation::Numerics::" + name)
|
||||
(include / header.name).write_text(text)
|
||||
config["composition_header_sha256"] = hashlib.sha256(header.read_bytes()).hexdigest()
|
||||
elif args.target.startswith("osx"):
|
||||
if not args.sdk or not (args.sdk / "SDKSettings.json").is_file():
|
||||
raise SystemExit("macOS target requires --sdk pointing to a macOS SDK")
|
||||
config["sdk"] = str(args.sdk.resolve())
|
||||
settings = args.sdk / "SDKSettings.json"
|
||||
if json.loads(settings.read_text()).get("Version") != "15.5":
|
||||
raise SystemExit("ANGLE metadata adapter is pinned to macOS SDK 15.5")
|
||||
config["sdk_settings_sha256"] = hashlib.sha256(settings.read_bytes()).hexdigest()
|
||||
if args.target.startswith('linux'):
|
||||
config['linux_sysroot'] = str(args.linux_sysroot.resolve()) if args.linux_sysroot else ''
|
||||
config['linux_headers'] = str(args.linux_headers.resolve()) if args.linux_headers else ''
|
||||
config['output'] = str(output)
|
||||
if args.target.startswith('linux'):
|
||||
root = Path(config['linux_sysroot'])
|
||||
abi = output / 'include-linux'
|
||||
abi.mkdir(exist_ok=True)
|
||||
cpu = 'x86_64' if config['target'].startswith('x86_64') else 'aarch64'
|
||||
for name in ('ffi.h', 'ffitarget.h'):
|
||||
for prefix in (root / 'usr/include' / (cpu + '-linux-gnu'), root / 'usr/include'):
|
||||
src = prefix / name
|
||||
if src.is_file():
|
||||
(abi / name).write_bytes(src.read_bytes())
|
||||
break
|
||||
config['linux_abi_headers'] = str(abi)
|
||||
pc = output / 'pkg-config'
|
||||
dirs = [root / 'usr/lib' / (cpu + '-linux-gnu') / 'pkgconfig', root / 'usr/lib/pkgconfig', root / 'usr/share/pkgconfig']
|
||||
pc.write_text('#!/bin/sh\nexport PKG_CONFIG_SYSROOT_DIR=' + shlex.quote(str(root)) + '\nexport PKG_CONFIG_LIBDIR=' + shlex.quote(':'.join(map(str, dirs))) + '\nexec /usr/bin/pkg-config "$@"\n')
|
||||
pc.chmod(0o755)
|
||||
for kind in ('cc', 'cxx'):
|
||||
raw = output / ('_cached-' + kind)
|
||||
mode = 'cc' if kind == 'cc' else 'c++'
|
||||
raw.write_text('#!/bin/sh\nexec ' + shlex.quote(zig) + ' ' + mode + ' -target ' + shlex.quote(config['target']) + ' "$@"\n')
|
||||
raw.chmod(0o755)
|
||||
descriptor = output / "toolchain.json"
|
||||
descriptor.write_text(json.dumps(config, indent=2) + "\n")
|
||||
for tool in ("cc", "cxx", "ar", "libtool"):
|
||||
executable = output / tool
|
||||
executable.write_text("#!/bin/sh\nexec python3 " + shlex.quote(str(Path(__file__).resolve())) +
|
||||
" run " + shlex.quote(str(descriptor)) + " " + tool + ' "$@"\n')
|
||||
executable.chmod(0o755)
|
||||
print(descriptor)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) > 1 and sys.argv[1] == "run":
|
||||
execute(json.loads(Path(sys.argv[2]).read_text()), sys.argv[3], sys.argv[4:])
|
||||
else:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--zig", default="zig")
|
||||
parser.add_argument("--target", choices=TARGETS, required=True)
|
||||
parser.add_argument("--sdk", type=Path)
|
||||
parser.add_argument("--mingw-headers", type=Path, help="Pinned extra WinRT headers, after Zig's headers")
|
||||
parser.add_argument("--linux-sysroot", type=Path)
|
||||
parser.add_argument("--linux-headers", type=Path)
|
||||
parser.add_argument("--output", type=Path, required=True)
|
||||
prepare(parser.parse_args())
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"branches": [
|
||||
{"major": 4, "ref": "skia4", "angle_branch": "7922", "revision": "2"}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
import json, os
|
||||
from pathlib import Path
|
||||
import xml.etree.ElementTree as ET
|
||||
lock = json.loads(os.environ["SOURCE_LOCK_JSON"])
|
||||
path = Path("build/linux-toolchain/release.lock.json")
|
||||
path.write_text(json.dumps(lock, indent=2) + "\n")
|
||||
project = Path("NuGet/StaticGraphics/StaticLink.Avalonia.csproj")
|
||||
root = ET.parse(project)
|
||||
root.find(".//Version").text = os.environ["PACKAGE_VERSION"]
|
||||
for item in root.findall(".//PackageReference"):
|
||||
if item.attrib.get("Include") == "SkiaSharp":
|
||||
item.set("Version", "[" + lock["skiasharp_version"] + "]")
|
||||
root.write(project, encoding="unicode")
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
rid="${RID:-linux-x64}"
|
||||
case "$rid" in
|
||||
linux-x64) cpu=x64; platform=linux/amd64 ;;
|
||||
linux-arm64) cpu=arm64; platform=linux/arm64 ;;
|
||||
*) echo "Debian container currently supports linux-x64 and linux-arm64: $rid" >&2; exit 2 ;;
|
||||
esac
|
||||
source_lock="$(realpath "${SOURCE_LOCK:-$root/build/linux-toolchain/sources.lock.json}")"
|
||||
case "$source_lock" in
|
||||
"$root/"*) container_lock="/src/${source_lock#"$root/"}" ;;
|
||||
*) echo "SOURCE_LOCK must be inside the mounted repository" >&2; exit 2 ;;
|
||||
esac
|
||||
lock_key="$(sha256sum "$source_lock" | cut -c1-16)"
|
||||
eval "$(python3 - "$source_lock" <<'PY'
|
||||
import json, shlex, sys
|
||||
lock = json.load(open(sys.argv[1]))
|
||||
for key, value in lock.items():
|
||||
print(f'{key.upper()}={shlex.quote(value)}')
|
||||
PY
|
||||
)"
|
||||
image="staticlink-debian12:$(sha256sum "$root/build/linux-toolchain/Dockerfile" | cut -c1-16)"
|
||||
docker build --platform "$platform" -t "$image" "$root/build/linux-toolchain"
|
||||
docker run --rm --platform "$platform" \
|
||||
--user "$(id -u):$(id -g)" \
|
||||
-v "$root:/src" -w /src \
|
||||
-e HOME=/tmp/staticlink-home \
|
||||
-e RID="$rid" -e TARGET_CPU="$cpu" \
|
||||
-e BUILD_JOBS="${BUILD_JOBS:-4}" \
|
||||
-e WORK_DIR="/src/External/NativeStatic/.work/native-$lock_key" \
|
||||
-e SOURCE_LOCK="$container_lock" \
|
||||
-e SKIASHARP_VERSION="$SKIASHARP_VERSION" -e SKIASHARP_REVISION="$SKIASHARP_REVISION" \
|
||||
-e ANGLE_BRANCH="$ANGLE_BRANCH" -e ANGLE_REVISION="$ANGLE_REVISION" \
|
||||
-e DEPOT_TOOLS_DIR=/src/External/NativeStatic/.work/depot_tools \
|
||||
"$image" bash -c '
|
||||
set -euo pipefail
|
||||
mkdir -p "$HOME" "$(dirname "$DEPOT_TOOLS_DIR")"
|
||||
# The image checkout is read-only for a non-root user; gclient needs a writable copy.
|
||||
if [[ ! -d "$DEPOT_TOOLS_DIR/.git" ]]; then
|
||||
cp -a /opt/depot_tools "$DEPOT_TOOLS_DIR"
|
||||
fi
|
||||
scripts/build-linux-static-graphics.sh "${1:-all}"
|
||||
cp /opt/staticlink/packages.lock "External/NativeStatic/$RID/toolchain-packages.lock"
|
||||
cp "$SOURCE_LOCK" "External/NativeStatic/$RID/sources.lock.json"
|
||||
' bash "${1:-all}"
|
||||
@@ -53,10 +53,20 @@ ensure_tools() {
|
||||
}
|
||||
|
||||
ensure_depot_tools() {
|
||||
local depot_dir="$WORK_DIR/depot_tools"
|
||||
local depot_dir="${DEPOT_TOOLS_DIR:-$WORK_DIR/depot_tools}"
|
||||
local python_bin_dir
|
||||
python_bin_dir="$(dirname "$(command -v python3)")"
|
||||
if [[ ! -d "$depot_dir/.git" ]]; then
|
||||
if [[ -n "${DEPOT_TOOLS_REVISION:-}" ]]; then
|
||||
if [[ ! -d "$depot_dir/.git" ]]; then
|
||||
git init "$depot_dir"
|
||||
git -C "$depot_dir" remote add origin https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
fi
|
||||
if [[ "$(git -C "$depot_dir" rev-parse HEAD 2>/dev/null || true)" != "$DEPOT_TOOLS_REVISION" ]]; then
|
||||
git -C "$depot_dir" fetch --depth 1 origin "$DEPOT_TOOLS_REVISION"
|
||||
git -C "$depot_dir" checkout --detach FETCH_HEAD
|
||||
fi
|
||||
export DEPOT_TOOLS_UPDATE=0
|
||||
elif [[ ! -d "$depot_dir/.git" ]]; then
|
||||
git clone --depth 1 https://chromium.googlesource.com/chromium/tools/depot_tools.git "$depot_dir"
|
||||
else
|
||||
git -C "$depot_dir" pull --ff-only
|
||||
@@ -136,7 +146,14 @@ PY
|
||||
|
||||
sync_skiasharp() {
|
||||
local src="$WORK_DIR/SkiaSharp-$SKIASHARP_VERSION"
|
||||
if [[ ! -d "$src/.git" ]]; then
|
||||
if [[ -n "${SKIASHARP_REVISION:-}" ]]; then
|
||||
if [[ ! -d "$src/.git" ]]; then
|
||||
git init "$src" >&2
|
||||
git -C "$src" remote add origin https://github.com/mono/SkiaSharp.git
|
||||
fi
|
||||
git -C "$src" fetch --depth 1 origin "$SKIASHARP_REVISION"
|
||||
git -C "$src" checkout --detach FETCH_HEAD >&2
|
||||
elif [[ ! -d "$src/.git" ]]; then
|
||||
git clone --depth 1 --branch "release/$SKIASHARP_VERSION" https://github.com/mono/SkiaSharp.git "$src"
|
||||
else
|
||||
git -C "$src" fetch --depth 1 origin "release/$SKIASHARP_VERSION"
|
||||
@@ -155,7 +172,7 @@ import sys
|
||||
|
||||
path = pathlib.Path(sys.argv[1])
|
||||
text = path.read_text()
|
||||
deps_path = path.with_name("DEPS")
|
||||
deps_path = path.parent.parent / "DEPS"
|
||||
if deps_path.exists():
|
||||
deps = deps_path.read_text()
|
||||
deps = re.sub(r'^\s*"third_party/externals/dng_sdk"\s*:\s*"[^"]+",\s*\n', '', deps, flags=re.MULTILINE)
|
||||
@@ -169,21 +186,21 @@ PY
|
||||
|
||||
sync_skia_deps() {
|
||||
local skia_dir="$1/externals/skia"
|
||||
if [[ ! -x "$skia_dir/bin/gn" ]]; then
|
||||
prepare_skia_git_sync_deps "$skia_dir"
|
||||
# GN can exist after a partial/failed sync; it is not a completion marker.
|
||||
# git-sync-deps reuses already-correct checkouts and repairs missing dependencies.
|
||||
prepare_skia_git_sync_deps "$skia_dir"
|
||||
|
||||
local attempt
|
||||
for attempt in $(seq 1 "$SKIA_DEPS_RETRIES"); do
|
||||
if python3 "$skia_dir/tools/git-sync-deps"; then
|
||||
return 0
|
||||
fi
|
||||
if [[ "$attempt" == "$SKIA_DEPS_RETRIES" ]]; then
|
||||
return 1
|
||||
fi
|
||||
echo "git-sync-deps failed; retrying ($attempt/$SKIA_DEPS_RETRIES)..." >&2
|
||||
sleep 10
|
||||
done
|
||||
fi
|
||||
local attempt
|
||||
for attempt in $(seq 1 "$SKIA_DEPS_RETRIES"); do
|
||||
if GIT_SYNC_DEPS_SKIP_EMSDK=1 python3 "$skia_dir/tools/git-sync-deps"; then
|
||||
return 0
|
||||
fi
|
||||
if [[ "$attempt" == "$SKIA_DEPS_RETRIES" ]]; then
|
||||
return 1
|
||||
fi
|
||||
echo "git-sync-deps failed; retrying ($attempt/$SKIA_DEPS_RETRIES)..." >&2
|
||||
sleep 10
|
||||
done
|
||||
}
|
||||
|
||||
build_skia() {
|
||||
@@ -233,7 +250,7 @@ extra_cflags_cc = [ "-frtti" ]
|
||||
extra_ldflags = [ "-static-libstdc++", "-static-libgcc" ]
|
||||
EOF_ARGS
|
||||
|
||||
(cd "$skia_dir" && "$skia_dir/bin/gn" gen "$out_dir")
|
||||
python3 "$ROOT_DIR/build/linux-toolchain/skia_compat.py" --source "$skia_dir" --out "$out_dir"
|
||||
ninja -C "$out_dir" -j "$BUILD_JOBS" skia SkiaSharp HarfBuzzSharp
|
||||
|
||||
copy_first_existing "$OUTPUT_DIR/libskia.a" \
|
||||
@@ -249,7 +266,14 @@ EOF_ARGS
|
||||
|
||||
sync_angle() {
|
||||
local src="$WORK_DIR/ANGLE-$ANGLE_BRANCH"
|
||||
if [[ ! -d "$src/.git" ]]; then
|
||||
if [[ -n "${ANGLE_REVISION:-}" ]]; then
|
||||
if [[ ! -d "$src/.git" ]]; then
|
||||
git init "$src" >&2
|
||||
git -C "$src" remote add origin https://github.com/google/angle.git
|
||||
fi
|
||||
git -C "$src" fetch --depth 1 origin "$ANGLE_REVISION"
|
||||
git -C "$src" checkout --detach FETCH_HEAD >&2
|
||||
elif [[ ! -d "$src/.git" ]]; then
|
||||
git clone --depth 1 --branch "chromium/$ANGLE_BRANCH" https://github.com/google/angle.git "$src"
|
||||
else
|
||||
git -C "$src" fetch --depth 1 origin "chromium/$ANGLE_BRANCH"
|
||||
@@ -544,4 +568,6 @@ main() {
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
|
||||
main "$@"
|
||||
fi
|
||||
@@ -30,7 +30,9 @@ static void StaticLinkAvaloniaPreinitializeAppKitFonts(void)
|
||||
}
|
||||
OBJC
|
||||
|
||||
clang -arch "$ARCH" \
|
||||
compiler=("${CC:-clang}")
|
||||
if [[ "${STATICLINK_ZIG_CROSS:-0}" != 1 ]]; then compiler+=(-arch "$ARCH"); fi
|
||||
"${compiler[@]}" \
|
||||
-mmacosx-version-min=12.0 \
|
||||
-fobjc-arc \
|
||||
-c "$src" \
|
||||
|
||||
@@ -33,8 +33,11 @@ ensure_depot_tools() {
|
||||
if [[ ! -d "$depot_dir/.git" ]]; then
|
||||
git clone --depth 1 https://chromium.googlesource.com/chromium/tools/depot_tools.git "$depot_dir"
|
||||
else
|
||||
git -C "$depot_dir" pull --ff-only
|
||||
: # The pinned checkout is refreshed below
|
||||
fi
|
||||
git -C "$depot_dir" fetch --depth 1 origin 8a5434051036b32412a2ecb10c213a72e3f3ccb9
|
||||
git -C "$depot_dir" checkout -q --force FETCH_HEAD
|
||||
export DEPOT_TOOLS_UPDATE=0
|
||||
export PATH="$depot_dir:$PATH"
|
||||
}
|
||||
|
||||
@@ -56,11 +59,15 @@ copy_first_existing() {
|
||||
sync_skiasharp() {
|
||||
local src="$WORK_DIR/SkiaSharp-$SKIASHARP_VERSION"
|
||||
if [[ ! -d "$src/.git" ]]; then
|
||||
git clone --depth 1 --branch "release/$SKIASHARP_VERSION" https://github.com/mono/SkiaSharp.git "$src"
|
||||
git clone --depth 1 --branch "v$SKIASHARP_VERSION" https://github.com/mono/SkiaSharp.git "$src"
|
||||
else
|
||||
git -C "$src" fetch --depth 1 origin "release/$SKIASHARP_VERSION"
|
||||
git -C "$src" fetch --depth 1 origin "${SKIASHARP_REVISION:-refs/tags/v$SKIASHARP_VERSION}"
|
||||
git -C "$src" checkout -q FETCH_HEAD
|
||||
fi
|
||||
if [[ -n "${SKIASHARP_REVISION:-}" ]]; then
|
||||
git -C "$src" fetch --depth 1 origin "$SKIASHARP_REVISION"
|
||||
git -C "$src" checkout -q --force FETCH_HEAD
|
||||
fi
|
||||
git -C "$src" submodule update --init --depth 1 externals/skia >&2
|
||||
echo "$src"
|
||||
}
|
||||
@@ -74,7 +81,7 @@ import sys
|
||||
|
||||
path = pathlib.Path(sys.argv[1])
|
||||
text = path.read_text()
|
||||
deps_path = path.with_name("DEPS")
|
||||
deps_path = path.parent.parent / "DEPS"
|
||||
if deps_path.exists():
|
||||
deps = deps_path.read_text()
|
||||
deps = re.sub(r'^\s*"third_party/externals/dng_sdk"\s*:\s*"[^"]+",\s*\n', '', deps, flags=re.MULTILINE)
|
||||
@@ -147,7 +154,7 @@ extra_cflags = [ "-DSKIA_C_DLL" ]
|
||||
extra_cflags_cc = [ "-frtti" ]
|
||||
EOF_ARGS
|
||||
|
||||
(cd "$skia_dir" && "$skia_dir/bin/gn" gen "$out_dir")
|
||||
python3 "$ROOT_DIR/build/linux-toolchain/skia_compat.py" --source "$skia_dir" --out "$out_dir"
|
||||
ninja -C "$out_dir" -j "$BUILD_JOBS" skia SkiaSharp HarfBuzzSharp
|
||||
copy_first_existing "$OUTPUT_DIR/libskia.a" "$out_dir/libskia.a" "$out_dir/obj/libskia.a"
|
||||
copy_first_existing "$OUTPUT_DIR/libSkiaSharp.a" "$out_dir/libSkiaSharp.a" "$out_dir/obj/libSkiaSharp.a"
|
||||
@@ -162,6 +169,10 @@ sync_angle() {
|
||||
git -C "$src" fetch --depth 1 origin "chromium/$ANGLE_BRANCH"
|
||||
git -C "$src" checkout -q FETCH_HEAD
|
||||
fi
|
||||
if [[ -n "${ANGLE_REVISION:-}" ]]; then
|
||||
git -C "$src" fetch --depth 1 origin "$ANGLE_REVISION"
|
||||
git -C "$src" checkout -q --force FETCH_HEAD
|
||||
fi
|
||||
echo "$src"
|
||||
}
|
||||
|
||||
|
||||
@@ -56,8 +56,13 @@ function Ensure-DepotTools {
|
||||
if (-not (Test-Path (Join-Path $depotDir ".git"))) {
|
||||
$null = git clone --depth 1 https://chromium.googlesource.com/chromium/tools/depot_tools.git $depotDir
|
||||
} else {
|
||||
$null = git -C $depotDir pull --ff-only
|
||||
# Refresh the pinned checkout below.
|
||||
}
|
||||
$null = git -C $depotDir fetch --depth 1 origin 8a5434051036b32412a2ecb10c213a72e3f3ccb9
|
||||
if ($LASTEXITCODE -ne 0) { throw "Cannot fetch pinned depot_tools" }
|
||||
$null = git -C $depotDir checkout -q --force FETCH_HEAD
|
||||
if ($LASTEXITCODE -ne 0) { throw "Cannot checkout pinned depot_tools" }
|
||||
$env:DEPOT_TOOLS_UPDATE = "0"
|
||||
$env:PATH = "$depotDir;$env:PATH"
|
||||
}
|
||||
|
||||
@@ -344,11 +349,17 @@ function New-WinX86SkiaStdcallThunks([string[]]$InputLibraries, [string[]]$Bindi
|
||||
function Sync-SkiaSharp {
|
||||
$src = Join-Path $WorkDir "SkiaSharp-$SkiaSharpVersion"
|
||||
if (-not (Test-Path (Join-Path $src ".git"))) {
|
||||
$null = git -c core.longpaths=true clone --depth 1 --branch "release/$SkiaSharpVersion" https://github.com/mono/SkiaSharp.git $src
|
||||
$null = git -c core.longpaths=true clone --depth 1 --branch "v$SkiaSharpVersion" https://github.com/mono/SkiaSharp.git $src
|
||||
} else {
|
||||
$null = git -C $src fetch --depth 1 origin "release/$SkiaSharpVersion"
|
||||
$null = git -C $src fetch --depth 1 origin "refs/tags/v$SkiaSharpVersion"
|
||||
$null = git -C $src checkout -q FETCH_HEAD
|
||||
}
|
||||
if ($env:SKIASHARP_REVISION) {
|
||||
$null = git -C $src fetch --depth 1 origin $env:SKIASHARP_REVISION
|
||||
if ($LASTEXITCODE -ne 0) { throw "Cannot fetch locked SkiaSharp commit" }
|
||||
$null = git -C $src checkout -q --force FETCH_HEAD
|
||||
if ($LASTEXITCODE -ne 0) { throw "Cannot checkout locked SkiaSharp commit" }
|
||||
}
|
||||
$null = git -C $src submodule update --init --depth 1 externals/skia
|
||||
return $src
|
||||
}
|
||||
@@ -359,7 +370,9 @@ function Patch-WinX86SkiaLinker($SkiaDir) {
|
||||
}
|
||||
|
||||
$linkerPath = Join-Path $SkiaDir "src\c\sk_linker.cpp"
|
||||
if (-not (Test-Path $linkerPath)) { return }
|
||||
$text = Get-Content -Path $linkerPath -Raw
|
||||
if ($text -notmatch 'skjson::ObjectValue') { return }
|
||||
$pattern = '(?m)^ skjson::ObjectValue\* a = nullptr;\r?\n auto r = \(\*a\)\["tmp"\]\.getType\(\);\r?$'
|
||||
$patched = [regex]::Replace($text, $pattern, ' int r = 0;')
|
||||
if ($patched -eq $text) {
|
||||
@@ -447,7 +460,8 @@ extra_cflags_cc = [ "/GR" ]
|
||||
|
||||
Push-Location $skiaDir
|
||||
try {
|
||||
& (Join-Path $skiaDir "bin\gn.exe") gen $outDir
|
||||
python (Join-Path $RootDir "build\linux-toolchain\skia_compat.py") --source $skiaDir --out $outDir
|
||||
if ($LASTEXITCODE -ne 0) { throw "Skia capability configuration failed" }
|
||||
ninja -C $outDir -j $BuildJobs skia SkiaSharp HarfBuzzSharp
|
||||
} finally {
|
||||
Pop-Location
|
||||
@@ -480,6 +494,12 @@ function Sync-Angle {
|
||||
$null = git -C $src fetch --depth 1 origin "chromium/$AngleBranch"
|
||||
$null = git -C $src checkout -q FETCH_HEAD
|
||||
}
|
||||
if ($env:ANGLE_REVISION) {
|
||||
$null = git -C $src fetch --depth 1 origin $env:ANGLE_REVISION
|
||||
if ($LASTEXITCODE -ne 0) { throw "Cannot fetch locked ANGLE commit" }
|
||||
$null = git -C $src checkout -q --force FETCH_HEAD
|
||||
if ($LASTEXITCODE -ne 0) { throw "Cannot checkout locked ANGLE commit" }
|
||||
}
|
||||
return $src
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Plan stable releases. HTTP/network errors fail closed; only 404 means absent."""
|
||||
import argparse, json, re, urllib.request, urllib.error
|
||||
from pathlib import Path
|
||||
|
||||
def get(url):
|
||||
for attempt in range(3):
|
||||
try:
|
||||
with urllib.request.urlopen(url, timeout=45) as response:
|
||||
return json.load(response)
|
||||
except urllib.error.HTTPError as error:
|
||||
if error.code == 404:
|
||||
return None
|
||||
if error.code < 500 and error.code != 429:
|
||||
raise
|
||||
if attempt == 2:
|
||||
raise
|
||||
except (OSError, TimeoutError):
|
||||
if attempt == 2:
|
||||
raise
|
||||
raise RuntimeError("Unreachable")
|
||||
|
||||
def plan(config, upstream, published, force=False):
|
||||
result = []
|
||||
for entry in config["branches"]:
|
||||
major = entry["major"]
|
||||
candidates = [v for v in upstream if re.fullmatch(r"\d+\.\d+\.\d+", v)
|
||||
and int(v.split(".")[0]) == major]
|
||||
version = entry.get("fixed_version") or max(candidates, key=lambda v: tuple(map(int, v.split("."))))
|
||||
package = f"{version}-{entry['angle_branch']}.{entry['revision']}"
|
||||
if entry.get("daily", True) and (force or package.lower() not in {v.lower() for v in published}):
|
||||
result.append({"ref": entry["ref"], "skiasharp_version": version, "package_version": package})
|
||||
return result
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--config", default="build/release-tracks.json")
|
||||
parser.add_argument("--output", default="release-plan.json")
|
||||
parser.add_argument("--force", action="store_true")
|
||||
args = parser.parse_args()
|
||||
upstream = get("https://api.nuget.org/v3-flatcontainer/skiasharp/index.json")
|
||||
published = get("https://api.nuget.org/v3-flatcontainer/staticlink.avalonia/index.json")
|
||||
if upstream is None:
|
||||
raise SystemExit("SkiaSharp package index is missing")
|
||||
result = plan(json.loads(Path(args.config).read_text()), upstream["versions"], (published or {}).get("versions", []), force=args.force)
|
||||
Path(args.output).write_text(json.dumps(result, indent=2) + "\n")
|
||||
print(json.dumps(result))
|
||||
Executable
+60
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
SOURCE_LOCK="${SOURCE_LOCK:-$SCRIPT_ROOT/build/linux-toolchain/sources.lock.json}"
|
||||
SOURCE_LOCK="$(realpath "$SOURCE_LOCK")"
|
||||
export WORK_DIR="${WORK_DIR:-$SCRIPT_ROOT/External/NativeStatic/.work/zig-sources}"
|
||||
export LLVM_AR="${LLVM_AR:-llvm-ar}"
|
||||
mkdir -p "$WORK_DIR"
|
||||
read -r SKIASHARP_VERSION SKIASHARP_REVISION ANGLE_BRANCH ANGLE_REVISION < <(
|
||||
python3 - "$SOURCE_LOCK" <<'PY'
|
||||
import json, sys
|
||||
lock = json.load(open(sys.argv[1]))
|
||||
print(lock['skiasharp_version'], lock['skiasharp_revision'], lock['angle_branch'], lock['angle_revision'])
|
||||
PY
|
||||
)
|
||||
export SKIASHARP_VERSION SKIASHARP_REVISION ANGLE_BRANCH ANGLE_REVISION
|
||||
export WORK_DIR="$WORK_DIR/$SKIASHARP_VERSION-$(sha256sum "$SOURCE_LOCK" | cut -c1-16)"
|
||||
mkdir -p "$WORK_DIR"
|
||||
source "$SCRIPT_ROOT/scripts/build-linux-static-graphics.sh"
|
||||
if [[ ! -d "$WORK_DIR/depot_tools/.git" ]]; then
|
||||
cp -a /opt/depot_tools "$WORK_DIR/depot_tools"
|
||||
fi
|
||||
export DEPOT_TOOLS_DIR="$WORK_DIR/depot_tools"
|
||||
ensure_tools
|
||||
ensure_depot_tools
|
||||
initialize_depot_tools_system_python "$DEPOT_TOOLS_DIR"
|
||||
patch_depot_tools_python_deps "$DEPOT_TOOLS_DIR"
|
||||
export VPYTHON_BYPASS="manually managed python not supported by chrome operations"
|
||||
skia_sharp="$(sync_skiasharp)"
|
||||
python3 "$SCRIPT_ROOT/build/linux-toolchain/sync-skia-deps.py" --source "$skia_sharp/externals/skia" --cache "$SCRIPT_ROOT/External/NativeStatic/.work/skia-deps"
|
||||
angle="$(sync_angle)"
|
||||
project_patch="$SCRIPT_ROOT/External/NativeStatic/patches/angle-chromium-$ANGLE_BRANCH.patch"
|
||||
if git -C "$angle" apply --reverse --check "$project_patch" >/dev/null 2>&1; then
|
||||
:
|
||||
else
|
||||
git -C "$angle" apply --check "$project_patch"
|
||||
git -C "$angle" apply "$project_patch"
|
||||
fi
|
||||
python3 - "$angle/.gclient" <<'PY'
|
||||
from pathlib import Path
|
||||
import sys
|
||||
Path(sys.argv[1]).write_text('''solutions = [{
|
||||
"name": ".", "url": "https://chromium.googlesource.com/angle/angle.git",
|
||||
"deps_file": "DEPS", "managed": False,
|
||||
"custom_deps": {"third_party/llvm-build/Release+Asserts": None},
|
||||
"custom_vars": {"checkout_angle_cl_deps": False, "checkout_angle_dawn_deps": False},
|
||||
}]
|
||||
target_os = ["linux", "win", "mac"]
|
||||
''')
|
||||
PY
|
||||
# Zig and the image's SDKs supply the compiler/runtime; skip native Xcode/MSVC
|
||||
# setup hooks while retaining the pinned source dependencies for every target.
|
||||
(cd "$angle" && gclient sync --nohooks --force)
|
||||
python3 - "$WORK_DIR/cross-sources.json" "$skia_sharp/externals/skia" "$angle" "$SOURCE_LOCK" <<'PY'
|
||||
import json, sys
|
||||
from pathlib import Path
|
||||
Path(sys.argv[1]).write_text(json.dumps({'skia': sys.argv[2], 'angle': sys.argv[3],
|
||||
'angle_gn': sys.argv[3] + '/buildtools/linux64/gn', 'source_lock': sys.argv[4]}, indent=2) + '\n')
|
||||
PY
|
||||
echo "Prepared $WORK_DIR/cross-sources.json"
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Resolve a published SkiaSharp tag and its Skia gitlink to immutable commits."""
|
||||
import argparse, json, re, subprocess, tempfile
|
||||
from pathlib import Path
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
def git(*args):
|
||||
return subprocess.check_output(["git", *args], text=True).strip()
|
||||
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument("--version", default="")
|
||||
p.add_argument("--output", default="build/linux-toolchain/release.lock.json")
|
||||
a = p.parse_args()
|
||||
root = ET.parse("NuGet/StaticGraphics/StaticLink.Avalonia.csproj").getroot()
|
||||
current = next(x.attrib["Version"] for x in root.findall(".//PackageReference") if x.attrib.get("Include") == "SkiaSharp")
|
||||
version = a.version or current
|
||||
if not re.fullmatch(r"\d+\.\d+\.\d+", version) or version.split(".")[0] != current.split(".")[0]:
|
||||
raise SystemExit("Only stable versions from this branch's SkiaSharp major are allowed")
|
||||
if current.startswith("2.") and version != "2.88.9":
|
||||
raise SystemExit("SkiaSharp 2 is frozen at 2.88.9")
|
||||
base, revision = root.findtext(".//Version").rsplit(".", 1)
|
||||
angle = base.split("-", 1)[1]
|
||||
# ANGLE remains fixed: changing SkiaSharp must not silently change its toolchain.
|
||||
profile = json.loads(Path("build/linux-toolchain/sources.lock.json").read_text())
|
||||
if profile["angle_branch"] != angle:
|
||||
raise SystemExit("ANGLE branch does not match the source lock")
|
||||
remote = "https://github.com/mono/SkiaSharp.git"
|
||||
refs = git("ls-remote", "--tags", remote, f"refs/tags/v{version}", f"refs/tags/v{version}^{{}}")
|
||||
if not refs:
|
||||
raise SystemExit(f"No immutable upstream release tag for {version}; refusing a moving branch")
|
||||
lines = refs.splitlines()
|
||||
commit = next((x.split()[0] for x in lines if x.endswith("^{}")), lines[0].split()[0])
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
git("init", "-q", tmp)
|
||||
git("-C", tmp, "fetch", "-q", "--depth=1", remote, commit)
|
||||
tree = git("-C", tmp, "ls-tree", "FETCH_HEAD", "externals/skia")
|
||||
mode, kind, skia, name = tree.split()
|
||||
if mode != "160000" or kind != "commit":
|
||||
raise SystemExit("Skia source is not a pinned git submodule")
|
||||
profile.update(skiasharp_version=version, skiasharp_revision=commit, skia_revision=skia)
|
||||
Path(a.output).write_text(json.dumps(profile, indent=2) + "\n")
|
||||
package = f"{version}-{angle}.{revision}"
|
||||
print(json.dumps({"skiasharp_version": version, "package_version": package, "lock": profile}))
|
||||
Reference in new issue
Block a user