A step-by-step guide to building and running this repro on a Mac, including the in-process benchmark run. This complements RUNNING.md with macOS specifics.
Authored/validated on Windows; the Mac Catalyst head is wired up and ready. This runbook is what to follow on the Mac.
# .NET 10 SDK — verify
dotnet --version # should print 10.x
# Xcode (required for any Apple build). Install from the App Store, then:
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -license accept
# The MAUI workload
dotnet workload install mauiKnow your Mac's CPU architecture — it picks the runtime identifier (RID):
uname -m
# arm64 -> Apple Silicon (M1/M2/M3/M4) -> RID: maccatalyst-arm64
# x86_64 -> Intel -> RID: maccatalyst-x64Set a shell variable you'll reuse below:
RID=maccatalyst-arm64 # or maccatalyst-x64 on Intelgit clone https://github.com/brianrob/repros.git
cd repros
# (main already contains this repro)cd src/MauiBenchDemo
dotnet build -c Release -f net10.0-maccatalyst -p:RuntimeIdentifier=$RIDThis produces an app bundle at:
bin/Release/net10.0-maccatalyst/$RID/MauiBenchDemo.app
Easiest:
dotnet build -c Release -f net10.0-maccatalyst -p:RuntimeIdentifier=$RID -t:RunA window opens. Click Increment counter, Go to Items list, or Run UI benchmarks (in-process) to trigger a run while the app stays open.
The benchmark switch is read from the --benchmark argument or the
RUN_BENCHMARKS=1 environment variable. Launch the inner executable inside
the app bundle (not open) so the terminal's stdout and environment are
inherited — that's how you see the live BenchmarkDotNet output and pass the env var:
APP=bin/Release/net10.0-maccatalyst/$RID/MauiBenchDemo.app
EXE="$APP/Contents/MacOS/MauiBenchDemo"
# Either of these works:
"$EXE" --benchmark
# or
RUN_BENCHMARKS=1 "$EXE"The app boots, runs the five benchmarks in-process (you'll see
Toolchain=InProcessNoEmitToolchain in the header), prints the table, then quits.
If
Contents/MacOS/MauiBenchDemodoesn't exist, list the bundle to find the executable name:ls "$APP/Contents/MacOS/".
BenchmarkDotNet.Artifacts/results/*-report-github.md <- the Markdown table
BenchmarkDotNet.Artifacts/results/*-report.csv
BenchmarkDotNet.Artifacts/results/*-report.html
BenchmarkDotNet.Artifacts/*.log
These are written relative to the process's working directory (the folder you ran the executable from).
-
dotnet --versionis 10.x anddotnet workload listshowsmaui. -
uname -mmatched theRIDyou used. - Release build succeeded with
-f net10.0-maccatalyst. - Headless run printed a table whose header says
Toolchain=InProcessNoEmitToolchainand.NET 10. - The process exited on its own (benchmark mode self-quits).
xcrun: error/ signing failures — re-run thexcode-selectandxcodebuild -license acceptsteps above; open Xcode once to finish setup.- Wrong architecture / "bad CPU type" — your
RIDdoesn't matchuname -m. Rebuild with the correctmaccatalyst-arm64vsmaccatalyst-x64. - No benchmark output / app just shows a window — you launched via
open(which doesn't inherit env vars) or forgot the switch. Use the innerContents/MacOS/MauiBenchDemoexecutable with--benchmark. - Want higher-precision numbers — switch
Job.ShortRuntoJob.DefaultinBenchmarks/BenchmarkLauncher.cs(CreateConfig). - Optimization warning — build
-c Release(Debug is allowed for iteration but not for trustworthy measurements).
- No
AllocConsolehack is needed on macOS: launched from a terminal, the app's stdout goes straight to your terminal. (That Windows-only code is guarded by#if WINDOWS.) - Everything still runs in one process — the BenchmarkDotNet engine thread and the live UIKit-backed MAUI UI share the address space, so there is no cross-process latency, exactly as on Windows.