Author SHA1 Message Date
geruipu 5ba4fe7808 Normalize native artifact layout before pack 2026-06-21 11:29:44 +08:00
geruipu 6474650f8a Avoid native package MSBuild property collision 2026-06-21 11:24:09 +08:00
geruipu 68db8faefa Make AvaloniaNative static link strict 2026-06-21 11:21:41 +08:00
geruipu 0418637f33 Bump graphics package after native split 2026-06-21 11:13:27 +08:00
geruipu 3e6f62eef4 Add AvaloniaNative direct PInvoke list 2026-06-21 11:08:13 +08:00
geruipu d68bffa85c Handle Avalonia versions without Numerge submodule 2026-06-21 10:33:10 +08:00
geruipu a700f4a124 Split AvaloniaNative static package 2026-06-21 10:30:29 +08:00
geruipu aa0118a4e3 Rename package to StaticLink.Avalonia 2026-06-21 10:03:22 +08:00
geruipu f685b52496 Run macOS smoke app with software rendering 2026-06-21 09:18:22 +08:00
geruipu 3193aaa0fd Force macOS direct PInvokes before ILC 2026-06-21 05:17:19 +08:00
geruipu 606f79757a Pack native static files recursively 2026-06-21 04:55:07 +08:00
geruipu bc5268bb6c Call macOS font width selector dynamically 2026-06-21 04:31:52 +08:00
geruipu 14e49ca1aa Run macOS Avalonia smoke app in CI 2026-06-21 04:08:32 +08:00
geruipu 37d6798862 Preinitialize macOS AppKit fonts before static graphics 2026-06-21 04:02:12 +08:00
geruipu a357d32bc2 Initialize Avalonia build submodule 2026-06-21 03:26:16 +08:00
geruipu 9532666793 Generate AvaloniaNative headers 2026-06-21 03:24:41 +08:00
geruipu 81e4f32d50 Build AvaloniaNative before macOS graphics 2026-06-21 03:21:26 +08:00
geruipu b3dee2dd87 Add macOS static AvaloniaNative experiment 2026-06-21 03:09:02 +08:00
geruipu 2db7a80ae6 Bundle macOS smoke app 2026-06-21 02:46:19 +08:00
geruipu 6fc0177b0d Use macos-14 for x64 smoke app 2026-06-21 02:42:11 +08:00
geruipu 2ee8d4423d Add Avalonia smoke release workflow 2026-06-21 01:52:40 +08:00
geruipu bfc015c0a7 Link libc++ on macOS 2026-06-21 01:42:19 +08:00
geruipu 8fea54c358 Fix Windows ANGLE static STL linkage 2026-06-21 01:04:00 +08:00
geruipu 4fb826fdb2 Restore ANGLE static target patching 2026-06-20 23:59:31 +08:00
geruipu ddb312a3cd Make ANGLE BUILD patch deterministic 2026-06-20 23:46:58 +08:00
geruipu b04d804d84 Rewrite ANGLE patch hunk 2026-06-20 23:43:07 +08:00
geruipu f62bf044f7 Fix ANGLE patch formatting 2026-06-20 23:39:51 +08:00
geruipu 3e9f6f90d2 Fix Windows ANGLE preflight 2026-06-20 23:36:32 +08:00
greepar 9433155105 Rename package to Shiroka Avalonia StaticLink 2026-06-20 23:07:50 +08:00
greepar 8dbcb291a9 Fix ANGLE GL and Visual Studio detection 2026-06-20 22:15:51 +08:00
greepar 783c50bf4d Install Linux Xext headers for ANGLE 2026-06-20 21:34:40 +08:00
greepar eaa0e54a93 Fix ANGLE platform toolchain dependencies 2026-06-20 21:05:15 +08:00
greepar dc22cf9fca Install Linux X11 headers for ANGLE 2026-06-20 20:42:42 +08:00
greepar e38f1e2013 Install Linux XCB headers for ANGLE 2026-06-20 20:30:46 +08:00
greepar 064612aaf6 Disable Linux ANGLE warning errors 2026-06-20 20:19:20 +08:00
greepar 400606f128 Use GCC for Linux ANGLE builds 2026-06-20 20:08:07 +08:00
greepar f12a124c52 Use local Windows toolchain for ANGLE 2026-06-20 20:05:10 +08:00
greepar f6f7277efa Stabilize native dependency sync 2026-06-20 19:55:27 +08:00
greepar 77a21718f1 Use system clang for Linux ANGLE builds 2026-06-20 19:34:20 +08:00
greepar c1dadcce88 Fix static graphics action builds 2026-06-20 19:22:36 +08:00
greepar 473327a5d7 Disable Windows FreeType Skia build 2026-06-20 18:43:45 +08:00
greepar edf93ab988 Disable ANGLE Linux sysroot builds 2026-06-20 18:39:57 +08:00
greepar feb7f4a3c7 Fix PowerShell path return values 2026-06-20 18:38:41 +08:00
greepar 41943a2266 Fix Windows build directory creation 2026-06-20 18:35:55 +08:00
greepar 178ed49772 Enable long paths for Windows native builds 2026-06-20 18:33:51 +08:00
greepar cd88a01c1f Fix native graphics build scripts 2026-06-20 18:31:52 +08:00
greepar eb9c503c48 Add universal Avalonia static graphics package 2026-06-20 18:24:33 +08:00
greepar 618f38bffb Initial commit 2026-06-20 18:04:46 +08:00
32 changed files with 805 additions and 1861 deletions

No files matched your search

@@ -0,0 +1,256 @@
name: macOS static AvaloniaNative experiment
on:
workflow_dispatch:
inputs:
publish_to_release:
description: Publish experimental artifacts to GitHub Release
required: true
default: true
type: boolean
permissions:
contents: write
jobs:
build-macos-native:
strategy:
fail-fast: false
matrix:
include:
- rid: osx-x64
runner: macos-14
target_cpu: x64
- rid: osx-arm64
runner: macos-latest
target_cpu: arm64
runs-on: ${{ matrix.runner }}
env:
RID: ${{ matrix.rid }}
TARGET_CPU: ${{ matrix.target_cpu }}
WORK_DIR: ${{ github.workspace }}/External/NativeStatic/.work
OUTPUT_DIR: ${{ github.workspace }}/External/NativeStatic/${{ matrix.rid }}/native
AVALONIA_VERSION: 11.3.14
steps:
- uses: actions/checkout@v4
- name: Setup .NET for Avalonia header generation
uses: actions/setup-dotnet@v4
with:
dotnet-version: "8.0.x"
- name: Build static AvaloniaNative
run: bash ./scripts/build-macos-avalonia-native-static.sh
- name: Build macOS static graphics libraries
run: bash ./scripts/build-macos-static-graphics.sh all
- name: Build macOS font preinit object
run: bash ./scripts/build-macos-font-preinit.sh
- name: List native outputs
run: find "External/NativeStatic/${{ matrix.rid }}/native" -maxdepth 1 -type f -print
- name: Upload macOS native libraries
uses: actions/upload-artifact@v4
with:
name: macos-static-native-${{ matrix.rid }}
path: External/NativeStatic/${{ matrix.rid }}/native/*
if-no-files-found: error
pack-experimental:
runs-on: ubuntu-latest
needs: build-macos-native
outputs:
package_version: ${{ steps.version.outputs.package_version }}
steps:
- uses: actions/checkout@v4
- name: Download macOS native libraries
uses: actions/download-artifact@v4
with:
pattern: macos-static-native-*
path: artifacts/native
- name: Stage native libraries
run: |
mkdir -p External/NativeStatic/osx-x64/native External/NativeStatic/osx-arm64/native
cp artifacts/native/macos-static-native-osx-x64/* External/NativeStatic/osx-x64/native/
cp artifacts/native/macos-static-native-osx-arm64/* External/NativeStatic/osx-arm64/native/
find External/NativeStatic/osx-x64/native External/NativeStatic/osx-arm64/native -maxdepth 1 -type f -print
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.x"
- name: Compute experimental package version
id: version
run: |
version="3.119.2-7151.8-macavn.${GITHUB_RUN_NUMBER}"
echo "package_version=$version" >> "$GITHUB_OUTPUT"
echo "$version"
- name: Pack experimental NuGet package
run: |
dotnet pack NuGet/StaticGraphics/StaticLink.Avalonia.csproj \
-c Release \
-o artifacts/nuget \
/p:PackageVersion=${{ steps.version.outputs.package_version }} \
/p:Version=${{ steps.version.outputs.package_version }}
dotnet pack NuGet/AvaloniaNative/StaticLink.Avalonia.Native.csproj \
-c Release \
-o artifacts/nuget \
/p:PackageVersion=11.3.14-macavn.${{ github.run_number }} \
/p:Version=11.3.14-macavn.${{ github.run_number }}
- name: Upload experimental NuGet package
uses: actions/upload-artifact@v4
with:
name: macos-static-avalonia-native-nuget
path: artifacts/nuget/*.nupkg
if-no-files-found: error
smoke-macos:
strategy:
fail-fast: false
matrix:
include:
- rid: osx-x64
runner: macos-14
- rid: osx-arm64
runner: macos-latest
runs-on: ${{ matrix.runner }}
needs: pack-experimental
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.x"
- name: Download experimental NuGet package
uses: actions/download-artifact@v4
with:
name: macos-static-avalonia-native-nuget
path: artifacts/nuget
- name: Publish Avalonia smoke app
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$projectDir = Join-Path $PWD "artifacts/avalonia-smoke-src"
$nativePackage = Get-ChildItem -Path "artifacts/nuget" -Filter "StaticLink.Avalonia.Native.*.nupkg" | Select-Object -First 1
if (-not $nativePackage) { throw "StaticLink AvaloniaNative NuGet package was not downloaded." }
if ($nativePackage.BaseName -notmatch '^StaticLink\.Avalonia\.Native\.(.+)$') { throw "Unexpected native package name: $($nativePackage.Name)" }
$nativeVersion = $Matches[1]
pwsh ./scripts/create-avalonia-smoke.ps1 `
-ProjectDir $projectDir `
-NuGetSource (Resolve-Path "artifacts/nuget") `
-StaticLinkVersion "${{ needs.pack-experimental.outputs.package_version }}" `
-StaticLinkNativeVersion $nativeVersion
dotnet publish (Join-Path $projectDir "AvaloniaStaticLinkSmoke.csproj") `
-c Release `
-r "${{ matrix.rid }}" `
--configfile (Join-Path $projectDir "NuGet.config") `
/p:PublishAot=true `
/p:SelfContained=true `
/p:PublishSingleFile=true `
/p:StripSymbols=true `
/p:PublishDir="$PWD/artifacts/smoke-${{ matrix.rid }}/"
- name: Verify static macOS output
shell: pwsh
run: |
$publishDir = "artifacts/smoke-${{ matrix.rid }}"
$blocked = Get-ChildItem -Path $publishDir -Recurse -File | Where-Object {
$_.Name -in @("libAvaloniaNative.dylib", "libHarfBuzzSharp.dylib", "libSkiaSharp.dylib")
}
if ($blocked) {
$blocked | ForEach-Object { Write-Error "Unexpected dynamic library: $($_.FullName)" }
exit 1
}
Get-ChildItem -Path $publishDir -Recurse -File | ForEach-Object { $_.FullName }
- name: Run Avalonia smoke app
shell: bash
run: |
set -euo pipefail
cd "artifacts/smoke-${{ matrix.rid }}"
chmod +x ./AvaloniaStaticLinkSmoke
python3 - <<'PY'
import pathlib
import subprocess
import sys
log = pathlib.Path("avalonia-smoke-run.log")
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()
log.write_text(output or "")
print(output or "")
print("Avalonia smoke app stayed alive for 15 seconds.")
sys.exit(0)
log.write_text(output or "")
print(output or "")
if proc.returncode == 0:
print("Avalonia smoke app exited normally.")
sys.exit(0)
print(f"Avalonia smoke app failed with exit code {proc.returncode}.", file=sys.stderr)
sys.exit(proc.returncode if proc.returncode > 0 else 1)
PY
- name: Upload macOS smoke app
uses: actions/upload-artifact@v4
with:
name: macos-static-avalonia-native-smoke-${{ matrix.rid }}
path: artifacts/smoke-${{ matrix.rid }}/**
if-no-files-found: error
release:
runs-on: ubuntu-latest
needs:
- pack-experimental
- smoke-macos
if: ${{ github.event_name == 'workflow_dispatch' && inputs.publish_to_release == true }}
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: release-artifacts
- name: Prepare release files
run: |
mkdir -p release-files
find release-artifacts/macos-static-avalonia-native-nuget -type f -name '*.nupkg' -exec cp {} release-files/ \;
for dir in release-artifacts/macos-static-avalonia-native-smoke-*; do
[ -d "$dir" ] || continue
name="$(basename "$dir")"
(cd "$dir" && zip -r "../../release-files/$name.zip" .)
done
ls -la release-files
- name: Publish experimental GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
release_tag="macos-static-avalonia-native-${GITHUB_RUN_NUMBER}"
if gh release view "$release_tag" >/dev/null 2>&1; then
gh release upload "$release_tag" release-files/* --clobber
else
gh release create "$release_tag" release-files/* \
--title "macOS static AvaloniaNative ${GITHUB_RUN_NUMBER}" \
--notes "Experimental macOS NativeAOT package with SkiaSharp, HarfBuzzSharp, and AvaloniaNative statically linked."
fi
-278
View File
@@ -1,278 +0,0 @@
name: staticlink-avalonia-native
on:
schedule:
- cron: "17 3 * * *"
workflow_dispatch:
inputs:
avalonia_version:
description: Avalonia version to build; empty uses the latest stable NuGet version
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
concurrency:
group: staticlink-avalonia-native
cancel-in-progress: false
jobs:
detect:
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
avalonia_version: ${{ steps.version.outputs.avalonia_version }}
package_version: ${{ steps.version.outputs.package_version }}
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
avalonia_version="$REQUESTED_VERSION"
if [ -z "$avalonia_version" ]; then
avalonia_version="$(curl --fail --silent --show-error --location \
https://api.nuget.org/v3-flatcontainer/avalonia/index.json \
| jq -r '[.versions[] | select(contains("-") | not)] | last')"
fi
if [ -z "$avalonia_version" ] || [ "$avalonia_version" = "null" ]; then
echo "Could not determine the latest 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"
should_build=true
if [ "$FORCE_BUILD" != "true" ] && curl --fail --silent --location --output /dev/null "$package_url"; then
should_build=false
fi
echo "Avalonia version: $avalonia_version"
echo "StaticLink.Avalonia.Native version: $package_version"
echo "Build required: $should_build"
echo "avalonia_version=$avalonia_version" >> "$GITHUB_OUTPUT"
echo "package_version=$package_version" >> "$GITHUB_OUTPUT"
echo "should_build=$should_build" >> "$GITHUB_OUTPUT"
build:
needs: detect
if: ${{ needs.detect.outputs.should_build == 'true' }}
strategy:
fail-fast: false
matrix:
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: ${{ needs.detect.outputs.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.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' }}
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-*
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-$rid/libAvaloniaNative.a" "External/AvaloniaNative/$rid/native/"
cp "artifacts/native/native-avalonia-$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=${{ needs.detect.outputs.package_version }} \
/p:Version=${{ needs.detect.outputs.package_version }}
- name: Upload NuGet package
uses: actions/upload-artifact@v4
with:
name: staticlink-avalonia-native-${{ needs.detect.outputs.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:
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-${{ needs.detect.outputs.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 "${{ needs.detect.outputs.avalonia_version }}" `
-StaticLinkNativeVersion "${{ needs.detect.outputs.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) }}
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-${{ needs.detect.outputs.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
@@ -1,106 +0,0 @@
name: staticlink-avalonia-repack
on:
workflow_dispatch:
inputs:
source_version:
description: Existing package version containing the static libraries
required: true
default: 3.119.4-7922.1
type: string
publish_to_nuget:
description: Publish package to nuget.org
required: true
default: false
type: boolean
jobs:
repack:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.x"
- name: Extract static libraries from existing package
env:
SOURCE_VERSION: ${{ inputs.source_version }}
run: |
python3 - <<'PY'
import os
import pathlib
import urllib.request
import zipfile
version = os.environ["SOURCE_VERSION"]
package = pathlib.Path("artifacts/source.nupkg")
package.parent.mkdir(parents=True, exist_ok=True)
urllib.request.urlretrieve(
f"https://api.nuget.org/v3-flatcontainer/staticlink.avalonia/{version}/staticlink.avalonia.{version}.nupkg",
package,
)
output = pathlib.Path("External/NativeStatic")
with zipfile.ZipFile(package) as archive:
for entry in archive.infolist():
name = entry.filename.replace("\\", "/")
if not name.startswith("static/") or name.endswith("/"):
continue
destination = output / name.removeprefix("static/")
destination.parent.mkdir(parents=True, exist_ok=True)
destination.write_bytes(archive.read(entry))
PY
- name: Verify static archives
run: |
for rid in linux-x64 linux-arm64 linux-musl-x64 linux-musl-arm64 osx-x64 osx-arm64; do
test -f External/NativeStatic/$rid/native/libskia.a
test -f External/NativeStatic/$rid/native/libSkiaSharp.a
test -f External/NativeStatic/$rid/native/libHarfBuzzSharp.a
test -f External/NativeStatic/$rid/native/libANGLE_static.a
test -f External/NativeStatic/$rid/native/libGLESv2_static.a
done
for rid in win-x64 win-x86 win-arm64; do
test -f External/NativeStatic/$rid/native/skia.lib
test -f External/NativeStatic/$rid/native/SkiaSharp.lib
test -f External/NativeStatic/$rid/native/libHarfBuzzSharp.lib
test -f External/NativeStatic/$rid/native/libANGLE_static.lib
test -f External/NativeStatic/$rid/native/libGLESv2_static.lib
done
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
- name: Verify portable NuGet paths
run: |
package=$(find artifacts/nuget -name 'StaticLink.Avalonia.*.nupkg' ! -name 'StaticLink.Avalonia.Native.*.nupkg' -print -quit)
test -n "$package"
if unzip -Z1 "$package" | grep -F '\'; then
echo "NuGet package contains Windows-only backslash paths."
exit 1
fi
unzip -Z1 "$package" | grep -Fx 'buildTransitive/StaticLink.Avalonia.props'
unzip -Z1 "$package" | grep -Fx 'buildTransitive/StaticLink.Avalonia.targets'
- name: Upload NuGet artifact
uses: actions/upload-artifact@v4
with:
name: staticlink-avalonia-repacked-nuget
path: artifacts/nuget/*.nupkg
if-no-files-found: error
- name: Publish to nuget.org
if: ${{ inputs.publish_to_nuget == true }}
env:
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
run: |
test -n "$NUGET_API_KEY"
dotnet nuget push artifacts/nuget/*.nupkg \
--source "https://api.nuget.org/v3/index.json" \
--api-key "$NUGET_API_KEY" \
--skip-duplicate
+240 -201
View File
@@ -18,48 +18,193 @@ on:
- "staticlink-avalonia-v*" - "staticlink-avalonia-v*"
env: env:
DOTNET_ALPINE_IMAGE: mcr.microsoft.com/dotnet/sdk:10.0.302-alpine3.23 SKIASHARP_VERSION: "3.119.2"
ANGLE_BRANCH: "7151"
jobs: jobs:
preflight:
uses: ./.github/workflows/static-graphics-preflight.yml
build-linux: build-linux:
needs: preflight strategy:
uses: ./.github/workflows/static-graphics-linux.yml fail-fast: false
with: matrix:
skiasharp_version: ${{ needs.preflight.outputs.skiasharp_version }} include:
angle_branch: ${{ needs.preflight.outputs.angle_branch }} - rid: linux-x64
target_cpu: x64
runner: ubuntu-latest
- rid: linux-arm64
target_cpu: arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v4
build-musl: - name: Install native build dependencies
needs: preflight run: |
uses: ./.github/workflows/static-graphics-musl.yml sudo apt-get update
with: 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
skiasharp_version: ${{ needs.preflight.outputs.skiasharp_version }}
angle_branch: ${{ needs.preflight.outputs.angle_branch }} - name: Build Linux static graphics libraries
dotnet_alpine_image: mcr.microsoft.com/dotnet/sdk:10.0.302-alpine3.23 env:
RID: ${{ matrix.rid }}
TARGET_CPU: ${{ matrix.target_cpu }}
LLVM_AR: llvm-ar
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
build-windows: build-windows:
needs: preflight strategy:
uses: ./.github/workflows/static-graphics-windows.yml fail-fast: false
with: matrix:
skiasharp_version: ${{ needs.preflight.outputs.skiasharp_version }} include:
angle_branch: ${{ needs.preflight.outputs.angle_branch }} - rid: win-x64
target_cpu: x64
msvc_arch: x64
- rid: win-arm64
target_cpu: arm64
msvc_arch: amd64_arm64
runs-on: windows-2022
steps:
- uses: actions/checkout@v4
- 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
build-macos: build-macos:
needs: preflight strategy:
uses: ./.github/workflows/static-graphics-macos.yml fail-fast: false
with: matrix:
skiasharp_version: ${{ needs.preflight.outputs.skiasharp_version }} include:
angle_branch: ${{ needs.preflight.outputs.angle_branch }} - rid: osx-x64
target_cpu: x64
runner: macos-14
- rid: osx-arm64
target_cpu: arm64
runner: macos-latest
runs-on: ${{ matrix.runner }}
env:
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: Install native build dependencies
run: brew install ninja
- name: Build macOS static graphics libraries
run: bash ./scripts/build-macos-static-graphics.sh all
- name: Build macOS font preinit object
run: bash scripts/build-macos-font-preinit.sh
- 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
build-macos-avalonia-native:
strategy:
fail-fast: false
matrix:
include:
- rid: osx-x64
runner: macos-14
avalonia_version: 11.3.14
- rid: osx-arm64
runner: macos-latest
avalonia_version: 11.3.14
- rid: osx-x64
runner: macos-14
avalonia_version: 12.0.3
- rid: osx-arm64
runner: macos-latest
avalonia_version: 12.0.3
runs-on: ${{ matrix.runner }}
env:
RID: ${{ matrix.rid }}
WORK_DIR: ${{ github.workspace }}/External/NativeStatic/.work
OUTPUT_DIR: ${{ github.workspace }}/External/NativeStatic/${{ matrix.rid }}/native
AVALONIA_VERSION: ${{ matrix.avalonia_version }}
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.avalonia_version }}-${{ matrix.rid }}
path: |
External/NativeStatic/${{ matrix.rid }}/native/libAvaloniaNative.a
External/NativeStatic/${{ matrix.rid }}/native/macos_font_preinit.o
if-no-files-found: error
pack: pack:
runs-on: ubuntu-24.04 runs-on: ubuntu-latest
needs: needs:
- build-linux - build-linux
- build-musl
- build-windows - build-windows
- build-macos - build-macos
- build-macos-avalonia-native
permissions: permissions:
contents: read contents: read
steps: steps:
@@ -68,7 +213,7 @@ jobs:
- name: Setup .NET - name: Setup .NET
uses: actions/setup-dotnet@v4 uses: actions/setup-dotnet@v4
with: with:
dotnet-version: "10.0.302" dotnet-version: "10.0.x"
- name: Download static archives - name: Download static archives
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
@@ -77,9 +222,16 @@ jobs:
path: External/NativeStatic path: External/NativeStatic
merge-multiple: false merge-multiple: false
- name: Download static AvaloniaNative archives
uses: actions/download-artifact@v4
with:
pattern: native-avalonia-*
path: External/AvaloniaNative
merge-multiple: false
- name: Move static archives into RID directories - name: Move static archives into RID directories
run: | run: |
for rid in win-x64 win-x86 win-arm64 linux-x64 linux-arm64 linux-musl-x64 linux-musl-arm64 osx-x64 osx-arm64; do for rid in win-x64 win-arm64 linux-x64 linux-arm64 osx-x64 osx-arm64; do
mkdir -p "External/NativeStatic/$rid" mkdir -p "External/NativeStatic/$rid"
mv "External/NativeStatic/native-static-$rid"/* "External/NativeStatic/$rid/" mv "External/NativeStatic/native-static-$rid"/* "External/NativeStatic/$rid/"
rmdir "External/NativeStatic/native-static-$rid" rmdir "External/NativeStatic/native-static-$rid"
@@ -91,7 +243,7 @@ jobs:
- name: Verify static archives - name: Verify static archives
run: | run: |
for rid in linux-x64 linux-arm64 linux-musl-x64 linux-musl-arm64 osx-x64 osx-arm64; do for rid in linux-x64 linux-arm64 osx-x64 osx-arm64; do
test -f External/NativeStatic/$rid/native/libskia.a test -f External/NativeStatic/$rid/native/libskia.a
test -f External/NativeStatic/$rid/native/libSkiaSharp.a test -f External/NativeStatic/$rid/native/libSkiaSharp.a
test -f External/NativeStatic/$rid/native/libHarfBuzzSharp.a test -f External/NativeStatic/$rid/native/libHarfBuzzSharp.a
@@ -99,29 +251,27 @@ jobs:
test -f External/NativeStatic/$rid/native/libGLESv2_static.a test -f External/NativeStatic/$rid/native/libGLESv2_static.a
done done
for rid in win-x64 win-x86 win-arm64; do for rid in win-x64 win-arm64; do
test -f External/NativeStatic/$rid/native/skia.lib test -f External/NativeStatic/$rid/native/skia.lib
test -f External/NativeStatic/$rid/native/SkiaSharp.lib test -f External/NativeStatic/$rid/native/SkiaSharp.lib
test -f External/NativeStatic/$rid/native/libHarfBuzzSharp.lib test -f External/NativeStatic/$rid/native/libHarfBuzzSharp.lib
test -f External/NativeStatic/$rid/native/libANGLE_static.lib test -f External/NativeStatic/$rid/native/libANGLE_static.lib
test -f External/NativeStatic/$rid/native/libGLESv2_static.lib test -f External/NativeStatic/$rid/native/libGLESv2_static.lib
done done
test -f External/NativeStatic/win-x86/native/skia_x86_stdcall_thunks.lib
- name: Pack NuGet package - name: Pack NuGet package
run: dotnet pack NuGet/StaticGraphics/StaticLink.Avalonia.csproj -c Release -o artifacts/nuget
- name: Verify portable NuGet paths
shell: bash
run: | run: |
package=$(find artifacts/nuget -name 'StaticLink.Avalonia.*.nupkg' ! -name 'StaticLink.Avalonia.Native.*.nupkg' -print -quit) dotnet pack NuGet/StaticGraphics/StaticLink.Avalonia.csproj -c Release -o artifacts/nuget
test -n "$package" for version in 11.3.14 12.0.3; do
if unzip -Z1 "$package" | grep -F '\'; then mkdir -p External/NativeStatic/osx-x64/native External/NativeStatic/osx-arm64/native
echo "NuGet package contains Windows-only backslash paths." cp External/AvaloniaNative/native-avalonia-$version-osx-x64/* External/NativeStatic/osx-x64/native/
exit 1 cp External/AvaloniaNative/native-avalonia-$version-osx-arm64/* External/NativeStatic/osx-arm64/native/
fi dotnet pack NuGet/AvaloniaNative/StaticLink.Avalonia.Native.csproj \
unzip -Z1 "$package" | grep -Fx 'buildTransitive/StaticLink.Avalonia.props' -c Release \
unzip -Z1 "$package" | grep -Fx 'buildTransitive/StaticLink.Avalonia.targets' -o artifacts/nuget \
/p:PackageVersion=$version.1 \
/p:Version=$version.1
done
- name: Upload NuGet artifact - name: Upload NuGet artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
@@ -132,6 +282,23 @@ jobs:
artifacts/nuget/*.snupkg artifacts/nuget/*.snupkg
if-no-files-found: error if-no-files-found: error
- 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 }}
run: |
if [ -z "$NUGET_API_KEY" ]; then
echo "NUGET_API_KEY secret is not configured. Skipping publish."
exit 0
fi
for package in artifacts/nuget/*.nupkg; do
dotnet nuget push "$package" \
--source "https://api.nuget.org/v3/index.json" \
--api-key "$NUGET_API_KEY" \
--skip-duplicate
done
smoke-avalonia: smoke-avalonia:
needs: pack needs: pack
strategy: strategy:
@@ -141,26 +308,29 @@ jobs:
- rid: win-x64 - rid: win-x64
runner: windows-2022 runner: windows-2022
msvc_arch: x64 msvc_arch: x64
- rid: win-x86
runner: windows-2022
msvc_arch: x86
- rid: win-arm64 - rid: win-arm64
runner: windows-2022 runner: windows-2022
msvc_arch: amd64_arm64 msvc_arch: amd64_arm64
- rid: linux-x64 - rid: linux-x64
runner: ubuntu-24.04 runner: ubuntu-latest
- rid: linux-arm64 - rid: linux-arm64
runner: ubuntu-24.04-arm runner: ubuntu-24.04-arm
- rid: linux-musl-x64
runner: ubuntu-24.04
- rid: linux-musl-arm64
runner: ubuntu-24.04-arm
- rid: osx-x64 - rid: osx-x64
runner: macos-15 runner: macos-14
avalonia_version: 11.3.14 avalonia_version: 11.3.14
native_version: 11.3.14.1
- rid: osx-arm64 - rid: osx-arm64
runner: macos-15 runner: macos-latest
avalonia_version: 11.3.14 avalonia_version: 11.3.14
native_version: 11.3.14.1
- rid: osx-x64
runner: macos-14
avalonia_version: 12.0.3
native_version: 12.0.3.1
- rid: osx-arm64
runner: macos-latest
avalonia_version: 12.0.3
native_version: 12.0.3.1
runs-on: ${{ matrix.runner }} runs-on: ${{ matrix.runner }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -172,15 +342,15 @@ jobs:
arch: ${{ matrix.msvc_arch }} arch: ${{ matrix.msvc_arch }}
- name: Install Linux publish dependencies - name: Install Linux publish dependencies
if: ${{ startsWith(matrix.rid, 'linux-') && !startsWith(matrix.rid, 'linux-musl-') }} if: ${{ startsWith(matrix.rid, 'linux-') }}
run: | run: |
sudo apt-get update 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 zlib1g-dev libfontconfig1-dev
- name: Setup .NET - name: Setup .NET
uses: actions/setup-dotnet@v4 uses: actions/setup-dotnet@v4
with: with:
dotnet-version: "10.0.302" dotnet-version: "10.0.x"
- name: Download NuGet package - name: Download NuGet package
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
@@ -189,7 +359,6 @@ jobs:
path: artifacts/nuget path: artifacts/nuget
- name: Publish Avalonia single-file smoke app - name: Publish Avalonia single-file smoke app
if: ${{ !startsWith(matrix.rid, 'linux-musl-') }}
shell: pwsh shell: pwsh
run: | run: |
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
@@ -197,10 +366,15 @@ jobs:
if (-not $package) { throw "StaticLink NuGet package was not downloaded." } if (-not $package) { throw "StaticLink NuGet package was not downloaded." }
if ($package.BaseName -notmatch '^StaticLink\.Avalonia\.(.+)$') { throw "Unexpected package name: $($package.Name)" } if ($package.BaseName -notmatch '^StaticLink\.Avalonia\.(.+)$') { throw "Unexpected package name: $($package.Name)" }
$version = $Matches[1] $version = $Matches[1]
$nativeVersion = "${{ matrix.native_version }}"
$avaloniaVersion = "${{ matrix.avalonia_version }}" $avaloniaVersion = "${{ matrix.avalonia_version }}"
if (-not $avaloniaVersion) { $avaloniaVersion = "11.3.14" } if (-not $avaloniaVersion) { $avaloniaVersion = "11.3.14" }
if ($nativeVersion) {
$nativePackage = Get-ChildItem -Path "artifacts/nuget" -Filter "StaticLink.Avalonia.Native.$nativeVersion.nupkg" | Select-Object -First 1
if (-not $nativePackage) { throw "StaticLink AvaloniaNative NuGet package $nativeVersion was not downloaded." }
}
$projectDir = Join-Path $PWD "artifacts/avalonia-smoke-src" $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 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") ` dotnet publish (Join-Path $projectDir "AvaloniaStaticLinkSmoke.csproj") `
-c Release ` -c Release `
-r "${{ matrix.rid }}" ` -r "${{ matrix.rid }}" `
@@ -211,29 +385,12 @@ jobs:
/p:StripSymbols=true ` /p:StripSymbols=true `
/p:PublishDir="$PWD/artifacts/smoke-${{ matrix.rid }}/" /p:PublishDir="$PWD/artifacts/smoke-${{ matrix.rid }}/"
- name: Publish Avalonia musl smoke app
if: ${{ startsWith(matrix.rid, 'linux-musl-') }}
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$package = Get-ChildItem -Path "artifacts/nuget" -Filter "StaticLink.Avalonia.*.nupkg" | Where-Object { $_.Name -notlike "StaticLink.Avalonia.Native.*" } | Select-Object -First 1
if (-not $package) { throw "StaticLink NuGet package was not downloaded." }
if ($package.BaseName -notmatch '^StaticLink\.Avalonia\.(.+)$') { throw "Unexpected package name: $($package.Name)" }
$version = $Matches[1]
$projectDir = Join-Path $PWD "artifacts/avalonia-smoke-src"
pwsh ./scripts/create-avalonia-smoke.ps1 -ProjectDir $projectDir -NuGetSource "/workspace/artifacts/nuget" -StaticLinkVersion $version -AvaloniaVersion "11.3.14"
docker run --rm `
-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 }}/"
- name: Verify no dynamic graphics libraries remain - name: Verify no dynamic graphics libraries remain
shell: pwsh shell: pwsh
run: | run: |
$publishDir = "artifacts/smoke-${{ matrix.rid }}" $publishDir = "artifacts/smoke-${{ matrix.rid }}"
$blocked = Get-ChildItem -Path $publishDir -Recurse -File | Where-Object { $blocked = Get-ChildItem -Path $publishDir -Recurse -File | Where-Object {
$_.Name -in @("libSkiaSharp.dll", "libHarfBuzzSharp.dll", "av_libglesv2.dll", "libSkiaSharp.so", "libHarfBuzzSharp.so", "libSkiaSharp.dylib", "libHarfBuzzSharp.dylib") $_.Name -in @("libSkiaSharp.dll", "libHarfBuzzSharp.dll", "av_libglesv2.dll", "libSkiaSharp.so", "libHarfBuzzSharp.so", "libAvaloniaNative.dylib", "libSkiaSharp.dylib", "libHarfBuzzSharp.dylib")
} }
if ($blocked) { if ($blocked) {
$blocked | ForEach-Object { Write-Error "Unexpected dynamic graphics library: $($_.FullName)" } $blocked | ForEach-Object { Write-Error "Unexpected dynamic graphics library: $($_.FullName)" }
@@ -241,78 +398,6 @@ jobs:
} }
Get-ChildItem -Path $publishDir -Recurse -File | ForEach-Object { $_.FullName } Get-ChildItem -Path $publishDir -Recurse -File | ForEach-Object { $_.FullName }
- name: Verify Windows executable architecture
if: ${{ startsWith(matrix.rid, 'win-') }}
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$app = Join-Path $PWD "artifacts/smoke-${{ matrix.rid }}/AvaloniaStaticLinkSmoke.exe"
$expectedMachine = @{
"win-x64" = "8664 machine"
"win-x86" = "14C machine"
"win-arm64" = "AA64 machine"
}["${{ matrix.rid }}"]
$headers = & dumpbin /headers $app | Out-String
if ($LASTEXITCODE -ne 0 -or $headers -notmatch [regex]::Escape($expectedMachine)) {
throw "Expected $expectedMachine in PE headers for $app.`n$headers"
}
- name: Run Windows Avalonia smoke app
if: ${{ matrix.rid == 'win-x64' || matrix.rid == 'win-x86' }}
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$publishDir = Join-Path $PWD "artifacts/smoke-${{ matrix.rid }}"
$app = Join-Path $publishDir "AvaloniaStaticLinkSmoke.exe"
$process = Start-Process -FilePath $app -WorkingDirectory $publishDir -PassThru
if ($process.WaitForExit(15000)) {
if ($process.ExitCode -eq 0) {
Write-Host "Avalonia Windows smoke app exited normally."
exit 0
}
throw "Avalonia Windows smoke app failed with exit code $($process.ExitCode)."
}
Stop-Process -Id $process.Id -Force
Write-Host "Avalonia Windows smoke app stayed alive for 15 seconds."
- name: Run Linux Avalonia smoke app
if: ${{ startsWith(matrix.rid, 'linux-') && !startsWith(matrix.rid, 'linux-musl-') }}
shell: bash
run: |
set +e
cd "artifacts/smoke-${{ matrix.rid }}"
chmod +x ./AvaloniaStaticLinkSmoke
timeout 15s xvfb-run -a ./AvaloniaStaticLinkSmoke
code=$?
if [ "$code" = 124 ] || [ "$code" = 143 ]; then
echo "Avalonia Linux smoke app stayed alive for 15 seconds."
exit 0
fi
exit "$code"
- name: Verify musl ELF dependencies
if: ${{ startsWith(matrix.rid, 'linux-musl-') }}
shell: bash
run: |
set -euo pipefail
docker run --rm \
-v "${{ github.workspace }}:/workspace" \
-w /workspace \
alpine:3.23 \
sh -c 'apk add --no-cache binutils pax-utils && app="artifacts/smoke-${{ matrix.rid }}/AvaloniaStaticLinkSmoke" && readelf -l "$app" | grep "Requesting program interpreter: /lib/ld-musl-" && scanelf -n "$app" && ! scanelf -n "$app" | grep -E "ld-linux|ld64.so"'
- name: Run Linux musl Avalonia smoke app
if: ${{ startsWith(matrix.rid, 'linux-musl-') }}
shell: bash
run: |
set -euo pipefail
docker run --rm \
-v "${{ github.workspace }}:/workspace" \
-w /workspace/artifacts/smoke-${{ matrix.rid }} \
alpine:3.23 \
sh -c 'apk add --no-cache xvfb-run libstdc++ libgcc fontconfig freetype ttf-dejavu libx11 libxcb libxext libxrender libxi libxrandr libxcursor libxfixes libxinerama libice libsm mesa-gl mesa-egl && fc-cache -f && fc-match sans && chmod +x ./AvaloniaStaticLinkSmoke && timeout 15s xvfb-run -a ./AvaloniaStaticLinkSmoke || code=$?; if [ "${code:-0}" = 124 ] || [ "${code:-0}" = 143 ]; then echo "Avalonia musl smoke app stayed alive for 15 seconds."; exit 0; fi; exit "${code:-0}"'
- name: Run macOS Avalonia smoke app - name: Run macOS Avalonia smoke app
if: ${{ startsWith(matrix.rid, 'osx-') }} if: ${{ startsWith(matrix.rid, 'osx-') }}
shell: bash shell: bash
@@ -360,65 +445,21 @@ jobs:
path: artifacts/smoke-${{ matrix.rid }}/** path: artifacts/smoke-${{ matrix.rid }}/**
if-no-files-found: error if-no-files-found: error
publish-nuget:
runs-on: ubuntu-24.04
needs:
- pack
- smoke-avalonia
steps:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.302"
- name: Download NuGet package
uses: actions/download-artifact@v4
with:
name: staticlink-avalonia-nuget
path: artifacts/nuget
- 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 }}
run: |
if [ -z "$NUGET_API_KEY" ]; then
echo "NUGET_API_KEY secret is not configured. Skipping publish."
exit 0
fi
for package in artifacts/nuget/*.nupkg; do
dotnet nuget push "$package" \
--source "https://api.nuget.org/v3/index.json" \
--api-key "$NUGET_API_KEY" \
--skip-duplicate
done
release: release:
runs-on: ubuntu-24.04 runs-on: ubuntu-latest
needs: needs:
- preflight
- pack - pack
- smoke-avalonia - smoke-avalonia
- publish-nuget
if: ${{ startsWith(github.ref, 'refs/tags/staticlink-avalonia-v') || (github.event_name == 'workflow_dispatch' && inputs.publish_to_release == true) }} if: ${{ startsWith(github.ref, 'refs/tags/staticlink-avalonia-v') || (github.event_name == 'workflow_dispatch' && inputs.publish_to_release == true) }}
permissions: permissions:
contents: write contents: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Download NuGet artifact - name: Download release artifacts
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: staticlink-avalonia-nuget
path: release-artifacts/staticlink-avalonia-nuget
- name: Download smoke artifacts
uses: actions/download-artifact@v4
with:
pattern: avalonia-smoke-*
path: release-artifacts path: release-artifacts
merge-multiple: false
- name: Prepare release files - name: Prepare release files
run: | run: |
@@ -434,21 +475,19 @@ jobs:
- name: Publish GitHub Release - name: Publish GitHub Release
env: env:
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ github.token }}
PACKAGE_VERSION: ${{ needs.preflight.outputs.package_version }}
run: | run: |
if [ "${GITHUB_REF_TYPE}" = "tag" ]; then if [ "${GITHUB_REF_TYPE}" = "tag" ]; then
release_tag="${GITHUB_REF_NAME}" release_tag="${GITHUB_REF_NAME}"
title="${GITHUB_REF_NAME}" title="${GITHUB_REF_NAME}"
else else
release_tag="staticlink-avalonia-v${PACKAGE_VERSION}" release_tag="staticlink-avalonia-smoke-${GITHUB_RUN_NUMBER}"
title="StaticLink.Avalonia ${PACKAGE_VERSION}" title="StaticLink.Avalonia smoke ${GITHUB_RUN_NUMBER}"
fi fi
if gh release view "$release_tag" >/dev/null 2>&1; then if gh release view "$release_tag" >/dev/null 2>&1; then
gh release upload "$release_tag" release-files/* --clobber gh release upload "$release_tag" release-files/* --clobber
else else
gh release create "$release_tag" release-files/* \ gh release create "$release_tag" release-files/* \
--target "$GITHUB_SHA" \
--title "$title" \ --title "$title" \
--notes "NuGet package plus Avalonia 11.3.14 NativeAOT single-file smoke apps for win-x64, win-x86, win-arm64, linux-x64, linux-arm64, linux-musl-x64, linux-musl-arm64, osx-x64, and osx-arm64." --notes "NuGet package plus Avalonia 11.3.14 NativeAOT single-file smoke apps for win-x64, win-arm64, linux-x64, linux-arm64, osx-x64, and osx-arm64."
fi fi
@@ -1,64 +0,0 @@
name: static-graphics-linux
on:
workflow_call:
inputs:
skiasharp_version:
required: true
type: string
angle_branch:
required: true
type: string
workflow_dispatch:
inputs:
skiasharp_version:
required: true
default: "3.119.4"
type: string
angle_branch:
required: true
default: "7922"
type: string
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
@@ -1,74 +0,0 @@
name: static-graphics-macos
on:
workflow_call:
inputs:
skiasharp_version:
required: true
type: string
angle_branch:
required: true
type: string
workflow_dispatch:
inputs:
skiasharp_version:
required: true
default: "3.119.4"
type: string
angle_branch:
required: true
default: "7922"
type: string
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
@@ -1,92 +0,0 @@
name: static-graphics-musl
on:
workflow_call:
inputs:
skiasharp_version:
required: true
type: string
angle_branch:
required: true
type: string
dotnet_alpine_image:
required: true
type: string
workflow_dispatch:
inputs:
skiasharp_version:
required: true
default: "3.119.4"
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
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
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
@@ -1,81 +0,0 @@
name: static-graphics-preflight
on:
workflow_call:
outputs:
package_version:
value: ${{ jobs.validate.outputs.package_version }}
skiasharp_version:
value: ${{ jobs.validate.outputs.skiasharp_version }}
angle_branch:
value: ${{ jobs.validate.outputs.angle_branch }}
workflow_dispatch:
jobs:
validate:
runs-on: ubuntu-24.04
outputs:
package_version: ${{ steps.versions.outputs.package_version }}
skiasharp_version: ${{ steps.versions.outputs.skiasharp_version }}
angle_branch: ${{ steps.versions.outputs.angle_branch }}
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.302"
- name: Read and validate versions
id: versions
shell: bash
run: |
python3 - <<'PY'
import os
import pathlib
import xml.etree.ElementTree as ET
project = pathlib.Path("NuGet/StaticGraphics/StaticLink.Avalonia.csproj")
root = ET.parse(project).getroot()
package_version = root.findtext(".//Version")
skia_reference = next(
item.attrib["Version"]
for item in root.findall(".//PackageReference")
if item.attrib.get("Include") == "SkiaSharp"
)
version_base, revision = package_version.rsplit(".", 1)
skiasharp_version, angle_branch = version_base.split("-", 1)
if not revision.isdigit() or skiasharp_version != skia_reference:
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}"
if os.environ.get("GITHUB_REF_NAME") != expected_tag:
raise SystemExit(f"Release tag must be {expected_tag}")
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output:
output.write(f"package_version={package_version}\n")
output.write(f"skiasharp_version={skiasharp_version}\n")
output.write(f"angle_branch={angle_branch}\n")
PY
- name: Validate upstream refs and ANGLE patch
env:
SKIASHARP_VERSION: ${{ steps.versions.outputs.skiasharp_version }}
ANGLE_BRANCH: ${{ steps.versions.outputs.angle_branch }}
shell: bash
run: |
set -euo pipefail
git ls-remote --exit-code --heads https://github.com/mono/SkiaSharp.git "refs/heads/release/${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"
- name: Validate scripts
shell: bash
run: |
set -euo pipefail
bash -n scripts/build-linux-static-graphics.sh
bash -n scripts/build-macos-static-graphics.sh
pwsh -NoProfile -Command '$files = @("scripts/build-windows-static-graphics.ps1", "scripts/create-avalonia-smoke.ps1"); foreach ($file in $files) { $errors = $null; [System.Management.Automation.Language.Parser]::ParseFile((Resolve-Path $file), [ref]$null, [ref]$errors) | Out-Null; if ($errors.Count) { $errors | Format-List | Out-String; exit 1 } }'
- name: Compile smoke project
run: dotnet build Smoke/AvaloniaStaticLinkSmoke/AvaloniaStaticLinkSmoke.csproj -c Release -p:PublishAot=false
@@ -1,92 +0,0 @@
name: static-graphics-windows
on:
workflow_call:
inputs:
skiasharp_version:
required: true
type: string
angle_branch:
required: true
type: string
workflow_dispatch:
inputs:
skiasharp_version:
required: true
default: "3.119.4"
type: string
angle_branch:
required: true
default: "7922"
type: string
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
-1
View File
@@ -4,4 +4,3 @@ artifacts/
*.nupkg *.nupkg
*.snupkg *.snupkg
External/NativeStatic/.work/ External/NativeStatic/.work/
External/AvaloniaNative/.work/
+64
View File
@@ -0,0 +1,64 @@
diff --git a/DEPS b/DEPS
index 9085ba513e..565840a832 100644
--- a/DEPS
+++ b/DEPS
@@ -696,11 +696,6 @@ deps = {
'dep_type': 'cipd',
},
- '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': {
'url': Var('android_git') + '/platform/external/cherry@4f8fb08d33ca5ff05a1c638f04c85bbb8d8b52cc',
@@ -722,12 +717,6 @@ deps = {
'condition': 'checkout_android and not build_with_chromium',
},
-
- 'third_party/dawn': {
- 'url': Var('dawn_git') + '/dawn.git' + '@' + Var('dawn_revision'),
- 'condition': 'not build_with_chromium'
- },
-
'third_party/depot_tools': {
'url': Var('chromium_git') + '/chromium/tools/depot_tools.git@1fcc527019d786502b02f71b8b764ee674a40953',
'condition': 'not build_with_chromium',
@@ -809,11 +798,6 @@ deps = {
'condition': 'not build_with_chromium',
},
- 'third_party/llvm/src': {
- 'url': Var('chromium_git') + '/external/github.com/llvm/llvm-project@1fd8d3fea53e6e4573cdce55bd38ef0a7813a442',
- 'condition': 'not build_with_chromium',
- },
-
'third_party/jdk': {
'packages': [
{
@@ -1000,11 +984,6 @@ deps = {
'condition': 'checkout_android and not build_with_chromium',
},
- 'third_party/SwiftShader': {
- 'url': Var('swiftshader_git') + '/SwiftShader@7905fa19e456df5aa8e2233a7ec5832c9c6c287b',
- 'condition': 'not build_with_chromium',
- },
-
'third_party/turbine/cipd': {
'packages': [
{
@@ -1016,10 +995,6 @@ deps = {
'dep_type': 'cipd',
},
- '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@b9aab6c35f37e6532011ddab976c3ca71819c074',
'condition': 'not build_with_chromium',
-64
View File
@@ -1,64 +0,0 @@
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;
-12
View File
@@ -1,12 +0,0 @@
# StaticLink.Avalonia.Native
Static `AvaloniaNative` libraries for macOS Avalonia NativeAOT publishing.
The package version matches the Avalonia version with a `.1` suffix. For example, use `StaticLink.Avalonia.Native` version `12.1.0.1` with Avalonia `12.1.0`.
```xml
<PackageReference Include="Avalonia" Version="12.1.0" />
<PackageReference Include="StaticLink.Avalonia.Native" Version="12.1.0.1" />
```
The package supports `osx-x64` and `osx-arm64` NativeAOT publishing.
@@ -1,12 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net10.0</TargetFramework>
<IsPackable>true</IsPackable> <IsPackable>true</IsPackable>
<NoBuild>true</NoBuild> <NoBuild>true</NoBuild>
<IncludeBuildOutput>false</IncludeBuildOutput> <IncludeBuildOutput>false</IncludeBuildOutput>
<SuppressDependenciesWhenPacking>false</SuppressDependenciesWhenPacking> <SuppressDependenciesWhenPacking>false</SuppressDependenciesWhenPacking>
<PackageId>StaticLink.Avalonia.Native</PackageId> <PackageId>StaticLink.Avalonia.Native</PackageId>
<Version>0.0.0</Version> <Version>11.3.14.1</Version>
<Authors>greepar</Authors> <Authors>greepar</Authors>
<Company>greepar</Company> <Company>greepar</Company>
<Description>Static AvaloniaNative library for macOS Avalonia NativeAOT publishing.</Description> <Description>Static AvaloniaNative library for macOS Avalonia NativeAOT publishing.</Description>
@@ -19,14 +19,14 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<None Include="README.md" Pack="true" PackagePath="README.md" /> <None Include="../StaticGraphics/README.md" Pack="true" PackagePath="README.md" />
<None Include="lib/net8.0/_._" Pack="true" PackagePath="lib/net8.0/_._" /> <None Include="lib/net10.0/_._" Pack="true" PackagePath="lib/net10.0/_._" />
<None Include="buildTransitive/StaticLink.Avalonia.Native.props" Pack="true" PackagePath="buildTransitive/$(PackageId).props" /> <None Include="buildTransitive/StaticLink.Avalonia.Native.props" Pack="true" PackagePath="buildTransitive/$(PackageId).props" />
<None Include="buildTransitive/StaticLink.Avalonia.Native.targets" Pack="true" PackagePath="buildTransitive/$(PackageId).targets" /> <None Include="buildTransitive/StaticLink.Avalonia.Native.targets" Pack="true" PackagePath="buildTransitive/$(PackageId).targets" />
<None Include="buildTransitive/StaticLink.Avalonia.Native.MacOSFontWarmup.cs" Pack="true" PackagePath="buildTransitive/StaticLink.Avalonia.Native.MacOSFontWarmup.cs" /> <None Include="buildTransitive/StaticLink.Avalonia.Native.MacOSFontWarmup.cs" Pack="true" PackagePath="buildTransitive/StaticLink.Avalonia.Native.MacOSFontWarmup.cs" />
<None Include="../../External/AvaloniaNative/osx-x64/native/libAvaloniaNative.a" Pack="true" PackagePath="static/osx-x64/native/libAvaloniaNative.a" /> <None Include="../../External/NativeStatic/osx-x64/native/libAvaloniaNative.a" Condition="Exists('../../External/NativeStatic/osx-x64/native/libAvaloniaNative.a')" Pack="true" PackagePath="static/osx-x64/native/libAvaloniaNative.a" />
<None Include="../../External/AvaloniaNative/osx-x64/native/macos_font_preinit.o" Pack="true" PackagePath="static/osx-x64/native/macos_font_preinit.o" /> <None Include="../../External/NativeStatic/osx-x64/native/macos_font_preinit.o" Condition="Exists('../../External/NativeStatic/osx-x64/native/macos_font_preinit.o')" Pack="true" PackagePath="static/osx-x64/native/macos_font_preinit.o" />
<None Include="../../External/AvaloniaNative/osx-arm64/native/libAvaloniaNative.a" Pack="true" PackagePath="static/osx-arm64/native/libAvaloniaNative.a" /> <None Include="../../External/NativeStatic/osx-arm64/native/libAvaloniaNative.a" Condition="Exists('../../External/NativeStatic/osx-arm64/native/libAvaloniaNative.a')" Pack="true" PackagePath="static/osx-arm64/native/libAvaloniaNative.a" />
<None Include="../../External/AvaloniaNative/osx-arm64/native/macos_font_preinit.o" Pack="true" PackagePath="static/osx-arm64/native/macos_font_preinit.o" /> <None Include="../../External/NativeStatic/osx-arm64/native/macos_font_preinit.o" Condition="Exists('../../External/NativeStatic/osx-arm64/native/macos_font_preinit.o')" Pack="true" PackagePath="static/osx-arm64/native/macos_font_preinit.o" />
</ItemGroup> </ItemGroup>
</Project> </Project>
@@ -18,8 +18,6 @@
<LinkerArg Include="-framework CoreFoundation" /> <LinkerArg Include="-framework CoreFoundation" />
<LinkerArg Include="-framework CoreGraphics" /> <LinkerArg Include="-framework CoreGraphics" />
<LinkerArg Include="-framework Foundation" /> <LinkerArg Include="-framework Foundation" />
<LinkerArg Include="-framework IOSurface" />
<LinkerArg Include="-framework Metal" />
<LinkerArg Include="-framework OpenGL" /> <LinkerArg Include="-framework OpenGL" />
<LinkerArg Include="-framework QuartzCore" /> <LinkerArg Include="-framework QuartzCore" />
<LinkerArg Include="-framework UniformTypeIdentifiers" /> <LinkerArg Include="-framework UniformTypeIdentifiers" />
File renamed without changes.
+45 -12
View File
@@ -1,6 +1,19 @@
# StaticLink.Avalonia # StaticLink.Avalonia
Static native libraries for Avalonia single-file NativeAOT publishing. Static native libraries for Avalonia NativeAOT publishing.
This package links Avalonia's graphics/native dependencies from static archives so NativeAOT publish output does not need the usual SkiaSharp, HarfBuzzSharp, ANGLE, or AvaloniaNative runtime files next to the executable.
Repository: <https://github.com/greepar/StaticLink.Avalonia>
## Supported RIDs
- `win-x64`
- `win-arm64`
- `linux-x64`
- `linux-arm64`
- `osx-x64`
- `osx-arm64`
## Install ## Install
@@ -8,16 +21,10 @@ Static native libraries for Avalonia single-file NativeAOT publishing.
dotnet add package StaticLink.Avalonia dotnet add package StaticLink.Avalonia
``` ```
Or add it manually: For fully static macOS output, also reference the AvaloniaNative package that matches your Avalonia version:
```xml ```bash
<PackageReference Include="StaticLink.Avalonia" Version="3.119.4-7922.1" /> dotnet add package StaticLink.Avalonia.Native --version 11.3.14.1
```
For macOS, also reference `StaticLink.Avalonia.Native`. This package is macOS-only and must match your Avalonia version because it contains `libAvaloniaNative.a`.
```xml
<PackageReference Include="StaticLink.Avalonia.Native" Version="11.3.14.1" />
``` ```
## Publish ## Publish
@@ -30,6 +37,32 @@ dotnet publish -c Release -r win-x64 \
-p:StripSymbols=true -p:StripSymbols=true
``` ```
Use the RID you need, such as `win-x86`, `linux-x64`, `linux-arm64`, `osx-arm64`, or `osx-x64`. Use the RID you need, for example `linux-x64`, `linux-arm64`, `osx-arm64`, or `osx-x64`.
For macOS, avoid the Metal renderer for fully static output. Use OpenGL or Software. For Linux, `lld` is recommended:
```bash
dotnet publish -c Release -r linux-x64 \
-p:PublishAot=true \
-p:SelfContained=true \
-p:PublishSingleFile=true \
-p:StripSymbols=true \
-p:LinkerFlavor=lld
```
For macOS, avoid the Metal renderer for fully static output. Use OpenGL or Software:
```csharp
.With(new AvaloniaNativePlatformOptions
{
RenderingMode = [AvaloniaNativeRenderingMode.OpenGl, AvaloniaNativeRenderingMode.Software]
})
```
## Notes
- The package is intended for Avalonia `11.3.x` NativeAOT apps.
- `StaticLink.Avalonia.Native` is version-specific because `libAvaloniaNative.a` must match Avalonia's native ABI.
- The CI builds and smoke-publishes all six supported RIDs.
- macOS smoke tests run the published app on GitHub Actions and require it to stay alive for 15 seconds.
- Other native dependencies used by your app, such as SQLite or audio libraries, are outside this package's scope.
@@ -1,12 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net10.0</TargetFramework>
<IsPackable>true</IsPackable> <IsPackable>true</IsPackable>
<NoBuild>true</NoBuild> <NoBuild>true</NoBuild>
<IncludeBuildOutput>false</IncludeBuildOutput> <IncludeBuildOutput>false</IncludeBuildOutput>
<SuppressDependenciesWhenPacking>false</SuppressDependenciesWhenPacking> <SuppressDependenciesWhenPacking>false</SuppressDependenciesWhenPacking>
<PackageId>StaticLink.Avalonia</PackageId> <PackageId>StaticLink.Avalonia</PackageId>
<Version>3.119.4-7922.1</Version> <Version>3.119.2-7151.10</Version>
<Authors>greepar</Authors> <Authors>greepar</Authors>
<Company>greepar</Company> <Company>greepar</Company>
<Description>Static SkiaSharp, HarfBuzzSharp, and ANGLE libraries for Avalonia NativeAOT single-file publishing.</Description> <Description>Static SkiaSharp, HarfBuzzSharp, and ANGLE libraries for Avalonia NativeAOT single-file publishing.</Description>
@@ -19,21 +19,18 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="SkiaSharp" Version="3.119.4" /> <PackageReference Include="SkiaSharp" Version="3.119.2" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="README.md" Pack="true" PackagePath="" /> <None Include="README.md" Pack="true" PackagePath="" />
<None Include="lib/net8.0/_._" Pack="true" PackagePath="lib/net8.0/_._" /> <None Include="lib/net10.0/_._" Pack="true" PackagePath="lib/net10.0/_._" />
<None Include="buildTransitive/StaticLink.Avalonia.props" Pack="true" PackagePath="buildTransitive/$(PackageId).props" /> <None Include="buildTransitive/StaticLink.Avalonia.props" Pack="true" PackagePath="buildTransitive/$(PackageId).props" />
<None Include="buildTransitive/StaticLink.Avalonia.targets" Pack="true" PackagePath="buildTransitive/$(PackageId).targets" /> <None Include="buildTransitive/StaticLink.Avalonia.targets" Pack="true" PackagePath="buildTransitive/$(PackageId).targets" />
<None Include="../../External/NativeStatic/win-x64/native/**/*" Pack="true" PackagePath="static/win-x64/native/%(RecursiveDir)%(Filename)%(Extension)" /> <None Include="../../External/NativeStatic/win-x64/native/**/*" Pack="true" PackagePath="static/win-x64/native/%(RecursiveDir)%(Filename)%(Extension)" />
<None Include="../../External/NativeStatic/win-x86/native/**/*" Pack="true" PackagePath="static/win-x86/native/%(RecursiveDir)%(Filename)%(Extension)" />
<None Include="../../External/NativeStatic/win-arm64/native/**/*" Pack="true" PackagePath="static/win-arm64/native/%(RecursiveDir)%(Filename)%(Extension)" /> <None Include="../../External/NativeStatic/win-arm64/native/**/*" Pack="true" PackagePath="static/win-arm64/native/%(RecursiveDir)%(Filename)%(Extension)" />
<None Include="../../External/NativeStatic/linux-x64/native/**/*" Pack="true" PackagePath="static/linux-x64/native/%(RecursiveDir)%(Filename)%(Extension)" /> <None Include="../../External/NativeStatic/linux-x64/native/**/*" Pack="true" PackagePath="static/linux-x64/native/%(RecursiveDir)%(Filename)%(Extension)" />
<None Include="../../External/NativeStatic/linux-arm64/native/**/*" Pack="true" PackagePath="static/linux-arm64/native/%(RecursiveDir)%(Filename)%(Extension)" /> <None Include="../../External/NativeStatic/linux-arm64/native/**/*" Pack="true" PackagePath="static/linux-arm64/native/%(RecursiveDir)%(Filename)%(Extension)" />
<None Include="../../External/NativeStatic/linux-musl-x64/native/**/*" Pack="true" PackagePath="static/linux-musl-x64/native/%(RecursiveDir)%(Filename)%(Extension)" />
<None Include="../../External/NativeStatic/linux-musl-arm64/native/**/*" Pack="true" PackagePath="static/linux-musl-arm64/native/%(RecursiveDir)%(Filename)%(Extension)" />
<None Include="../../External/NativeStatic/osx-x64/native/**/*" Exclude="../../External/NativeStatic/osx-x64/native/libAvaloniaNative.a;../../External/NativeStatic/osx-x64/native/macos_font_preinit.o" Pack="true" PackagePath="static/osx-x64/native/%(RecursiveDir)%(Filename)%(Extension)" /> <None Include="../../External/NativeStatic/osx-x64/native/**/*" Exclude="../../External/NativeStatic/osx-x64/native/libAvaloniaNative.a;../../External/NativeStatic/osx-x64/native/macos_font_preinit.o" Pack="true" PackagePath="static/osx-x64/native/%(RecursiveDir)%(Filename)%(Extension)" />
<None Include="../../External/NativeStatic/osx-arm64/native/**/*" Exclude="../../External/NativeStatic/osx-arm64/native/libAvaloniaNative.a;../../External/NativeStatic/osx-arm64/native/macos_font_preinit.o" Pack="true" PackagePath="static/osx-arm64/native/%(RecursiveDir)%(Filename)%(Extension)" /> <None Include="../../External/NativeStatic/osx-arm64/native/**/*" Exclude="../../External/NativeStatic/osx-arm64/native/libAvaloniaNative.a;../../External/NativeStatic/osx-arm64/native/macos_font_preinit.o" Pack="true" PackagePath="static/osx-arm64/native/%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup> </ItemGroup>
@@ -1,25 +1,21 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<_StaticLinkAvaloniaRid Condition="'$(RuntimeIdentifier)' == 'win-x64'">win-x64</_StaticLinkAvaloniaRid> <_StaticLinkAvaloniaRid Condition="'$(RuntimeIdentifier)' == 'win-x64'">win-x64</_StaticLinkAvaloniaRid>
<_StaticLinkAvaloniaRid Condition="'$(RuntimeIdentifier)' == 'win-x86'">win-x86</_StaticLinkAvaloniaRid>
<_StaticLinkAvaloniaRid Condition="'$(RuntimeIdentifier)' == 'win-arm64'">win-arm64</_StaticLinkAvaloniaRid> <_StaticLinkAvaloniaRid Condition="'$(RuntimeIdentifier)' == 'win-arm64'">win-arm64</_StaticLinkAvaloniaRid>
<_StaticLinkAvaloniaRid Condition="'$(RuntimeIdentifier)' == 'linux-x64'">linux-x64</_StaticLinkAvaloniaRid> <_StaticLinkAvaloniaRid Condition="'$(RuntimeIdentifier)' == 'linux-x64'">linux-x64</_StaticLinkAvaloniaRid>
<_StaticLinkAvaloniaRid Condition="'$(RuntimeIdentifier)' == 'linux-arm64'">linux-arm64</_StaticLinkAvaloniaRid> <_StaticLinkAvaloniaRid Condition="'$(RuntimeIdentifier)' == 'linux-arm64'">linux-arm64</_StaticLinkAvaloniaRid>
<_StaticLinkAvaloniaRid Condition="'$(RuntimeIdentifier)' == 'linux-musl-x64'">linux-musl-x64</_StaticLinkAvaloniaRid>
<_StaticLinkAvaloniaRid Condition="'$(RuntimeIdentifier)' == 'linux-musl-arm64'">linux-musl-arm64</_StaticLinkAvaloniaRid>
<_StaticLinkAvaloniaRid Condition="'$(RuntimeIdentifier)' == 'osx-x64'">osx-x64</_StaticLinkAvaloniaRid> <_StaticLinkAvaloniaRid Condition="'$(RuntimeIdentifier)' == 'osx-x64'">osx-x64</_StaticLinkAvaloniaRid>
<_StaticLinkAvaloniaRid Condition="'$(RuntimeIdentifier)' == 'osx-arm64'">osx-arm64</_StaticLinkAvaloniaRid> <_StaticLinkAvaloniaRid Condition="'$(RuntimeIdentifier)' == 'osx-arm64'">osx-arm64</_StaticLinkAvaloniaRid>
<_StaticLinkAvaloniaNativeRoot Condition="'$(_StaticLinkAvaloniaRid)' != ''">$(StaticLinkAvaloniaRoot)$(_StaticLinkAvaloniaRid)/native</_StaticLinkAvaloniaNativeRoot> <_StaticLinkAvaloniaNativeRoot Condition="'$(_StaticLinkAvaloniaRid)' != ''">$(StaticLinkAvaloniaRoot)$(_StaticLinkAvaloniaRid)/native</_StaticLinkAvaloniaNativeRoot>
<LinkerFlavor Condition="'$(LinkerFlavor)' == '' and ('$(RuntimeIdentifier)' == 'linux-x64' or '$(RuntimeIdentifier)' == 'linux-arm64' or '$(RuntimeIdentifier)' == 'linux-musl-x64' or '$(RuntimeIdentifier)' == 'linux-musl-arm64')">lld</LinkerFlavor> <LinkerFlavor Condition="'$(LinkerFlavor)' == '' and ('$(RuntimeIdentifier)' == 'linux-x64' or '$(RuntimeIdentifier)' == 'linux-arm64')">lld</LinkerFlavor>
</PropertyGroup> </PropertyGroup>
<ItemGroup Condition="'$(PublishAot)' == 'true' and ('$(RuntimeIdentifier)' == 'win-x64' or '$(RuntimeIdentifier)' == 'win-x86' or '$(RuntimeIdentifier)' == 'win-arm64') and '$(_StaticLinkAvaloniaNativeRoot)' != ''"> <ItemGroup Condition="'$(PublishAot)' == 'true' and ('$(RuntimeIdentifier)' == 'win-x64' or '$(RuntimeIdentifier)' == 'win-arm64') and '$(_StaticLinkAvaloniaNativeRoot)' != ''">
<DirectPInvoke Include="libHarfBuzzSharp" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libHarfBuzzSharp.lib')" /> <DirectPInvoke Include="libHarfBuzzSharp" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libHarfBuzzSharp.lib')" />
<DirectPInvoke Include="libSkiaSharp" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/SkiaSharp.lib')" /> <DirectPInvoke Include="libSkiaSharp" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/SkiaSharp.lib')" />
<DirectPInvoke Include="libGLESv2" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libGLESv2_static.lib')" /> <DirectPInvoke Include="libGLESv2" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libGLESv2_static.lib')" />
<DirectPInvoke Include="av_libglesv2" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libGLESv2_static.lib')" /> <DirectPInvoke Include="av_libglesv2" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libGLESv2_static.lib')" />
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/libHarfBuzzSharp.lib" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libHarfBuzzSharp.lib')" /> <NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/libHarfBuzzSharp.lib" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libHarfBuzzSharp.lib')" />
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/skia_x86_stdcall_thunks.lib" Condition="'$(RuntimeIdentifier)' == 'win-x86' and Exists('$(_StaticLinkAvaloniaNativeRoot)/skia_x86_stdcall_thunks.lib')" />
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/skia.lib" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/skia.lib')" /> <NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/skia.lib" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/skia.lib')" />
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/SkiaSharp.lib" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/SkiaSharp.lib')" /> <NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/SkiaSharp.lib" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/SkiaSharp.lib')" />
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/libANGLE_static.lib" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libANGLE_static.lib')" /> <NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/libANGLE_static.lib" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libANGLE_static.lib')" />
@@ -34,51 +30,7 @@
<LinkerArg Include="d3d12.lib;d3dcompiler.lib" /> <LinkerArg Include="d3d12.lib;d3dcompiler.lib" />
</ItemGroup> </ItemGroup>
<Target Name="StaticLinkAvaloniaAddWindowsDirectPInvokes" <ItemGroup Condition="'$(PublishAot)' == 'true' and ('$(RuntimeIdentifier)' == 'linux-x64' or '$(RuntimeIdentifier)' == 'linux-arm64') and '$(_StaticLinkAvaloniaNativeRoot)' != ''">
BeforeTargets="WriteIlcRspFileForCompilation"
Condition="'$(PublishAot)' == 'true' and ('$(RuntimeIdentifier)' == 'win-x64' or '$(RuntimeIdentifier)' == 'win-x86' or '$(RuntimeIdentifier)' == 'win-arm64') and '$(_StaticLinkAvaloniaNativeRoot)' != ''">
<PropertyGroup>
<_StaticLinkAvaloniaDirectPInvokeList>$(NativeIntermediateOutputPath)staticlink-avalonia.directpinvokes.txt</_StaticLinkAvaloniaDirectPInvokeList>
</PropertyGroup>
<ItemGroup>
<_StaticLinkAvaloniaDirectPInvoke Include="libHarfBuzzSharp" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libHarfBuzzSharp.lib')" />
<_StaticLinkAvaloniaDirectPInvoke Include="libHarfBuzzSharp.dll" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libHarfBuzzSharp.lib')" />
<_StaticLinkAvaloniaDirectPInvoke Include="libSkiaSharp" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/SkiaSharp.lib')" />
<_StaticLinkAvaloniaDirectPInvoke Include="libSkiaSharp.dll" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/SkiaSharp.lib')" />
<_StaticLinkAvaloniaDirectPInvoke Include="libGLESv2" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libGLESv2_static.lib')" />
<_StaticLinkAvaloniaDirectPInvoke Include="libGLESv2.dll" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libGLESv2_static.lib')" />
<_StaticLinkAvaloniaDirectPInvoke Include="av_libglesv2" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libGLESv2_static.lib')" />
<_StaticLinkAvaloniaDirectPInvoke Include="av_libglesv2.dll" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libGLESv2_static.lib')" />
</ItemGroup>
<WriteLinesToFile File="$(_StaticLinkAvaloniaDirectPInvokeList)" Lines="@(_StaticLinkAvaloniaDirectPInvoke)" Overwrite="true" />
<ItemGroup>
<DirectPInvoke Include="@(_StaticLinkAvaloniaDirectPInvoke)" />
<DirectPInvokeList Include="$(_StaticLinkAvaloniaDirectPInvokeList)" />
</ItemGroup>
</Target>
<Target Name="StaticLinkAvaloniaAddWindowsNativeLibraries"
BeforeTargets="LinkNative"
Condition="'$(PublishAot)' == 'true' and ('$(RuntimeIdentifier)' == 'win-x64' or '$(RuntimeIdentifier)' == 'win-x86' or '$(RuntimeIdentifier)' == 'win-arm64') and '$(_StaticLinkAvaloniaNativeRoot)' != ''">
<ItemGroup>
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/libHarfBuzzSharp.lib" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libHarfBuzzSharp.lib')" />
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/skia_x86_stdcall_thunks.lib" Condition="'$(RuntimeIdentifier)' == 'win-x86' and Exists('$(_StaticLinkAvaloniaNativeRoot)/skia_x86_stdcall_thunks.lib')" />
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/skia.lib" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/skia.lib')" />
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/SkiaSharp.lib" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/SkiaSharp.lib')" />
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/libANGLE_static.lib" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libANGLE_static.lib')" />
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/libGLESv2_static.lib" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libGLESv2_static.lib')" />
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/libc++.lib" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libc++.lib')" />
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/libc++abi.lib" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libc++abi.lib')" />
<LinkerArg Include="d3d9.lib;dxguid.lib" />
<LinkerArg Include="dxgi.lib" />
<LinkerArg Include="Gdi32.lib;User32.lib" />
<LinkerArg Include="synchronization.lib" />
<LinkerArg Include="fontsub.lib;Ole32.lib;USP10.lib" />
<LinkerArg Include="d3d12.lib;d3dcompiler.lib" />
</ItemGroup>
</Target>
<ItemGroup Condition="'$(PublishAot)' == 'true' and ('$(RuntimeIdentifier)' == 'linux-x64' or '$(RuntimeIdentifier)' == 'linux-arm64' or '$(RuntimeIdentifier)' == 'linux-musl-x64' or '$(RuntimeIdentifier)' == 'linux-musl-arm64') and '$(_StaticLinkAvaloniaNativeRoot)' != ''">
<DirectPInvoke Include="libHarfBuzzSharp" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libHarfBuzzSharp.a')" /> <DirectPInvoke Include="libHarfBuzzSharp" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libHarfBuzzSharp.a')" />
<DirectPInvoke Include="libSkiaSharp" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libSkiaSharp.a')" /> <DirectPInvoke Include="libSkiaSharp" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libSkiaSharp.a')" />
<NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/libHarfBuzzSharp.a" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libHarfBuzzSharp.a')" /> <NativeLibrary Include="$(_StaticLinkAvaloniaNativeRoot)/libHarfBuzzSharp.a" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libHarfBuzzSharp.a')" />
@@ -91,7 +43,7 @@
<NativeSystemLibrary Include="fontconfig" /> <NativeSystemLibrary Include="fontconfig" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(PublishAot)' == 'true' and ('$(RuntimeIdentifier)' == 'linux-x64' or '$(RuntimeIdentifier)' == 'linux-arm64' or '$(RuntimeIdentifier)' == 'linux-musl-x64' or '$(RuntimeIdentifier)' == 'linux-musl-arm64') and '$(_StaticLinkAvaloniaNativeRoot)' != '' and '$(LinkerFlavor)' == 'lld'"> <ItemGroup Condition="'$(PublishAot)' == 'true' and ('$(RuntimeIdentifier)' == 'linux-x64' or '$(RuntimeIdentifier)' == 'linux-arm64') and '$(_StaticLinkAvaloniaNativeRoot)' != '' and '$(LinkerFlavor)' == 'lld'">
<LinkerArg Include="-Wl,-z,nostart-stop-gc" /> <LinkerArg Include="-Wl,-z,nostart-stop-gc" />
<LinkerArg Include="-Wl,--allow-multiple-definition" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libskia.a')" /> <LinkerArg Include="-Wl,--allow-multiple-definition" Condition="Exists('$(_StaticLinkAvaloniaNativeRoot)/libskia.a')" />
</ItemGroup> </ItemGroup>
File renamed without changes.
+40 -34
View File
@@ -1,6 +1,19 @@
# StaticLink.Avalonia # StaticLink.Avalonia
Static native libraries for Avalonia single-file NativeAOT publishing. Static native libraries for Avalonia NativeAOT publishing.
This package links Avalonia's graphics/native dependencies from static archives so NativeAOT publish output does not need the usual SkiaSharp, HarfBuzzSharp, ANGLE, or AvaloniaNative runtime files next to the executable.
Repository: <https://github.com/greepar/StaticLink.Avalonia>
## Supported RIDs
- `win-x64`
- `win-arm64`
- `linux-x64`
- `linux-arm64`
- `osx-x64`
- `osx-arm64`
## Install ## Install
@@ -8,24 +21,10 @@ Static native libraries for Avalonia single-file NativeAOT publishing.
dotnet add package StaticLink.Avalonia dotnet add package StaticLink.Avalonia
``` ```
Or add it manually: For fully static macOS output, also reference the AvaloniaNative package that matches your Avalonia version:
```xml ```bash
<PackageReference Include="StaticLink.Avalonia" Version="3.119.4-7922.1" /> dotnet add package StaticLink.Avalonia.Native --version 11.3.14.1
```
`3.119.4-7922.1` supports Avalonia 11. If you need the SkiaSharp 2 line for an Avalonia 11 project, use this optional package variant:
```xml
<PackageReference Include="StaticLink.Avalonia" Version="2.88.9-7151.10" />
```
`2.88.9-7151.10` is only for Avalonia 11 projects that specifically want SkiaSharp 2.
For macOS, also reference `StaticLink.Avalonia.Native`. This package is macOS-only and must match your Avalonia version because it contains `libAvaloniaNative.a`.
```xml
<PackageReference Include="StaticLink.Avalonia.Native" Version="11.3.14.1" />
``` ```
## Publish ## Publish
@@ -38,25 +37,32 @@ dotnet publish -c Release -r win-x64 \
-p:StripSymbols=true -p:StripSymbols=true
``` ```
Use the RID you need, such as `win-x86`, `linux-x64`, `linux-arm64`, `osx-arm64`, or `osx-x64`. Use the RID you need, for example `linux-x64`, `linux-arm64`, `osx-arm64`, or `osx-x64`.
For macOS, avoid the Metal renderer for fully static output. Use OpenGL or Software. For Linux, `lld` is recommended:
## Native Package Automation ```bash
dotnet publish -c Release -r linux-x64 \
-p:PublishAot=true \
-p:SelfContained=true \
-p:PublishSingleFile=true \
-p:StripSymbols=true \
-p:LinkerFlavor=lld
```
`.github/workflows/nuget-avalonia-native.yml` runs daily and checks the latest stable `Avalonia` version on NuGet.org. If `StaticLink.Avalonia.Native.<AvaloniaVersion>.1` does not exist, it builds both macOS architectures from the matching Avalonia source tag, runs NativeAOT smoke tests, and publishes the package with NuGet Trusted Publishing. For macOS, avoid the Metal renderer for fully static output. Use OpenGL or Software:
Configure NuGet.org Trusted Publishing for this repository and the `nuget-avalonia-native.yml` workflow, then add the NuGet.org account name as the repository variable `NUGET_USER`. No long-lived NuGet API key is used by this workflow. ```csharp
.With(new AvaloniaNativePlatformOptions
{
RenderingMode = [AvaloniaNativeRenderingMode.OpenGl, AvaloniaNativeRenderingMode.Software]
})
```
## Static Graphics Automation ## Notes
`.github/workflows/nuget-static-graphics.yml` runs a fast version, upstream-ref, patch, script, and smoke-project preflight before starting native builds. It then calls independent Windows, Linux, Linux musl, and macOS workflows, packs their artifacts, runs all NativeAOT smoke tests, and only then publishes NuGet and GitHub Release assets. - The package is intended for Avalonia `11.3.x` NativeAOT apps.
- `StaticLink.Avalonia.Native` is version-specific because `libAvaloniaNative.a` must match Avalonia's native ABI.
The platform workflows can also be dispatched independently when diagnosing a single platform: - The CI builds and smoke-publishes all six supported RIDs.
- macOS smoke tests run the published app on GitHub Actions and require it to stay alive for 15 seconds.
- `static-graphics-windows.yml` - Other native dependencies used by your app, such as SQLite or audio libraries, are outside this package's scope.
- `static-graphics-linux.yml`
- `static-graphics-musl.yml`
- `static-graphics-macos.yml`
The release workflow derives the SkiaSharp version and ANGLE branch from `NuGet/StaticGraphics/StaticLink.Avalonia.csproj`. Native source and build directories are cached by platform, RID, version, patch, and build script.
-7
View File
@@ -1,7 +0,0 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="AvaloniaStaticLinkSmoke.App">
<Application.Styles>
<FluentTheme />
</Application.Styles>
</Application>
@@ -1,23 +0,0 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
namespace AvaloniaStaticLinkSmoke;
public sealed partial class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow();
}
base.OnFrameworkInitializationCompleted();
}
}
@@ -1,26 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="SmokeVersions.props" Condition="Exists('SmokeVersions.props')" />
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
<PublishAot>true</PublishAot>
<SelfContained>true</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>true</PublishTrimmed>
<PublishReadyToRun>false</PublishReadyToRun>
<InvariantGlobalization>true</InvariantGlobalization>
<AvaloniaVersion Condition="'$(AvaloniaVersion)' == ''">11.3.14</AvaloniaVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="$(AvaloniaVersion)" />
<PackageReference Include="Avalonia.Desktop" Version="$(AvaloniaVersion)" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="$(AvaloniaVersion)" />
<PackageReference Include="StaticLink.Avalonia" Version="$(StaticLinkVersion)" Condition="'$(StaticLinkVersion)' != ''" />
<PackageReference Include="StaticLink.Avalonia.Native" Version="$(StaticLinkNativeVersion)" Condition="'$(StaticLinkNativeVersion)' != ''" />
</ItemGroup>
</Project>
@@ -1,13 +0,0 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="AvaloniaStaticLinkSmoke.MainWindow"
Width="420"
Height="220"
Title="Avalonia StaticLink Smoke">
<Border Padding="24">
<StackPanel Spacing="8" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="Avalonia static link smoke" FontSize="24" FontWeight="SemiBold" HorizontalAlignment="Center" />
<TextBlock Text="NativeAOT single-file publish" HorizontalAlignment="Center" />
</StackPanel>
</Border>
</Window>
@@ -1,11 +0,0 @@
using Avalonia.Controls;
namespace AvaloniaStaticLinkSmoke;
public sealed partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
-54
View File
@@ -1,54 +0,0 @@
using Avalonia;
namespace AvaloniaStaticLinkSmoke;
internal static class Program
{
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
public static AppBuilder BuildAvaloniaApp()
{
var builder = AppBuilder.Configure<App>()
.UsePlatformDetect()
.LogToTrace();
if (OperatingSystem.IsWindows())
{
builder = builder.With(new Win32PlatformOptions
{
RenderingMode =
[
Win32RenderingMode.AngleEgl,
Win32RenderingMode.Software
]
});
}
if (OperatingSystem.IsLinux())
{
builder = builder.With(new X11PlatformOptions
{
RenderingMode =
[
X11RenderingMode.Glx,
X11RenderingMode.Software
]
});
}
if (OperatingSystem.IsMacOS())
{
builder = builder.With(new AvaloniaNativePlatformOptions
{
RenderingMode =
[
AvaloniaNativeRenderingMode.OpenGl,
AvaloniaNativeRenderingMode.Software
]
});
}
return builder;
}
}
+7 -225
View File
@@ -6,8 +6,8 @@ WORK_DIR="${WORK_DIR:-$ROOT_DIR/External/NativeStatic/.work}"
TARGET_CPU="${TARGET_CPU:-x64}" TARGET_CPU="${TARGET_CPU:-x64}"
RID="${RID:-linux-$TARGET_CPU}" RID="${RID:-linux-$TARGET_CPU}"
OUTPUT_DIR="${OUTPUT_DIR:-$ROOT_DIR/External/NativeStatic/$RID}" OUTPUT_DIR="${OUTPUT_DIR:-$ROOT_DIR/External/NativeStatic/$RID}"
SKIASHARP_VERSION="${SKIASHARP_VERSION:-3.119.4}" SKIASHARP_VERSION="${SKIASHARP_VERSION:-3.119.2}"
ANGLE_BRANCH="${ANGLE_BRANCH:-7922}" ANGLE_BRANCH="${ANGLE_BRANCH:-7151}"
BUILD_JOBS="${BUILD_JOBS:-$(nproc)}" BUILD_JOBS="${BUILD_JOBS:-$(nproc)}"
ANGLE_PATCH_DIR="${ANGLE_PATCH_DIR:-$ROOT_DIR/External/NativeStatic/patches}" ANGLE_PATCH_DIR="${ANGLE_PATCH_DIR:-$ROOT_DIR/External/NativeStatic/patches}"
LLVM_AR="${LLVM_AR:-llvm-ar-19}" LLVM_AR="${LLVM_AR:-llvm-ar-19}"
@@ -20,8 +20,8 @@ Usage: scripts/build-linux-static-graphics.sh [skia|angle|all]
Environment: Environment:
WORK_DIR Source/build cache directory. Default: External/NativeStatic/.work WORK_DIR Source/build cache directory. Default: External/NativeStatic/.work
OUTPUT_DIR Final static library directory. Default: External/NativeStatic/linux-$TARGET_CPU OUTPUT_DIR Final static library directory. Default: External/NativeStatic/linux-$TARGET_CPU
SKIASHARP_VERSION SkiaSharp release branch version. Default: 3.119.4 SKIASHARP_VERSION SkiaSharp release branch version. Default: 3.119.2
ANGLE_BRANCH ANGLE chromium branch. Default: 7922 ANGLE_BRANCH ANGLE chromium branch. Default: 7151
TARGET_CPU GN target_cpu. Default: x64. Supported: x64, arm64 TARGET_CPU GN target_cpu. Default: x64. Supported: x64, arm64
RID Output RID. Default: linux-$TARGET_CPU RID Output RID. Default: linux-$TARGET_CPU
BUILD_JOBS Ninja parallelism. Default: nproc BUILD_JOBS Ninja parallelism. Default: nproc
@@ -37,10 +37,6 @@ require_cmd() {
fi fi
} }
is_musl_rid() {
[[ "$RID" == linux-musl-* ]]
}
ensure_tools() { ensure_tools() {
require_cmd git require_cmd git
require_cmd python3 require_cmd python3
@@ -54,84 +50,12 @@ ensure_tools() {
ensure_depot_tools() { ensure_depot_tools() {
local depot_dir="$WORK_DIR/depot_tools" local depot_dir="$WORK_DIR/depot_tools"
local python_bin_dir
python_bin_dir="$(dirname "$(command -v python3)")"
if [[ ! -d "$depot_dir/.git" ]]; then if [[ ! -d "$depot_dir/.git" ]]; then
git clone --depth 1 https://chromium.googlesource.com/chromium/tools/depot_tools.git "$depot_dir" git clone --depth 1 https://chromium.googlesource.com/chromium/tools/depot_tools.git "$depot_dir"
else else
git -C "$depot_dir" pull --ff-only git -C "$depot_dir" pull --ff-only
fi fi
if is_musl_rid; then export PATH="$depot_dir:$PATH"
initialize_depot_tools_system_python "$depot_dir"
patch_depot_tools_python_deps "$depot_dir"
fi
export PATH="$python_bin_dir:$depot_dir:$PATH"
}
initialize_depot_tools_system_python() {
local depot_dir="$1"
local python_bin_dir
python_bin_dir="$(dirname "$(command -v python3)")"
if [[ -d "$depot_dir" ]]; then
python3 - "$depot_dir" "$python_bin_dir" <<'PY'
import os
import pathlib
import sys
depot_dir = pathlib.Path(sys.argv[1]).resolve()
python_bin_dir = pathlib.Path(sys.argv[2]).resolve()
marker = depot_dir / "python3_bin_reldir.txt"
marker.write_text(os.path.relpath(python_bin_dir, depot_dir) + "\n")
PY
fi
}
patch_depot_tools_python_deps() {
local depot_dir="$1"
local gsutil_dir="$depot_dir/external_bin/gsutil/gsutil_4.68/gsutil"
local gsutil_third_party="$gsutil_dir/third_party"
if [[ -d "$gsutil_dir" && ! -f "$gsutil_dir/six.py" ]]; then
python3 - "$gsutil_dir/six.py" <<'PY'
import pathlib
import shutil
import six
import sys
src = pathlib.Path(six.__file__)
dest = pathlib.Path(sys.argv[1])
shutil.copyfile(src, dest)
PY
fi
if [[ -d "$gsutil_third_party" && ! -f "$gsutil_third_party/six.py" ]]; then
python3 - "$gsutil_third_party/six.py" <<'PY'
import pathlib
import shutil
import six
import sys
src = pathlib.Path(six.__file__)
dest = pathlib.Path(sys.argv[1])
shutil.copyfile(src, dest)
PY
fi
}
prepend_python_module_path() {
local module="$1"
local module_dir
module_dir="$(python3 - "$module" <<'PY'
import importlib
import pathlib
import sys
module = importlib.import_module(sys.argv[1])
print(pathlib.Path(module.__file__).parent)
PY
)"
export PYTHONPATH="$module_dir:${PYTHONPATH:-}"
} }
sync_skiasharp() { sync_skiasharp() {
@@ -149,17 +73,11 @@ sync_skiasharp() {
prepare_skia_git_sync_deps() { prepare_skia_git_sync_deps() {
local sync_deps="$1/tools/git-sync-deps" local sync_deps="$1/tools/git-sync-deps"
python3 - "$sync_deps" <<'PY' python3 - "$sync_deps" <<'PY'
import re
import pathlib import pathlib
import sys import sys
path = pathlib.Path(sys.argv[1]) path = pathlib.Path(sys.argv[1])
text = path.read_text() text = path.read_text()
deps_path = path.with_name("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)
deps_path.write_text(deps)
old = " multithread(git_checkout_to_directory, list_of_arg_lists)" old = " multithread(git_checkout_to_directory, list_of_arg_lists)"
new = " for args in list_of_arg_lists:\n git_checkout_to_directory(*args)" new = " for args in list_of_arg_lists:\n git_checkout_to_directory(*args)"
if old in text: if old in text:
@@ -268,28 +186,16 @@ build_angle() {
cd "$src" cd "$src"
apply_angle_patches "$src" apply_angle_patches "$src"
python3 scripts/bootstrap.py python3 scripts/bootstrap.py
if is_musl_rid; then
initialize_depot_tools_system_python "$src/third_party/depot_tools"
patch_depot_tools_python_deps "$src/third_party/depot_tools"
prepend_python_module_path six
prepare_angle_gcs_artifacts "$src"
prepare_musl_clang_toolchain
fi
prepare_musl_libstdcxx_headers
gclient sync -f -D -R gclient sync -f -D -R
local out_dir="$src/out/linux-static-$TARGET_CPU" local out_dir="$src/out/linux-static-$TARGET_CPU"
local angle_is_clang="true"
if [[ "$TARGET_CPU" == "arm64" ]] && ! is_musl_rid; then
angle_is_clang="false"
fi
mkdir -p "$out_dir" mkdir -p "$out_dir"
cat >"$out_dir/args.gn" <<EOF_ARGS cat >"$out_dir/args.gn" <<EOF_ARGS
target_os = "linux" target_os = "linux"
target_cpu = "$TARGET_CPU" target_cpu = "$TARGET_CPU"
is_debug = false is_debug = false
is_component_build = false is_component_build = false
is_clang = $angle_is_clang is_clang = false
treat_warnings_as_errors = false treat_warnings_as_errors = false
use_custom_libcxx = false use_custom_libcxx = false
use_sysroot = false use_sysroot = false
@@ -302,9 +208,7 @@ angle_enable_swiftshader = false
angle_enable_vulkan = false angle_enable_vulkan = false
angle_enable_wgpu = false angle_enable_wgpu = false
EOF_ARGS EOF_ARGS
if is_musl_rid; then
printf 'clang_base_path = "%s/clang"\nclang_use_chrome_plugins = false\nclang_version = "%s"\n' "$WORK_DIR" "$(clang -dumpversion | cut -d. -f1)" >>"$out_dir/args.gn"
fi
gn gen "$out_dir" gn gen "$out_dir"
ninja -C "$out_dir" -j "$BUILD_JOBS" libANGLE_static libGLESv2_static ninja -C "$out_dir" -j "$BUILD_JOBS" libANGLE_static libGLESv2_static
@@ -358,128 +262,6 @@ PY
fi fi
} }
prepare_angle_gcs_artifacts() {
local src="$1"
download_angle_gcs_artifact \
angle-glslang-validator \
"$src/tools/glslang/glslang_validator.sha1" \
"$src/tools/glslang/glslang_validator"
download_angle_gcs_artifact \
angle-flex-bison \
"$src/tools/flex-bison/linux/bison.sha1" \
"$src/tools/flex-bison/linux/bison"
download_angle_gcs_artifact \
angle-flex-bison \
"$src/tools/flex-bison/linux/flex.sha1" \
"$src/tools/flex-bison/linux/flex"
}
download_angle_gcs_artifact() {
local bucket="$1"
local sha_file="$2"
local output="$3"
if [[ -f "$sha_file" && ! -f "$output" ]]; then
local sha
sha="$(tr -d '[:space:]' <"$sha_file")"
curl -fsSL "https://storage.googleapis.com/$bucket/$sha" -o "$output"
chmod +x "$output"
fi
}
prepare_musl_libstdcxx_headers() {
if ! is_musl_rid; then
return 0
fi
local arch
local musl_triple
case "$TARGET_CPU" in
x64)
arch="x86_64"
musl_triple="x86_64-linux-musl"
;;
arm64)
arch="aarch64"
musl_triple="aarch64-linux-musl"
;;
*)
echo "Unsupported musl ANGLE target_cpu for libstdc++ headers: $TARGET_CPU" >&2
return 1
;;
esac
local cxx_root
cxx_root="$(find /usr/include/c++ -mindepth 1 -maxdepth 1 -type d -print -quit 2>/dev/null || true)"
if [[ -z "$cxx_root" ]]; then
echo "Could not find libstdc++ include root" >&2
return 1
fi
local src_dir="$cxx_root/${arch}-alpine-linux-musl"
local dest_dir="$cxx_root/$musl_triple"
if [[ ! -d "$src_dir" ]]; then
echo "Could not find Alpine libstdc++ target headers: $src_dir" >&2
return 1
fi
ln -sfn "$src_dir" "$dest_dir"
}
prepare_musl_clang_toolchain() {
local arch
local gnu_triple
case "$TARGET_CPU" in
x64)
arch="x86_64"
gnu_triple="x86_64-unknown-linux-gnu"
;;
arm64)
arch="aarch64"
gnu_triple="aarch64-unknown-linux-gnu"
;;
*)
echo "Unsupported musl ANGLE target_cpu: $TARGET_CPU" >&2
return 1
;;
esac
local clang_version
clang_version="$(clang -dumpversion | cut -d. -f1)"
local toolchain_dir="$WORK_DIR/clang"
local runtime
runtime="$(find /usr/lib/llvm* /usr/lib/clang -path "*${arch}*" -name 'libclang_rt.builtins*.a' -print -quit 2>/dev/null || true)"
if [[ -z "$runtime" ]]; then
echo "Could not find Alpine compiler-rt builtins for $arch" >&2
return 1
fi
mkdir -p "$toolchain_dir/bin" "$toolchain_dir/lib/clang/$clang_version/lib/$gnu_triple"
ln -sf "$runtime" "$toolchain_dir/lib/clang/$clang_version/lib/$gnu_triple/libclang_rt.builtins.a"
cat >"$toolchain_dir/bin/clang-wrapper.py" <<'PY'
#!/usr/bin/env python3
import os
import sys
blocked = (
"-fdiagnostics-show-inlining-chain",
"-fno-lifetime-dse",
"-fsanitize-ignore-for-ubsan-feature=",
)
args = [arg for arg in sys.argv[1:] if not arg.startswith(blocked)]
compiler = "/usr/bin/clang++" if os.path.basename(sys.argv[0]) == "clang++" else "/usr/bin/clang"
os.execv(compiler, [compiler, *args])
PY
chmod +x "$toolchain_dir/bin/clang-wrapper.py"
ln -sf clang-wrapper.py "$toolchain_dir/bin/clang"
ln -sf clang-wrapper.py "$toolchain_dir/bin/clang++"
for tool in llvm-ar llvm-ranlib llvm-nm; do
if command -v "$tool" >/dev/null 2>&1; then
ln -sf "$(command -v "$tool")" "$toolchain_dir/bin/$tool"
fi
done
}
copy_first_existing() { copy_first_existing() {
local dest="$1" local dest="$1"
shift shift
@@ -3,8 +3,8 @@ set -euo pipefail
RID="${RID:-osx-arm64}" RID="${RID:-osx-arm64}"
AVALONIA_VERSION="${AVALONIA_VERSION:-11.3.14}" AVALONIA_VERSION="${AVALONIA_VERSION:-11.3.14}"
WORK_DIR="${WORK_DIR:-$PWD/External/AvaloniaNative/.work}" WORK_DIR="${WORK_DIR:-$PWD/External/NativeStatic/.work}"
OUTPUT_DIR="${OUTPUT_DIR:-$PWD/External/AvaloniaNative/$RID/native}" OUTPUT_DIR="${OUTPUT_DIR:-$PWD/External/NativeStatic/$RID/native}"
BUILD_JOBS="${BUILD_JOBS:-$(sysctl -n hw.ncpu 2>/dev/null || echo 4)}" BUILD_JOBS="${BUILD_JOBS:-$(sysctl -n hw.ncpu 2>/dev/null || echo 4)}"
case "$RID" in case "$RID" in
+2 -10
View File
@@ -6,8 +6,8 @@ WORK_DIR="${WORK_DIR:-$ROOT_DIR/External/NativeStatic/.work}"
TARGET_CPU="${TARGET_CPU:-arm64}" TARGET_CPU="${TARGET_CPU:-arm64}"
RID="${RID:-osx-$TARGET_CPU}" RID="${RID:-osx-$TARGET_CPU}"
OUTPUT_DIR="${OUTPUT_DIR:-$ROOT_DIR/External/NativeStatic/$RID}" OUTPUT_DIR="${OUTPUT_DIR:-$ROOT_DIR/External/NativeStatic/$RID}"
SKIASHARP_VERSION="${SKIASHARP_VERSION:-3.119.4}" SKIASHARP_VERSION="${SKIASHARP_VERSION:-3.119.2}"
ANGLE_BRANCH="${ANGLE_BRANCH:-7922}" ANGLE_BRANCH="${ANGLE_BRANCH:-7151}"
BUILD_JOBS="${BUILD_JOBS:-$(sysctl -n hw.ncpu)}" BUILD_JOBS="${BUILD_JOBS:-$(sysctl -n hw.ncpu)}"
ANGLE_PATCH_DIR="${ANGLE_PATCH_DIR:-$ROOT_DIR/External/NativeStatic/patches}" ANGLE_PATCH_DIR="${ANGLE_PATCH_DIR:-$ROOT_DIR/External/NativeStatic/patches}"
SKIA_DEPS_RETRIES="${SKIA_DEPS_RETRIES:-3}" SKIA_DEPS_RETRIES="${SKIA_DEPS_RETRIES:-3}"
@@ -68,17 +68,11 @@ sync_skiasharp() {
prepare_skia_git_sync_deps() { prepare_skia_git_sync_deps() {
local sync_deps="$1/tools/git-sync-deps" local sync_deps="$1/tools/git-sync-deps"
python3 - "$sync_deps" <<'PY' python3 - "$sync_deps" <<'PY'
import re
import pathlib import pathlib
import sys import sys
path = pathlib.Path(sys.argv[1]) path = pathlib.Path(sys.argv[1])
text = path.read_text() text = path.read_text()
deps_path = path.with_name("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)
deps_path.write_text(deps)
old = " multithread(git_checkout_to_directory, list_of_arg_lists)" old = " multithread(git_checkout_to_directory, list_of_arg_lists)"
new = " for args in list_of_arg_lists:\n git_checkout_to_directory(*args)" new = " for args in list_of_arg_lists:\n git_checkout_to_directory(*args)"
if old in text: if old in text:
@@ -118,12 +112,10 @@ build_skia() {
cat >"$out_dir/args.gn" <<EOF_ARGS cat >"$out_dir/args.gn" <<EOF_ARGS
target_os = "mac" target_os = "mac"
target_cpu = "$TARGET_CPU" target_cpu = "$TARGET_CPU"
min_macos_version = "10.13"
is_official_build = true is_official_build = true
is_static_skiasharp = true is_static_skiasharp = true
skia_enable_tools = false skia_enable_tools = false
skia_enable_ganesh = true skia_enable_ganesh = true
skia_use_metal = true
skia_enable_pdf = false skia_enable_pdf = false
skia_enable_skottie = false skia_enable_skottie = false
skia_use_dng_sdk = false skia_use_dng_sdk = false
+6 -288
View File
@@ -7,8 +7,8 @@ $ErrorActionPreference = "Stop"
$RootDir = Split-Path -Parent $PSScriptRoot $RootDir = Split-Path -Parent $PSScriptRoot
$WorkDir = if ($env:WORK_DIR) { $env:WORK_DIR } else { Join-Path $RootDir "External\NativeStatic\.work" } $WorkDir = if ($env:WORK_DIR) { $env:WORK_DIR } else { Join-Path $RootDir "External\NativeStatic\.work" }
$SkiaSharpVersion = if ($env:SKIASHARP_VERSION) { $env:SKIASHARP_VERSION } else { "3.119.4" } $SkiaSharpVersion = if ($env:SKIASHARP_VERSION) { $env:SKIASHARP_VERSION } else { "3.119.2" }
$AngleBranch = if ($env:ANGLE_BRANCH) { $env:ANGLE_BRANCH } else { "7922" } $AngleBranch = if ($env:ANGLE_BRANCH) { $env:ANGLE_BRANCH } else { "7151" }
$TargetCpu = if ($env:TARGET_CPU) { $env:TARGET_CPU } else { "x64" } $TargetCpu = if ($env:TARGET_CPU) { $env:TARGET_CPU } else { "x64" }
$Rid = if ($env:RID) { $env:RID } else { "win-$TargetCpu" } $Rid = if ($env:RID) { $env:RID } else { "win-$TargetCpu" }
$OutputDir = if ($env:OUTPUT_DIR) { $env:OUTPUT_DIR } else { Join-Path $RootDir "External\NativeStatic\$Rid" } $OutputDir = if ($env:OUTPUT_DIR) { $env:OUTPUT_DIR } else { Join-Path $RootDir "External\NativeStatic\$Rid" }
@@ -72,275 +72,6 @@ function Copy-FirstExisting($Destination, [string[]]$Candidates) {
throw "None of the expected files exist for ${Destination}: $($Candidates -join ', ')" throw "None of the expected files exist for ${Destination}: $($Candidates -join ', ')"
} }
function Split-ParameterList($Parameters) {
if ([string]::IsNullOrWhiteSpace($Parameters)) {
return @()
}
$items = [System.Collections.Generic.List[string]]::new()
$start = 0
$depth = 0
for ($i = 0; $i -lt $Parameters.Length; $i++) {
$ch = $Parameters[$i]
if ($ch -eq '[' -or $ch -eq '(' -or $ch -eq '<') {
$depth++
} elseif ($ch -eq ']' -or $ch -eq ')' -or $ch -eq '>') {
if ($depth -gt 0) { $depth-- }
} elseif ($ch -eq ',' -and $depth -eq 0) {
$items.Add($Parameters.Substring($start, $i - $start).Trim())
$start = $i + 1
}
}
$items.Add($Parameters.Substring($start).Trim())
return $items | Where-Object { $_ }
}
function Get-X86NativeParameterSize($Parameter) {
$parameter = [regex]::Replace($Parameter, '/\*.*?\*/', '').Trim()
$parameter = [regex]::Replace($parameter, '\[[^\]]+\]\s*', '').Trim()
$parameter = [regex]::Replace($parameter, '\b(ref|out|in)\b\s*', '').Trim()
if (-not $parameter) { return 0 }
$parts = $parameter -split '\s+'
if ($parts.Length -gt 1) {
$type = ($parts[0..($parts.Length - 2)] -join ' ')
} else {
$type = $parts[0]
}
$type = $type.Trim()
if ($script:X86GeneratedStructSizes -and $script:X86GeneratedStructSizes.ContainsKey($type)) {
return $script:X86GeneratedStructSizes[$type]
}
if ($type.Contains('*') -or $type.EndsWith('[]') -or $type -eq 'String' -or $type -eq 'string' -or $type.EndsWith('Delegate')) {
return 4
}
switch -Regex ($type) {
'^(Int64|UInt64|long|ulong|Double|double)$' { return 8 }
default { return 4 }
}
}
function Align-X86Size($Size, $Alignment) {
if ($Alignment -le 1) { return $Size }
return [int]([Math]::Ceiling($Size / [double]$Alignment) * $Alignment)
}
function Get-X86ManagedTypeLayout($Type, $KnownSizes) {
if ($Type.Contains('*') -or $Type.Contains('delegate*') -or $Type.EndsWith('[]') -or $Type.EndsWith('Delegate')) {
return @{ Size = 4; Alignment = 4 }
}
switch -Regex ($Type) {
'^(Byte|SByte|bool)$' { return @{ Size = 1; Alignment = 1 } }
'^(Int16|UInt16|short|ushort|Char)$' { return @{ Size = 2; Alignment = 2 } }
'^(Int64|UInt64|long|ulong|Double|double)$' { return @{ Size = 8; Alignment = 4 } }
default {
if ($KnownSizes.ContainsKey($Type)) {
return @{ Size = $KnownSizes[$Type]; Alignment = 4 }
}
return @{ Size = 4; Alignment = 4 }
}
}
}
function Get-X86GeneratedStructSizes($BindingFiles) {
$structFields = @{}
foreach ($bindingFile in $BindingFiles) {
$lines = Get-Content -Path $bindingFile
$current = $null
$depth = 0
$includeStack = @($true)
foreach ($line in $lines) {
if ($line -match '^\s*#if\s+USE_LIBRARY_IMPORT\b') {
$includeStack += $includeStack[-1]
continue
}
if ($line -match '^\s*#else\b') {
if ($includeStack.Count -gt 1) {
$parentActive = $includeStack[-2]
$includeStack[-1] = $parentActive -and (-not $includeStack[-1])
}
continue
}
if ($line -match '^\s*#endif\b') {
if ($includeStack.Count -gt 1) {
$includeStack = @($includeStack[0..($includeStack.Count - 2)])
}
continue
}
if (-not $includeStack[-1]) {
continue
}
if (-not $current -and $line -match '\bstruct\s+([A-Za-z0-9_]+)\b') {
$current = $Matches[1]
$structFields[$current] = [System.Collections.Generic.List[string]]::new()
$depth = ([regex]::Matches($line, '\{')).Count - ([regex]::Matches($line, '\}')).Count
continue
}
if ($current) {
if ($depth -eq 1 -and $line -match '^\s*public\s+(.+?)\s+[A-Za-z0-9_]+;\s*$') {
$fieldType = ([regex]::Replace($Matches[1].Trim(), '#if.*$', '')).Trim()
$structFields[$current].Add($fieldType)
}
$depth += ([regex]::Matches($line, '\{')).Count
$depth -= ([regex]::Matches($line, '\}')).Count
if ($depth -le 0) {
$current = $null
}
}
}
}
$sizes = @{}
$pending = @($structFields.Keys)
while ($pending.Count -gt 0) {
$next = @()
$progress = $false
foreach ($name in $pending) {
$offset = 0
$maxAlign = 1
$resolved = $true
foreach ($fieldType in $structFields[$name]) {
if ($structFields.ContainsKey($fieldType) -and -not $sizes.ContainsKey($fieldType)) {
$resolved = $false
break
}
$layout = Get-X86ManagedTypeLayout $fieldType $sizes
$maxAlign = [Math]::Max($maxAlign, [Math]::Min($layout.Alignment, 4))
$offset = Align-X86Size $offset ([Math]::Min($layout.Alignment, 4))
$offset += $layout.Size
}
if ($resolved) {
$sizes[$name] = Align-X86Size $offset $maxAlign
$progress = $true
} else {
$next += $name
}
}
if (-not $progress) { break }
$pending = $next
}
return $sizes
}
function Get-X86PInvokeThunks($BindingFiles, $DefinedSymbols) {
$thunks = @{}
$signaturePattern = 'internal static (?:extern|partial)\s+.+?\s+((?:sk|gr|hb)_[A-Za-z0-9_]+)\s*\((.*?)\);'
$script:X86GeneratedStructSizes = Get-X86GeneratedStructSizes $BindingFiles
foreach ($bindingFile in $BindingFiles) {
if (-not (Test-Path $bindingFile)) {
throw "Missing binding file for win-x86 thunk generation: $bindingFile"
}
$content = Get-Content -Raw -Path $bindingFile
foreach ($match in [regex]::Matches($content, $signaturePattern, [System.Text.RegularExpressions.RegexOptions]::Singleline)) {
$symbol = "_$($match.Groups[1].Value)"
if (-not $DefinedSymbols.ContainsKey($symbol)) {
continue
}
$bytes = 0
foreach ($parameter in Split-ParameterList $match.Groups[2].Value) {
$bytes += Get-X86NativeParameterSize $parameter
}
$decorated = "${symbol}@${bytes}"
$thunks[$decorated] = [pscustomobject]@{
Symbol = $symbol
Bytes = $bytes
Decorated = $decorated
}
}
}
return $thunks.Values | Sort-Object Symbol, Bytes
}
function New-WinX86SkiaStdcallThunks([string[]]$InputLibraries, [string[]]$BindingFiles, $Destination) {
if ($TargetCpu -ne "x86") {
return
}
$llvmNm = Get-Command llvm-nm.exe -ErrorAction SilentlyContinue
if (-not $llvmNm) {
$llvmNm = Get-Command llvm-nm -ErrorAction SilentlyContinue
}
if (-not $llvmNm) {
throw "Missing required command: llvm-nm"
}
Require-Command ml.exe
Require-Command lib.exe
$thunkDir = Join-Path $WorkDir "win-x86-skia-stdcall-thunks"
New-Item -ItemType Directory -Path $thunkDir -Force | Out-Null
$asmPath = Join-Path $thunkDir "skia_x86_stdcall_thunks.asm"
$objPath = Join-Path $thunkDir "skia_x86_stdcall_thunks.obj"
$definedSymbols = @{}
foreach ($library in $InputLibraries) {
& $llvmNm.Source --defined-only $library |
ForEach-Object {
if ($_ -match '\sT\s(_(?:sk|gr|hb)_[A-Za-z0-9_]+)$') {
$definedSymbols[$Matches[1]] = $true
}
}
}
if (-not $definedSymbols.Count) {
throw "No SkiaSharp/HarfBuzzSharp C API symbols found in $($InputLibraries -join ', ')"
}
$thunks = @(Get-X86PInvokeThunks $BindingFiles $definedSymbols)
if (-not $thunks) {
throw "No win-x86 stdcall thunks generated from $($BindingFiles -join ', ')"
}
$lines = [System.Collections.Generic.List[string]]::new()
$lines.Add("OPTION CASEMAP:NONE")
$lines.Add(".386")
$lines.Add(".model flat")
foreach ($symbol in ($thunks | Select-Object -ExpandProperty Symbol -Unique)) {
$lines.Add("EXTERN ${symbol}:PROC")
}
$lines.Add("_TEXT SEGMENT")
foreach ($thunk in $thunks) {
$lines.Add("PUBLIC $($thunk.Decorated)")
$lines.Add("$($thunk.Decorated) PROC")
for ($offset = 0; $offset -lt $thunk.Bytes; $offset += 4) {
$lines.Add(" push DWORD PTR [esp+$($thunk.Bytes)]")
}
$lines.Add(" call $($thunk.Symbol)")
if ($thunk.Bytes -gt 0) {
$lines.Add(" add esp, $($thunk.Bytes)")
}
$lines.Add(" ret $($thunk.Bytes)")
$lines.Add("$($thunk.Decorated) ENDP")
}
$lines.Add("_TEXT ENDS")
$lines.Add("END")
Set-Content -Path $asmPath -Value $lines -Encoding ASCII
& ml.exe /nologo /c /coff /safeseh /Fo$objPath $asmPath
if ($LASTEXITCODE -ne 0) {
throw "Failed to assemble win-x86 Skia stdcall thunks."
}
& lib.exe /nologo /out:$Destination $objPath
if ($LASTEXITCODE -ne 0) {
throw "Failed to archive win-x86 Skia stdcall thunks."
}
Write-Host "Wrote $Destination"
}
function Sync-SkiaSharp { function Sync-SkiaSharp {
$src = Join-Path $WorkDir "SkiaSharp-$SkiaSharpVersion" $src = Join-Path $WorkDir "SkiaSharp-$SkiaSharpVersion"
if (-not (Test-Path (Join-Path $src ".git"))) { if (-not (Test-Path (Join-Path $src ".git"))) {
@@ -356,12 +87,6 @@ function Sync-SkiaSharp {
function Prepare-SkiaGitSyncDeps($SkiaDir) { function Prepare-SkiaGitSyncDeps($SkiaDir) {
$syncDeps = Join-Path $SkiaDir "tools\git-sync-deps" $syncDeps = Join-Path $SkiaDir "tools\git-sync-deps"
$text = Get-Content -Path $syncDeps -Raw $text = Get-Content -Path $syncDeps -Raw
$depsPath = Join-Path $SkiaDir "DEPS"
if (Test-Path $depsPath) {
$depsText = Get-Content -Path $depsPath -Raw
$depsText = [regex]::Replace($depsText, '(?m)^\s*"third_party/externals/dng_sdk"\s*:\s*"[^"]+",\s*\r?\n', '')
Set-Content -Path $depsPath -Value $depsText -NoNewline -Encoding UTF8
}
$old = " multithread(git_checkout_to_directory, list_of_arg_lists)" $old = " multithread(git_checkout_to_directory, list_of_arg_lists)"
$new = " for args in list_of_arg_lists:`n git_checkout_to_directory(*args)" $new = " for args in list_of_arg_lists:`n git_checkout_to_directory(*args)"
if ($text.Contains($old)) { if ($text.Contains($old)) {
@@ -421,7 +146,7 @@ skia_use_system_libpng = false
skia_use_system_libwebp = false skia_use_system_libwebp = false
skia_use_system_zlib = false skia_use_system_zlib = false
skia_use_vulkan = false skia_use_vulkan = false
skia_use_xps = true skia_use_xps = false
extra_cflags = [ "-DSKIA_C_DLL" ] extra_cflags = [ "-DSKIA_C_DLL" ]
extra_cflags_cc = [ "/GR" ] extra_cflags_cc = [ "/GR" ]
"@ | Set-Content -Path (Join-Path $outDir "args.gn") -Encoding ASCII "@ | Set-Content -Path (Join-Path $outDir "args.gn") -Encoding ASCII
@@ -434,12 +159,9 @@ extra_cflags_cc = [ "/GR" ]
Pop-Location Pop-Location
} }
$skiaLib = Join-Path $OutputDir "skia.lib" Copy-FirstExisting (Join-Path $OutputDir "skia.lib") @((Join-Path $outDir "skia.lib"), (Join-Path $outDir "obj\skia.lib"))
$skiaSharpLib = Join-Path $OutputDir "SkiaSharp.lib" Copy-FirstExisting (Join-Path $OutputDir "SkiaSharp.lib") @((Join-Path $outDir "SkiaSharp.lib"), (Join-Path $outDir "obj\SkiaSharp.lib"))
$harfbuzzLib = Join-Path $OutputDir "libHarfBuzzSharp.lib" Copy-FirstExisting (Join-Path $OutputDir "libHarfBuzzSharp.lib") @(
Copy-FirstExisting $skiaLib @((Join-Path $outDir "skia.lib"), (Join-Path $outDir "obj\skia.lib"))
Copy-FirstExisting $skiaSharpLib @((Join-Path $outDir "SkiaSharp.lib"), (Join-Path $outDir "obj\SkiaSharp.lib"))
Copy-FirstExisting $harfbuzzLib @(
(Join-Path $outDir "libHarfBuzzSharp.lib"), (Join-Path $outDir "libHarfBuzzSharp.lib"),
(Join-Path $outDir "HarfBuzzSharp.lib"), (Join-Path $outDir "HarfBuzzSharp.lib"),
(Join-Path $outDir "obj\libHarfBuzzSharp.lib"), (Join-Path $outDir "obj\libHarfBuzzSharp.lib"),
@@ -447,10 +169,6 @@ extra_cflags_cc = [ "/GR" ]
(Join-Path $outDir "obj\HarfBuzzSharp\libHarfBuzzSharp.lib"), (Join-Path $outDir "obj\HarfBuzzSharp\libHarfBuzzSharp.lib"),
(Join-Path $outDir "obj\HarfBuzzSharp\HarfBuzzSharp.lib") (Join-Path $outDir "obj\HarfBuzzSharp\HarfBuzzSharp.lib")
) )
New-WinX86SkiaStdcallThunks `
-InputLibraries @($skiaLib, $skiaSharpLib, $harfbuzzLib) `
-BindingFiles @((Join-Path $src "binding\SkiaSharp\SkiaApi.generated.cs"), (Join-Path $src "binding\HarfBuzzSharp\HarfBuzzApi.generated.cs")) `
-Destination (Join-Path $OutputDir "skia_x86_stdcall_thunks.lib")
} }
function Sync-Angle { function Sync-Angle {
+127 -22
View File
@@ -5,7 +5,8 @@ param(
[Parameter(Mandatory = $true)] [Parameter(Mandatory = $true)]
[string]$NuGetSource, [string]$NuGetSource,
[string]$StaticLinkVersion = "", [Parameter(Mandatory = $true)]
[string]$StaticLinkVersion,
[string]$AvaloniaVersion = "11.3.14", [string]$AvaloniaVersion = "11.3.14",
@@ -14,36 +15,140 @@ param(
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
$templateDir = Join-Path (Split-Path -Parent $PSScriptRoot) "Smoke/AvaloniaStaticLinkSmoke"
if (-not (Test-Path (Join-Path $templateDir "AvaloniaStaticLinkSmoke.csproj"))) {
throw "Smoke project template was not found: $templateDir"
}
New-Item -ItemType Directory -Path $ProjectDir -Force | Out-Null New-Item -ItemType Directory -Path $ProjectDir -Force | Out-Null
Copy-Item (Join-Path $templateDir "*") -Destination $ProjectDir -Recurse -Force
$escapedNuGetSource = [System.Security.SecurityElement]::Escape($NuGetSource) $nativeReference = ""
$escapedAvaloniaVersion = [System.Security.SecurityElement]::Escape($AvaloniaVersion) if ($StaticLinkNativeVersion) {
$escapedStaticLinkVersion = [System.Security.SecurityElement]::Escape($StaticLinkVersion) $nativeReference = "`n <PackageReference Include=`"StaticLink.Avalonia.Native`" Version=`"$StaticLinkNativeVersion`" />"
$escapedStaticLinkNativeVersion = [System.Security.SecurityElement]::Escape($StaticLinkNativeVersion) }
@"
<Project>
<PropertyGroup>
<AvaloniaVersion>$escapedAvaloniaVersion</AvaloniaVersion>
<StaticLinkVersion>$escapedStaticLinkVersion</StaticLinkVersion>
<StaticLinkNativeVersion>$escapedStaticLinkNativeVersion</StaticLinkNativeVersion>
</PropertyGroup>
</Project>
"@ | Set-Content -Path (Join-Path $ProjectDir "SmokeVersions.props") -Encoding UTF8
@" @"
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<packageSources> <packageSources>
<clear /> <clear />
<add key="local-staticlink" value="$escapedNuGetSource" /> <add key="local-staticlink" value="$NuGetSource" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources> </packageSources>
</configuration> </configuration>
"@ | Set-Content -Path (Join-Path $ProjectDir "NuGet.config") -Encoding UTF8 "@ | Set-Content -Path (Join-Path $ProjectDir "NuGet.config") -Encoding UTF8
@"
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
<PublishAot>true</PublishAot>
<SelfContained>true</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>true</PublishTrimmed>
<PublishReadyToRun>false</PublishReadyToRun>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="$AvaloniaVersion" />
<PackageReference Include="Avalonia.Desktop" Version="$AvaloniaVersion" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="$AvaloniaVersion" />
<PackageReference Include="StaticLink.Avalonia" Version="$StaticLinkVersion" />$nativeReference
</ItemGroup>
</Project>
"@ | Set-Content -Path (Join-Path $ProjectDir "AvaloniaStaticLinkSmoke.csproj") -Encoding UTF8
@"
using Avalonia;
namespace AvaloniaStaticLinkSmoke;
internal static class Program
{
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
public static AppBuilder BuildAvaloniaApp()
{
var builder = AppBuilder.Configure<App>()
.UsePlatformDetect()
.LogToTrace();
if (OperatingSystem.IsMacOS())
{
builder = builder.With(new AvaloniaNativePlatformOptions
{
RenderingMode = [AvaloniaNativeRenderingMode.Software]
});
}
return builder;
}
}
"@ | Set-Content -Path (Join-Path $ProjectDir "Program.cs") -Encoding UTF8
@"
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
namespace AvaloniaStaticLinkSmoke;
public sealed partial class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow();
}
base.OnFrameworkInitializationCompleted();
}
}
"@ | Set-Content -Path (Join-Path $ProjectDir "App.axaml.cs") -Encoding UTF8
@"
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="AvaloniaStaticLinkSmoke.App">
<Application.Styles>
<FluentTheme />
</Application.Styles>
</Application>
"@ | Set-Content -Path (Join-Path $ProjectDir "App.axaml") -Encoding UTF8
@"
using Avalonia.Controls;
namespace AvaloniaStaticLinkSmoke;
public sealed partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
"@ | Set-Content -Path (Join-Path $ProjectDir "MainWindow.axaml.cs") -Encoding UTF8
@"
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="AvaloniaStaticLinkSmoke.MainWindow"
Width="420"
Height="220"
Title="Avalonia StaticLink Smoke">
<Border Padding="24">
<StackPanel Spacing="8" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="Avalonia $AvaloniaVersion" FontSize="24" FontWeight="SemiBold" HorizontalAlignment="Center" />
<TextBlock Text="StaticLink NativeAOT smoke publish" HorizontalAlignment="Center" />
</StackPanel>
</Border>
</Window>
"@ | Set-Content -Path (Join-Path $ProjectDir "MainWindow.axaml") -Encoding UTF8