Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
86a6c57
Migrate WinML EP downloads to WinML 2.x (reg-free runtime)
bmehta001 Jun 4, 2026
331c4db
Nits
bmehta001 Jun 10, 2026
0187b8f
Guard QueryWindowsBuild helper inside FOUNDRY_LOCAL_HAS_EP_CATALOG
bmehta001 Jun 10, 2026
fdcaafc
FindWinMLEpCatalog: drop unused WINML_EP_CATALOG_HEADER_DIR output
bmehta001 Jun 10, 2026
97139a9
winml_ep_bootstrapper: prefer OSVERSIONINFOW over RTL_OSVERSIONINFOW
bmehta001 Jun 10, 2026
3d7ee58
tests: cover WinML 2.x EnsureReady end-to-end register path
bmehta001 Jun 10, 2026
8436bf7
cs/test: accept '.git' file in addition to '.git' directory
bmehta001 Jun 10, 2026
84f81b9
build: only compile WinML EP bootstrapper when WinML SKU is enabled
bmehta001 Jun 10, 2026
70825fb
docs: clarify WinML bootstrapper OS version requirements
bmehta001 Jun 11, 2026
6c4f55c
build: drop unused FOUNDRY_LOCAL_USE_WINML compile definition
bmehta001 Jun 11, 2026
509d939
cs: collapse WinML SKU TFM to net8.0;net9.0 (drop Windows-specific TFM)
bmehta001 Jun 11, 2026
81e0233
docs: correct WinML Windows SDK note and stale memory
bmehta001 Jun 11, 2026
fc5389d
docs: clarify per-project TFM matrix in DEVELOPMENT.md
bmehta001 Jun 11, 2026
4f72731
cs/test: re-enable VisionTests under WinML SKU
bmehta001 Jun 11, 2026
52093e3
docs: rewrite WinML comments to describe code, not change rationale
bmehta001 Jun 11, 2026
8d4f73c
test(cs): multi-target net8.0;net9.0 for build coverage, run on net9.0
bmehta001 Jun 12, 2026
84f917a
manager: drop stale WebGPU/WinML coexistence TODO
bmehta001 Jun 12, 2026
d9ffe60
test/ep_detection: drop stale CUDA/WebGPU name skip
bmehta001 Jun 12, 2026
8cd8062
test/cs: collapse duplicate TargetFrameworks declarations
bmehta001 Jun 12, 2026
103696a
cleanup: drop stale WinAppSDK installs, _winml.json ref, orphan JS he…
bmehta001 Jun 12, 2026
68361f3
cleanup: drop stale Win32 include + WindowsAppRuntime/version doc refs
bmehta001 Jun 13, 2026
c79332b
winml_ep: forward incremental download progress + sync doc with impl
bmehta001 Jun 13, 2026
5f107d1
winml_ep: report raw progress, cache library path, single-SoT version
bmehta001 Jun 13, 2026
9bee1a7
cleanup: address Copilot review comments
bmehta001 Jun 13, 2026
a87cb9b
docs: fix EpDetectionPlan progress-callback description
bmehta001 Jun 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions .pipelines/foundry-local-packaging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,13 @@ parameters:
variables:
- group: FoundryLocal-ESRP-Signing
# C++ SDK (sdk_v2/cpp) native dependency versions. Must match cmake defaults
# in sdk_v2/deps_versions.json and sdk_v2/deps_versions_winml.json.
# in sdk_v2/deps_versions.json.
- name: cppOrtVersion
value: '1.25.1'
- name: cppOrtVersionWinml
# Pinned to the WinML-aligned ORT line so foundry_local.dll's ORT ABI matches
# the WinML EP catalog plugins it loads. See FindOnnxRuntime.cmake.
value: '1.23.2.3'
- name: cppGenaiVersion
value: '0.13.2'
- name: cppWinmlVersion
value: '1.8.2192'
value: '2.1.70'
- name: cppBuildConfig
value: 'RelWithDebInfo'

Expand Down Expand Up @@ -269,6 +265,5 @@ extends:
parameters:
buildConfig: $(cppBuildConfig)
ortVersion: $(cppOrtVersion)
ortVersionWinml: $(cppOrtVersionWinml)
genaiVersion: $(cppGenaiVersion)
winmlVersion: $(cppWinmlVersion)
39 changes: 16 additions & 23 deletions .pipelines/v2/sdk_v2-pipeline-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ are gated separately via `.pipelines/v1/templates/stages-sdk-v1.yml`.
`foundry-local-sdk-winml` when `FL_PYTHON_PACKAGE_NAME` is set in the
environment. The same backend also handles ORT pin rewriting (decision 8).
8. **Single source of truth for ORT/GenAI versions.** ORT and GenAI versions
live in `sdk_v2/deps_versions.json` (standard) and
`sdk_v2/deps_versions_winml.json` (WinML). Both files have shape
live in `sdk_v2/deps_versions.json`. The file shape is
`{ "onnxruntime": { "version": "..." }, "onnxruntime-genai": { "version": "..." } }`.
Consumers:
- **C++ build:** `sdk_v2/cpp/cmake/Find{OnnxRuntime,OnnxRuntimeGenAI}.cmake`
Expand Down Expand Up @@ -175,15 +174,13 @@ compute_version
* All build stages are independent (`dependsOn: [compute_version]`) and run
in parallel.
* Both pack stages run on every build (PR and `main`).
* The WinML build stages link against ORT 1.23.x (pinned via
`ortVersionWinml`) so the binary's ORT ABI matches the WinML EP catalog
plugins it loads. The base stages link against ORT 1.25.x.
* WinML and non-WinML build stages link against the same ORT version
(`ortVersion`, currently 1.25.x). WinML 2.x is reg-free and uses the
standard ORT package, so a separate WinML-aligned ORT pin is no longer
required.
* Tests run on `cpp_build_win_x64`, `cpp_build_win_x64_winml`,
`cpp_build_linux_x64`, and `cpp_build_osx_arm64`. The two ARM64 Windows
stages cross-compile from an x64 host and skip tests. The WinML x64 stage
runs the full suite — the C++ `VisionFixture` and the C# `VisionTests`
self-skip on the WinML-aligned ORT (older than the cataloged vision
models require), so the rest of the suite still exercises that configuration.
stages cross-compile from an x64 host and skip tests.

## Per-stage artifacts

Expand Down Expand Up @@ -245,35 +242,31 @@ purposes:

1. **Version pinning** — the `KEY=PATH` pairs are passed via
`--cmake_extra_defines` (`ORT_FETCH_URL`, `GENAI_FETCH_URL`,
`WINML_EP_CATALOG_FETCH_URL`, `WINAPPSDK_FOUNDATION_FETCH_URL`,
`ORT_GPU_LINUX_FETCH_URL`) so the cmake defaults in
`FindOnnxRuntime.cmake` / `FindOnnxRuntimeGenAI.cmake` are never
silently substituted.
`WINML_EP_CATALOG_FETCH_URL`, `ORT_GPU_LINUX_FETCH_URL`) so the cmake
defaults in `FindOnnxRuntime.cmake` / `FindOnnxRuntimeGenAI.cmake` are
never silently substituted.
2. **Stage isolation** — the build step no longer needs network access to
the package feed once prefetch has completed.

Versions are pipeline-level variables, currently:

* `ortVersion` `1.25.1` (`Microsoft.ML.OnnxRuntime.Foundry`)
* `ortVersionWinml` `1.23.2.3` (WinML-aligned ORT line, used by the WinML build stages)
* `genaiVersion` `0.13.2` (`Microsoft.ML.OnnxRuntimeGenAI.Foundry`)
* `winmlVersion` `1.8.2192` (`Microsoft.WindowsAppSDK.ML`)
* `winmlVersion` `2.1.70` (`Microsoft.Windows.AI.MachineLearning`, WinML 2.x reg-free)

These must be kept in sync with the cmake defaults and with
`sdk_v2/deps_versions[_winml].json` (decision 8). When bumping, update
both places in the same PR.
`sdk_v2/deps_versions.json` (decision 8). When bumping, update both places
in the same PR.

The shared download logic is in `steps-prefetch-nuget.yml` and exposes both
a PowerShell (Windows) and a bash (Linux/macOS) implementation behind a
`shell` parameter. It emits a single pipeline variable `cmakeFetchDefines`
containing the quoted `KEY=PATH` pairs to splice into the build command.

WinML is special-cased: `Microsoft.WindowsAppSDK.ML` has a transitive
dependency on `Microsoft.WindowsAppSDK.Foundation` whose exact min version
is often unpublished, so the pwsh branch shells out to `nuget install
... -DependencyVersion Lowest` to let the resolver pick a satisfying
version, then emits fetch URLs for both `.nupkg`s. The bash branch fails
fast if `includeWinml=true` is ever passed — WinML is Windows-only.
WinML downloads `Microsoft.Windows.AI.MachineLearning` directly from
nuget.org as a single self-contained reg-free package — no transitive
WinAppSDK Foundation resolution needed. The bash branch fails fast if
`includeWinml=true` is ever passed — WinML is Windows-only.

## Test data

Expand Down
8 changes: 3 additions & 5 deletions .pipelines/v2/templates/stages-build-native.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ parameters:
type: string
- name: ortVersion
type: string
- name: ortVersionWinml
type: string
- name: genaiVersion
type: string
- name: winmlVersion
Expand Down Expand Up @@ -181,7 +179,7 @@ stages:
parameters:
arch: x64
buildConfig: ${{ parameters.buildConfig }}
ortVersion: ${{ parameters.ortVersionWinml }}
ortVersion: ${{ parameters.ortVersion }}
genaiVersion: ${{ parameters.genaiVersion }}
winmlVersion: ${{ parameters.winmlVersion }}
useWinml: true
Expand Down Expand Up @@ -214,7 +212,7 @@ stages:
parameters:
arch: arm64
buildConfig: ${{ parameters.buildConfig }}
ortVersion: ${{ parameters.ortVersionWinml }}
ortVersion: ${{ parameters.ortVersion }}
genaiVersion: ${{ parameters.genaiVersion }}
winmlVersion: ${{ parameters.winmlVersion }}
useWinml: true
Expand Down Expand Up @@ -297,6 +295,6 @@ stages:
steps:
- template: steps-pack-nuget.yml
parameters:
ortVersion: ${{ parameters.ortVersionWinml }}
ortVersion: ${{ parameters.ortVersion }}
genaiVersion: ${{ parameters.genaiVersion }}
variant: winml
3 changes: 0 additions & 3 deletions .pipelines/v2/templates/stages-sdk-v2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ parameters:
default: 'RelWithDebInfo'
- name: ortVersion
type: string
- name: ortVersionWinml
type: string
- name: genaiVersion
type: string
- name: winmlVersion
Expand All @@ -30,7 +28,6 @@ stages:
parameters:
buildConfig: ${{ parameters.buildConfig }}
ortVersion: ${{ parameters.ortVersion }}
ortVersionWinml: ${{ parameters.ortVersionWinml }}
genaiVersion: ${{ parameters.genaiVersion }}
winmlVersion: ${{ parameters.winmlVersion }}

Expand Down
24 changes: 9 additions & 15 deletions .pipelines/v2/templates/steps-build-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
# buildConfig – CMake config (Debug, Release, RelWithDebInfo, MinSizeRel)
# ortVersion – Microsoft.ML.OnnxRuntime.Foundry version
# genaiVersion – Microsoft.ML.OnnxRuntimeGenAI.Foundry version
# winmlVersion – Microsoft.WindowsAppSDK.ML version
# useWinml – Build the WinML variant (--use_winml). Caller is responsible
# for passing the WinML-aligned ortVersion (e.g. 1.23.2.3).
# winmlVersion – Microsoft.Windows.AI.MachineLearning version
# useWinml – Build the WinML variant (--use_winml).
# runTests – Whether to run tests
# stageHeaders – Whether to stage public headers as a separate artifact

Expand Down Expand Up @@ -151,17 +150,12 @@ steps:
# libcurl/libssl/zlib/brotli* into foundry_local.dll (see
# sdk_v2/cpp/triplets/x64-windows.cmake), so the only runtime payload is
# foundry_local.dll itself.
# - WinML build: foundry_local.dll picks up one extra static import —
# Microsoft.WindowsAppRuntime.Bootstrap.dll — which is the entry point
# that calls MddBootstrapInitialize2 to register the system-installed
# Windows App Runtime. Bootstrap.dll must travel with the wheel because
# end-user / CI machines don't have it on PATH otherwise. Everything
# downstream of Bootstrap (Microsoft.Windows.AI.MachineLearning.dll,
# DirectML, the WinML-flavored ORT, etc.) is supplied by the system
# App Runtime that Bootstrap registers — Microsoft.Windows.AI.MachineLearning
# is delay-loaded (see /DELAYLOAD in CMakeLists.txt) so it is NOT needed at
# foundry_local.dll load time. ORT/GenAI come from the onnxruntime-core /
# onnxruntime-genai-core pip deps.
# - WinML build: foundry_local.dll picks up one extra runtime dependency,
# Microsoft.Windows.AI.MachineLearning.dll, which must travel with the wheel.
# The WinML DLL is delay-loaded (see /DELAYLOAD in CMakeLists.txt) so it is
# NOT needed at foundry_local.dll load time, but the cmake post-build copy
# stages it next to foundry_local.dll for runtime EP discovery. ORT/GenAI
# come from the onnxruntime-core / onnxruntime-genai-core pip deps.
- task: PowerShell@2
displayName: 'Stage native artifacts'
inputs:
Expand All @@ -179,7 +173,7 @@ steps:
(Join-Path $linkDir 'foundry_local.lib')
)
if ($${{ parameters.useWinml }}) {
$sources += (Join-Path $binDir 'Microsoft.WindowsAppRuntime.Bootstrap.dll')
$sources += (Join-Path $binDir 'Microsoft.Windows.AI.MachineLearning.dll')
}

foreach ($s in $sources) {
Expand Down
74 changes: 43 additions & 31 deletions .pipelines/v2/templates/steps-prefetch-nuget.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# Parameters:
# ortVersion – Microsoft.ML.OnnxRuntime.Foundry version
# genaiVersion – Microsoft.ML.OnnxRuntimeGenAI.Foundry version
# winmlVersion – Microsoft.WindowsAppSDK.ML version (Windows only)
# winmlVersion – Microsoft.Windows.AI.MachineLearning version (Windows only)
# includeWinml – Download WinML and emit WINML_EP_CATALOG_FETCH_URL
# includeOrtGpuLinux – Also download Microsoft.ML.OnnxRuntime.Gpu.Linux (Linux only)
# shell – 'pwsh' (Windows/macOS) or 'bash' (Linux)
Expand All @@ -32,6 +32,39 @@ parameters:

steps:

# Fail fast if the pipeline-pinned versions drift from the cmake source of
# truth in sdk_v2/deps_versions.json.
- task: PowerShell@2
displayName: 'Validate pinned versions match deps_versions.json'
inputs:
targetType: inline
pwsh: true
script: |
$ErrorActionPreference = 'Stop'
$depsFile = Join-Path "$(Build.SourcesDirectory)" "sdk_v2/deps_versions.json"
if (-not (Test-Path $depsFile)) { throw "deps_versions.json not found at $depsFile" }
$deps = Get-Content $depsFile -Raw | ConvertFrom-Json
$expected = @{
'onnxruntime' = '${{ parameters.ortVersion }}'
'onnxruntime-genai' = '${{ parameters.genaiVersion }}'
}
if ('${{ parameters.winmlVersion }}' -ne '') {
$expected['windows-ai-machinelearning'] = '${{ parameters.winmlVersion }}'
}
$errors = @()
foreach ($key in $expected.Keys) {
$actual = $deps.$key.version
if ($actual -ne $expected[$key]) {
$errors += " $key`: pipeline says '$($expected[$key])', deps_versions.json says '$actual'"
}
}
if ($errors.Count -gt 0) {
Write-Host "Version drift detected between pipeline literals and sdk_v2/deps_versions.json:"
$errors | ForEach-Object { Write-Host $_ }
throw "Bump the matching cpp*Version variable in .pipelines/foundry-local-packaging.yml"
}
Write-Host "Pinned versions agree with sdk_v2/deps_versions.json."

- ${{ if eq(parameters.shell, 'pwsh') }}:
- task: PowerShell@2
displayName: 'Pre-download NuGet packages'
Expand Down Expand Up @@ -74,34 +107,15 @@ steps:
}

if ($${{ parameters.includeWinml }}) {
# WinML's bootstrap dep (Microsoft.WindowsAppSDK.Foundation) is a transitive dep of
# Microsoft.WindowsAppSDK.ML, and nuget min-version semantics mean the exact min
# version often isn't published — only later patches are. Defer to `nuget install`
# so the real resolver picks a satisfying version.
$winmlDir = "$cacheDir/winml-resolved"
if (Test-Path $winmlDir) { Remove-Item -Recurse -Force $winmlDir }
New-Item -ItemType Directory -Force -Path $winmlDir | Out-Null
Write-Host "Resolving Microsoft.WindowsAppSDK.ML ${{ parameters.winmlVersion }} via nuget install"
nuget install Microsoft.WindowsAppSDK.ML `
-Version '${{ parameters.winmlVersion }}' `
-OutputDirectory $winmlDir `
-Source 'https://api.nuget.org/v3/index.json' `
-DependencyVersion Lowest `
-PackageSaveMode nupkg `
-DirectDownload `
-Verbosity quiet
if ($LASTEXITCODE -ne 0) { throw "nuget install Microsoft.WindowsAppSDK.ML failed (exit $LASTEXITCODE)" }

$mlNupkg = Get-ChildItem $winmlDir -Recurse -Filter 'Microsoft.WindowsAppSDK.ML.*.nupkg' |
Select-Object -First 1
$foundationNupkg = Get-ChildItem $winmlDir -Recurse -Filter 'Microsoft.WindowsAppSDK.Foundation.*.nupkg' |
Select-Object -First 1
if (-not $mlNupkg) { throw "Microsoft.WindowsAppSDK.ML .nupkg not found under $winmlDir after nuget install" }
if (-not $foundationNupkg) { throw "Microsoft.WindowsAppSDK.Foundation .nupkg not found under $winmlDir after nuget install" }
Write-Host " -> $($mlNupkg.FullName) ($($mlNupkg.Length) bytes)"
Write-Host " -> $($foundationNupkg.FullName) ($($foundationNupkg.Length) bytes)"
$defines += "WINML_EP_CATALOG_FETCH_URL=$($mlNupkg.FullName)"
$defines += "WINAPPSDK_FOUNDATION_FETCH_URL=$($foundationNupkg.FullName)"
# WinML 2.x (Microsoft.Windows.AI.MachineLearning) is reg-free — a single self-contained
# native package with no transitive Windows App SDK Foundation dependency to resolve.
$winmlUrl = "$feed/Microsoft.Windows.AI.MachineLearning/${{ parameters.winmlVersion }}"
$winmlOut = "$cacheDir/winml.nupkg"
Write-Host "Downloading Microsoft.Windows.AI.MachineLearning ${{ parameters.winmlVersion }}"
Invoke-WebRequest -Uri $winmlUrl -OutFile $winmlOut
if (-not (Test-Path $winmlOut)) { throw "WinML download failed" }
Comment thread
bmehta001 marked this conversation as resolved.
Write-Host " -> $winmlOut ($((Get-Item $winmlOut).Length) bytes)"
$defines += "WINML_EP_CATALOG_FETCH_URL=$winmlOut"
}

$joined = ($defines | ForEach-Object { "`"$_`"" }) -join ' '
Expand All @@ -126,8 +140,6 @@ steps:
)
if [ "${{ parameters.includeWinml }}" = "True" ]; then
# WinML is Windows-only; the bash branch should never receive includeWinml=true.
# If this fires, the prefetch needs to mirror the pwsh logic that resolves the
# Microsoft.WindowsAppSDK.Foundation version from the .ML nuspec dependency list.
echo "ERROR: includeWinml=true is not supported on the bash prefetch branch (WinML is Windows-only)." >&2
exit 1
fi
Expand Down
41 changes: 23 additions & 18 deletions .pipelines/v2/templates/steps-test-cs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,6 @@ steps:
- task: NuGetAuthenticate@1
displayName: 'Authenticate NuGet feeds'

- ${{ if eq(parameters.isWinML, true) }}:
- task: PowerShell@2
displayName: 'Install Windows App SDK Runtime'
inputs:
targetType: 'inline'
pwsh: true
script: |
$installerUrl = "https://aka.ms/windowsappsdk/1.8/latest/windowsappruntimeinstall-x64.exe"
$installerPath = "$env:TEMP\windowsappruntimeinstall.exe"
Invoke-WebRequest -Uri $installerUrl -OutFile $installerPath
& $installerPath --quiet --force
if ($LASTEXITCODE -ne 0) { throw "Windows App SDK Runtime install failed" }
errorActionPreference: 'stop'

# Per-job NuGet isolation to prevent "Central Directory corrupt" / file-locking
# errors when multiple C# test jobs (regular + WinML) run concurrently on the
# same reused agent. Keyed by $(System.JobId); cleaned on each run.
Expand Down Expand Up @@ -168,10 +154,29 @@ steps:
pwsh: true
script: |
$proj = "$(Build.SourcesDirectory)/sdk_v2/cs/test/FoundryLocal.Tests/Microsoft.AI.Foundry.Local.Tests.csproj"
dotnet test $proj `
--no-build --configuration Release `
/p:UseWinML=${{ parameters.isWinML }}
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }

# Test TFMs:
# * net9.0 covers the .NET (Core) runtime test surface.
# * net462 (Windows only, non-WinML) exercises the netstandard2.0 surface
# + polyfills at runtime on .NET Framework.
# The csproj also targets net8.0, but only as build-time coverage — the .NET
# back-compat guarantee means a successful net9.0 test run validates the same
# assemblies for net8.0 consumers.
$frameworks = @('net9.0')
$isWin = $IsWindows -or ($PSVersionTable.Platform -eq $null)
$isWinML = '${{ parameters.isWinML }}' -eq 'True'
if ($isWin -and -not $isWinML) {
$frameworks += 'net462'
}

foreach ($tfm in $frameworks) {
Write-Host "=== dotnet test --framework $tfm ==="
dotnet test $proj `
--no-build --configuration Release `
--framework $tfm `
/p:UseWinML=${{ parameters.isWinML }}
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
}
env:
TF_BUILD: 'true'
FOUNDRY_TEST_DATA_DIR: ${{ parameters.testDataSharedDir }}
14 changes: 0 additions & 14 deletions .pipelines/v2/templates/steps-test-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,6 @@ steps:
addToPath: true
architecture: '${{ parameters.pythonArchitecture }}'

- ${{ if eq(parameters.isWinML, true) }}:
- task: PowerShell@2
displayName: 'Install Windows App SDK Runtime'
inputs:
targetType: 'inline'
pwsh: true
script: |
$installerUrl = "https://aka.ms/windowsappsdk/1.8/latest/windowsappruntimeinstall-x64.exe"
$installerPath = "$env:TEMP\windowsappruntimeinstall.exe"
Invoke-WebRequest -Uri $installerUrl -OutFile $installerPath
& $installerPath --quiet --force
if ($LASTEXITCODE -ne 0) { throw "Windows App SDK Runtime install failed" }
errorActionPreference: 'stop'

# Job-local venv so installs never pollute the agent's site-packages.
- task: PowerShell@2
displayName: 'Create test venv'
Expand Down
2 changes: 1 addition & 1 deletion memories/repo/cs-local-packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ dotnet pack src/Microsoft.AI.Foundry.Local.csproj -o ../../local-packages /p:IsP
dotnet pack src/Microsoft.AI.Foundry.Local.csproj -o ../../local-packages /p:IsPacking=true /p:UseWinML=true /p:TreatWarningsAsErrors=false -c Release
```
- `IsPacking=true` auto-sets `Version=0.5.0-dev.local.<yyyyMMddHHmmss>` (see `Microsoft.AI.Foundry.Local.csproj`).
- `UseWinML=true` flips `PackageId`/`AssemblyName` to `Microsoft.AI.Foundry.Local.WinML`, single-targets `net9.0-windows10.0.26100.0`.
- `UseWinML=true` flips `PackageId`/`AssemblyName` to `Microsoft.AI.Foundry.Local.WinML`; both SKUs share the `net8.0;net9.0` TFM set (WinML SKU omits `netstandard2.0`).
- Cross-platform + WinML are independent packages — most samples reference WinML on Windows and the cross-platform package elsewhere, so both must be packed.

## Full clean-rebuild
Expand Down
Loading
Loading