[xaprepare] Use Microsoft.SourceLink.GitHub instead of hand-rolled SourceLink.json - #11821

Merged
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-adopt-sourcelink-github
Jun 30, 2026
Merged

[xaprepare] Use Microsoft.SourceLink.GitHub instead of hand-rolled SourceLink.json#11821
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-adopt-sourcelink-github

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Member

Summary

Stop generating bin/Build$(Configuration)/SourceLink.json from xaprepare and stop overriding $(SourceLink) in Configuration.props. Let Microsoft.SourceLink.GitHub (which is already pinned at 8.0.0 in Directory.Build.targets, but until now only Included in one project) produce SourceLink the canonical Arcade way for every project.

Changes

  • Directory.Build.targets — promoted Microsoft.SourceLink.GitHub 8.0.0 from a PackageReference Update to a broad PackageReference Include with PrivateAssets="All" so every project in the repo picks it up.
  • src/Microsoft.Android.Run/Microsoft.Android.Run.csproj — dropped the now-redundant explicit <PackageReference Include="Microsoft.SourceLink.GitHub" />.
  • Configuration.props — deleted the <PropertyGroup> that overrode $(SourceLink) with the path to the generated json file. The canonical package now sets $(SourceLink) itself.
  • build-tools/xaprepare/xaprepare/Application/GeneratedSourceLinkJsonFile.cs — deleted.
  • build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs — removed Get_SourceLink_Json, both references in GetFilesToGenerate, and the gitSubmodules / xaCommit fields plus the git/submodule prelude in Execute (no other generator in this file used them). Switched Execute from async back to a synchronous Task.FromResult since the only await was the deleted submodule walk.
  • build-tools/xaprepare/xaprepare/Application/GeneratedFile.cs — deleted the now-orphaned SkipGeneratedFile class (only caller was Get_SourceLink_Json).

Net: -99/+8 lines, one file deleted.

Verification

Built Mono.Android.csproj, Xamarin.Android.Build.Tasks.csproj, and xaprepare.csproj in Debug after a clean build.cmd Prepare. All succeeded with 0 errors.

Ran sourcelink print-json on bin\Debug\lib\packs\Microsoft.Android.Runtime.37.android\37.0.0\runtimes\android\lib\net11.0\Mono.Android.pdb:

{"documents":{
"<repo>\\*": "https://raw.githubusercontent.com/dotnet/android/138c93d5a5b369e5d9b6867607afefa7502cd787/*",
"<repo>\\external\\android-api-docs\\*": "https://raw.githubusercontent.com/dotnet/android-api-docs/d382c5bd406432083901e51a4e87cd677b8759d8/*",
"<repo>\\external\\constexpr-xxh3\\*": "https://raw.githubusercontent.com/chys87/constexpr-xxh3/aebcee75c8b6c2458fa8ae151754a8ba833bd697/*",
"<repo>\\external\\debugger-libs\\*": "https://raw.githubusercontent.com/mono/debugger-libs/e7fbb713d156d11193ed404783ad6fe9c4042a6d/*",
"<repo>\\external\\Java.Interop\\*": "https://raw.githubusercontent.com/dotnet/java-interop/8d544738ad294b4faf13d189eeeb02f0313e00b3/*",
"<repo>\\external\\libunwind\\*": "https://raw.githubusercontent.com/libunwind/libunwind/e97c9ef82f8b48d0c7f713be4fa7b15e634d76b8/*",
"<repo>\\external\\lz4\\*": "https://raw.githubusercontent.com/lz4/lz4/ebb370ca83af193212df4dcbadcc5d87bc0de2f0/*",
"<repo>\\external\\robin-map\\*": "https://raw.githubusercontent.com/xamarin/robin-map/d37a41003bfbc7e12e34601f93c18ca2ff6d7c07/*",
"<repo>\\external\\termux-elf-cleaner\\*": "https://raw.githubusercontent.com/termux/termux-elf-cleaner/ee5385e004a9d67bdc289e43939691b260e06b03/*",
"<repo>\\external\\xamarin-android-tools\\*": "https://raw.githubusercontent.com/dotnet/android-tools/367724d6ba93db20294681769de97b9cdecb58a0/*",
"<repo>\\external\\xxHash\\*": "https://raw.githubusercontent.com/Cyan4973/xxHash/bbb27a5efb85b92a0486cf361a8635715a53f6ba/*"
}}

Every submodule from .gitmodules is mapped to its correct upstream raw.githubusercontent.com URL — full parity with what GeneratedSourceLinkJsonFile produced before.

Out of scope

Step_GenerateCGManifest, GitSubmoduleInfo, GitRunner, and the GitCommit* prep tasks are still used by cgmanifest generation and XAVersionInfo.targets; they're intentionally left for a follow-up PR.

Precedent

Continues the xaprepare slim-down work in #11568, #11580, #11608, #11613, #11631, #11657, #11658, #11731, #11732, #11733, #11737, #11740, #11760, #11803.

…urceLink.json
Stop generating bin/Build$(Configuration)/SourceLink.json from xaprepare and stop overriding $(SourceLink) in Configuration.props. Promote Microsoft.SourceLink.GitHub from a PackageReference Update to a broad PackageReference Include in Directory.Build.targets so every project picks it up, then drop the explicit Include from Microsoft.Android.Run.csproj.
Verified with 'sourcelink print-json' on bin\Debug\lib\packs\Microsoft.Android.Runtime.37.android\37.0.0\runtimes\android\lib\net11.0\Mono.Android.pdb: the canonical package produces a documents map covering dotnet/android plus every submodule (Java.Interop, xamarin-android-tools, android-api-docs, constexpr-xxh3, debugger-libs, libunwind, lz4, robin-map, termux-elf-cleaner, xxHash) pointing at the correct upstream raw.githubusercontent.com URLs.
Step_GenerateCGManifest and GitSubmoduleInfo / GitRunner are intentionally left for a follow-up.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 30, 2026 14:07

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR switches the repo’s SourceLink generation to the standard Arcade/MSBuild approach by enabling Microsoft.SourceLink.GitHub repo-wide, and removes the now-redundant xaprepare-generated SourceLink.json plumbing.

Changes:

  • Add a repo-wide PackageReference to Microsoft.SourceLink.GitHub (PrivateAssets=All) via Directory.Build.targets, and remove the per-project reference from Microsoft.Android.Run.
  • Stop overriding $(SourceLink) in Configuration.props, letting the SourceLink package set it canonically.
  • Remove xaprepare’s SourceLink.json generator and related scaffolding (including the SkipGeneratedFile helper).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
Directory.Build.targetsAdds global Microsoft.SourceLink.GitHub package reference for SourceLink across the repo.
src/Microsoft.Android.Run/Microsoft.Android.Run.csprojRemoves redundant explicit SourceLink package reference.
Configuration.propsRemoves $(SourceLink) override pointing to generated SourceLink.json.
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.csRemoves SourceLink.json generation path and simplifies execution flow.
build-tools/xaprepare/xaprepare/Application/GeneratedSourceLinkJsonFile.csDeletes the hand-rolled SourceLink.json generator implementation.
build-tools/xaprepare/xaprepare/Application/GeneratedFile.csRemoves the now-orphaned SkipGeneratedFile helper type.
Comments suppressed due to low confidence (1)

build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs:52

  • Scenario_Required still adds new Step_GenerateFiles (atBuildStart: true, onlyRequired: true), but GetFilesToGenerate() now returns null for that case, so the step generates no files at all. That seems to contradict the scenario description (“generate build files”) and makes the scenario effectively a no-op after this PR.
 if (atBuildStart) {
if (onlyRequired) {
return null;
} else {
return new List <GeneratedFile> {
Get_Configuration_OperatingSystem_props (context),
Get_XABuildConfig_cs (context),
};
}

@jonathanpeppersjonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 30, 2026
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

Verified the CI build artifacts for this PR (build 1487951).

Downloaded nuget-unsigned-symbols, extracted the symbols .nupkgs, and ran sourcelink print-json on representative PDBs from across the SDK / Runtime / Ref packages. Every assembly's SourceLink covers dotnet/android plus all submodules:

Mono.Android.pdb (Microsoft.Android.Runtime.37.android symbols package):

{"documents":{
"/Users/cloudtest/vss/_work/1/s/android/*":"https://raw.githubusercontent.com/dotnet/android/917981be97def8f5d046c8b1b28dca25771d8198/*",
"/Users/cloudtest/vss/_work/1/s/android/external/android-api-docs/*":"https://raw.githubusercontent.com/dotnet/android-api-docs/d382c5bd406432083901e51a4e87cd677b8759d8/*",
"/Users/cloudtest/vss/_work/1/s/android/external/constexpr-xxh3/*":"https://raw.githubusercontent.com/chys87/constexpr-xxh3/aebcee75c8b6c2458fa8ae151754a8ba833bd697/*",
"/Users/cloudtest/vss/_work/1/s/android/external/debugger-libs/*":"https://raw.githubusercontent.com/mono/debugger-libs/e7fbb713d156d11193ed404783ad6fe9c4042a6d/*",
"/Users/cloudtest/vss/_work/1/s/android/external/Java.Interop/*":"https://raw.githubusercontent.com/dotnet/java-interop/8d544738ad294b4faf13d189eeeb02f0313e00b3/*",
"/Users/cloudtest/vss/_work/1/s/android/external/libunwind/*":"https://raw.githubusercontent.com/libunwind/libunwind/e97c9ef82f8b48d0c7f713be4fa7b15e634d76b8/*",
"/Users/cloudtest/vss/_work/1/s/android/external/lz4/*":"https://raw.githubusercontent.com/dotnet/lz4/ebb370ca83af193212df4dcbadcc5d87bc0de2f0/*",
"/Users/cloudtest/vss/_work/1/s/android/external/robin-map/*":"https://raw.githubusercontent.com/xamarin/robin-map/d37a41003bfbc7e12e34601f93c18ca2ff6d7c07/*",
"/Users/cloudtest/vss/_work/1/s/android/external/termux-elf-cleaner/*":"https://raw.githubusercontent.com/termux/termux-elf-cleaner/ee5385e004a9d67bdc289e43939691b260e06b03/*",
"/Users/cloudtest/vss/_work/1/s/android/external/xamarin-android-tools/*":"https://raw.githubusercontent.com/dotnet/android-tools/367724d6ba93db20294681769de97b9cdecb58a0/*",
"/Users/cloudtest/vss/_work/1/s/android/external/xxHash/*":"https://raw.githubusercontent.com/Cyan4973/xxHash/bbb27a5efb85b92a0486cf361a8635715a53f6ba/*"
}}

Same coverage on:

  • Xamarin.Android.Build.Tasks.pdb (Microsoft.Android.Sdk.Windows symbols) — repo + all 10 submodule mappings.
  • Microsoft.Android.Sdk.ILLink.pdb (Microsoft.Android.Sdk.Windows symbols) — repo + all 10 submodule mappings.
  • Java.Interop.pdb — own Java.Interop repo + its nested xamarin-android-tools submodule.

All URLs match .gitmodules exactly (including the dotnet/lz4 upstream). Microsoft.Android.Ref.37 produces a reference-only assembly with no embedded source link section, which is expected for ref assemblies.

@jonathanpeppers
jonathanpeppers merged commit b0fe694 into mainJun 30, 2026
41 checks passed
@jonathanpeppers
jonathanpeppers deleted the jonathanpeppers-adopt-sourcelink-github branch June 30, 2026 19:45
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11826)
## Summary
Moves `XABuildConfig.cs` generation out of `xaprepare` and into a new strong-named class library at `src/AndroidBuildConfig/AndroidBuildConfig.csproj` that produces `AndroidBuildConfig.dll`.
This continues the incremental removal of `xaprepare`, following the precedent set by `cmake-config.csproj` (#11760) and the recent batch #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11803, #11821, #11825.
It also fixes a long-standing wart: previously `XABuildConfig.cs` was `<Compile Include>`'d into three different assemblies (`Xamarin.Android.Build.Tasks`, `Xamarin.ProjectTools`, and `Xamarin.Android.Build.Tests`), so every test that mentioned `XABuildConfig` produced a `CS0436` "type conflicts with imported type" warning — about **22** of them.
Wrapping the type in its own assembly collapses it to a single definition that every consumer references normally. After this change `Xamarin.Android.Build.Tests` builds with **7** warnings (none for `XABuildConfig`).
## How it works
`src/AndroidBuildConfig/AndroidBuildConfig.csproj`:
- `Microsoft.NET.Sdk` / `netstandard2.0`, strong-named with `product.snk`.
- `ProjectReference`s `Xamarin.Android.Tools.AndroidSdk` (for the `AndroidTargetArch` enum used by the template).
- `<UsingTask>`s `ReplaceFileContents`, `GitCommitHash`, and `GitBranch` from `$(PrepTasksAssembly)`, all with `TaskFactory="TaskHostFactory" Runtime="NET"` per repo convention.
- The `_GenerateXABuildConfig` target runs `BeforeTargets="BeforeCompile;CoreCompile"`, computes every substitution from MSBuild properties already exposed by `Configuration.props` (NDK major/minor/micro via `$(_XAAndroidNdkPkgRevision.Split('.'))`, API levels via `Split`/`Contains`, full commit hash via `GitCommitHash.CommitHash`, branch via `GitBranch.Branch`), and writes the file to `$(IntermediateOutputPath)XABuildConfig.cs`. The `<Compile Include>` lives inside the target so it resolves at execution time, when `IntermediateOutputPath` is final.
- `XABuildConfig` is now `public static class` instead of `internal static class`.
The three consumer csprojs lose their `<Compile Include="…XABuildConfig.cs" />` and now have a normal `<ProjectReference Include="…AndroidBuildConfig.csproj" />` (no `ReferenceOutputAssembly="False"`).
`build-tools/installers/create-installers.targets` ships `AndroidBuildConfig.dll` + `.pdb` alongside `Xamarin.Android.Build.Tasks.dll`.
## xaprepare cleanup
Removed dead code that only existed to feed the old `Get_XABuildConfig_cs` step:
- `Step_GenerateFiles.Get_XABuildConfig_cs` and its `GetMajor` / `GetMinor` locals
- `BuildInfo`: `NDKRevision`, `NDKVersionMajor`, `NDKVersionMinor`, `NDKVersionMicro`, `NDKVersion`, `XACommitHash`, `XABranch`, `GatherGitInfo`, `DetermineXACommitInfo`, `cachedNdkVersion`
- `Context`: the `if (SelectedScenario.NeedsGitBuildInfo) { await BuildInfo.GatherGitInfo … }` block
- `Scenario.NeedsGitBuildInfo` (and the `NeedsGitBuildInfo = true;` setters in `Scenario_Standard` and `Scenario_Required`)
- `BuildAndroidPlatforms.cs` — entire file (only contained constants used by the deleted code)
- `Utilities.ParseAndroidPkgRevision`
- `GitRunner.GetTopCommitHash` and `GitRunner.GetBranchName` (class retained — still used by `BuildInfo.DetermineLastVersionChangeCommit`)
## Files
**Added**
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
**Renamed/moved**
- `build-tools/scripts/XABuildConfig.cs.in` → `src/AndroidBuildConfig/XABuildConfig.cs.in` (`static class` → `public static class`)
**Modified**
- `src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Xamarin.ProjectTools.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj`
- `build-tools/installers/create-installers.targets`
- `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs`
- `build-tools/xaprepare/xaprepare/Application/BuildInfo.cs`
- `build-tools/xaprepare/xaprepare/Application/Context.cs`
- `build-tools/xaprepare/xaprepare/Application/Scenario.cs`
- `build-tools/xaprepare/xaprepare/Application/Utilities.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Required.cs`
- `build-tools/xaprepare/xaprepare/ToolRunners/GitRunner.cs`
- `build-tools/xaprepare/README.md`
**Deleted**
- `build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs`
## Verification
- `AndroidBuildConfig.csproj`: 0 warnings, 0 errors.
- `Xamarin.Android.Build.Tasks.csproj`: 0 errors, 85 pre-existing unrelated warnings (none for `XABuildConfig`).
- `Xamarin.Android.Build.Tests.csproj`: 0 errors, **7** warnings — down from ~22; all `CS0436 XABuildConfig` conflicts eliminated.
- `xaprepare.csproj`: 0 warnings, 0 errors.
- Generated `XABuildConfig.cs` is semantically identical to the pre-change xaprepare output. The only token difference is the intentional `static class` → `public static class`; everything else (NDK split, API-level major/minor split, supported-ABIs semicolon list, full commit hash, branch name, etc.) matches the previous baseline byte-for-byte.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11825)
Continues the incremental removal of `xaprepare` by moving the
`cgmanifest.json` generator out of the C# step
`Step_GenerateCGManifest` and into a YAML `pwsh:` step that runs only
on CI.
The file is consumed exclusively by the Azure DevOps Component
Governance Detection task (auto-injected on internal pipelines by
`eng/common/core-templates/job/job.yml`). It is not consumed by any
in-repo build target, so generating it from the C# Prepare step is no
longer necessary.
We cannot drop the file outright: `eng/common` ships CG infrastructure
but it is not yet wired to auto-discover submodules in our pipelines,
so the explicit `cgmanifest.json` is still the source of truth.
Files:
* Added: `build-tools/automation/yaml-templates/generate-cgmanifest.yaml`
* Modified: `build-windows-steps.yaml`, `build-macos-steps.yaml`,
`build-linux-steps.yaml`, `commercial-build.yaml` (call the new
template after the Prepare/`make jenkins` step)
* Modified: `Scenario_Standard.cs` (drop registration)
* Modified: `GitRunner.cs` (remove now-unused `ConfigList` and
`SubmoduleStatus` methods)
* Deleted: `Step_GenerateCGManifest.cs`
Verification: byte-for-byte diff of the YAML-generated
`cgmanifest.json` against the previous C# output on Debug:
Baseline=3144 New=3144
Total byte differences: 0
Precedent PRs in this stream: #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803,
#11821.
### Simplify generate-cgmanifest.yaml using ConvertTo-Json
Replace the hand-rolled StringBuilder JSON emission with PowerShell's
`ConvertTo-Json`. The output is no longer byte-identical to the
previous C# output (2-space indent instead of 4, and slightly
different whitespace), but it is still valid JSON matching the
component-detection-manifest schema. The Azure DevOps Component
Governance Detection task parses the file, so formatting does not
matter.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
On Windows, xaprepare's Step_GenerateFiles.Windows.cs writes
external/Java.Interop/bin/Build$(Configuration)/JdkInfo.props from
build-tools/xaprepare/xaprepare/Resources/JdkInfo.Windows.props.in.
But this file is immediately overwritten. The PrepareWindows.targets
Prepare flow runs, in order:
1. `dotnet xaprepare -a` — writes JdkInfo.props (this code).
2. `MSBuild Xamarin.Android.BootstrapTasks.sln` — does not read JdkInfo.props.
3. `MSBuild src/workloads/workloads.csproj` — does not read JdkInfo.props.
4. `CallTarget PrepareJavaInterop` → `dotnet build -t:Prepare Java.Interop.sln`
→ external/Java.Interop/build-tools/scripts/Prepare.targets → runs the
`JdkInfo` MSBuild task → overwrites JdkInfo.props with its own generated
content.
Nothing between step 1 and step 4 reads the file, and Java.Interop's Prepare
always regenerates it. Now that external/Java.Interop is in-tree, we can
safely delete the redundant write.
This is the smallest-diff removal:
* Delete Step_GenerateFiles.Windows.cs (the AddOSSpecificSteps partial).
* Delete Resources/JdkInfo.Windows.props.in.
* In Step_GenerateFiles.cs, drop the `partial void AddOSSpecificSteps`
declaration and collapse GetFilesToGenerate so `atBuildStart == false`
returns null. Ctor surface (atBuildStart, onlyRequired) is unchanged so
Scenario_Required.cs is unaffected.
* In Scenario_Standard.cs, remove the AddEndSteps override — the only
thing it did was schedule the now-empty Step_GenerateFiles(atBuildStart:
false).
Preserved (future slices will address these):
* Get_Configuration_OperatingSystem_props (D1).
* OperatingSystems/*.cs and Context.OS.* surface.
* PrepareWindows.targets, DotNet.targets, Java.Interop's Prepare.targets.
Verification:
* dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug
→ Build succeeded. 0 Warning(s). 0 Error(s).
* build.cmd -t:Prepare -c Debug (Windows, cold tree) → succeeds; the file
external/Java.Interop/bin/BuildDebug/JdkInfo.props exists.
* Compare-Object of the resulting JdkInfo.props before vs after this
change → byte-identical (1493 bytes, SHA256
DE59A8061B7657831788FFED7BC1DEECA442E9181605083A4553DE7AC8C003A1),
confirming Java.Interop's overwrite is what always ends up on disk.
* Grep audit under build-tools/xaprepare/: no remaining references to
Step_GenerateFiles.Windows, JdkInfo.Windows.props.in, or
AddOSSpecificSteps.
Follows previous xaprepare deletion slices #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821,
#11825, #11826.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jul 3, 2026
…xaprepare project (#11959)
Follow-up to #11956, which moved the JDK half of `Configuration.OperatingSystem.props` to Java.Interop's `JdkInfo.props`. The remaining NDK / OS-info half has zero real consumers, so this PR:
1. Deletes the last generator template (`Configuration.OperatingSystem.props.in`).
2. Cascades through `Step_GenerateFiles`, both `Scenario_*` classes (which now had zero steps), and every supporting `OperatingSystems/`, `Context.*OS.cs`, `EssentialTools.*`, `ToolRunners/*`, `Configurables.*`, `Application/*`, and `Main.cs` file that only existed to feed the scenarios.
3. Deletes the whole `build-tools/xaprepare/` project.
4. Patches every integration point (`Makefile`, `PrepareWindows.targets`, `BuildEverything.mk`, CI YAML, docs) so `build.cmd -t:Prepare` and `make prepare` still work end-to-end.
## `Configuration.OperatingSystem.props.in` placeholder audit
| Placeholder | Consumers outside the `.in` file | Action |
| --- | --- | --- |
| `HostOsName` | none | drop |
| `HostOsFlavor` | none | drop |
| `HostOsRelease` | none | drop |
| `HostBits` | none (`ArchiveBase.HostBits` in `src/Xamarin.Installer.AndroidSDK/` is an unrelated C# property) | drop |
| `NdkLlvmTag` | none (the NDK toolchain OS tag is resolved elsewhere via `_NdkToolchainOSTag` in `androidsdk.targets`) | drop |
| `HostCpuCount` | only `Configuration.props:72` via `$(MakeConcurrency)` | drop |
## `$(MakeConcurrency)` audit
The only definition was `Configuration.props:72`. A repo-wide grep of `.targets`, `.props`, `.projitems`, `Makefile`, and `.mk` files found zero consumers of the MSBuild property. The `MakeConcurrency` hits under `build-tools/xaprepare/` were an unrelated C# `Context.MakeConcurrency` property.
**Result:** dropped the `MakeConcurrency` MSBuild property entirely (no `$([System.Environment]::ProcessorCount)` replacement needed) and removed the `$(MakeConcurrency)` bullet in `Documentation/building/configuration.md`.
## xaprepare integration audit (grep-confirmed, patched here)
| Location | Change |
| --- | --- |
| `build-tools/xaprepare/` (entire tree) | **deleted** — 86 tracked files |
| `Configuration.props` | dropped `<Import>` of the generated OS props, dropped `MakeConcurrency`, tidied the "between xaprepare and package creation tools" comment |
| `.gitignore` | dropped `Configuration.OperatingSystem.props` |
| `build-tools/scripts/PrepareWindows.targets` | removed `_XAPrepareExe`, `_XAPrepareStandardArgs`, `_BuildXAPrepare` target, and the `Exec dotnet $(_XAPrepareExe)` line. Repointed `Prepare` at `_InstallDotNet`. Kept the space-in-path guard, BootstrapTasks / workloads MSBuilds, and `PrepareJavaInterop` |
| `Makefile` | dropped `PREPARE_PROJECT`, `PREPARE_NET_FX`, `PREPARE_ARGS`, `PREPARE_MSBUILD_FLAGS`, `PREPARE_SCENARIO`, `PREPARE_CI_PR`, `PREPARE_CI`, `_PREPARE_CI_MODE_*`, `_PREPARE_ARGS`, and all their conditionals. Dropped the `dotnet run --project xaprepare.csproj` line from `prepare`. Deleted the `prepare-help` target |
| `build-tools/scripts/BuildEverything.mk` | `jenkins` no longer branches on `PREPARE_CI_PR`/`PREPARE_CI`; just `$(MAKE) prepare && $(MAKE) leeroy` |
| `.github/workflows/copilot-setup-steps.yml` | dropped now-unused `PREPARE_CI=1` |
| `build-tools/automation/azure-pipelines-apidocs.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-linux-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-macos-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/commercial-build.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/copy-extra-result-files.yaml` | dropped `**/Configuration.OperatingSystem.props` glob and the stale `Step_CopyExtraResultFilesForCI` xaprepare-step comment |
| `build-tools/automation/yaml-templates/generate-cgmanifest.yaml` | dropped the stale `Step_GenerateCGManifest` xaprepare-step comment |
| `build-tools/automation/yaml-templates/setup-jdk-variables.yaml` | renamed `$xaPrepareJdkPath` → `$xaJdkPath` for hygiene |
| `Documentation/workflow/HowToAddNewApiLevel.md` | rewrote the "Add New Platform" section to point at `<_PlatformPackage>` entries in `src/androidsdk/androidsdk.targets` instead of `AndroidToolchain.cs`; updated the `--android-sdk-platforms=all` recipe to `dotnet-local build src/androidsdk/androidsdk.csproj -p:AndroidSdkPlatforms=all` |
| `Documentation/building/unix/dependencies.md` | JDK-version link now points at `$(MicrosoftOpenJDKVersion)` in `/Configuration.props` instead of the deleted `Configurables.cs` |
| `Documentation/building/configuration.md` | removed the `$(MakeConcurrency)` bullet |
**Historical breadcrumb comments left as-is** (still accurate and useful for git-archaeology):
- `.github/skills/update-tpn/SKILL.md`
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
- `src/androidsdk/androidsdk.targets`
- `src/native/cmake-config/cmake-config.csproj`
- `src/workloads/workloads.csproj`
## Verification
- `build.cmd Prepare` — succeeded end-to-end on Windows (0 warnings, 0 errors). The trimmed `Prepare` target ran through `_InstallDotNet`, the space-in-path guard, `Xamarin.Android.BootstrapTasks.sln`, `src/workloads/workloads.csproj`, and `PrepareJavaInterop`.
- `dotnet build src\Xamarin.Android.Build.Tasks\Xamarin.Android.Build.Tasks.csproj -c Debug` — 0 errors (93 pre-existing warnings from `src/Mono.Android/` and generated MCW, unrelated to this change).
- Repo-wide grep for `HostOsName`, `HostOsFlavor`, `HostOsRelease`, `HostCpuCount`, `NdkLlvmTag`, and the MSBuild `MakeConcurrency` property — clean.
- Repo-wide grep for `xaprepare` — clean apart from the five intentional historical breadcrumb comments listed above.
## Diff stat
102 files changed, 25 insertions(+), 7891 deletions(-).
## Precedent chain
Continues the multi-slice teardown started by #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821, #11825, #11826, #11945, #11946, #11956.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 31, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

ready-to-reviewThis PR is ready to review/merge, I think any CI failures are just flaky (ignorable).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@jonathanpeppers@simonrozsival
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

[xaprepare] Use Microsoft.SourceLink.GitHub instead of hand-rolled SourceLink.json - #11821

Merged
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-adopt-sourcelink-github
Jun 30, 2026
Merged

[xaprepare] Use Microsoft.SourceLink.GitHub instead of hand-rolled SourceLink.json#11821
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-adopt-sourcelink-github

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Member

Summary

Stop generating bin/Build$(Configuration)/SourceLink.json from xaprepare and stop overriding $(SourceLink) in Configuration.props. Let Microsoft.SourceLink.GitHub (which is already pinned at 8.0.0 in Directory.Build.targets, but until now only Included in one project) produce SourceLink the canonical Arcade way for every project.

Changes

  • Directory.Build.targets — promoted Microsoft.SourceLink.GitHub 8.0.0 from a PackageReference Update to a broad PackageReference Include with PrivateAssets="All" so every project in the repo picks it up.
  • src/Microsoft.Android.Run/Microsoft.Android.Run.csproj — dropped the now-redundant explicit <PackageReference Include="Microsoft.SourceLink.GitHub" />.
  • Configuration.props — deleted the <PropertyGroup> that overrode $(SourceLink) with the path to the generated json file. The canonical package now sets $(SourceLink) itself.
  • build-tools/xaprepare/xaprepare/Application/GeneratedSourceLinkJsonFile.cs — deleted.
  • build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs — removed Get_SourceLink_Json, both references in GetFilesToGenerate, and the gitSubmodules / xaCommit fields plus the git/submodule prelude in Execute (no other generator in this file used them). Switched Execute from async back to a synchronous Task.FromResult since the only await was the deleted submodule walk.
  • build-tools/xaprepare/xaprepare/Application/GeneratedFile.cs — deleted the now-orphaned SkipGeneratedFile class (only caller was Get_SourceLink_Json).

Net: -99/+8 lines, one file deleted.

Verification

Built Mono.Android.csproj, Xamarin.Android.Build.Tasks.csproj, and xaprepare.csproj in Debug after a clean build.cmd Prepare. All succeeded with 0 errors.

Ran sourcelink print-json on bin\Debug\lib\packs\Microsoft.Android.Runtime.37.android\37.0.0\runtimes\android\lib\net11.0\Mono.Android.pdb:

{"documents":{
"<repo>\\*": "https://raw.githubusercontent.com/dotnet/android/138c93d5a5b369e5d9b6867607afefa7502cd787/*",
"<repo>\\external\\android-api-docs\\*": "https://raw.githubusercontent.com/dotnet/android-api-docs/d382c5bd406432083901e51a4e87cd677b8759d8/*",
"<repo>\\external\\constexpr-xxh3\\*": "https://raw.githubusercontent.com/chys87/constexpr-xxh3/aebcee75c8b6c2458fa8ae151754a8ba833bd697/*",
"<repo>\\external\\debugger-libs\\*": "https://raw.githubusercontent.com/mono/debugger-libs/e7fbb713d156d11193ed404783ad6fe9c4042a6d/*",
"<repo>\\external\\Java.Interop\\*": "https://raw.githubusercontent.com/dotnet/java-interop/8d544738ad294b4faf13d189eeeb02f0313e00b3/*",
"<repo>\\external\\libunwind\\*": "https://raw.githubusercontent.com/libunwind/libunwind/e97c9ef82f8b48d0c7f713be4fa7b15e634d76b8/*",
"<repo>\\external\\lz4\\*": "https://raw.githubusercontent.com/lz4/lz4/ebb370ca83af193212df4dcbadcc5d87bc0de2f0/*",
"<repo>\\external\\robin-map\\*": "https://raw.githubusercontent.com/xamarin/robin-map/d37a41003bfbc7e12e34601f93c18ca2ff6d7c07/*",
"<repo>\\external\\termux-elf-cleaner\\*": "https://raw.githubusercontent.com/termux/termux-elf-cleaner/ee5385e004a9d67bdc289e43939691b260e06b03/*",
"<repo>\\external\\xamarin-android-tools\\*": "https://raw.githubusercontent.com/dotnet/android-tools/367724d6ba93db20294681769de97b9cdecb58a0/*",
"<repo>\\external\\xxHash\\*": "https://raw.githubusercontent.com/Cyan4973/xxHash/bbb27a5efb85b92a0486cf361a8635715a53f6ba/*"
}}

Every submodule from .gitmodules is mapped to its correct upstream raw.githubusercontent.com URL — full parity with what GeneratedSourceLinkJsonFile produced before.

Out of scope

Step_GenerateCGManifest, GitSubmoduleInfo, GitRunner, and the GitCommit* prep tasks are still used by cgmanifest generation and XAVersionInfo.targets; they're intentionally left for a follow-up PR.

Precedent

Continues the xaprepare slim-down work in #11568, #11580, #11608, #11613, #11631, #11657, #11658, #11731, #11732, #11733, #11737, #11740, #11760, #11803.

…urceLink.json
Stop generating bin/Build$(Configuration)/SourceLink.json from xaprepare and stop overriding $(SourceLink) in Configuration.props. Promote Microsoft.SourceLink.GitHub from a PackageReference Update to a broad PackageReference Include in Directory.Build.targets so every project picks it up, then drop the explicit Include from Microsoft.Android.Run.csproj.
Verified with 'sourcelink print-json' on bin\Debug\lib\packs\Microsoft.Android.Runtime.37.android\37.0.0\runtimes\android\lib\net11.0\Mono.Android.pdb: the canonical package produces a documents map covering dotnet/android plus every submodule (Java.Interop, xamarin-android-tools, android-api-docs, constexpr-xxh3, debugger-libs, libunwind, lz4, robin-map, termux-elf-cleaner, xxHash) pointing at the correct upstream raw.githubusercontent.com URLs.
Step_GenerateCGManifest and GitSubmoduleInfo / GitRunner are intentionally left for a follow-up.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 30, 2026 14:07

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR switches the repo’s SourceLink generation to the standard Arcade/MSBuild approach by enabling Microsoft.SourceLink.GitHub repo-wide, and removes the now-redundant xaprepare-generated SourceLink.json plumbing.

Changes:

  • Add a repo-wide PackageReference to Microsoft.SourceLink.GitHub (PrivateAssets=All) via Directory.Build.targets, and remove the per-project reference from Microsoft.Android.Run.
  • Stop overriding $(SourceLink) in Configuration.props, letting the SourceLink package set it canonically.
  • Remove xaprepare’s SourceLink.json generator and related scaffolding (including the SkipGeneratedFile helper).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
Directory.Build.targetsAdds global Microsoft.SourceLink.GitHub package reference for SourceLink across the repo.
src/Microsoft.Android.Run/Microsoft.Android.Run.csprojRemoves redundant explicit SourceLink package reference.
Configuration.propsRemoves $(SourceLink) override pointing to generated SourceLink.json.
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.csRemoves SourceLink.json generation path and simplifies execution flow.
build-tools/xaprepare/xaprepare/Application/GeneratedSourceLinkJsonFile.csDeletes the hand-rolled SourceLink.json generator implementation.
build-tools/xaprepare/xaprepare/Application/GeneratedFile.csRemoves the now-orphaned SkipGeneratedFile helper type.
Comments suppressed due to low confidence (1)

build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs:52

  • Scenario_Required still adds new Step_GenerateFiles (atBuildStart: true, onlyRequired: true), but GetFilesToGenerate() now returns null for that case, so the step generates no files at all. That seems to contradict the scenario description (“generate build files”) and makes the scenario effectively a no-op after this PR.
 if (atBuildStart) {
if (onlyRequired) {
return null;
} else {
return new List <GeneratedFile> {
Get_Configuration_OperatingSystem_props (context),
Get_XABuildConfig_cs (context),
};
}

@jonathanpeppersjonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 30, 2026
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

Verified the CI build artifacts for this PR (build 1487951).

Downloaded nuget-unsigned-symbols, extracted the symbols .nupkgs, and ran sourcelink print-json on representative PDBs from across the SDK / Runtime / Ref packages. Every assembly's SourceLink covers dotnet/android plus all submodules:

Mono.Android.pdb (Microsoft.Android.Runtime.37.android symbols package):

{"documents":{
"/Users/cloudtest/vss/_work/1/s/android/*":"https://raw.githubusercontent.com/dotnet/android/917981be97def8f5d046c8b1b28dca25771d8198/*",
"/Users/cloudtest/vss/_work/1/s/android/external/android-api-docs/*":"https://raw.githubusercontent.com/dotnet/android-api-docs/d382c5bd406432083901e51a4e87cd677b8759d8/*",
"/Users/cloudtest/vss/_work/1/s/android/external/constexpr-xxh3/*":"https://raw.githubusercontent.com/chys87/constexpr-xxh3/aebcee75c8b6c2458fa8ae151754a8ba833bd697/*",
"/Users/cloudtest/vss/_work/1/s/android/external/debugger-libs/*":"https://raw.githubusercontent.com/mono/debugger-libs/e7fbb713d156d11193ed404783ad6fe9c4042a6d/*",
"/Users/cloudtest/vss/_work/1/s/android/external/Java.Interop/*":"https://raw.githubusercontent.com/dotnet/java-interop/8d544738ad294b4faf13d189eeeb02f0313e00b3/*",
"/Users/cloudtest/vss/_work/1/s/android/external/libunwind/*":"https://raw.githubusercontent.com/libunwind/libunwind/e97c9ef82f8b48d0c7f713be4fa7b15e634d76b8/*",
"/Users/cloudtest/vss/_work/1/s/android/external/lz4/*":"https://raw.githubusercontent.com/dotnet/lz4/ebb370ca83af193212df4dcbadcc5d87bc0de2f0/*",
"/Users/cloudtest/vss/_work/1/s/android/external/robin-map/*":"https://raw.githubusercontent.com/xamarin/robin-map/d37a41003bfbc7e12e34601f93c18ca2ff6d7c07/*",
"/Users/cloudtest/vss/_work/1/s/android/external/termux-elf-cleaner/*":"https://raw.githubusercontent.com/termux/termux-elf-cleaner/ee5385e004a9d67bdc289e43939691b260e06b03/*",
"/Users/cloudtest/vss/_work/1/s/android/external/xamarin-android-tools/*":"https://raw.githubusercontent.com/dotnet/android-tools/367724d6ba93db20294681769de97b9cdecb58a0/*",
"/Users/cloudtest/vss/_work/1/s/android/external/xxHash/*":"https://raw.githubusercontent.com/Cyan4973/xxHash/bbb27a5efb85b92a0486cf361a8635715a53f6ba/*"
}}

Same coverage on:

  • Xamarin.Android.Build.Tasks.pdb (Microsoft.Android.Sdk.Windows symbols) — repo + all 10 submodule mappings.
  • Microsoft.Android.Sdk.ILLink.pdb (Microsoft.Android.Sdk.Windows symbols) — repo + all 10 submodule mappings.
  • Java.Interop.pdb — own Java.Interop repo + its nested xamarin-android-tools submodule.

All URLs match .gitmodules exactly (including the dotnet/lz4 upstream). Microsoft.Android.Ref.37 produces a reference-only assembly with no embedded source link section, which is expected for ref assemblies.

@jonathanpeppers
jonathanpeppers merged commit b0fe694 into mainJun 30, 2026
41 checks passed
@jonathanpeppers
jonathanpeppers deleted the jonathanpeppers-adopt-sourcelink-github branch June 30, 2026 19:45
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11826)
## Summary
Moves `XABuildConfig.cs` generation out of `xaprepare` and into a new strong-named class library at `src/AndroidBuildConfig/AndroidBuildConfig.csproj` that produces `AndroidBuildConfig.dll`.
This continues the incremental removal of `xaprepare`, following the precedent set by `cmake-config.csproj` (#11760) and the recent batch #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11803, #11821, #11825.
It also fixes a long-standing wart: previously `XABuildConfig.cs` was `<Compile Include>`'d into three different assemblies (`Xamarin.Android.Build.Tasks`, `Xamarin.ProjectTools`, and `Xamarin.Android.Build.Tests`), so every test that mentioned `XABuildConfig` produced a `CS0436` "type conflicts with imported type" warning — about **22** of them.
Wrapping the type in its own assembly collapses it to a single definition that every consumer references normally. After this change `Xamarin.Android.Build.Tests` builds with **7** warnings (none for `XABuildConfig`).
## How it works
`src/AndroidBuildConfig/AndroidBuildConfig.csproj`:
- `Microsoft.NET.Sdk` / `netstandard2.0`, strong-named with `product.snk`.
- `ProjectReference`s `Xamarin.Android.Tools.AndroidSdk` (for the `AndroidTargetArch` enum used by the template).
- `<UsingTask>`s `ReplaceFileContents`, `GitCommitHash`, and `GitBranch` from `$(PrepTasksAssembly)`, all with `TaskFactory="TaskHostFactory" Runtime="NET"` per repo convention.
- The `_GenerateXABuildConfig` target runs `BeforeTargets="BeforeCompile;CoreCompile"`, computes every substitution from MSBuild properties already exposed by `Configuration.props` (NDK major/minor/micro via `$(_XAAndroidNdkPkgRevision.Split('.'))`, API levels via `Split`/`Contains`, full commit hash via `GitCommitHash.CommitHash`, branch via `GitBranch.Branch`), and writes the file to `$(IntermediateOutputPath)XABuildConfig.cs`. The `<Compile Include>` lives inside the target so it resolves at execution time, when `IntermediateOutputPath` is final.
- `XABuildConfig` is now `public static class` instead of `internal static class`.
The three consumer csprojs lose their `<Compile Include="…XABuildConfig.cs" />` and now have a normal `<ProjectReference Include="…AndroidBuildConfig.csproj" />` (no `ReferenceOutputAssembly="False"`).
`build-tools/installers/create-installers.targets` ships `AndroidBuildConfig.dll` + `.pdb` alongside `Xamarin.Android.Build.Tasks.dll`.
## xaprepare cleanup
Removed dead code that only existed to feed the old `Get_XABuildConfig_cs` step:
- `Step_GenerateFiles.Get_XABuildConfig_cs` and its `GetMajor` / `GetMinor` locals
- `BuildInfo`: `NDKRevision`, `NDKVersionMajor`, `NDKVersionMinor`, `NDKVersionMicro`, `NDKVersion`, `XACommitHash`, `XABranch`, `GatherGitInfo`, `DetermineXACommitInfo`, `cachedNdkVersion`
- `Context`: the `if (SelectedScenario.NeedsGitBuildInfo) { await BuildInfo.GatherGitInfo … }` block
- `Scenario.NeedsGitBuildInfo` (and the `NeedsGitBuildInfo = true;` setters in `Scenario_Standard` and `Scenario_Required`)
- `BuildAndroidPlatforms.cs` — entire file (only contained constants used by the deleted code)
- `Utilities.ParseAndroidPkgRevision`
- `GitRunner.GetTopCommitHash` and `GitRunner.GetBranchName` (class retained — still used by `BuildInfo.DetermineLastVersionChangeCommit`)
## Files
**Added**
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
**Renamed/moved**
- `build-tools/scripts/XABuildConfig.cs.in` → `src/AndroidBuildConfig/XABuildConfig.cs.in` (`static class` → `public static class`)
**Modified**
- `src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Xamarin.ProjectTools.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj`
- `build-tools/installers/create-installers.targets`
- `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs`
- `build-tools/xaprepare/xaprepare/Application/BuildInfo.cs`
- `build-tools/xaprepare/xaprepare/Application/Context.cs`
- `build-tools/xaprepare/xaprepare/Application/Scenario.cs`
- `build-tools/xaprepare/xaprepare/Application/Utilities.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Required.cs`
- `build-tools/xaprepare/xaprepare/ToolRunners/GitRunner.cs`
- `build-tools/xaprepare/README.md`
**Deleted**
- `build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs`
## Verification
- `AndroidBuildConfig.csproj`: 0 warnings, 0 errors.
- `Xamarin.Android.Build.Tasks.csproj`: 0 errors, 85 pre-existing unrelated warnings (none for `XABuildConfig`).
- `Xamarin.Android.Build.Tests.csproj`: 0 errors, **7** warnings — down from ~22; all `CS0436 XABuildConfig` conflicts eliminated.
- `xaprepare.csproj`: 0 warnings, 0 errors.
- Generated `XABuildConfig.cs` is semantically identical to the pre-change xaprepare output. The only token difference is the intentional `static class` → `public static class`; everything else (NDK split, API-level major/minor split, supported-ABIs semicolon list, full commit hash, branch name, etc.) matches the previous baseline byte-for-byte.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11825)
Continues the incremental removal of `xaprepare` by moving the
`cgmanifest.json` generator out of the C# step
`Step_GenerateCGManifest` and into a YAML `pwsh:` step that runs only
on CI.
The file is consumed exclusively by the Azure DevOps Component
Governance Detection task (auto-injected on internal pipelines by
`eng/common/core-templates/job/job.yml`). It is not consumed by any
in-repo build target, so generating it from the C# Prepare step is no
longer necessary.
We cannot drop the file outright: `eng/common` ships CG infrastructure
but it is not yet wired to auto-discover submodules in our pipelines,
so the explicit `cgmanifest.json` is still the source of truth.
Files:
* Added: `build-tools/automation/yaml-templates/generate-cgmanifest.yaml`
* Modified: `build-windows-steps.yaml`, `build-macos-steps.yaml`,
`build-linux-steps.yaml`, `commercial-build.yaml` (call the new
template after the Prepare/`make jenkins` step)
* Modified: `Scenario_Standard.cs` (drop registration)
* Modified: `GitRunner.cs` (remove now-unused `ConfigList` and
`SubmoduleStatus` methods)
* Deleted: `Step_GenerateCGManifest.cs`
Verification: byte-for-byte diff of the YAML-generated
`cgmanifest.json` against the previous C# output on Debug:
Baseline=3144 New=3144
Total byte differences: 0
Precedent PRs in this stream: #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803,
#11821.
### Simplify generate-cgmanifest.yaml using ConvertTo-Json
Replace the hand-rolled StringBuilder JSON emission with PowerShell's
`ConvertTo-Json`. The output is no longer byte-identical to the
previous C# output (2-space indent instead of 4, and slightly
different whitespace), but it is still valid JSON matching the
component-detection-manifest schema. The Azure DevOps Component
Governance Detection task parses the file, so formatting does not
matter.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
On Windows, xaprepare's Step_GenerateFiles.Windows.cs writes
external/Java.Interop/bin/Build$(Configuration)/JdkInfo.props from
build-tools/xaprepare/xaprepare/Resources/JdkInfo.Windows.props.in.
But this file is immediately overwritten. The PrepareWindows.targets
Prepare flow runs, in order:
1. `dotnet xaprepare -a` — writes JdkInfo.props (this code).
2. `MSBuild Xamarin.Android.BootstrapTasks.sln` — does not read JdkInfo.props.
3. `MSBuild src/workloads/workloads.csproj` — does not read JdkInfo.props.
4. `CallTarget PrepareJavaInterop` → `dotnet build -t:Prepare Java.Interop.sln`
→ external/Java.Interop/build-tools/scripts/Prepare.targets → runs the
`JdkInfo` MSBuild task → overwrites JdkInfo.props with its own generated
content.
Nothing between step 1 and step 4 reads the file, and Java.Interop's Prepare
always regenerates it. Now that external/Java.Interop is in-tree, we can
safely delete the redundant write.
This is the smallest-diff removal:
* Delete Step_GenerateFiles.Windows.cs (the AddOSSpecificSteps partial).
* Delete Resources/JdkInfo.Windows.props.in.
* In Step_GenerateFiles.cs, drop the `partial void AddOSSpecificSteps`
declaration and collapse GetFilesToGenerate so `atBuildStart == false`
returns null. Ctor surface (atBuildStart, onlyRequired) is unchanged so
Scenario_Required.cs is unaffected.
* In Scenario_Standard.cs, remove the AddEndSteps override — the only
thing it did was schedule the now-empty Step_GenerateFiles(atBuildStart:
false).
Preserved (future slices will address these):
* Get_Configuration_OperatingSystem_props (D1).
* OperatingSystems/*.cs and Context.OS.* surface.
* PrepareWindows.targets, DotNet.targets, Java.Interop's Prepare.targets.
Verification:
* dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug
→ Build succeeded. 0 Warning(s). 0 Error(s).
* build.cmd -t:Prepare -c Debug (Windows, cold tree) → succeeds; the file
external/Java.Interop/bin/BuildDebug/JdkInfo.props exists.
* Compare-Object of the resulting JdkInfo.props before vs after this
change → byte-identical (1493 bytes, SHA256
DE59A8061B7657831788FFED7BC1DEECA442E9181605083A4553DE7AC8C003A1),
confirming Java.Interop's overwrite is what always ends up on disk.
* Grep audit under build-tools/xaprepare/: no remaining references to
Step_GenerateFiles.Windows, JdkInfo.Windows.props.in, or
AddOSSpecificSteps.
Follows previous xaprepare deletion slices #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821,
#11825, #11826.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jul 3, 2026
…xaprepare project (#11959)
Follow-up to #11956, which moved the JDK half of `Configuration.OperatingSystem.props` to Java.Interop's `JdkInfo.props`. The remaining NDK / OS-info half has zero real consumers, so this PR:
1. Deletes the last generator template (`Configuration.OperatingSystem.props.in`).
2. Cascades through `Step_GenerateFiles`, both `Scenario_*` classes (which now had zero steps), and every supporting `OperatingSystems/`, `Context.*OS.cs`, `EssentialTools.*`, `ToolRunners/*`, `Configurables.*`, `Application/*`, and `Main.cs` file that only existed to feed the scenarios.
3. Deletes the whole `build-tools/xaprepare/` project.
4. Patches every integration point (`Makefile`, `PrepareWindows.targets`, `BuildEverything.mk`, CI YAML, docs) so `build.cmd -t:Prepare` and `make prepare` still work end-to-end.
## `Configuration.OperatingSystem.props.in` placeholder audit
| Placeholder | Consumers outside the `.in` file | Action |
| --- | --- | --- |
| `HostOsName` | none | drop |
| `HostOsFlavor` | none | drop |
| `HostOsRelease` | none | drop |
| `HostBits` | none (`ArchiveBase.HostBits` in `src/Xamarin.Installer.AndroidSDK/` is an unrelated C# property) | drop |
| `NdkLlvmTag` | none (the NDK toolchain OS tag is resolved elsewhere via `_NdkToolchainOSTag` in `androidsdk.targets`) | drop |
| `HostCpuCount` | only `Configuration.props:72` via `$(MakeConcurrency)` | drop |
## `$(MakeConcurrency)` audit
The only definition was `Configuration.props:72`. A repo-wide grep of `.targets`, `.props`, `.projitems`, `Makefile`, and `.mk` files found zero consumers of the MSBuild property. The `MakeConcurrency` hits under `build-tools/xaprepare/` were an unrelated C# `Context.MakeConcurrency` property.
**Result:** dropped the `MakeConcurrency` MSBuild property entirely (no `$([System.Environment]::ProcessorCount)` replacement needed) and removed the `$(MakeConcurrency)` bullet in `Documentation/building/configuration.md`.
## xaprepare integration audit (grep-confirmed, patched here)
| Location | Change |
| --- | --- |
| `build-tools/xaprepare/` (entire tree) | **deleted** — 86 tracked files |
| `Configuration.props` | dropped `<Import>` of the generated OS props, dropped `MakeConcurrency`, tidied the "between xaprepare and package creation tools" comment |
| `.gitignore` | dropped `Configuration.OperatingSystem.props` |
| `build-tools/scripts/PrepareWindows.targets` | removed `_XAPrepareExe`, `_XAPrepareStandardArgs`, `_BuildXAPrepare` target, and the `Exec dotnet $(_XAPrepareExe)` line. Repointed `Prepare` at `_InstallDotNet`. Kept the space-in-path guard, BootstrapTasks / workloads MSBuilds, and `PrepareJavaInterop` |
| `Makefile` | dropped `PREPARE_PROJECT`, `PREPARE_NET_FX`, `PREPARE_ARGS`, `PREPARE_MSBUILD_FLAGS`, `PREPARE_SCENARIO`, `PREPARE_CI_PR`, `PREPARE_CI`, `_PREPARE_CI_MODE_*`, `_PREPARE_ARGS`, and all their conditionals. Dropped the `dotnet run --project xaprepare.csproj` line from `prepare`. Deleted the `prepare-help` target |
| `build-tools/scripts/BuildEverything.mk` | `jenkins` no longer branches on `PREPARE_CI_PR`/`PREPARE_CI`; just `$(MAKE) prepare && $(MAKE) leeroy` |
| `.github/workflows/copilot-setup-steps.yml` | dropped now-unused `PREPARE_CI=1` |
| `build-tools/automation/azure-pipelines-apidocs.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-linux-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-macos-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/commercial-build.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/copy-extra-result-files.yaml` | dropped `**/Configuration.OperatingSystem.props` glob and the stale `Step_CopyExtraResultFilesForCI` xaprepare-step comment |
| `build-tools/automation/yaml-templates/generate-cgmanifest.yaml` | dropped the stale `Step_GenerateCGManifest` xaprepare-step comment |
| `build-tools/automation/yaml-templates/setup-jdk-variables.yaml` | renamed `$xaPrepareJdkPath` → `$xaJdkPath` for hygiene |
| `Documentation/workflow/HowToAddNewApiLevel.md` | rewrote the "Add New Platform" section to point at `<_PlatformPackage>` entries in `src/androidsdk/androidsdk.targets` instead of `AndroidToolchain.cs`; updated the `--android-sdk-platforms=all` recipe to `dotnet-local build src/androidsdk/androidsdk.csproj -p:AndroidSdkPlatforms=all` |
| `Documentation/building/unix/dependencies.md` | JDK-version link now points at `$(MicrosoftOpenJDKVersion)` in `/Configuration.props` instead of the deleted `Configurables.cs` |
| `Documentation/building/configuration.md` | removed the `$(MakeConcurrency)` bullet |
**Historical breadcrumb comments left as-is** (still accurate and useful for git-archaeology):
- `.github/skills/update-tpn/SKILL.md`
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
- `src/androidsdk/androidsdk.targets`
- `src/native/cmake-config/cmake-config.csproj`
- `src/workloads/workloads.csproj`
## Verification
- `build.cmd Prepare` — succeeded end-to-end on Windows (0 warnings, 0 errors). The trimmed `Prepare` target ran through `_InstallDotNet`, the space-in-path guard, `Xamarin.Android.BootstrapTasks.sln`, `src/workloads/workloads.csproj`, and `PrepareJavaInterop`.
- `dotnet build src\Xamarin.Android.Build.Tasks\Xamarin.Android.Build.Tasks.csproj -c Debug` — 0 errors (93 pre-existing warnings from `src/Mono.Android/` and generated MCW, unrelated to this change).
- Repo-wide grep for `HostOsName`, `HostOsFlavor`, `HostOsRelease`, `HostCpuCount`, `NdkLlvmTag`, and the MSBuild `MakeConcurrency` property — clean.
- Repo-wide grep for `xaprepare` — clean apart from the five intentional historical breadcrumb comments listed above.
## Diff stat
102 files changed, 25 insertions(+), 7891 deletions(-).
## Precedent chain
Continues the multi-slice teardown started by #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821, #11825, #11826, #11945, #11946, #11956.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 31, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

ready-to-reviewThis PR is ready to review/merge, I think any CI failures are just flaky (ignorable).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@jonathanpeppers@simonrozsival
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[xaprepare] Use Microsoft.SourceLink.GitHub instead of hand-rolled SourceLink.json - #11821

Merged
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-adopt-sourcelink-github
Jun 30, 2026
Merged

[xaprepare] Use Microsoft.SourceLink.GitHub instead of hand-rolled SourceLink.json#11821
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-adopt-sourcelink-github

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Member

Summary

Stop generating bin/Build$(Configuration)/SourceLink.json from xaprepare and stop overriding $(SourceLink) in Configuration.props. Let Microsoft.SourceLink.GitHub (which is already pinned at 8.0.0 in Directory.Build.targets, but until now only Included in one project) produce SourceLink the canonical Arcade way for every project.

Changes

  • Directory.Build.targets — promoted Microsoft.SourceLink.GitHub 8.0.0 from a PackageReference Update to a broad PackageReference Include with PrivateAssets="All" so every project in the repo picks it up.
  • src/Microsoft.Android.Run/Microsoft.Android.Run.csproj — dropped the now-redundant explicit <PackageReference Include="Microsoft.SourceLink.GitHub" />.
  • Configuration.props — deleted the <PropertyGroup> that overrode $(SourceLink) with the path to the generated json file. The canonical package now sets $(SourceLink) itself.
  • build-tools/xaprepare/xaprepare/Application/GeneratedSourceLinkJsonFile.cs — deleted.
  • build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs — removed Get_SourceLink_Json, both references in GetFilesToGenerate, and the gitSubmodules / xaCommit fields plus the git/submodule prelude in Execute (no other generator in this file used them). Switched Execute from async back to a synchronous Task.FromResult since the only await was the deleted submodule walk.
  • build-tools/xaprepare/xaprepare/Application/GeneratedFile.cs — deleted the now-orphaned SkipGeneratedFile class (only caller was Get_SourceLink_Json).

Net: -99/+8 lines, one file deleted.

Verification

Built Mono.Android.csproj, Xamarin.Android.Build.Tasks.csproj, and xaprepare.csproj in Debug after a clean build.cmd Prepare. All succeeded with 0 errors.

Ran sourcelink print-json on bin\Debug\lib\packs\Microsoft.Android.Runtime.37.android\37.0.0\runtimes\android\lib\net11.0\Mono.Android.pdb:

{"documents":{
"<repo>\\*": "https://raw.githubusercontent.com/dotnet/android/138c93d5a5b369e5d9b6867607afefa7502cd787/*",
"<repo>\\external\\android-api-docs\\*": "https://raw.githubusercontent.com/dotnet/android-api-docs/d382c5bd406432083901e51a4e87cd677b8759d8/*",
"<repo>\\external\\constexpr-xxh3\\*": "https://raw.githubusercontent.com/chys87/constexpr-xxh3/aebcee75c8b6c2458fa8ae151754a8ba833bd697/*",
"<repo>\\external\\debugger-libs\\*": "https://raw.githubusercontent.com/mono/debugger-libs/e7fbb713d156d11193ed404783ad6fe9c4042a6d/*",
"<repo>\\external\\Java.Interop\\*": "https://raw.githubusercontent.com/dotnet/java-interop/8d544738ad294b4faf13d189eeeb02f0313e00b3/*",
"<repo>\\external\\libunwind\\*": "https://raw.githubusercontent.com/libunwind/libunwind/e97c9ef82f8b48d0c7f713be4fa7b15e634d76b8/*",
"<repo>\\external\\lz4\\*": "https://raw.githubusercontent.com/lz4/lz4/ebb370ca83af193212df4dcbadcc5d87bc0de2f0/*",
"<repo>\\external\\robin-map\\*": "https://raw.githubusercontent.com/xamarin/robin-map/d37a41003bfbc7e12e34601f93c18ca2ff6d7c07/*",
"<repo>\\external\\termux-elf-cleaner\\*": "https://raw.githubusercontent.com/termux/termux-elf-cleaner/ee5385e004a9d67bdc289e43939691b260e06b03/*",
"<repo>\\external\\xamarin-android-tools\\*": "https://raw.githubusercontent.com/dotnet/android-tools/367724d6ba93db20294681769de97b9cdecb58a0/*",
"<repo>\\external\\xxHash\\*": "https://raw.githubusercontent.com/Cyan4973/xxHash/bbb27a5efb85b92a0486cf361a8635715a53f6ba/*"
}}

Every submodule from .gitmodules is mapped to its correct upstream raw.githubusercontent.com URL — full parity with what GeneratedSourceLinkJsonFile produced before.

Out of scope

Step_GenerateCGManifest, GitSubmoduleInfo, GitRunner, and the GitCommit* prep tasks are still used by cgmanifest generation and XAVersionInfo.targets; they're intentionally left for a follow-up PR.

Precedent

Continues the xaprepare slim-down work in #11568, #11580, #11608, #11613, #11631, #11657, #11658, #11731, #11732, #11733, #11737, #11740, #11760, #11803.

…urceLink.json
Stop generating bin/Build$(Configuration)/SourceLink.json from xaprepare and stop overriding $(SourceLink) in Configuration.props. Promote Microsoft.SourceLink.GitHub from a PackageReference Update to a broad PackageReference Include in Directory.Build.targets so every project picks it up, then drop the explicit Include from Microsoft.Android.Run.csproj.
Verified with 'sourcelink print-json' on bin\Debug\lib\packs\Microsoft.Android.Runtime.37.android\37.0.0\runtimes\android\lib\net11.0\Mono.Android.pdb: the canonical package produces a documents map covering dotnet/android plus every submodule (Java.Interop, xamarin-android-tools, android-api-docs, constexpr-xxh3, debugger-libs, libunwind, lz4, robin-map, termux-elf-cleaner, xxHash) pointing at the correct upstream raw.githubusercontent.com URLs.
Step_GenerateCGManifest and GitSubmoduleInfo / GitRunner are intentionally left for a follow-up.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 30, 2026 14:07

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR switches the repo’s SourceLink generation to the standard Arcade/MSBuild approach by enabling Microsoft.SourceLink.GitHub repo-wide, and removes the now-redundant xaprepare-generated SourceLink.json plumbing.

Changes:

  • Add a repo-wide PackageReference to Microsoft.SourceLink.GitHub (PrivateAssets=All) via Directory.Build.targets, and remove the per-project reference from Microsoft.Android.Run.
  • Stop overriding $(SourceLink) in Configuration.props, letting the SourceLink package set it canonically.
  • Remove xaprepare’s SourceLink.json generator and related scaffolding (including the SkipGeneratedFile helper).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
Directory.Build.targetsAdds global Microsoft.SourceLink.GitHub package reference for SourceLink across the repo.
src/Microsoft.Android.Run/Microsoft.Android.Run.csprojRemoves redundant explicit SourceLink package reference.
Configuration.propsRemoves $(SourceLink) override pointing to generated SourceLink.json.
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.csRemoves SourceLink.json generation path and simplifies execution flow.
build-tools/xaprepare/xaprepare/Application/GeneratedSourceLinkJsonFile.csDeletes the hand-rolled SourceLink.json generator implementation.
build-tools/xaprepare/xaprepare/Application/GeneratedFile.csRemoves the now-orphaned SkipGeneratedFile helper type.
Comments suppressed due to low confidence (1)

build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs:52

  • Scenario_Required still adds new Step_GenerateFiles (atBuildStart: true, onlyRequired: true), but GetFilesToGenerate() now returns null for that case, so the step generates no files at all. That seems to contradict the scenario description (“generate build files”) and makes the scenario effectively a no-op after this PR.
 if (atBuildStart) {
if (onlyRequired) {
return null;
} else {
return new List <GeneratedFile> {
Get_Configuration_OperatingSystem_props (context),
Get_XABuildConfig_cs (context),
};
}

@jonathanpeppersjonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 30, 2026
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

Verified the CI build artifacts for this PR (build 1487951).

Downloaded nuget-unsigned-symbols, extracted the symbols .nupkgs, and ran sourcelink print-json on representative PDBs from across the SDK / Runtime / Ref packages. Every assembly's SourceLink covers dotnet/android plus all submodules:

Mono.Android.pdb (Microsoft.Android.Runtime.37.android symbols package):

{"documents":{
"/Users/cloudtest/vss/_work/1/s/android/*":"https://raw.githubusercontent.com/dotnet/android/917981be97def8f5d046c8b1b28dca25771d8198/*",
"/Users/cloudtest/vss/_work/1/s/android/external/android-api-docs/*":"https://raw.githubusercontent.com/dotnet/android-api-docs/d382c5bd406432083901e51a4e87cd677b8759d8/*",
"/Users/cloudtest/vss/_work/1/s/android/external/constexpr-xxh3/*":"https://raw.githubusercontent.com/chys87/constexpr-xxh3/aebcee75c8b6c2458fa8ae151754a8ba833bd697/*",
"/Users/cloudtest/vss/_work/1/s/android/external/debugger-libs/*":"https://raw.githubusercontent.com/mono/debugger-libs/e7fbb713d156d11193ed404783ad6fe9c4042a6d/*",
"/Users/cloudtest/vss/_work/1/s/android/external/Java.Interop/*":"https://raw.githubusercontent.com/dotnet/java-interop/8d544738ad294b4faf13d189eeeb02f0313e00b3/*",
"/Users/cloudtest/vss/_work/1/s/android/external/libunwind/*":"https://raw.githubusercontent.com/libunwind/libunwind/e97c9ef82f8b48d0c7f713be4fa7b15e634d76b8/*",
"/Users/cloudtest/vss/_work/1/s/android/external/lz4/*":"https://raw.githubusercontent.com/dotnet/lz4/ebb370ca83af193212df4dcbadcc5d87bc0de2f0/*",
"/Users/cloudtest/vss/_work/1/s/android/external/robin-map/*":"https://raw.githubusercontent.com/xamarin/robin-map/d37a41003bfbc7e12e34601f93c18ca2ff6d7c07/*",
"/Users/cloudtest/vss/_work/1/s/android/external/termux-elf-cleaner/*":"https://raw.githubusercontent.com/termux/termux-elf-cleaner/ee5385e004a9d67bdc289e43939691b260e06b03/*",
"/Users/cloudtest/vss/_work/1/s/android/external/xamarin-android-tools/*":"https://raw.githubusercontent.com/dotnet/android-tools/367724d6ba93db20294681769de97b9cdecb58a0/*",
"/Users/cloudtest/vss/_work/1/s/android/external/xxHash/*":"https://raw.githubusercontent.com/Cyan4973/xxHash/bbb27a5efb85b92a0486cf361a8635715a53f6ba/*"
}}

Same coverage on:

  • Xamarin.Android.Build.Tasks.pdb (Microsoft.Android.Sdk.Windows symbols) — repo + all 10 submodule mappings.
  • Microsoft.Android.Sdk.ILLink.pdb (Microsoft.Android.Sdk.Windows symbols) — repo + all 10 submodule mappings.
  • Java.Interop.pdb — own Java.Interop repo + its nested xamarin-android-tools submodule.

All URLs match .gitmodules exactly (including the dotnet/lz4 upstream). Microsoft.Android.Ref.37 produces a reference-only assembly with no embedded source link section, which is expected for ref assemblies.

@jonathanpeppers
jonathanpeppers merged commit b0fe694 into mainJun 30, 2026
41 checks passed
@jonathanpeppers
jonathanpeppers deleted the jonathanpeppers-adopt-sourcelink-github branch June 30, 2026 19:45
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11826)
## Summary
Moves `XABuildConfig.cs` generation out of `xaprepare` and into a new strong-named class library at `src/AndroidBuildConfig/AndroidBuildConfig.csproj` that produces `AndroidBuildConfig.dll`.
This continues the incremental removal of `xaprepare`, following the precedent set by `cmake-config.csproj` (#11760) and the recent batch #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11803, #11821, #11825.
It also fixes a long-standing wart: previously `XABuildConfig.cs` was `<Compile Include>`'d into three different assemblies (`Xamarin.Android.Build.Tasks`, `Xamarin.ProjectTools`, and `Xamarin.Android.Build.Tests`), so every test that mentioned `XABuildConfig` produced a `CS0436` "type conflicts with imported type" warning — about **22** of them.
Wrapping the type in its own assembly collapses it to a single definition that every consumer references normally. After this change `Xamarin.Android.Build.Tests` builds with **7** warnings (none for `XABuildConfig`).
## How it works
`src/AndroidBuildConfig/AndroidBuildConfig.csproj`:
- `Microsoft.NET.Sdk` / `netstandard2.0`, strong-named with `product.snk`.
- `ProjectReference`s `Xamarin.Android.Tools.AndroidSdk` (for the `AndroidTargetArch` enum used by the template).
- `<UsingTask>`s `ReplaceFileContents`, `GitCommitHash`, and `GitBranch` from `$(PrepTasksAssembly)`, all with `TaskFactory="TaskHostFactory" Runtime="NET"` per repo convention.
- The `_GenerateXABuildConfig` target runs `BeforeTargets="BeforeCompile;CoreCompile"`, computes every substitution from MSBuild properties already exposed by `Configuration.props` (NDK major/minor/micro via `$(_XAAndroidNdkPkgRevision.Split('.'))`, API levels via `Split`/`Contains`, full commit hash via `GitCommitHash.CommitHash`, branch via `GitBranch.Branch`), and writes the file to `$(IntermediateOutputPath)XABuildConfig.cs`. The `<Compile Include>` lives inside the target so it resolves at execution time, when `IntermediateOutputPath` is final.
- `XABuildConfig` is now `public static class` instead of `internal static class`.
The three consumer csprojs lose their `<Compile Include="…XABuildConfig.cs" />` and now have a normal `<ProjectReference Include="…AndroidBuildConfig.csproj" />` (no `ReferenceOutputAssembly="False"`).
`build-tools/installers/create-installers.targets` ships `AndroidBuildConfig.dll` + `.pdb` alongside `Xamarin.Android.Build.Tasks.dll`.
## xaprepare cleanup
Removed dead code that only existed to feed the old `Get_XABuildConfig_cs` step:
- `Step_GenerateFiles.Get_XABuildConfig_cs` and its `GetMajor` / `GetMinor` locals
- `BuildInfo`: `NDKRevision`, `NDKVersionMajor`, `NDKVersionMinor`, `NDKVersionMicro`, `NDKVersion`, `XACommitHash`, `XABranch`, `GatherGitInfo`, `DetermineXACommitInfo`, `cachedNdkVersion`
- `Context`: the `if (SelectedScenario.NeedsGitBuildInfo) { await BuildInfo.GatherGitInfo … }` block
- `Scenario.NeedsGitBuildInfo` (and the `NeedsGitBuildInfo = true;` setters in `Scenario_Standard` and `Scenario_Required`)
- `BuildAndroidPlatforms.cs` — entire file (only contained constants used by the deleted code)
- `Utilities.ParseAndroidPkgRevision`
- `GitRunner.GetTopCommitHash` and `GitRunner.GetBranchName` (class retained — still used by `BuildInfo.DetermineLastVersionChangeCommit`)
## Files
**Added**
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
**Renamed/moved**
- `build-tools/scripts/XABuildConfig.cs.in` → `src/AndroidBuildConfig/XABuildConfig.cs.in` (`static class` → `public static class`)
**Modified**
- `src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Xamarin.ProjectTools.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj`
- `build-tools/installers/create-installers.targets`
- `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs`
- `build-tools/xaprepare/xaprepare/Application/BuildInfo.cs`
- `build-tools/xaprepare/xaprepare/Application/Context.cs`
- `build-tools/xaprepare/xaprepare/Application/Scenario.cs`
- `build-tools/xaprepare/xaprepare/Application/Utilities.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Required.cs`
- `build-tools/xaprepare/xaprepare/ToolRunners/GitRunner.cs`
- `build-tools/xaprepare/README.md`
**Deleted**
- `build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs`
## Verification
- `AndroidBuildConfig.csproj`: 0 warnings, 0 errors.
- `Xamarin.Android.Build.Tasks.csproj`: 0 errors, 85 pre-existing unrelated warnings (none for `XABuildConfig`).
- `Xamarin.Android.Build.Tests.csproj`: 0 errors, **7** warnings — down from ~22; all `CS0436 XABuildConfig` conflicts eliminated.
- `xaprepare.csproj`: 0 warnings, 0 errors.
- Generated `XABuildConfig.cs` is semantically identical to the pre-change xaprepare output. The only token difference is the intentional `static class` → `public static class`; everything else (NDK split, API-level major/minor split, supported-ABIs semicolon list, full commit hash, branch name, etc.) matches the previous baseline byte-for-byte.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11825)
Continues the incremental removal of `xaprepare` by moving the
`cgmanifest.json` generator out of the C# step
`Step_GenerateCGManifest` and into a YAML `pwsh:` step that runs only
on CI.
The file is consumed exclusively by the Azure DevOps Component
Governance Detection task (auto-injected on internal pipelines by
`eng/common/core-templates/job/job.yml`). It is not consumed by any
in-repo build target, so generating it from the C# Prepare step is no
longer necessary.
We cannot drop the file outright: `eng/common` ships CG infrastructure
but it is not yet wired to auto-discover submodules in our pipelines,
so the explicit `cgmanifest.json` is still the source of truth.
Files:
* Added: `build-tools/automation/yaml-templates/generate-cgmanifest.yaml`
* Modified: `build-windows-steps.yaml`, `build-macos-steps.yaml`,
`build-linux-steps.yaml`, `commercial-build.yaml` (call the new
template after the Prepare/`make jenkins` step)
* Modified: `Scenario_Standard.cs` (drop registration)
* Modified: `GitRunner.cs` (remove now-unused `ConfigList` and
`SubmoduleStatus` methods)
* Deleted: `Step_GenerateCGManifest.cs`
Verification: byte-for-byte diff of the YAML-generated
`cgmanifest.json` against the previous C# output on Debug:
Baseline=3144 New=3144
Total byte differences: 0
Precedent PRs in this stream: #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803,
#11821.
### Simplify generate-cgmanifest.yaml using ConvertTo-Json
Replace the hand-rolled StringBuilder JSON emission with PowerShell's
`ConvertTo-Json`. The output is no longer byte-identical to the
previous C# output (2-space indent instead of 4, and slightly
different whitespace), but it is still valid JSON matching the
component-detection-manifest schema. The Azure DevOps Component
Governance Detection task parses the file, so formatting does not
matter.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
On Windows, xaprepare's Step_GenerateFiles.Windows.cs writes
external/Java.Interop/bin/Build$(Configuration)/JdkInfo.props from
build-tools/xaprepare/xaprepare/Resources/JdkInfo.Windows.props.in.
But this file is immediately overwritten. The PrepareWindows.targets
Prepare flow runs, in order:
1. `dotnet xaprepare -a` — writes JdkInfo.props (this code).
2. `MSBuild Xamarin.Android.BootstrapTasks.sln` — does not read JdkInfo.props.
3. `MSBuild src/workloads/workloads.csproj` — does not read JdkInfo.props.
4. `CallTarget PrepareJavaInterop` → `dotnet build -t:Prepare Java.Interop.sln`
→ external/Java.Interop/build-tools/scripts/Prepare.targets → runs the
`JdkInfo` MSBuild task → overwrites JdkInfo.props with its own generated
content.
Nothing between step 1 and step 4 reads the file, and Java.Interop's Prepare
always regenerates it. Now that external/Java.Interop is in-tree, we can
safely delete the redundant write.
This is the smallest-diff removal:
* Delete Step_GenerateFiles.Windows.cs (the AddOSSpecificSteps partial).
* Delete Resources/JdkInfo.Windows.props.in.
* In Step_GenerateFiles.cs, drop the `partial void AddOSSpecificSteps`
declaration and collapse GetFilesToGenerate so `atBuildStart == false`
returns null. Ctor surface (atBuildStart, onlyRequired) is unchanged so
Scenario_Required.cs is unaffected.
* In Scenario_Standard.cs, remove the AddEndSteps override — the only
thing it did was schedule the now-empty Step_GenerateFiles(atBuildStart:
false).
Preserved (future slices will address these):
* Get_Configuration_OperatingSystem_props (D1).
* OperatingSystems/*.cs and Context.OS.* surface.
* PrepareWindows.targets, DotNet.targets, Java.Interop's Prepare.targets.
Verification:
* dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug
→ Build succeeded. 0 Warning(s). 0 Error(s).
* build.cmd -t:Prepare -c Debug (Windows, cold tree) → succeeds; the file
external/Java.Interop/bin/BuildDebug/JdkInfo.props exists.
* Compare-Object of the resulting JdkInfo.props before vs after this
change → byte-identical (1493 bytes, SHA256
DE59A8061B7657831788FFED7BC1DEECA442E9181605083A4553DE7AC8C003A1),
confirming Java.Interop's overwrite is what always ends up on disk.
* Grep audit under build-tools/xaprepare/: no remaining references to
Step_GenerateFiles.Windows, JdkInfo.Windows.props.in, or
AddOSSpecificSteps.
Follows previous xaprepare deletion slices #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821,
#11825, #11826.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jul 3, 2026
…xaprepare project (#11959)
Follow-up to #11956, which moved the JDK half of `Configuration.OperatingSystem.props` to Java.Interop's `JdkInfo.props`. The remaining NDK / OS-info half has zero real consumers, so this PR:
1. Deletes the last generator template (`Configuration.OperatingSystem.props.in`).
2. Cascades through `Step_GenerateFiles`, both `Scenario_*` classes (which now had zero steps), and every supporting `OperatingSystems/`, `Context.*OS.cs`, `EssentialTools.*`, `ToolRunners/*`, `Configurables.*`, `Application/*`, and `Main.cs` file that only existed to feed the scenarios.
3. Deletes the whole `build-tools/xaprepare/` project.
4. Patches every integration point (`Makefile`, `PrepareWindows.targets`, `BuildEverything.mk`, CI YAML, docs) so `build.cmd -t:Prepare` and `make prepare` still work end-to-end.
## `Configuration.OperatingSystem.props.in` placeholder audit
| Placeholder | Consumers outside the `.in` file | Action |
| --- | --- | --- |
| `HostOsName` | none | drop |
| `HostOsFlavor` | none | drop |
| `HostOsRelease` | none | drop |
| `HostBits` | none (`ArchiveBase.HostBits` in `src/Xamarin.Installer.AndroidSDK/` is an unrelated C# property) | drop |
| `NdkLlvmTag` | none (the NDK toolchain OS tag is resolved elsewhere via `_NdkToolchainOSTag` in `androidsdk.targets`) | drop |
| `HostCpuCount` | only `Configuration.props:72` via `$(MakeConcurrency)` | drop |
## `$(MakeConcurrency)` audit
The only definition was `Configuration.props:72`. A repo-wide grep of `.targets`, `.props`, `.projitems`, `Makefile`, and `.mk` files found zero consumers of the MSBuild property. The `MakeConcurrency` hits under `build-tools/xaprepare/` were an unrelated C# `Context.MakeConcurrency` property.
**Result:** dropped the `MakeConcurrency` MSBuild property entirely (no `$([System.Environment]::ProcessorCount)` replacement needed) and removed the `$(MakeConcurrency)` bullet in `Documentation/building/configuration.md`.
## xaprepare integration audit (grep-confirmed, patched here)
| Location | Change |
| --- | --- |
| `build-tools/xaprepare/` (entire tree) | **deleted** — 86 tracked files |
| `Configuration.props` | dropped `<Import>` of the generated OS props, dropped `MakeConcurrency`, tidied the "between xaprepare and package creation tools" comment |
| `.gitignore` | dropped `Configuration.OperatingSystem.props` |
| `build-tools/scripts/PrepareWindows.targets` | removed `_XAPrepareExe`, `_XAPrepareStandardArgs`, `_BuildXAPrepare` target, and the `Exec dotnet $(_XAPrepareExe)` line. Repointed `Prepare` at `_InstallDotNet`. Kept the space-in-path guard, BootstrapTasks / workloads MSBuilds, and `PrepareJavaInterop` |
| `Makefile` | dropped `PREPARE_PROJECT`, `PREPARE_NET_FX`, `PREPARE_ARGS`, `PREPARE_MSBUILD_FLAGS`, `PREPARE_SCENARIO`, `PREPARE_CI_PR`, `PREPARE_CI`, `_PREPARE_CI_MODE_*`, `_PREPARE_ARGS`, and all their conditionals. Dropped the `dotnet run --project xaprepare.csproj` line from `prepare`. Deleted the `prepare-help` target |
| `build-tools/scripts/BuildEverything.mk` | `jenkins` no longer branches on `PREPARE_CI_PR`/`PREPARE_CI`; just `$(MAKE) prepare && $(MAKE) leeroy` |
| `.github/workflows/copilot-setup-steps.yml` | dropped now-unused `PREPARE_CI=1` |
| `build-tools/automation/azure-pipelines-apidocs.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-linux-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-macos-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/commercial-build.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/copy-extra-result-files.yaml` | dropped `**/Configuration.OperatingSystem.props` glob and the stale `Step_CopyExtraResultFilesForCI` xaprepare-step comment |
| `build-tools/automation/yaml-templates/generate-cgmanifest.yaml` | dropped the stale `Step_GenerateCGManifest` xaprepare-step comment |
| `build-tools/automation/yaml-templates/setup-jdk-variables.yaml` | renamed `$xaPrepareJdkPath` → `$xaJdkPath` for hygiene |
| `Documentation/workflow/HowToAddNewApiLevel.md` | rewrote the "Add New Platform" section to point at `<_PlatformPackage>` entries in `src/androidsdk/androidsdk.targets` instead of `AndroidToolchain.cs`; updated the `--android-sdk-platforms=all` recipe to `dotnet-local build src/androidsdk/androidsdk.csproj -p:AndroidSdkPlatforms=all` |
| `Documentation/building/unix/dependencies.md` | JDK-version link now points at `$(MicrosoftOpenJDKVersion)` in `/Configuration.props` instead of the deleted `Configurables.cs` |
| `Documentation/building/configuration.md` | removed the `$(MakeConcurrency)` bullet |
**Historical breadcrumb comments left as-is** (still accurate and useful for git-archaeology):
- `.github/skills/update-tpn/SKILL.md`
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
- `src/androidsdk/androidsdk.targets`
- `src/native/cmake-config/cmake-config.csproj`
- `src/workloads/workloads.csproj`
## Verification
- `build.cmd Prepare` — succeeded end-to-end on Windows (0 warnings, 0 errors). The trimmed `Prepare` target ran through `_InstallDotNet`, the space-in-path guard, `Xamarin.Android.BootstrapTasks.sln`, `src/workloads/workloads.csproj`, and `PrepareJavaInterop`.
- `dotnet build src\Xamarin.Android.Build.Tasks\Xamarin.Android.Build.Tasks.csproj -c Debug` — 0 errors (93 pre-existing warnings from `src/Mono.Android/` and generated MCW, unrelated to this change).
- Repo-wide grep for `HostOsName`, `HostOsFlavor`, `HostOsRelease`, `HostCpuCount`, `NdkLlvmTag`, and the MSBuild `MakeConcurrency` property — clean.
- Repo-wide grep for `xaprepare` — clean apart from the five intentional historical breadcrumb comments listed above.
## Diff stat
102 files changed, 25 insertions(+), 7891 deletions(-).
## Precedent chain
Continues the multi-slice teardown started by #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821, #11825, #11826, #11945, #11946, #11956.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 31, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

ready-to-reviewThis PR is ready to review/merge, I think any CI failures are just flaky (ignorable).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@jonathanpeppers@simonrozsival
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[xaprepare] Use Microsoft.SourceLink.GitHub instead of hand-rolled SourceLink.json - #11821

Merged
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-adopt-sourcelink-github
Jun 30, 2026
Merged

[xaprepare] Use Microsoft.SourceLink.GitHub instead of hand-rolled SourceLink.json#11821
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-adopt-sourcelink-github

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Member

Summary

Stop generating bin/Build$(Configuration)/SourceLink.json from xaprepare and stop overriding $(SourceLink) in Configuration.props. Let Microsoft.SourceLink.GitHub (which is already pinned at 8.0.0 in Directory.Build.targets, but until now only Included in one project) produce SourceLink the canonical Arcade way for every project.

Changes

  • Directory.Build.targets — promoted Microsoft.SourceLink.GitHub 8.0.0 from a PackageReference Update to a broad PackageReference Include with PrivateAssets="All" so every project in the repo picks it up.
  • src/Microsoft.Android.Run/Microsoft.Android.Run.csproj — dropped the now-redundant explicit <PackageReference Include="Microsoft.SourceLink.GitHub" />.
  • Configuration.props — deleted the <PropertyGroup> that overrode $(SourceLink) with the path to the generated json file. The canonical package now sets $(SourceLink) itself.
  • build-tools/xaprepare/xaprepare/Application/GeneratedSourceLinkJsonFile.cs — deleted.
  • build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs — removed Get_SourceLink_Json, both references in GetFilesToGenerate, and the gitSubmodules / xaCommit fields plus the git/submodule prelude in Execute (no other generator in this file used them). Switched Execute from async back to a synchronous Task.FromResult since the only await was the deleted submodule walk.
  • build-tools/xaprepare/xaprepare/Application/GeneratedFile.cs — deleted the now-orphaned SkipGeneratedFile class (only caller was Get_SourceLink_Json).

Net: -99/+8 lines, one file deleted.

Verification

Built Mono.Android.csproj, Xamarin.Android.Build.Tasks.csproj, and xaprepare.csproj in Debug after a clean build.cmd Prepare. All succeeded with 0 errors.

Ran sourcelink print-json on bin\Debug\lib\packs\Microsoft.Android.Runtime.37.android\37.0.0\runtimes\android\lib\net11.0\Mono.Android.pdb:

{"documents":{
"<repo>\\*": "https://raw.githubusercontent.com/dotnet/android/138c93d5a5b369e5d9b6867607afefa7502cd787/*",
"<repo>\\external\\android-api-docs\\*": "https://raw.githubusercontent.com/dotnet/android-api-docs/d382c5bd406432083901e51a4e87cd677b8759d8/*",
"<repo>\\external\\constexpr-xxh3\\*": "https://raw.githubusercontent.com/chys87/constexpr-xxh3/aebcee75c8b6c2458fa8ae151754a8ba833bd697/*",
"<repo>\\external\\debugger-libs\\*": "https://raw.githubusercontent.com/mono/debugger-libs/e7fbb713d156d11193ed404783ad6fe9c4042a6d/*",
"<repo>\\external\\Java.Interop\\*": "https://raw.githubusercontent.com/dotnet/java-interop/8d544738ad294b4faf13d189eeeb02f0313e00b3/*",
"<repo>\\external\\libunwind\\*": "https://raw.githubusercontent.com/libunwind/libunwind/e97c9ef82f8b48d0c7f713be4fa7b15e634d76b8/*",
"<repo>\\external\\lz4\\*": "https://raw.githubusercontent.com/lz4/lz4/ebb370ca83af193212df4dcbadcc5d87bc0de2f0/*",
"<repo>\\external\\robin-map\\*": "https://raw.githubusercontent.com/xamarin/robin-map/d37a41003bfbc7e12e34601f93c18ca2ff6d7c07/*",
"<repo>\\external\\termux-elf-cleaner\\*": "https://raw.githubusercontent.com/termux/termux-elf-cleaner/ee5385e004a9d67bdc289e43939691b260e06b03/*",
"<repo>\\external\\xamarin-android-tools\\*": "https://raw.githubusercontent.com/dotnet/android-tools/367724d6ba93db20294681769de97b9cdecb58a0/*",
"<repo>\\external\\xxHash\\*": "https://raw.githubusercontent.com/Cyan4973/xxHash/bbb27a5efb85b92a0486cf361a8635715a53f6ba/*"
}}

Every submodule from .gitmodules is mapped to its correct upstream raw.githubusercontent.com URL — full parity with what GeneratedSourceLinkJsonFile produced before.

Out of scope

Step_GenerateCGManifest, GitSubmoduleInfo, GitRunner, and the GitCommit* prep tasks are still used by cgmanifest generation and XAVersionInfo.targets; they're intentionally left for a follow-up PR.

Precedent

Continues the xaprepare slim-down work in #11568, #11580, #11608, #11613, #11631, #11657, #11658, #11731, #11732, #11733, #11737, #11740, #11760, #11803.

…urceLink.json
Stop generating bin/Build$(Configuration)/SourceLink.json from xaprepare and stop overriding $(SourceLink) in Configuration.props. Promote Microsoft.SourceLink.GitHub from a PackageReference Update to a broad PackageReference Include in Directory.Build.targets so every project picks it up, then drop the explicit Include from Microsoft.Android.Run.csproj.
Verified with 'sourcelink print-json' on bin\Debug\lib\packs\Microsoft.Android.Runtime.37.android\37.0.0\runtimes\android\lib\net11.0\Mono.Android.pdb: the canonical package produces a documents map covering dotnet/android plus every submodule (Java.Interop, xamarin-android-tools, android-api-docs, constexpr-xxh3, debugger-libs, libunwind, lz4, robin-map, termux-elf-cleaner, xxHash) pointing at the correct upstream raw.githubusercontent.com URLs.
Step_GenerateCGManifest and GitSubmoduleInfo / GitRunner are intentionally left for a follow-up.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 30, 2026 14:07

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR switches the repo’s SourceLink generation to the standard Arcade/MSBuild approach by enabling Microsoft.SourceLink.GitHub repo-wide, and removes the now-redundant xaprepare-generated SourceLink.json plumbing.

Changes:

  • Add a repo-wide PackageReference to Microsoft.SourceLink.GitHub (PrivateAssets=All) via Directory.Build.targets, and remove the per-project reference from Microsoft.Android.Run.
  • Stop overriding $(SourceLink) in Configuration.props, letting the SourceLink package set it canonically.
  • Remove xaprepare’s SourceLink.json generator and related scaffolding (including the SkipGeneratedFile helper).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
Directory.Build.targetsAdds global Microsoft.SourceLink.GitHub package reference for SourceLink across the repo.
src/Microsoft.Android.Run/Microsoft.Android.Run.csprojRemoves redundant explicit SourceLink package reference.
Configuration.propsRemoves $(SourceLink) override pointing to generated SourceLink.json.
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.csRemoves SourceLink.json generation path and simplifies execution flow.
build-tools/xaprepare/xaprepare/Application/GeneratedSourceLinkJsonFile.csDeletes the hand-rolled SourceLink.json generator implementation.
build-tools/xaprepare/xaprepare/Application/GeneratedFile.csRemoves the now-orphaned SkipGeneratedFile helper type.
Comments suppressed due to low confidence (1)

build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs:52

  • Scenario_Required still adds new Step_GenerateFiles (atBuildStart: true, onlyRequired: true), but GetFilesToGenerate() now returns null for that case, so the step generates no files at all. That seems to contradict the scenario description (“generate build files”) and makes the scenario effectively a no-op after this PR.
 if (atBuildStart) {
if (onlyRequired) {
return null;
} else {
return new List <GeneratedFile> {
Get_Configuration_OperatingSystem_props (context),
Get_XABuildConfig_cs (context),
};
}

@jonathanpeppersjonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 30, 2026
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

Verified the CI build artifacts for this PR (build 1487951).

Downloaded nuget-unsigned-symbols, extracted the symbols .nupkgs, and ran sourcelink print-json on representative PDBs from across the SDK / Runtime / Ref packages. Every assembly's SourceLink covers dotnet/android plus all submodules:

Mono.Android.pdb (Microsoft.Android.Runtime.37.android symbols package):

{"documents":{
"/Users/cloudtest/vss/_work/1/s/android/*":"https://raw.githubusercontent.com/dotnet/android/917981be97def8f5d046c8b1b28dca25771d8198/*",
"/Users/cloudtest/vss/_work/1/s/android/external/android-api-docs/*":"https://raw.githubusercontent.com/dotnet/android-api-docs/d382c5bd406432083901e51a4e87cd677b8759d8/*",
"/Users/cloudtest/vss/_work/1/s/android/external/constexpr-xxh3/*":"https://raw.githubusercontent.com/chys87/constexpr-xxh3/aebcee75c8b6c2458fa8ae151754a8ba833bd697/*",
"/Users/cloudtest/vss/_work/1/s/android/external/debugger-libs/*":"https://raw.githubusercontent.com/mono/debugger-libs/e7fbb713d156d11193ed404783ad6fe9c4042a6d/*",
"/Users/cloudtest/vss/_work/1/s/android/external/Java.Interop/*":"https://raw.githubusercontent.com/dotnet/java-interop/8d544738ad294b4faf13d189eeeb02f0313e00b3/*",
"/Users/cloudtest/vss/_work/1/s/android/external/libunwind/*":"https://raw.githubusercontent.com/libunwind/libunwind/e97c9ef82f8b48d0c7f713be4fa7b15e634d76b8/*",
"/Users/cloudtest/vss/_work/1/s/android/external/lz4/*":"https://raw.githubusercontent.com/dotnet/lz4/ebb370ca83af193212df4dcbadcc5d87bc0de2f0/*",
"/Users/cloudtest/vss/_work/1/s/android/external/robin-map/*":"https://raw.githubusercontent.com/xamarin/robin-map/d37a41003bfbc7e12e34601f93c18ca2ff6d7c07/*",
"/Users/cloudtest/vss/_work/1/s/android/external/termux-elf-cleaner/*":"https://raw.githubusercontent.com/termux/termux-elf-cleaner/ee5385e004a9d67bdc289e43939691b260e06b03/*",
"/Users/cloudtest/vss/_work/1/s/android/external/xamarin-android-tools/*":"https://raw.githubusercontent.com/dotnet/android-tools/367724d6ba93db20294681769de97b9cdecb58a0/*",
"/Users/cloudtest/vss/_work/1/s/android/external/xxHash/*":"https://raw.githubusercontent.com/Cyan4973/xxHash/bbb27a5efb85b92a0486cf361a8635715a53f6ba/*"
}}

Same coverage on:

  • Xamarin.Android.Build.Tasks.pdb (Microsoft.Android.Sdk.Windows symbols) — repo + all 10 submodule mappings.
  • Microsoft.Android.Sdk.ILLink.pdb (Microsoft.Android.Sdk.Windows symbols) — repo + all 10 submodule mappings.
  • Java.Interop.pdb — own Java.Interop repo + its nested xamarin-android-tools submodule.

All URLs match .gitmodules exactly (including the dotnet/lz4 upstream). Microsoft.Android.Ref.37 produces a reference-only assembly with no embedded source link section, which is expected for ref assemblies.

@jonathanpeppers
jonathanpeppers merged commit b0fe694 into mainJun 30, 2026
41 checks passed
@jonathanpeppers
jonathanpeppers deleted the jonathanpeppers-adopt-sourcelink-github branch June 30, 2026 19:45
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11826)
## Summary
Moves `XABuildConfig.cs` generation out of `xaprepare` and into a new strong-named class library at `src/AndroidBuildConfig/AndroidBuildConfig.csproj` that produces `AndroidBuildConfig.dll`.
This continues the incremental removal of `xaprepare`, following the precedent set by `cmake-config.csproj` (#11760) and the recent batch #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11803, #11821, #11825.
It also fixes a long-standing wart: previously `XABuildConfig.cs` was `<Compile Include>`'d into three different assemblies (`Xamarin.Android.Build.Tasks`, `Xamarin.ProjectTools`, and `Xamarin.Android.Build.Tests`), so every test that mentioned `XABuildConfig` produced a `CS0436` "type conflicts with imported type" warning — about **22** of them.
Wrapping the type in its own assembly collapses it to a single definition that every consumer references normally. After this change `Xamarin.Android.Build.Tests` builds with **7** warnings (none for `XABuildConfig`).
## How it works
`src/AndroidBuildConfig/AndroidBuildConfig.csproj`:
- `Microsoft.NET.Sdk` / `netstandard2.0`, strong-named with `product.snk`.
- `ProjectReference`s `Xamarin.Android.Tools.AndroidSdk` (for the `AndroidTargetArch` enum used by the template).
- `<UsingTask>`s `ReplaceFileContents`, `GitCommitHash`, and `GitBranch` from `$(PrepTasksAssembly)`, all with `TaskFactory="TaskHostFactory" Runtime="NET"` per repo convention.
- The `_GenerateXABuildConfig` target runs `BeforeTargets="BeforeCompile;CoreCompile"`, computes every substitution from MSBuild properties already exposed by `Configuration.props` (NDK major/minor/micro via `$(_XAAndroidNdkPkgRevision.Split('.'))`, API levels via `Split`/`Contains`, full commit hash via `GitCommitHash.CommitHash`, branch via `GitBranch.Branch`), and writes the file to `$(IntermediateOutputPath)XABuildConfig.cs`. The `<Compile Include>` lives inside the target so it resolves at execution time, when `IntermediateOutputPath` is final.
- `XABuildConfig` is now `public static class` instead of `internal static class`.
The three consumer csprojs lose their `<Compile Include="…XABuildConfig.cs" />` and now have a normal `<ProjectReference Include="…AndroidBuildConfig.csproj" />` (no `ReferenceOutputAssembly="False"`).
`build-tools/installers/create-installers.targets` ships `AndroidBuildConfig.dll` + `.pdb` alongside `Xamarin.Android.Build.Tasks.dll`.
## xaprepare cleanup
Removed dead code that only existed to feed the old `Get_XABuildConfig_cs` step:
- `Step_GenerateFiles.Get_XABuildConfig_cs` and its `GetMajor` / `GetMinor` locals
- `BuildInfo`: `NDKRevision`, `NDKVersionMajor`, `NDKVersionMinor`, `NDKVersionMicro`, `NDKVersion`, `XACommitHash`, `XABranch`, `GatherGitInfo`, `DetermineXACommitInfo`, `cachedNdkVersion`
- `Context`: the `if (SelectedScenario.NeedsGitBuildInfo) { await BuildInfo.GatherGitInfo … }` block
- `Scenario.NeedsGitBuildInfo` (and the `NeedsGitBuildInfo = true;` setters in `Scenario_Standard` and `Scenario_Required`)
- `BuildAndroidPlatforms.cs` — entire file (only contained constants used by the deleted code)
- `Utilities.ParseAndroidPkgRevision`
- `GitRunner.GetTopCommitHash` and `GitRunner.GetBranchName` (class retained — still used by `BuildInfo.DetermineLastVersionChangeCommit`)
## Files
**Added**
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
**Renamed/moved**
- `build-tools/scripts/XABuildConfig.cs.in` → `src/AndroidBuildConfig/XABuildConfig.cs.in` (`static class` → `public static class`)
**Modified**
- `src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Xamarin.ProjectTools.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj`
- `build-tools/installers/create-installers.targets`
- `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs`
- `build-tools/xaprepare/xaprepare/Application/BuildInfo.cs`
- `build-tools/xaprepare/xaprepare/Application/Context.cs`
- `build-tools/xaprepare/xaprepare/Application/Scenario.cs`
- `build-tools/xaprepare/xaprepare/Application/Utilities.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Required.cs`
- `build-tools/xaprepare/xaprepare/ToolRunners/GitRunner.cs`
- `build-tools/xaprepare/README.md`
**Deleted**
- `build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs`
## Verification
- `AndroidBuildConfig.csproj`: 0 warnings, 0 errors.
- `Xamarin.Android.Build.Tasks.csproj`: 0 errors, 85 pre-existing unrelated warnings (none for `XABuildConfig`).
- `Xamarin.Android.Build.Tests.csproj`: 0 errors, **7** warnings — down from ~22; all `CS0436 XABuildConfig` conflicts eliminated.
- `xaprepare.csproj`: 0 warnings, 0 errors.
- Generated `XABuildConfig.cs` is semantically identical to the pre-change xaprepare output. The only token difference is the intentional `static class` → `public static class`; everything else (NDK split, API-level major/minor split, supported-ABIs semicolon list, full commit hash, branch name, etc.) matches the previous baseline byte-for-byte.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11825)
Continues the incremental removal of `xaprepare` by moving the
`cgmanifest.json` generator out of the C# step
`Step_GenerateCGManifest` and into a YAML `pwsh:` step that runs only
on CI.
The file is consumed exclusively by the Azure DevOps Component
Governance Detection task (auto-injected on internal pipelines by
`eng/common/core-templates/job/job.yml`). It is not consumed by any
in-repo build target, so generating it from the C# Prepare step is no
longer necessary.
We cannot drop the file outright: `eng/common` ships CG infrastructure
but it is not yet wired to auto-discover submodules in our pipelines,
so the explicit `cgmanifest.json` is still the source of truth.
Files:
* Added: `build-tools/automation/yaml-templates/generate-cgmanifest.yaml`
* Modified: `build-windows-steps.yaml`, `build-macos-steps.yaml`,
`build-linux-steps.yaml`, `commercial-build.yaml` (call the new
template after the Prepare/`make jenkins` step)
* Modified: `Scenario_Standard.cs` (drop registration)
* Modified: `GitRunner.cs` (remove now-unused `ConfigList` and
`SubmoduleStatus` methods)
* Deleted: `Step_GenerateCGManifest.cs`
Verification: byte-for-byte diff of the YAML-generated
`cgmanifest.json` against the previous C# output on Debug:
Baseline=3144 New=3144
Total byte differences: 0
Precedent PRs in this stream: #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803,
#11821.
### Simplify generate-cgmanifest.yaml using ConvertTo-Json
Replace the hand-rolled StringBuilder JSON emission with PowerShell's
`ConvertTo-Json`. The output is no longer byte-identical to the
previous C# output (2-space indent instead of 4, and slightly
different whitespace), but it is still valid JSON matching the
component-detection-manifest schema. The Azure DevOps Component
Governance Detection task parses the file, so formatting does not
matter.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
On Windows, xaprepare's Step_GenerateFiles.Windows.cs writes
external/Java.Interop/bin/Build$(Configuration)/JdkInfo.props from
build-tools/xaprepare/xaprepare/Resources/JdkInfo.Windows.props.in.
But this file is immediately overwritten. The PrepareWindows.targets
Prepare flow runs, in order:
1. `dotnet xaprepare -a` — writes JdkInfo.props (this code).
2. `MSBuild Xamarin.Android.BootstrapTasks.sln` — does not read JdkInfo.props.
3. `MSBuild src/workloads/workloads.csproj` — does not read JdkInfo.props.
4. `CallTarget PrepareJavaInterop` → `dotnet build -t:Prepare Java.Interop.sln`
→ external/Java.Interop/build-tools/scripts/Prepare.targets → runs the
`JdkInfo` MSBuild task → overwrites JdkInfo.props with its own generated
content.
Nothing between step 1 and step 4 reads the file, and Java.Interop's Prepare
always regenerates it. Now that external/Java.Interop is in-tree, we can
safely delete the redundant write.
This is the smallest-diff removal:
* Delete Step_GenerateFiles.Windows.cs (the AddOSSpecificSteps partial).
* Delete Resources/JdkInfo.Windows.props.in.
* In Step_GenerateFiles.cs, drop the `partial void AddOSSpecificSteps`
declaration and collapse GetFilesToGenerate so `atBuildStart == false`
returns null. Ctor surface (atBuildStart, onlyRequired) is unchanged so
Scenario_Required.cs is unaffected.
* In Scenario_Standard.cs, remove the AddEndSteps override — the only
thing it did was schedule the now-empty Step_GenerateFiles(atBuildStart:
false).
Preserved (future slices will address these):
* Get_Configuration_OperatingSystem_props (D1).
* OperatingSystems/*.cs and Context.OS.* surface.
* PrepareWindows.targets, DotNet.targets, Java.Interop's Prepare.targets.
Verification:
* dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug
→ Build succeeded. 0 Warning(s). 0 Error(s).
* build.cmd -t:Prepare -c Debug (Windows, cold tree) → succeeds; the file
external/Java.Interop/bin/BuildDebug/JdkInfo.props exists.
* Compare-Object of the resulting JdkInfo.props before vs after this
change → byte-identical (1493 bytes, SHA256
DE59A8061B7657831788FFED7BC1DEECA442E9181605083A4553DE7AC8C003A1),
confirming Java.Interop's overwrite is what always ends up on disk.
* Grep audit under build-tools/xaprepare/: no remaining references to
Step_GenerateFiles.Windows, JdkInfo.Windows.props.in, or
AddOSSpecificSteps.
Follows previous xaprepare deletion slices #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821,
#11825, #11826.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jul 3, 2026
…xaprepare project (#11959)
Follow-up to #11956, which moved the JDK half of `Configuration.OperatingSystem.props` to Java.Interop's `JdkInfo.props`. The remaining NDK / OS-info half has zero real consumers, so this PR:
1. Deletes the last generator template (`Configuration.OperatingSystem.props.in`).
2. Cascades through `Step_GenerateFiles`, both `Scenario_*` classes (which now had zero steps), and every supporting `OperatingSystems/`, `Context.*OS.cs`, `EssentialTools.*`, `ToolRunners/*`, `Configurables.*`, `Application/*`, and `Main.cs` file that only existed to feed the scenarios.
3. Deletes the whole `build-tools/xaprepare/` project.
4. Patches every integration point (`Makefile`, `PrepareWindows.targets`, `BuildEverything.mk`, CI YAML, docs) so `build.cmd -t:Prepare` and `make prepare` still work end-to-end.
## `Configuration.OperatingSystem.props.in` placeholder audit
| Placeholder | Consumers outside the `.in` file | Action |
| --- | --- | --- |
| `HostOsName` | none | drop |
| `HostOsFlavor` | none | drop |
| `HostOsRelease` | none | drop |
| `HostBits` | none (`ArchiveBase.HostBits` in `src/Xamarin.Installer.AndroidSDK/` is an unrelated C# property) | drop |
| `NdkLlvmTag` | none (the NDK toolchain OS tag is resolved elsewhere via `_NdkToolchainOSTag` in `androidsdk.targets`) | drop |
| `HostCpuCount` | only `Configuration.props:72` via `$(MakeConcurrency)` | drop |
## `$(MakeConcurrency)` audit
The only definition was `Configuration.props:72`. A repo-wide grep of `.targets`, `.props`, `.projitems`, `Makefile`, and `.mk` files found zero consumers of the MSBuild property. The `MakeConcurrency` hits under `build-tools/xaprepare/` were an unrelated C# `Context.MakeConcurrency` property.
**Result:** dropped the `MakeConcurrency` MSBuild property entirely (no `$([System.Environment]::ProcessorCount)` replacement needed) and removed the `$(MakeConcurrency)` bullet in `Documentation/building/configuration.md`.
## xaprepare integration audit (grep-confirmed, patched here)
| Location | Change |
| --- | --- |
| `build-tools/xaprepare/` (entire tree) | **deleted** — 86 tracked files |
| `Configuration.props` | dropped `<Import>` of the generated OS props, dropped `MakeConcurrency`, tidied the "between xaprepare and package creation tools" comment |
| `.gitignore` | dropped `Configuration.OperatingSystem.props` |
| `build-tools/scripts/PrepareWindows.targets` | removed `_XAPrepareExe`, `_XAPrepareStandardArgs`, `_BuildXAPrepare` target, and the `Exec dotnet $(_XAPrepareExe)` line. Repointed `Prepare` at `_InstallDotNet`. Kept the space-in-path guard, BootstrapTasks / workloads MSBuilds, and `PrepareJavaInterop` |
| `Makefile` | dropped `PREPARE_PROJECT`, `PREPARE_NET_FX`, `PREPARE_ARGS`, `PREPARE_MSBUILD_FLAGS`, `PREPARE_SCENARIO`, `PREPARE_CI_PR`, `PREPARE_CI`, `_PREPARE_CI_MODE_*`, `_PREPARE_ARGS`, and all their conditionals. Dropped the `dotnet run --project xaprepare.csproj` line from `prepare`. Deleted the `prepare-help` target |
| `build-tools/scripts/BuildEverything.mk` | `jenkins` no longer branches on `PREPARE_CI_PR`/`PREPARE_CI`; just `$(MAKE) prepare && $(MAKE) leeroy` |
| `.github/workflows/copilot-setup-steps.yml` | dropped now-unused `PREPARE_CI=1` |
| `build-tools/automation/azure-pipelines-apidocs.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-linux-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-macos-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/commercial-build.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/copy-extra-result-files.yaml` | dropped `**/Configuration.OperatingSystem.props` glob and the stale `Step_CopyExtraResultFilesForCI` xaprepare-step comment |
| `build-tools/automation/yaml-templates/generate-cgmanifest.yaml` | dropped the stale `Step_GenerateCGManifest` xaprepare-step comment |
| `build-tools/automation/yaml-templates/setup-jdk-variables.yaml` | renamed `$xaPrepareJdkPath` → `$xaJdkPath` for hygiene |
| `Documentation/workflow/HowToAddNewApiLevel.md` | rewrote the "Add New Platform" section to point at `<_PlatformPackage>` entries in `src/androidsdk/androidsdk.targets` instead of `AndroidToolchain.cs`; updated the `--android-sdk-platforms=all` recipe to `dotnet-local build src/androidsdk/androidsdk.csproj -p:AndroidSdkPlatforms=all` |
| `Documentation/building/unix/dependencies.md` | JDK-version link now points at `$(MicrosoftOpenJDKVersion)` in `/Configuration.props` instead of the deleted `Configurables.cs` |
| `Documentation/building/configuration.md` | removed the `$(MakeConcurrency)` bullet |
**Historical breadcrumb comments left as-is** (still accurate and useful for git-archaeology):
- `.github/skills/update-tpn/SKILL.md`
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
- `src/androidsdk/androidsdk.targets`
- `src/native/cmake-config/cmake-config.csproj`
- `src/workloads/workloads.csproj`
## Verification
- `build.cmd Prepare` — succeeded end-to-end on Windows (0 warnings, 0 errors). The trimmed `Prepare` target ran through `_InstallDotNet`, the space-in-path guard, `Xamarin.Android.BootstrapTasks.sln`, `src/workloads/workloads.csproj`, and `PrepareJavaInterop`.
- `dotnet build src\Xamarin.Android.Build.Tasks\Xamarin.Android.Build.Tasks.csproj -c Debug` — 0 errors (93 pre-existing warnings from `src/Mono.Android/` and generated MCW, unrelated to this change).
- Repo-wide grep for `HostOsName`, `HostOsFlavor`, `HostOsRelease`, `HostCpuCount`, `NdkLlvmTag`, and the MSBuild `MakeConcurrency` property — clean.
- Repo-wide grep for `xaprepare` — clean apart from the five intentional historical breadcrumb comments listed above.
## Diff stat
102 files changed, 25 insertions(+), 7891 deletions(-).
## Precedent chain
Continues the multi-slice teardown started by #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821, #11825, #11826, #11945, #11946, #11956.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 31, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

ready-to-reviewThis PR is ready to review/merge, I think any CI failures are just flaky (ignorable).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@jonathanpeppers@simonrozsival
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

[xaprepare] Use Microsoft.SourceLink.GitHub instead of hand-rolled SourceLink.json - #11821

Merged
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-adopt-sourcelink-github
Jun 30, 2026
Merged

[xaprepare] Use Microsoft.SourceLink.GitHub instead of hand-rolled SourceLink.json#11821
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-adopt-sourcelink-github

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Member

Summary

Stop generating bin/Build$(Configuration)/SourceLink.json from xaprepare and stop overriding $(SourceLink) in Configuration.props. Let Microsoft.SourceLink.GitHub (which is already pinned at 8.0.0 in Directory.Build.targets, but until now only Included in one project) produce SourceLink the canonical Arcade way for every project.

Changes

  • Directory.Build.targets — promoted Microsoft.SourceLink.GitHub 8.0.0 from a PackageReference Update to a broad PackageReference Include with PrivateAssets="All" so every project in the repo picks it up.
  • src/Microsoft.Android.Run/Microsoft.Android.Run.csproj — dropped the now-redundant explicit <PackageReference Include="Microsoft.SourceLink.GitHub" />.
  • Configuration.props — deleted the <PropertyGroup> that overrode $(SourceLink) with the path to the generated json file. The canonical package now sets $(SourceLink) itself.
  • build-tools/xaprepare/xaprepare/Application/GeneratedSourceLinkJsonFile.cs — deleted.
  • build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs — removed Get_SourceLink_Json, both references in GetFilesToGenerate, and the gitSubmodules / xaCommit fields plus the git/submodule prelude in Execute (no other generator in this file used them). Switched Execute from async back to a synchronous Task.FromResult since the only await was the deleted submodule walk.
  • build-tools/xaprepare/xaprepare/Application/GeneratedFile.cs — deleted the now-orphaned SkipGeneratedFile class (only caller was Get_SourceLink_Json).

Net: -99/+8 lines, one file deleted.

Verification

Built Mono.Android.csproj, Xamarin.Android.Build.Tasks.csproj, and xaprepare.csproj in Debug after a clean build.cmd Prepare. All succeeded with 0 errors.

Ran sourcelink print-json on bin\Debug\lib\packs\Microsoft.Android.Runtime.37.android\37.0.0\runtimes\android\lib\net11.0\Mono.Android.pdb:

{"documents":{
"<repo>\\*": "https://raw.githubusercontent.com/dotnet/android/138c93d5a5b369e5d9b6867607afefa7502cd787/*",
"<repo>\\external\\android-api-docs\\*": "https://raw.githubusercontent.com/dotnet/android-api-docs/d382c5bd406432083901e51a4e87cd677b8759d8/*",
"<repo>\\external\\constexpr-xxh3\\*": "https://raw.githubusercontent.com/chys87/constexpr-xxh3/aebcee75c8b6c2458fa8ae151754a8ba833bd697/*",
"<repo>\\external\\debugger-libs\\*": "https://raw.githubusercontent.com/mono/debugger-libs/e7fbb713d156d11193ed404783ad6fe9c4042a6d/*",
"<repo>\\external\\Java.Interop\\*": "https://raw.githubusercontent.com/dotnet/java-interop/8d544738ad294b4faf13d189eeeb02f0313e00b3/*",
"<repo>\\external\\libunwind\\*": "https://raw.githubusercontent.com/libunwind/libunwind/e97c9ef82f8b48d0c7f713be4fa7b15e634d76b8/*",
"<repo>\\external\\lz4\\*": "https://raw.githubusercontent.com/lz4/lz4/ebb370ca83af193212df4dcbadcc5d87bc0de2f0/*",
"<repo>\\external\\robin-map\\*": "https://raw.githubusercontent.com/xamarin/robin-map/d37a41003bfbc7e12e34601f93c18ca2ff6d7c07/*",
"<repo>\\external\\termux-elf-cleaner\\*": "https://raw.githubusercontent.com/termux/termux-elf-cleaner/ee5385e004a9d67bdc289e43939691b260e06b03/*",
"<repo>\\external\\xamarin-android-tools\\*": "https://raw.githubusercontent.com/dotnet/android-tools/367724d6ba93db20294681769de97b9cdecb58a0/*",
"<repo>\\external\\xxHash\\*": "https://raw.githubusercontent.com/Cyan4973/xxHash/bbb27a5efb85b92a0486cf361a8635715a53f6ba/*"
}}

Every submodule from .gitmodules is mapped to its correct upstream raw.githubusercontent.com URL — full parity with what GeneratedSourceLinkJsonFile produced before.

Out of scope

Step_GenerateCGManifest, GitSubmoduleInfo, GitRunner, and the GitCommit* prep tasks are still used by cgmanifest generation and XAVersionInfo.targets; they're intentionally left for a follow-up PR.

Precedent

Continues the xaprepare slim-down work in #11568, #11580, #11608, #11613, #11631, #11657, #11658, #11731, #11732, #11733, #11737, #11740, #11760, #11803.

…urceLink.json
Stop generating bin/Build$(Configuration)/SourceLink.json from xaprepare and stop overriding $(SourceLink) in Configuration.props. Promote Microsoft.SourceLink.GitHub from a PackageReference Update to a broad PackageReference Include in Directory.Build.targets so every project picks it up, then drop the explicit Include from Microsoft.Android.Run.csproj.
Verified with 'sourcelink print-json' on bin\Debug\lib\packs\Microsoft.Android.Runtime.37.android\37.0.0\runtimes\android\lib\net11.0\Mono.Android.pdb: the canonical package produces a documents map covering dotnet/android plus every submodule (Java.Interop, xamarin-android-tools, android-api-docs, constexpr-xxh3, debugger-libs, libunwind, lz4, robin-map, termux-elf-cleaner, xxHash) pointing at the correct upstream raw.githubusercontent.com URLs.
Step_GenerateCGManifest and GitSubmoduleInfo / GitRunner are intentionally left for a follow-up.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 30, 2026 14:07

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR switches the repo’s SourceLink generation to the standard Arcade/MSBuild approach by enabling Microsoft.SourceLink.GitHub repo-wide, and removes the now-redundant xaprepare-generated SourceLink.json plumbing.

Changes:

  • Add a repo-wide PackageReference to Microsoft.SourceLink.GitHub (PrivateAssets=All) via Directory.Build.targets, and remove the per-project reference from Microsoft.Android.Run.
  • Stop overriding $(SourceLink) in Configuration.props, letting the SourceLink package set it canonically.
  • Remove xaprepare’s SourceLink.json generator and related scaffolding (including the SkipGeneratedFile helper).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
Directory.Build.targetsAdds global Microsoft.SourceLink.GitHub package reference for SourceLink across the repo.
src/Microsoft.Android.Run/Microsoft.Android.Run.csprojRemoves redundant explicit SourceLink package reference.
Configuration.propsRemoves $(SourceLink) override pointing to generated SourceLink.json.
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.csRemoves SourceLink.json generation path and simplifies execution flow.
build-tools/xaprepare/xaprepare/Application/GeneratedSourceLinkJsonFile.csDeletes the hand-rolled SourceLink.json generator implementation.
build-tools/xaprepare/xaprepare/Application/GeneratedFile.csRemoves the now-orphaned SkipGeneratedFile helper type.
Comments suppressed due to low confidence (1)

build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs:52

  • Scenario_Required still adds new Step_GenerateFiles (atBuildStart: true, onlyRequired: true), but GetFilesToGenerate() now returns null for that case, so the step generates no files at all. That seems to contradict the scenario description (“generate build files”) and makes the scenario effectively a no-op after this PR.
 if (atBuildStart) {
if (onlyRequired) {
return null;
} else {
return new List <GeneratedFile> {
Get_Configuration_OperatingSystem_props (context),
Get_XABuildConfig_cs (context),
};
}

@jonathanpeppersjonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 30, 2026
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

Verified the CI build artifacts for this PR (build 1487951).

Downloaded nuget-unsigned-symbols, extracted the symbols .nupkgs, and ran sourcelink print-json on representative PDBs from across the SDK / Runtime / Ref packages. Every assembly's SourceLink covers dotnet/android plus all submodules:

Mono.Android.pdb (Microsoft.Android.Runtime.37.android symbols package):

{"documents":{
"/Users/cloudtest/vss/_work/1/s/android/*":"https://raw.githubusercontent.com/dotnet/android/917981be97def8f5d046c8b1b28dca25771d8198/*",
"/Users/cloudtest/vss/_work/1/s/android/external/android-api-docs/*":"https://raw.githubusercontent.com/dotnet/android-api-docs/d382c5bd406432083901e51a4e87cd677b8759d8/*",
"/Users/cloudtest/vss/_work/1/s/android/external/constexpr-xxh3/*":"https://raw.githubusercontent.com/chys87/constexpr-xxh3/aebcee75c8b6c2458fa8ae151754a8ba833bd697/*",
"/Users/cloudtest/vss/_work/1/s/android/external/debugger-libs/*":"https://raw.githubusercontent.com/mono/debugger-libs/e7fbb713d156d11193ed404783ad6fe9c4042a6d/*",
"/Users/cloudtest/vss/_work/1/s/android/external/Java.Interop/*":"https://raw.githubusercontent.com/dotnet/java-interop/8d544738ad294b4faf13d189eeeb02f0313e00b3/*",
"/Users/cloudtest/vss/_work/1/s/android/external/libunwind/*":"https://raw.githubusercontent.com/libunwind/libunwind/e97c9ef82f8b48d0c7f713be4fa7b15e634d76b8/*",
"/Users/cloudtest/vss/_work/1/s/android/external/lz4/*":"https://raw.githubusercontent.com/dotnet/lz4/ebb370ca83af193212df4dcbadcc5d87bc0de2f0/*",
"/Users/cloudtest/vss/_work/1/s/android/external/robin-map/*":"https://raw.githubusercontent.com/xamarin/robin-map/d37a41003bfbc7e12e34601f93c18ca2ff6d7c07/*",
"/Users/cloudtest/vss/_work/1/s/android/external/termux-elf-cleaner/*":"https://raw.githubusercontent.com/termux/termux-elf-cleaner/ee5385e004a9d67bdc289e43939691b260e06b03/*",
"/Users/cloudtest/vss/_work/1/s/android/external/xamarin-android-tools/*":"https://raw.githubusercontent.com/dotnet/android-tools/367724d6ba93db20294681769de97b9cdecb58a0/*",
"/Users/cloudtest/vss/_work/1/s/android/external/xxHash/*":"https://raw.githubusercontent.com/Cyan4973/xxHash/bbb27a5efb85b92a0486cf361a8635715a53f6ba/*"
}}

Same coverage on:

  • Xamarin.Android.Build.Tasks.pdb (Microsoft.Android.Sdk.Windows symbols) — repo + all 10 submodule mappings.
  • Microsoft.Android.Sdk.ILLink.pdb (Microsoft.Android.Sdk.Windows symbols) — repo + all 10 submodule mappings.
  • Java.Interop.pdb — own Java.Interop repo + its nested xamarin-android-tools submodule.

All URLs match .gitmodules exactly (including the dotnet/lz4 upstream). Microsoft.Android.Ref.37 produces a reference-only assembly with no embedded source link section, which is expected for ref assemblies.

@jonathanpeppers
jonathanpeppers merged commit b0fe694 into mainJun 30, 2026
41 checks passed
@jonathanpeppers
jonathanpeppers deleted the jonathanpeppers-adopt-sourcelink-github branch June 30, 2026 19:45
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11826)
## Summary
Moves `XABuildConfig.cs` generation out of `xaprepare` and into a new strong-named class library at `src/AndroidBuildConfig/AndroidBuildConfig.csproj` that produces `AndroidBuildConfig.dll`.
This continues the incremental removal of `xaprepare`, following the precedent set by `cmake-config.csproj` (#11760) and the recent batch #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11803, #11821, #11825.
It also fixes a long-standing wart: previously `XABuildConfig.cs` was `<Compile Include>`'d into three different assemblies (`Xamarin.Android.Build.Tasks`, `Xamarin.ProjectTools`, and `Xamarin.Android.Build.Tests`), so every test that mentioned `XABuildConfig` produced a `CS0436` "type conflicts with imported type" warning — about **22** of them.
Wrapping the type in its own assembly collapses it to a single definition that every consumer references normally. After this change `Xamarin.Android.Build.Tests` builds with **7** warnings (none for `XABuildConfig`).
## How it works
`src/AndroidBuildConfig/AndroidBuildConfig.csproj`:
- `Microsoft.NET.Sdk` / `netstandard2.0`, strong-named with `product.snk`.
- `ProjectReference`s `Xamarin.Android.Tools.AndroidSdk` (for the `AndroidTargetArch` enum used by the template).
- `<UsingTask>`s `ReplaceFileContents`, `GitCommitHash`, and `GitBranch` from `$(PrepTasksAssembly)`, all with `TaskFactory="TaskHostFactory" Runtime="NET"` per repo convention.
- The `_GenerateXABuildConfig` target runs `BeforeTargets="BeforeCompile;CoreCompile"`, computes every substitution from MSBuild properties already exposed by `Configuration.props` (NDK major/minor/micro via `$(_XAAndroidNdkPkgRevision.Split('.'))`, API levels via `Split`/`Contains`, full commit hash via `GitCommitHash.CommitHash`, branch via `GitBranch.Branch`), and writes the file to `$(IntermediateOutputPath)XABuildConfig.cs`. The `<Compile Include>` lives inside the target so it resolves at execution time, when `IntermediateOutputPath` is final.
- `XABuildConfig` is now `public static class` instead of `internal static class`.
The three consumer csprojs lose their `<Compile Include="…XABuildConfig.cs" />` and now have a normal `<ProjectReference Include="…AndroidBuildConfig.csproj" />` (no `ReferenceOutputAssembly="False"`).
`build-tools/installers/create-installers.targets` ships `AndroidBuildConfig.dll` + `.pdb` alongside `Xamarin.Android.Build.Tasks.dll`.
## xaprepare cleanup
Removed dead code that only existed to feed the old `Get_XABuildConfig_cs` step:
- `Step_GenerateFiles.Get_XABuildConfig_cs` and its `GetMajor` / `GetMinor` locals
- `BuildInfo`: `NDKRevision`, `NDKVersionMajor`, `NDKVersionMinor`, `NDKVersionMicro`, `NDKVersion`, `XACommitHash`, `XABranch`, `GatherGitInfo`, `DetermineXACommitInfo`, `cachedNdkVersion`
- `Context`: the `if (SelectedScenario.NeedsGitBuildInfo) { await BuildInfo.GatherGitInfo … }` block
- `Scenario.NeedsGitBuildInfo` (and the `NeedsGitBuildInfo = true;` setters in `Scenario_Standard` and `Scenario_Required`)
- `BuildAndroidPlatforms.cs` — entire file (only contained constants used by the deleted code)
- `Utilities.ParseAndroidPkgRevision`
- `GitRunner.GetTopCommitHash` and `GitRunner.GetBranchName` (class retained — still used by `BuildInfo.DetermineLastVersionChangeCommit`)
## Files
**Added**
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
**Renamed/moved**
- `build-tools/scripts/XABuildConfig.cs.in` → `src/AndroidBuildConfig/XABuildConfig.cs.in` (`static class` → `public static class`)
**Modified**
- `src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Xamarin.ProjectTools.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj`
- `build-tools/installers/create-installers.targets`
- `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs`
- `build-tools/xaprepare/xaprepare/Application/BuildInfo.cs`
- `build-tools/xaprepare/xaprepare/Application/Context.cs`
- `build-tools/xaprepare/xaprepare/Application/Scenario.cs`
- `build-tools/xaprepare/xaprepare/Application/Utilities.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Required.cs`
- `build-tools/xaprepare/xaprepare/ToolRunners/GitRunner.cs`
- `build-tools/xaprepare/README.md`
**Deleted**
- `build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs`
## Verification
- `AndroidBuildConfig.csproj`: 0 warnings, 0 errors.
- `Xamarin.Android.Build.Tasks.csproj`: 0 errors, 85 pre-existing unrelated warnings (none for `XABuildConfig`).
- `Xamarin.Android.Build.Tests.csproj`: 0 errors, **7** warnings — down from ~22; all `CS0436 XABuildConfig` conflicts eliminated.
- `xaprepare.csproj`: 0 warnings, 0 errors.
- Generated `XABuildConfig.cs` is semantically identical to the pre-change xaprepare output. The only token difference is the intentional `static class` → `public static class`; everything else (NDK split, API-level major/minor split, supported-ABIs semicolon list, full commit hash, branch name, etc.) matches the previous baseline byte-for-byte.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11825)
Continues the incremental removal of `xaprepare` by moving the
`cgmanifest.json` generator out of the C# step
`Step_GenerateCGManifest` and into a YAML `pwsh:` step that runs only
on CI.
The file is consumed exclusively by the Azure DevOps Component
Governance Detection task (auto-injected on internal pipelines by
`eng/common/core-templates/job/job.yml`). It is not consumed by any
in-repo build target, so generating it from the C# Prepare step is no
longer necessary.
We cannot drop the file outright: `eng/common` ships CG infrastructure
but it is not yet wired to auto-discover submodules in our pipelines,
so the explicit `cgmanifest.json` is still the source of truth.
Files:
* Added: `build-tools/automation/yaml-templates/generate-cgmanifest.yaml`
* Modified: `build-windows-steps.yaml`, `build-macos-steps.yaml`,
`build-linux-steps.yaml`, `commercial-build.yaml` (call the new
template after the Prepare/`make jenkins` step)
* Modified: `Scenario_Standard.cs` (drop registration)
* Modified: `GitRunner.cs` (remove now-unused `ConfigList` and
`SubmoduleStatus` methods)
* Deleted: `Step_GenerateCGManifest.cs`
Verification: byte-for-byte diff of the YAML-generated
`cgmanifest.json` against the previous C# output on Debug:
Baseline=3144 New=3144
Total byte differences: 0
Precedent PRs in this stream: #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803,
#11821.
### Simplify generate-cgmanifest.yaml using ConvertTo-Json
Replace the hand-rolled StringBuilder JSON emission with PowerShell's
`ConvertTo-Json`. The output is no longer byte-identical to the
previous C# output (2-space indent instead of 4, and slightly
different whitespace), but it is still valid JSON matching the
component-detection-manifest schema. The Azure DevOps Component
Governance Detection task parses the file, so formatting does not
matter.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
On Windows, xaprepare's Step_GenerateFiles.Windows.cs writes
external/Java.Interop/bin/Build$(Configuration)/JdkInfo.props from
build-tools/xaprepare/xaprepare/Resources/JdkInfo.Windows.props.in.
But this file is immediately overwritten. The PrepareWindows.targets
Prepare flow runs, in order:
1. `dotnet xaprepare -a` — writes JdkInfo.props (this code).
2. `MSBuild Xamarin.Android.BootstrapTasks.sln` — does not read JdkInfo.props.
3. `MSBuild src/workloads/workloads.csproj` — does not read JdkInfo.props.
4. `CallTarget PrepareJavaInterop` → `dotnet build -t:Prepare Java.Interop.sln`
→ external/Java.Interop/build-tools/scripts/Prepare.targets → runs the
`JdkInfo` MSBuild task → overwrites JdkInfo.props with its own generated
content.
Nothing between step 1 and step 4 reads the file, and Java.Interop's Prepare
always regenerates it. Now that external/Java.Interop is in-tree, we can
safely delete the redundant write.
This is the smallest-diff removal:
* Delete Step_GenerateFiles.Windows.cs (the AddOSSpecificSteps partial).
* Delete Resources/JdkInfo.Windows.props.in.
* In Step_GenerateFiles.cs, drop the `partial void AddOSSpecificSteps`
declaration and collapse GetFilesToGenerate so `atBuildStart == false`
returns null. Ctor surface (atBuildStart, onlyRequired) is unchanged so
Scenario_Required.cs is unaffected.
* In Scenario_Standard.cs, remove the AddEndSteps override — the only
thing it did was schedule the now-empty Step_GenerateFiles(atBuildStart:
false).
Preserved (future slices will address these):
* Get_Configuration_OperatingSystem_props (D1).
* OperatingSystems/*.cs and Context.OS.* surface.
* PrepareWindows.targets, DotNet.targets, Java.Interop's Prepare.targets.
Verification:
* dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug
→ Build succeeded. 0 Warning(s). 0 Error(s).
* build.cmd -t:Prepare -c Debug (Windows, cold tree) → succeeds; the file
external/Java.Interop/bin/BuildDebug/JdkInfo.props exists.
* Compare-Object of the resulting JdkInfo.props before vs after this
change → byte-identical (1493 bytes, SHA256
DE59A8061B7657831788FFED7BC1DEECA442E9181605083A4553DE7AC8C003A1),
confirming Java.Interop's overwrite is what always ends up on disk.
* Grep audit under build-tools/xaprepare/: no remaining references to
Step_GenerateFiles.Windows, JdkInfo.Windows.props.in, or
AddOSSpecificSteps.
Follows previous xaprepare deletion slices #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821,
#11825, #11826.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jul 3, 2026
…xaprepare project (#11959)
Follow-up to #11956, which moved the JDK half of `Configuration.OperatingSystem.props` to Java.Interop's `JdkInfo.props`. The remaining NDK / OS-info half has zero real consumers, so this PR:
1. Deletes the last generator template (`Configuration.OperatingSystem.props.in`).
2. Cascades through `Step_GenerateFiles`, both `Scenario_*` classes (which now had zero steps), and every supporting `OperatingSystems/`, `Context.*OS.cs`, `EssentialTools.*`, `ToolRunners/*`, `Configurables.*`, `Application/*`, and `Main.cs` file that only existed to feed the scenarios.
3. Deletes the whole `build-tools/xaprepare/` project.
4. Patches every integration point (`Makefile`, `PrepareWindows.targets`, `BuildEverything.mk`, CI YAML, docs) so `build.cmd -t:Prepare` and `make prepare` still work end-to-end.
## `Configuration.OperatingSystem.props.in` placeholder audit
| Placeholder | Consumers outside the `.in` file | Action |
| --- | --- | --- |
| `HostOsName` | none | drop |
| `HostOsFlavor` | none | drop |
| `HostOsRelease` | none | drop |
| `HostBits` | none (`ArchiveBase.HostBits` in `src/Xamarin.Installer.AndroidSDK/` is an unrelated C# property) | drop |
| `NdkLlvmTag` | none (the NDK toolchain OS tag is resolved elsewhere via `_NdkToolchainOSTag` in `androidsdk.targets`) | drop |
| `HostCpuCount` | only `Configuration.props:72` via `$(MakeConcurrency)` | drop |
## `$(MakeConcurrency)` audit
The only definition was `Configuration.props:72`. A repo-wide grep of `.targets`, `.props`, `.projitems`, `Makefile`, and `.mk` files found zero consumers of the MSBuild property. The `MakeConcurrency` hits under `build-tools/xaprepare/` were an unrelated C# `Context.MakeConcurrency` property.
**Result:** dropped the `MakeConcurrency` MSBuild property entirely (no `$([System.Environment]::ProcessorCount)` replacement needed) and removed the `$(MakeConcurrency)` bullet in `Documentation/building/configuration.md`.
## xaprepare integration audit (grep-confirmed, patched here)
| Location | Change |
| --- | --- |
| `build-tools/xaprepare/` (entire tree) | **deleted** — 86 tracked files |
| `Configuration.props` | dropped `<Import>` of the generated OS props, dropped `MakeConcurrency`, tidied the "between xaprepare and package creation tools" comment |
| `.gitignore` | dropped `Configuration.OperatingSystem.props` |
| `build-tools/scripts/PrepareWindows.targets` | removed `_XAPrepareExe`, `_XAPrepareStandardArgs`, `_BuildXAPrepare` target, and the `Exec dotnet $(_XAPrepareExe)` line. Repointed `Prepare` at `_InstallDotNet`. Kept the space-in-path guard, BootstrapTasks / workloads MSBuilds, and `PrepareJavaInterop` |
| `Makefile` | dropped `PREPARE_PROJECT`, `PREPARE_NET_FX`, `PREPARE_ARGS`, `PREPARE_MSBUILD_FLAGS`, `PREPARE_SCENARIO`, `PREPARE_CI_PR`, `PREPARE_CI`, `_PREPARE_CI_MODE_*`, `_PREPARE_ARGS`, and all their conditionals. Dropped the `dotnet run --project xaprepare.csproj` line from `prepare`. Deleted the `prepare-help` target |
| `build-tools/scripts/BuildEverything.mk` | `jenkins` no longer branches on `PREPARE_CI_PR`/`PREPARE_CI`; just `$(MAKE) prepare && $(MAKE) leeroy` |
| `.github/workflows/copilot-setup-steps.yml` | dropped now-unused `PREPARE_CI=1` |
| `build-tools/automation/azure-pipelines-apidocs.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-linux-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-macos-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/commercial-build.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/copy-extra-result-files.yaml` | dropped `**/Configuration.OperatingSystem.props` glob and the stale `Step_CopyExtraResultFilesForCI` xaprepare-step comment |
| `build-tools/automation/yaml-templates/generate-cgmanifest.yaml` | dropped the stale `Step_GenerateCGManifest` xaprepare-step comment |
| `build-tools/automation/yaml-templates/setup-jdk-variables.yaml` | renamed `$xaPrepareJdkPath` → `$xaJdkPath` for hygiene |
| `Documentation/workflow/HowToAddNewApiLevel.md` | rewrote the "Add New Platform" section to point at `<_PlatformPackage>` entries in `src/androidsdk/androidsdk.targets` instead of `AndroidToolchain.cs`; updated the `--android-sdk-platforms=all` recipe to `dotnet-local build src/androidsdk/androidsdk.csproj -p:AndroidSdkPlatforms=all` |
| `Documentation/building/unix/dependencies.md` | JDK-version link now points at `$(MicrosoftOpenJDKVersion)` in `/Configuration.props` instead of the deleted `Configurables.cs` |
| `Documentation/building/configuration.md` | removed the `$(MakeConcurrency)` bullet |
**Historical breadcrumb comments left as-is** (still accurate and useful for git-archaeology):
- `.github/skills/update-tpn/SKILL.md`
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
- `src/androidsdk/androidsdk.targets`
- `src/native/cmake-config/cmake-config.csproj`
- `src/workloads/workloads.csproj`
## Verification
- `build.cmd Prepare` — succeeded end-to-end on Windows (0 warnings, 0 errors). The trimmed `Prepare` target ran through `_InstallDotNet`, the space-in-path guard, `Xamarin.Android.BootstrapTasks.sln`, `src/workloads/workloads.csproj`, and `PrepareJavaInterop`.
- `dotnet build src\Xamarin.Android.Build.Tasks\Xamarin.Android.Build.Tasks.csproj -c Debug` — 0 errors (93 pre-existing warnings from `src/Mono.Android/` and generated MCW, unrelated to this change).
- Repo-wide grep for `HostOsName`, `HostOsFlavor`, `HostOsRelease`, `HostCpuCount`, `NdkLlvmTag`, and the MSBuild `MakeConcurrency` property — clean.
- Repo-wide grep for `xaprepare` — clean apart from the five intentional historical breadcrumb comments listed above.
## Diff stat
102 files changed, 25 insertions(+), 7891 deletions(-).
## Precedent chain
Continues the multi-slice teardown started by #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821, #11825, #11826, #11945, #11946, #11956.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 31, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

ready-to-reviewThis PR is ready to review/merge, I think any CI failures are just flaky (ignorable).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@jonathanpeppers@simonrozsival
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[xaprepare] Use Microsoft.SourceLink.GitHub instead of hand-rolled SourceLink.json - #11821

Merged
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-adopt-sourcelink-github
Jun 30, 2026
Merged

[xaprepare] Use Microsoft.SourceLink.GitHub instead of hand-rolled SourceLink.json#11821
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-adopt-sourcelink-github

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Member

Summary

Stop generating bin/Build$(Configuration)/SourceLink.json from xaprepare and stop overriding $(SourceLink) in Configuration.props. Let Microsoft.SourceLink.GitHub (which is already pinned at 8.0.0 in Directory.Build.targets, but until now only Included in one project) produce SourceLink the canonical Arcade way for every project.

Changes

  • Directory.Build.targets — promoted Microsoft.SourceLink.GitHub 8.0.0 from a PackageReference Update to a broad PackageReference Include with PrivateAssets="All" so every project in the repo picks it up.
  • src/Microsoft.Android.Run/Microsoft.Android.Run.csproj — dropped the now-redundant explicit <PackageReference Include="Microsoft.SourceLink.GitHub" />.
  • Configuration.props — deleted the <PropertyGroup> that overrode $(SourceLink) with the path to the generated json file. The canonical package now sets $(SourceLink) itself.
  • build-tools/xaprepare/xaprepare/Application/GeneratedSourceLinkJsonFile.cs — deleted.
  • build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs — removed Get_SourceLink_Json, both references in GetFilesToGenerate, and the gitSubmodules / xaCommit fields plus the git/submodule prelude in Execute (no other generator in this file used them). Switched Execute from async back to a synchronous Task.FromResult since the only await was the deleted submodule walk.
  • build-tools/xaprepare/xaprepare/Application/GeneratedFile.cs — deleted the now-orphaned SkipGeneratedFile class (only caller was Get_SourceLink_Json).

Net: -99/+8 lines, one file deleted.

Verification

Built Mono.Android.csproj, Xamarin.Android.Build.Tasks.csproj, and xaprepare.csproj in Debug after a clean build.cmd Prepare. All succeeded with 0 errors.

Ran sourcelink print-json on bin\Debug\lib\packs\Microsoft.Android.Runtime.37.android\37.0.0\runtimes\android\lib\net11.0\Mono.Android.pdb:

{"documents":{
"<repo>\\*": "https://raw.githubusercontent.com/dotnet/android/138c93d5a5b369e5d9b6867607afefa7502cd787/*",
"<repo>\\external\\android-api-docs\\*": "https://raw.githubusercontent.com/dotnet/android-api-docs/d382c5bd406432083901e51a4e87cd677b8759d8/*",
"<repo>\\external\\constexpr-xxh3\\*": "https://raw.githubusercontent.com/chys87/constexpr-xxh3/aebcee75c8b6c2458fa8ae151754a8ba833bd697/*",
"<repo>\\external\\debugger-libs\\*": "https://raw.githubusercontent.com/mono/debugger-libs/e7fbb713d156d11193ed404783ad6fe9c4042a6d/*",
"<repo>\\external\\Java.Interop\\*": "https://raw.githubusercontent.com/dotnet/java-interop/8d544738ad294b4faf13d189eeeb02f0313e00b3/*",
"<repo>\\external\\libunwind\\*": "https://raw.githubusercontent.com/libunwind/libunwind/e97c9ef82f8b48d0c7f713be4fa7b15e634d76b8/*",
"<repo>\\external\\lz4\\*": "https://raw.githubusercontent.com/lz4/lz4/ebb370ca83af193212df4dcbadcc5d87bc0de2f0/*",
"<repo>\\external\\robin-map\\*": "https://raw.githubusercontent.com/xamarin/robin-map/d37a41003bfbc7e12e34601f93c18ca2ff6d7c07/*",
"<repo>\\external\\termux-elf-cleaner\\*": "https://raw.githubusercontent.com/termux/termux-elf-cleaner/ee5385e004a9d67bdc289e43939691b260e06b03/*",
"<repo>\\external\\xamarin-android-tools\\*": "https://raw.githubusercontent.com/dotnet/android-tools/367724d6ba93db20294681769de97b9cdecb58a0/*",
"<repo>\\external\\xxHash\\*": "https://raw.githubusercontent.com/Cyan4973/xxHash/bbb27a5efb85b92a0486cf361a8635715a53f6ba/*"
}}

Every submodule from .gitmodules is mapped to its correct upstream raw.githubusercontent.com URL — full parity with what GeneratedSourceLinkJsonFile produced before.

Out of scope

Step_GenerateCGManifest, GitSubmoduleInfo, GitRunner, and the GitCommit* prep tasks are still used by cgmanifest generation and XAVersionInfo.targets; they're intentionally left for a follow-up PR.

Precedent

Continues the xaprepare slim-down work in #11568, #11580, #11608, #11613, #11631, #11657, #11658, #11731, #11732, #11733, #11737, #11740, #11760, #11803.

…urceLink.json
Stop generating bin/Build$(Configuration)/SourceLink.json from xaprepare and stop overriding $(SourceLink) in Configuration.props. Promote Microsoft.SourceLink.GitHub from a PackageReference Update to a broad PackageReference Include in Directory.Build.targets so every project picks it up, then drop the explicit Include from Microsoft.Android.Run.csproj.
Verified with 'sourcelink print-json' on bin\Debug\lib\packs\Microsoft.Android.Runtime.37.android\37.0.0\runtimes\android\lib\net11.0\Mono.Android.pdb: the canonical package produces a documents map covering dotnet/android plus every submodule (Java.Interop, xamarin-android-tools, android-api-docs, constexpr-xxh3, debugger-libs, libunwind, lz4, robin-map, termux-elf-cleaner, xxHash) pointing at the correct upstream raw.githubusercontent.com URLs.
Step_GenerateCGManifest and GitSubmoduleInfo / GitRunner are intentionally left for a follow-up.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 30, 2026 14:07

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR switches the repo’s SourceLink generation to the standard Arcade/MSBuild approach by enabling Microsoft.SourceLink.GitHub repo-wide, and removes the now-redundant xaprepare-generated SourceLink.json plumbing.

Changes:

  • Add a repo-wide PackageReference to Microsoft.SourceLink.GitHub (PrivateAssets=All) via Directory.Build.targets, and remove the per-project reference from Microsoft.Android.Run.
  • Stop overriding $(SourceLink) in Configuration.props, letting the SourceLink package set it canonically.
  • Remove xaprepare’s SourceLink.json generator and related scaffolding (including the SkipGeneratedFile helper).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
Directory.Build.targetsAdds global Microsoft.SourceLink.GitHub package reference for SourceLink across the repo.
src/Microsoft.Android.Run/Microsoft.Android.Run.csprojRemoves redundant explicit SourceLink package reference.
Configuration.propsRemoves $(SourceLink) override pointing to generated SourceLink.json.
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.csRemoves SourceLink.json generation path and simplifies execution flow.
build-tools/xaprepare/xaprepare/Application/GeneratedSourceLinkJsonFile.csDeletes the hand-rolled SourceLink.json generator implementation.
build-tools/xaprepare/xaprepare/Application/GeneratedFile.csRemoves the now-orphaned SkipGeneratedFile helper type.
Comments suppressed due to low confidence (1)

build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs:52

  • Scenario_Required still adds new Step_GenerateFiles (atBuildStart: true, onlyRequired: true), but GetFilesToGenerate() now returns null for that case, so the step generates no files at all. That seems to contradict the scenario description (“generate build files”) and makes the scenario effectively a no-op after this PR.
 if (atBuildStart) {
if (onlyRequired) {
return null;
} else {
return new List <GeneratedFile> {
Get_Configuration_OperatingSystem_props (context),
Get_XABuildConfig_cs (context),
};
}

@jonathanpeppersjonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 30, 2026
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

Verified the CI build artifacts for this PR (build 1487951).

Downloaded nuget-unsigned-symbols, extracted the symbols .nupkgs, and ran sourcelink print-json on representative PDBs from across the SDK / Runtime / Ref packages. Every assembly's SourceLink covers dotnet/android plus all submodules:

Mono.Android.pdb (Microsoft.Android.Runtime.37.android symbols package):

{"documents":{
"/Users/cloudtest/vss/_work/1/s/android/*":"https://raw.githubusercontent.com/dotnet/android/917981be97def8f5d046c8b1b28dca25771d8198/*",
"/Users/cloudtest/vss/_work/1/s/android/external/android-api-docs/*":"https://raw.githubusercontent.com/dotnet/android-api-docs/d382c5bd406432083901e51a4e87cd677b8759d8/*",
"/Users/cloudtest/vss/_work/1/s/android/external/constexpr-xxh3/*":"https://raw.githubusercontent.com/chys87/constexpr-xxh3/aebcee75c8b6c2458fa8ae151754a8ba833bd697/*",
"/Users/cloudtest/vss/_work/1/s/android/external/debugger-libs/*":"https://raw.githubusercontent.com/mono/debugger-libs/e7fbb713d156d11193ed404783ad6fe9c4042a6d/*",
"/Users/cloudtest/vss/_work/1/s/android/external/Java.Interop/*":"https://raw.githubusercontent.com/dotnet/java-interop/8d544738ad294b4faf13d189eeeb02f0313e00b3/*",
"/Users/cloudtest/vss/_work/1/s/android/external/libunwind/*":"https://raw.githubusercontent.com/libunwind/libunwind/e97c9ef82f8b48d0c7f713be4fa7b15e634d76b8/*",
"/Users/cloudtest/vss/_work/1/s/android/external/lz4/*":"https://raw.githubusercontent.com/dotnet/lz4/ebb370ca83af193212df4dcbadcc5d87bc0de2f0/*",
"/Users/cloudtest/vss/_work/1/s/android/external/robin-map/*":"https://raw.githubusercontent.com/xamarin/robin-map/d37a41003bfbc7e12e34601f93c18ca2ff6d7c07/*",
"/Users/cloudtest/vss/_work/1/s/android/external/termux-elf-cleaner/*":"https://raw.githubusercontent.com/termux/termux-elf-cleaner/ee5385e004a9d67bdc289e43939691b260e06b03/*",
"/Users/cloudtest/vss/_work/1/s/android/external/xamarin-android-tools/*":"https://raw.githubusercontent.com/dotnet/android-tools/367724d6ba93db20294681769de97b9cdecb58a0/*",
"/Users/cloudtest/vss/_work/1/s/android/external/xxHash/*":"https://raw.githubusercontent.com/Cyan4973/xxHash/bbb27a5efb85b92a0486cf361a8635715a53f6ba/*"
}}

Same coverage on:

  • Xamarin.Android.Build.Tasks.pdb (Microsoft.Android.Sdk.Windows symbols) — repo + all 10 submodule mappings.
  • Microsoft.Android.Sdk.ILLink.pdb (Microsoft.Android.Sdk.Windows symbols) — repo + all 10 submodule mappings.
  • Java.Interop.pdb — own Java.Interop repo + its nested xamarin-android-tools submodule.

All URLs match .gitmodules exactly (including the dotnet/lz4 upstream). Microsoft.Android.Ref.37 produces a reference-only assembly with no embedded source link section, which is expected for ref assemblies.

@jonathanpeppers
jonathanpeppers merged commit b0fe694 into mainJun 30, 2026
41 checks passed
@jonathanpeppers
jonathanpeppers deleted the jonathanpeppers-adopt-sourcelink-github branch June 30, 2026 19:45
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11826)
## Summary
Moves `XABuildConfig.cs` generation out of `xaprepare` and into a new strong-named class library at `src/AndroidBuildConfig/AndroidBuildConfig.csproj` that produces `AndroidBuildConfig.dll`.
This continues the incremental removal of `xaprepare`, following the precedent set by `cmake-config.csproj` (#11760) and the recent batch #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11803, #11821, #11825.
It also fixes a long-standing wart: previously `XABuildConfig.cs` was `<Compile Include>`'d into three different assemblies (`Xamarin.Android.Build.Tasks`, `Xamarin.ProjectTools`, and `Xamarin.Android.Build.Tests`), so every test that mentioned `XABuildConfig` produced a `CS0436` "type conflicts with imported type" warning — about **22** of them.
Wrapping the type in its own assembly collapses it to a single definition that every consumer references normally. After this change `Xamarin.Android.Build.Tests` builds with **7** warnings (none for `XABuildConfig`).
## How it works
`src/AndroidBuildConfig/AndroidBuildConfig.csproj`:
- `Microsoft.NET.Sdk` / `netstandard2.0`, strong-named with `product.snk`.
- `ProjectReference`s `Xamarin.Android.Tools.AndroidSdk` (for the `AndroidTargetArch` enum used by the template).
- `<UsingTask>`s `ReplaceFileContents`, `GitCommitHash`, and `GitBranch` from `$(PrepTasksAssembly)`, all with `TaskFactory="TaskHostFactory" Runtime="NET"` per repo convention.
- The `_GenerateXABuildConfig` target runs `BeforeTargets="BeforeCompile;CoreCompile"`, computes every substitution from MSBuild properties already exposed by `Configuration.props` (NDK major/minor/micro via `$(_XAAndroidNdkPkgRevision.Split('.'))`, API levels via `Split`/`Contains`, full commit hash via `GitCommitHash.CommitHash`, branch via `GitBranch.Branch`), and writes the file to `$(IntermediateOutputPath)XABuildConfig.cs`. The `<Compile Include>` lives inside the target so it resolves at execution time, when `IntermediateOutputPath` is final.
- `XABuildConfig` is now `public static class` instead of `internal static class`.
The three consumer csprojs lose their `<Compile Include="…XABuildConfig.cs" />` and now have a normal `<ProjectReference Include="…AndroidBuildConfig.csproj" />` (no `ReferenceOutputAssembly="False"`).
`build-tools/installers/create-installers.targets` ships `AndroidBuildConfig.dll` + `.pdb` alongside `Xamarin.Android.Build.Tasks.dll`.
## xaprepare cleanup
Removed dead code that only existed to feed the old `Get_XABuildConfig_cs` step:
- `Step_GenerateFiles.Get_XABuildConfig_cs` and its `GetMajor` / `GetMinor` locals
- `BuildInfo`: `NDKRevision`, `NDKVersionMajor`, `NDKVersionMinor`, `NDKVersionMicro`, `NDKVersion`, `XACommitHash`, `XABranch`, `GatherGitInfo`, `DetermineXACommitInfo`, `cachedNdkVersion`
- `Context`: the `if (SelectedScenario.NeedsGitBuildInfo) { await BuildInfo.GatherGitInfo … }` block
- `Scenario.NeedsGitBuildInfo` (and the `NeedsGitBuildInfo = true;` setters in `Scenario_Standard` and `Scenario_Required`)
- `BuildAndroidPlatforms.cs` — entire file (only contained constants used by the deleted code)
- `Utilities.ParseAndroidPkgRevision`
- `GitRunner.GetTopCommitHash` and `GitRunner.GetBranchName` (class retained — still used by `BuildInfo.DetermineLastVersionChangeCommit`)
## Files
**Added**
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
**Renamed/moved**
- `build-tools/scripts/XABuildConfig.cs.in` → `src/AndroidBuildConfig/XABuildConfig.cs.in` (`static class` → `public static class`)
**Modified**
- `src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Xamarin.ProjectTools.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj`
- `build-tools/installers/create-installers.targets`
- `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs`
- `build-tools/xaprepare/xaprepare/Application/BuildInfo.cs`
- `build-tools/xaprepare/xaprepare/Application/Context.cs`
- `build-tools/xaprepare/xaprepare/Application/Scenario.cs`
- `build-tools/xaprepare/xaprepare/Application/Utilities.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Required.cs`
- `build-tools/xaprepare/xaprepare/ToolRunners/GitRunner.cs`
- `build-tools/xaprepare/README.md`
**Deleted**
- `build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs`
## Verification
- `AndroidBuildConfig.csproj`: 0 warnings, 0 errors.
- `Xamarin.Android.Build.Tasks.csproj`: 0 errors, 85 pre-existing unrelated warnings (none for `XABuildConfig`).
- `Xamarin.Android.Build.Tests.csproj`: 0 errors, **7** warnings — down from ~22; all `CS0436 XABuildConfig` conflicts eliminated.
- `xaprepare.csproj`: 0 warnings, 0 errors.
- Generated `XABuildConfig.cs` is semantically identical to the pre-change xaprepare output. The only token difference is the intentional `static class` → `public static class`; everything else (NDK split, API-level major/minor split, supported-ABIs semicolon list, full commit hash, branch name, etc.) matches the previous baseline byte-for-byte.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11825)
Continues the incremental removal of `xaprepare` by moving the
`cgmanifest.json` generator out of the C# step
`Step_GenerateCGManifest` and into a YAML `pwsh:` step that runs only
on CI.
The file is consumed exclusively by the Azure DevOps Component
Governance Detection task (auto-injected on internal pipelines by
`eng/common/core-templates/job/job.yml`). It is not consumed by any
in-repo build target, so generating it from the C# Prepare step is no
longer necessary.
We cannot drop the file outright: `eng/common` ships CG infrastructure
but it is not yet wired to auto-discover submodules in our pipelines,
so the explicit `cgmanifest.json` is still the source of truth.
Files:
* Added: `build-tools/automation/yaml-templates/generate-cgmanifest.yaml`
* Modified: `build-windows-steps.yaml`, `build-macos-steps.yaml`,
`build-linux-steps.yaml`, `commercial-build.yaml` (call the new
template after the Prepare/`make jenkins` step)
* Modified: `Scenario_Standard.cs` (drop registration)
* Modified: `GitRunner.cs` (remove now-unused `ConfigList` and
`SubmoduleStatus` methods)
* Deleted: `Step_GenerateCGManifest.cs`
Verification: byte-for-byte diff of the YAML-generated
`cgmanifest.json` against the previous C# output on Debug:
Baseline=3144 New=3144
Total byte differences: 0
Precedent PRs in this stream: #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803,
#11821.
### Simplify generate-cgmanifest.yaml using ConvertTo-Json
Replace the hand-rolled StringBuilder JSON emission with PowerShell's
`ConvertTo-Json`. The output is no longer byte-identical to the
previous C# output (2-space indent instead of 4, and slightly
different whitespace), but it is still valid JSON matching the
component-detection-manifest schema. The Azure DevOps Component
Governance Detection task parses the file, so formatting does not
matter.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
On Windows, xaprepare's Step_GenerateFiles.Windows.cs writes
external/Java.Interop/bin/Build$(Configuration)/JdkInfo.props from
build-tools/xaprepare/xaprepare/Resources/JdkInfo.Windows.props.in.
But this file is immediately overwritten. The PrepareWindows.targets
Prepare flow runs, in order:
1. `dotnet xaprepare -a` — writes JdkInfo.props (this code).
2. `MSBuild Xamarin.Android.BootstrapTasks.sln` — does not read JdkInfo.props.
3. `MSBuild src/workloads/workloads.csproj` — does not read JdkInfo.props.
4. `CallTarget PrepareJavaInterop` → `dotnet build -t:Prepare Java.Interop.sln`
→ external/Java.Interop/build-tools/scripts/Prepare.targets → runs the
`JdkInfo` MSBuild task → overwrites JdkInfo.props with its own generated
content.
Nothing between step 1 and step 4 reads the file, and Java.Interop's Prepare
always regenerates it. Now that external/Java.Interop is in-tree, we can
safely delete the redundant write.
This is the smallest-diff removal:
* Delete Step_GenerateFiles.Windows.cs (the AddOSSpecificSteps partial).
* Delete Resources/JdkInfo.Windows.props.in.
* In Step_GenerateFiles.cs, drop the `partial void AddOSSpecificSteps`
declaration and collapse GetFilesToGenerate so `atBuildStart == false`
returns null. Ctor surface (atBuildStart, onlyRequired) is unchanged so
Scenario_Required.cs is unaffected.
* In Scenario_Standard.cs, remove the AddEndSteps override — the only
thing it did was schedule the now-empty Step_GenerateFiles(atBuildStart:
false).
Preserved (future slices will address these):
* Get_Configuration_OperatingSystem_props (D1).
* OperatingSystems/*.cs and Context.OS.* surface.
* PrepareWindows.targets, DotNet.targets, Java.Interop's Prepare.targets.
Verification:
* dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug
→ Build succeeded. 0 Warning(s). 0 Error(s).
* build.cmd -t:Prepare -c Debug (Windows, cold tree) → succeeds; the file
external/Java.Interop/bin/BuildDebug/JdkInfo.props exists.
* Compare-Object of the resulting JdkInfo.props before vs after this
change → byte-identical (1493 bytes, SHA256
DE59A8061B7657831788FFED7BC1DEECA442E9181605083A4553DE7AC8C003A1),
confirming Java.Interop's overwrite is what always ends up on disk.
* Grep audit under build-tools/xaprepare/: no remaining references to
Step_GenerateFiles.Windows, JdkInfo.Windows.props.in, or
AddOSSpecificSteps.
Follows previous xaprepare deletion slices #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821,
#11825, #11826.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jul 3, 2026
…xaprepare project (#11959)
Follow-up to #11956, which moved the JDK half of `Configuration.OperatingSystem.props` to Java.Interop's `JdkInfo.props`. The remaining NDK / OS-info half has zero real consumers, so this PR:
1. Deletes the last generator template (`Configuration.OperatingSystem.props.in`).
2. Cascades through `Step_GenerateFiles`, both `Scenario_*` classes (which now had zero steps), and every supporting `OperatingSystems/`, `Context.*OS.cs`, `EssentialTools.*`, `ToolRunners/*`, `Configurables.*`, `Application/*`, and `Main.cs` file that only existed to feed the scenarios.
3. Deletes the whole `build-tools/xaprepare/` project.
4. Patches every integration point (`Makefile`, `PrepareWindows.targets`, `BuildEverything.mk`, CI YAML, docs) so `build.cmd -t:Prepare` and `make prepare` still work end-to-end.
## `Configuration.OperatingSystem.props.in` placeholder audit
| Placeholder | Consumers outside the `.in` file | Action |
| --- | --- | --- |
| `HostOsName` | none | drop |
| `HostOsFlavor` | none | drop |
| `HostOsRelease` | none | drop |
| `HostBits` | none (`ArchiveBase.HostBits` in `src/Xamarin.Installer.AndroidSDK/` is an unrelated C# property) | drop |
| `NdkLlvmTag` | none (the NDK toolchain OS tag is resolved elsewhere via `_NdkToolchainOSTag` in `androidsdk.targets`) | drop |
| `HostCpuCount` | only `Configuration.props:72` via `$(MakeConcurrency)` | drop |
## `$(MakeConcurrency)` audit
The only definition was `Configuration.props:72`. A repo-wide grep of `.targets`, `.props`, `.projitems`, `Makefile`, and `.mk` files found zero consumers of the MSBuild property. The `MakeConcurrency` hits under `build-tools/xaprepare/` were an unrelated C# `Context.MakeConcurrency` property.
**Result:** dropped the `MakeConcurrency` MSBuild property entirely (no `$([System.Environment]::ProcessorCount)` replacement needed) and removed the `$(MakeConcurrency)` bullet in `Documentation/building/configuration.md`.
## xaprepare integration audit (grep-confirmed, patched here)
| Location | Change |
| --- | --- |
| `build-tools/xaprepare/` (entire tree) | **deleted** — 86 tracked files |
| `Configuration.props` | dropped `<Import>` of the generated OS props, dropped `MakeConcurrency`, tidied the "between xaprepare and package creation tools" comment |
| `.gitignore` | dropped `Configuration.OperatingSystem.props` |
| `build-tools/scripts/PrepareWindows.targets` | removed `_XAPrepareExe`, `_XAPrepareStandardArgs`, `_BuildXAPrepare` target, and the `Exec dotnet $(_XAPrepareExe)` line. Repointed `Prepare` at `_InstallDotNet`. Kept the space-in-path guard, BootstrapTasks / workloads MSBuilds, and `PrepareJavaInterop` |
| `Makefile` | dropped `PREPARE_PROJECT`, `PREPARE_NET_FX`, `PREPARE_ARGS`, `PREPARE_MSBUILD_FLAGS`, `PREPARE_SCENARIO`, `PREPARE_CI_PR`, `PREPARE_CI`, `_PREPARE_CI_MODE_*`, `_PREPARE_ARGS`, and all their conditionals. Dropped the `dotnet run --project xaprepare.csproj` line from `prepare`. Deleted the `prepare-help` target |
| `build-tools/scripts/BuildEverything.mk` | `jenkins` no longer branches on `PREPARE_CI_PR`/`PREPARE_CI`; just `$(MAKE) prepare && $(MAKE) leeroy` |
| `.github/workflows/copilot-setup-steps.yml` | dropped now-unused `PREPARE_CI=1` |
| `build-tools/automation/azure-pipelines-apidocs.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-linux-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-macos-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/commercial-build.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/copy-extra-result-files.yaml` | dropped `**/Configuration.OperatingSystem.props` glob and the stale `Step_CopyExtraResultFilesForCI` xaprepare-step comment |
| `build-tools/automation/yaml-templates/generate-cgmanifest.yaml` | dropped the stale `Step_GenerateCGManifest` xaprepare-step comment |
| `build-tools/automation/yaml-templates/setup-jdk-variables.yaml` | renamed `$xaPrepareJdkPath` → `$xaJdkPath` for hygiene |
| `Documentation/workflow/HowToAddNewApiLevel.md` | rewrote the "Add New Platform" section to point at `<_PlatformPackage>` entries in `src/androidsdk/androidsdk.targets` instead of `AndroidToolchain.cs`; updated the `--android-sdk-platforms=all` recipe to `dotnet-local build src/androidsdk/androidsdk.csproj -p:AndroidSdkPlatforms=all` |
| `Documentation/building/unix/dependencies.md` | JDK-version link now points at `$(MicrosoftOpenJDKVersion)` in `/Configuration.props` instead of the deleted `Configurables.cs` |
| `Documentation/building/configuration.md` | removed the `$(MakeConcurrency)` bullet |
**Historical breadcrumb comments left as-is** (still accurate and useful for git-archaeology):
- `.github/skills/update-tpn/SKILL.md`
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
- `src/androidsdk/androidsdk.targets`
- `src/native/cmake-config/cmake-config.csproj`
- `src/workloads/workloads.csproj`
## Verification
- `build.cmd Prepare` — succeeded end-to-end on Windows (0 warnings, 0 errors). The trimmed `Prepare` target ran through `_InstallDotNet`, the space-in-path guard, `Xamarin.Android.BootstrapTasks.sln`, `src/workloads/workloads.csproj`, and `PrepareJavaInterop`.
- `dotnet build src\Xamarin.Android.Build.Tasks\Xamarin.Android.Build.Tasks.csproj -c Debug` — 0 errors (93 pre-existing warnings from `src/Mono.Android/` and generated MCW, unrelated to this change).
- Repo-wide grep for `HostOsName`, `HostOsFlavor`, `HostOsRelease`, `HostCpuCount`, `NdkLlvmTag`, and the MSBuild `MakeConcurrency` property — clean.
- Repo-wide grep for `xaprepare` — clean apart from the five intentional historical breadcrumb comments listed above.
## Diff stat
102 files changed, 25 insertions(+), 7891 deletions(-).
## Precedent chain
Continues the multi-slice teardown started by #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821, #11825, #11826, #11945, #11946, #11956.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 31, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

ready-to-reviewThis PR is ready to review/merge, I think any CI failures are just flaky (ignorable).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@jonathanpeppers@simonrozsival
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[xaprepare] Use Microsoft.SourceLink.GitHub instead of hand-rolled SourceLink.json - #11821

Merged
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-adopt-sourcelink-github
Jun 30, 2026
Merged

[xaprepare] Use Microsoft.SourceLink.GitHub instead of hand-rolled SourceLink.json#11821
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-adopt-sourcelink-github

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Member

Summary

Stop generating bin/Build$(Configuration)/SourceLink.json from xaprepare and stop overriding $(SourceLink) in Configuration.props. Let Microsoft.SourceLink.GitHub (which is already pinned at 8.0.0 in Directory.Build.targets, but until now only Included in one project) produce SourceLink the canonical Arcade way for every project.

Changes

  • Directory.Build.targets — promoted Microsoft.SourceLink.GitHub 8.0.0 from a PackageReference Update to a broad PackageReference Include with PrivateAssets="All" so every project in the repo picks it up.
  • src/Microsoft.Android.Run/Microsoft.Android.Run.csproj — dropped the now-redundant explicit <PackageReference Include="Microsoft.SourceLink.GitHub" />.
  • Configuration.props — deleted the <PropertyGroup> that overrode $(SourceLink) with the path to the generated json file. The canonical package now sets $(SourceLink) itself.
  • build-tools/xaprepare/xaprepare/Application/GeneratedSourceLinkJsonFile.cs — deleted.
  • build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs — removed Get_SourceLink_Json, both references in GetFilesToGenerate, and the gitSubmodules / xaCommit fields plus the git/submodule prelude in Execute (no other generator in this file used them). Switched Execute from async back to a synchronous Task.FromResult since the only await was the deleted submodule walk.
  • build-tools/xaprepare/xaprepare/Application/GeneratedFile.cs — deleted the now-orphaned SkipGeneratedFile class (only caller was Get_SourceLink_Json).

Net: -99/+8 lines, one file deleted.

Verification

Built Mono.Android.csproj, Xamarin.Android.Build.Tasks.csproj, and xaprepare.csproj in Debug after a clean build.cmd Prepare. All succeeded with 0 errors.

Ran sourcelink print-json on bin\Debug\lib\packs\Microsoft.Android.Runtime.37.android\37.0.0\runtimes\android\lib\net11.0\Mono.Android.pdb:

{"documents":{
"<repo>\\*": "https://raw.githubusercontent.com/dotnet/android/138c93d5a5b369e5d9b6867607afefa7502cd787/*",
"<repo>\\external\\android-api-docs\\*": "https://raw.githubusercontent.com/dotnet/android-api-docs/d382c5bd406432083901e51a4e87cd677b8759d8/*",
"<repo>\\external\\constexpr-xxh3\\*": "https://raw.githubusercontent.com/chys87/constexpr-xxh3/aebcee75c8b6c2458fa8ae151754a8ba833bd697/*",
"<repo>\\external\\debugger-libs\\*": "https://raw.githubusercontent.com/mono/debugger-libs/e7fbb713d156d11193ed404783ad6fe9c4042a6d/*",
"<repo>\\external\\Java.Interop\\*": "https://raw.githubusercontent.com/dotnet/java-interop/8d544738ad294b4faf13d189eeeb02f0313e00b3/*",
"<repo>\\external\\libunwind\\*": "https://raw.githubusercontent.com/libunwind/libunwind/e97c9ef82f8b48d0c7f713be4fa7b15e634d76b8/*",
"<repo>\\external\\lz4\\*": "https://raw.githubusercontent.com/lz4/lz4/ebb370ca83af193212df4dcbadcc5d87bc0de2f0/*",
"<repo>\\external\\robin-map\\*": "https://raw.githubusercontent.com/xamarin/robin-map/d37a41003bfbc7e12e34601f93c18ca2ff6d7c07/*",
"<repo>\\external\\termux-elf-cleaner\\*": "https://raw.githubusercontent.com/termux/termux-elf-cleaner/ee5385e004a9d67bdc289e43939691b260e06b03/*",
"<repo>\\external\\xamarin-android-tools\\*": "https://raw.githubusercontent.com/dotnet/android-tools/367724d6ba93db20294681769de97b9cdecb58a0/*",
"<repo>\\external\\xxHash\\*": "https://raw.githubusercontent.com/Cyan4973/xxHash/bbb27a5efb85b92a0486cf361a8635715a53f6ba/*"
}}

Every submodule from .gitmodules is mapped to its correct upstream raw.githubusercontent.com URL — full parity with what GeneratedSourceLinkJsonFile produced before.

Out of scope

Step_GenerateCGManifest, GitSubmoduleInfo, GitRunner, and the GitCommit* prep tasks are still used by cgmanifest generation and XAVersionInfo.targets; they're intentionally left for a follow-up PR.

Precedent

Continues the xaprepare slim-down work in #11568, #11580, #11608, #11613, #11631, #11657, #11658, #11731, #11732, #11733, #11737, #11740, #11760, #11803.

…urceLink.json
Stop generating bin/Build$(Configuration)/SourceLink.json from xaprepare and stop overriding $(SourceLink) in Configuration.props. Promote Microsoft.SourceLink.GitHub from a PackageReference Update to a broad PackageReference Include in Directory.Build.targets so every project picks it up, then drop the explicit Include from Microsoft.Android.Run.csproj.
Verified with 'sourcelink print-json' on bin\Debug\lib\packs\Microsoft.Android.Runtime.37.android\37.0.0\runtimes\android\lib\net11.0\Mono.Android.pdb: the canonical package produces a documents map covering dotnet/android plus every submodule (Java.Interop, xamarin-android-tools, android-api-docs, constexpr-xxh3, debugger-libs, libunwind, lz4, robin-map, termux-elf-cleaner, xxHash) pointing at the correct upstream raw.githubusercontent.com URLs.
Step_GenerateCGManifest and GitSubmoduleInfo / GitRunner are intentionally left for a follow-up.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 30, 2026 14:07

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR switches the repo’s SourceLink generation to the standard Arcade/MSBuild approach by enabling Microsoft.SourceLink.GitHub repo-wide, and removes the now-redundant xaprepare-generated SourceLink.json plumbing.

Changes:

  • Add a repo-wide PackageReference to Microsoft.SourceLink.GitHub (PrivateAssets=All) via Directory.Build.targets, and remove the per-project reference from Microsoft.Android.Run.
  • Stop overriding $(SourceLink) in Configuration.props, letting the SourceLink package set it canonically.
  • Remove xaprepare’s SourceLink.json generator and related scaffolding (including the SkipGeneratedFile helper).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
Directory.Build.targetsAdds global Microsoft.SourceLink.GitHub package reference for SourceLink across the repo.
src/Microsoft.Android.Run/Microsoft.Android.Run.csprojRemoves redundant explicit SourceLink package reference.
Configuration.propsRemoves $(SourceLink) override pointing to generated SourceLink.json.
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.csRemoves SourceLink.json generation path and simplifies execution flow.
build-tools/xaprepare/xaprepare/Application/GeneratedSourceLinkJsonFile.csDeletes the hand-rolled SourceLink.json generator implementation.
build-tools/xaprepare/xaprepare/Application/GeneratedFile.csRemoves the now-orphaned SkipGeneratedFile helper type.
Comments suppressed due to low confidence (1)

build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs:52

  • Scenario_Required still adds new Step_GenerateFiles (atBuildStart: true, onlyRequired: true), but GetFilesToGenerate() now returns null for that case, so the step generates no files at all. That seems to contradict the scenario description (“generate build files”) and makes the scenario effectively a no-op after this PR.
 if (atBuildStart) {
if (onlyRequired) {
return null;
} else {
return new List <GeneratedFile> {
Get_Configuration_OperatingSystem_props (context),
Get_XABuildConfig_cs (context),
};
}

@jonathanpeppersjonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 30, 2026
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

Verified the CI build artifacts for this PR (build 1487951).

Downloaded nuget-unsigned-symbols, extracted the symbols .nupkgs, and ran sourcelink print-json on representative PDBs from across the SDK / Runtime / Ref packages. Every assembly's SourceLink covers dotnet/android plus all submodules:

Mono.Android.pdb (Microsoft.Android.Runtime.37.android symbols package):

{"documents":{
"/Users/cloudtest/vss/_work/1/s/android/*":"https://raw.githubusercontent.com/dotnet/android/917981be97def8f5d046c8b1b28dca25771d8198/*",
"/Users/cloudtest/vss/_work/1/s/android/external/android-api-docs/*":"https://raw.githubusercontent.com/dotnet/android-api-docs/d382c5bd406432083901e51a4e87cd677b8759d8/*",
"/Users/cloudtest/vss/_work/1/s/android/external/constexpr-xxh3/*":"https://raw.githubusercontent.com/chys87/constexpr-xxh3/aebcee75c8b6c2458fa8ae151754a8ba833bd697/*",
"/Users/cloudtest/vss/_work/1/s/android/external/debugger-libs/*":"https://raw.githubusercontent.com/mono/debugger-libs/e7fbb713d156d11193ed404783ad6fe9c4042a6d/*",
"/Users/cloudtest/vss/_work/1/s/android/external/Java.Interop/*":"https://raw.githubusercontent.com/dotnet/java-interop/8d544738ad294b4faf13d189eeeb02f0313e00b3/*",
"/Users/cloudtest/vss/_work/1/s/android/external/libunwind/*":"https://raw.githubusercontent.com/libunwind/libunwind/e97c9ef82f8b48d0c7f713be4fa7b15e634d76b8/*",
"/Users/cloudtest/vss/_work/1/s/android/external/lz4/*":"https://raw.githubusercontent.com/dotnet/lz4/ebb370ca83af193212df4dcbadcc5d87bc0de2f0/*",
"/Users/cloudtest/vss/_work/1/s/android/external/robin-map/*":"https://raw.githubusercontent.com/xamarin/robin-map/d37a41003bfbc7e12e34601f93c18ca2ff6d7c07/*",
"/Users/cloudtest/vss/_work/1/s/android/external/termux-elf-cleaner/*":"https://raw.githubusercontent.com/termux/termux-elf-cleaner/ee5385e004a9d67bdc289e43939691b260e06b03/*",
"/Users/cloudtest/vss/_work/1/s/android/external/xamarin-android-tools/*":"https://raw.githubusercontent.com/dotnet/android-tools/367724d6ba93db20294681769de97b9cdecb58a0/*",
"/Users/cloudtest/vss/_work/1/s/android/external/xxHash/*":"https://raw.githubusercontent.com/Cyan4973/xxHash/bbb27a5efb85b92a0486cf361a8635715a53f6ba/*"
}}

Same coverage on:

  • Xamarin.Android.Build.Tasks.pdb (Microsoft.Android.Sdk.Windows symbols) — repo + all 10 submodule mappings.
  • Microsoft.Android.Sdk.ILLink.pdb (Microsoft.Android.Sdk.Windows symbols) — repo + all 10 submodule mappings.
  • Java.Interop.pdb — own Java.Interop repo + its nested xamarin-android-tools submodule.

All URLs match .gitmodules exactly (including the dotnet/lz4 upstream). Microsoft.Android.Ref.37 produces a reference-only assembly with no embedded source link section, which is expected for ref assemblies.

@jonathanpeppers
jonathanpeppers merged commit b0fe694 into mainJun 30, 2026
41 checks passed
@jonathanpeppers
jonathanpeppers deleted the jonathanpeppers-adopt-sourcelink-github branch June 30, 2026 19:45
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11826)
## Summary
Moves `XABuildConfig.cs` generation out of `xaprepare` and into a new strong-named class library at `src/AndroidBuildConfig/AndroidBuildConfig.csproj` that produces `AndroidBuildConfig.dll`.
This continues the incremental removal of `xaprepare`, following the precedent set by `cmake-config.csproj` (#11760) and the recent batch #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11803, #11821, #11825.
It also fixes a long-standing wart: previously `XABuildConfig.cs` was `<Compile Include>`'d into three different assemblies (`Xamarin.Android.Build.Tasks`, `Xamarin.ProjectTools`, and `Xamarin.Android.Build.Tests`), so every test that mentioned `XABuildConfig` produced a `CS0436` "type conflicts with imported type" warning — about **22** of them.
Wrapping the type in its own assembly collapses it to a single definition that every consumer references normally. After this change `Xamarin.Android.Build.Tests` builds with **7** warnings (none for `XABuildConfig`).
## How it works
`src/AndroidBuildConfig/AndroidBuildConfig.csproj`:
- `Microsoft.NET.Sdk` / `netstandard2.0`, strong-named with `product.snk`.
- `ProjectReference`s `Xamarin.Android.Tools.AndroidSdk` (for the `AndroidTargetArch` enum used by the template).
- `<UsingTask>`s `ReplaceFileContents`, `GitCommitHash`, and `GitBranch` from `$(PrepTasksAssembly)`, all with `TaskFactory="TaskHostFactory" Runtime="NET"` per repo convention.
- The `_GenerateXABuildConfig` target runs `BeforeTargets="BeforeCompile;CoreCompile"`, computes every substitution from MSBuild properties already exposed by `Configuration.props` (NDK major/minor/micro via `$(_XAAndroidNdkPkgRevision.Split('.'))`, API levels via `Split`/`Contains`, full commit hash via `GitCommitHash.CommitHash`, branch via `GitBranch.Branch`), and writes the file to `$(IntermediateOutputPath)XABuildConfig.cs`. The `<Compile Include>` lives inside the target so it resolves at execution time, when `IntermediateOutputPath` is final.
- `XABuildConfig` is now `public static class` instead of `internal static class`.
The three consumer csprojs lose their `<Compile Include="…XABuildConfig.cs" />` and now have a normal `<ProjectReference Include="…AndroidBuildConfig.csproj" />` (no `ReferenceOutputAssembly="False"`).
`build-tools/installers/create-installers.targets` ships `AndroidBuildConfig.dll` + `.pdb` alongside `Xamarin.Android.Build.Tasks.dll`.
## xaprepare cleanup
Removed dead code that only existed to feed the old `Get_XABuildConfig_cs` step:
- `Step_GenerateFiles.Get_XABuildConfig_cs` and its `GetMajor` / `GetMinor` locals
- `BuildInfo`: `NDKRevision`, `NDKVersionMajor`, `NDKVersionMinor`, `NDKVersionMicro`, `NDKVersion`, `XACommitHash`, `XABranch`, `GatherGitInfo`, `DetermineXACommitInfo`, `cachedNdkVersion`
- `Context`: the `if (SelectedScenario.NeedsGitBuildInfo) { await BuildInfo.GatherGitInfo … }` block
- `Scenario.NeedsGitBuildInfo` (and the `NeedsGitBuildInfo = true;` setters in `Scenario_Standard` and `Scenario_Required`)
- `BuildAndroidPlatforms.cs` — entire file (only contained constants used by the deleted code)
- `Utilities.ParseAndroidPkgRevision`
- `GitRunner.GetTopCommitHash` and `GitRunner.GetBranchName` (class retained — still used by `BuildInfo.DetermineLastVersionChangeCommit`)
## Files
**Added**
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
**Renamed/moved**
- `build-tools/scripts/XABuildConfig.cs.in` → `src/AndroidBuildConfig/XABuildConfig.cs.in` (`static class` → `public static class`)
**Modified**
- `src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Xamarin.ProjectTools.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj`
- `build-tools/installers/create-installers.targets`
- `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs`
- `build-tools/xaprepare/xaprepare/Application/BuildInfo.cs`
- `build-tools/xaprepare/xaprepare/Application/Context.cs`
- `build-tools/xaprepare/xaprepare/Application/Scenario.cs`
- `build-tools/xaprepare/xaprepare/Application/Utilities.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Required.cs`
- `build-tools/xaprepare/xaprepare/ToolRunners/GitRunner.cs`
- `build-tools/xaprepare/README.md`
**Deleted**
- `build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs`
## Verification
- `AndroidBuildConfig.csproj`: 0 warnings, 0 errors.
- `Xamarin.Android.Build.Tasks.csproj`: 0 errors, 85 pre-existing unrelated warnings (none for `XABuildConfig`).
- `Xamarin.Android.Build.Tests.csproj`: 0 errors, **7** warnings — down from ~22; all `CS0436 XABuildConfig` conflicts eliminated.
- `xaprepare.csproj`: 0 warnings, 0 errors.
- Generated `XABuildConfig.cs` is semantically identical to the pre-change xaprepare output. The only token difference is the intentional `static class` → `public static class`; everything else (NDK split, API-level major/minor split, supported-ABIs semicolon list, full commit hash, branch name, etc.) matches the previous baseline byte-for-byte.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11825)
Continues the incremental removal of `xaprepare` by moving the
`cgmanifest.json` generator out of the C# step
`Step_GenerateCGManifest` and into a YAML `pwsh:` step that runs only
on CI.
The file is consumed exclusively by the Azure DevOps Component
Governance Detection task (auto-injected on internal pipelines by
`eng/common/core-templates/job/job.yml`). It is not consumed by any
in-repo build target, so generating it from the C# Prepare step is no
longer necessary.
We cannot drop the file outright: `eng/common` ships CG infrastructure
but it is not yet wired to auto-discover submodules in our pipelines,
so the explicit `cgmanifest.json` is still the source of truth.
Files:
* Added: `build-tools/automation/yaml-templates/generate-cgmanifest.yaml`
* Modified: `build-windows-steps.yaml`, `build-macos-steps.yaml`,
`build-linux-steps.yaml`, `commercial-build.yaml` (call the new
template after the Prepare/`make jenkins` step)
* Modified: `Scenario_Standard.cs` (drop registration)
* Modified: `GitRunner.cs` (remove now-unused `ConfigList` and
`SubmoduleStatus` methods)
* Deleted: `Step_GenerateCGManifest.cs`
Verification: byte-for-byte diff of the YAML-generated
`cgmanifest.json` against the previous C# output on Debug:
Baseline=3144 New=3144
Total byte differences: 0
Precedent PRs in this stream: #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803,
#11821.
### Simplify generate-cgmanifest.yaml using ConvertTo-Json
Replace the hand-rolled StringBuilder JSON emission with PowerShell's
`ConvertTo-Json`. The output is no longer byte-identical to the
previous C# output (2-space indent instead of 4, and slightly
different whitespace), but it is still valid JSON matching the
component-detection-manifest schema. The Azure DevOps Component
Governance Detection task parses the file, so formatting does not
matter.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
On Windows, xaprepare's Step_GenerateFiles.Windows.cs writes
external/Java.Interop/bin/Build$(Configuration)/JdkInfo.props from
build-tools/xaprepare/xaprepare/Resources/JdkInfo.Windows.props.in.
But this file is immediately overwritten. The PrepareWindows.targets
Prepare flow runs, in order:
1. `dotnet xaprepare -a` — writes JdkInfo.props (this code).
2. `MSBuild Xamarin.Android.BootstrapTasks.sln` — does not read JdkInfo.props.
3. `MSBuild src/workloads/workloads.csproj` — does not read JdkInfo.props.
4. `CallTarget PrepareJavaInterop` → `dotnet build -t:Prepare Java.Interop.sln`
→ external/Java.Interop/build-tools/scripts/Prepare.targets → runs the
`JdkInfo` MSBuild task → overwrites JdkInfo.props with its own generated
content.
Nothing between step 1 and step 4 reads the file, and Java.Interop's Prepare
always regenerates it. Now that external/Java.Interop is in-tree, we can
safely delete the redundant write.
This is the smallest-diff removal:
* Delete Step_GenerateFiles.Windows.cs (the AddOSSpecificSteps partial).
* Delete Resources/JdkInfo.Windows.props.in.
* In Step_GenerateFiles.cs, drop the `partial void AddOSSpecificSteps`
declaration and collapse GetFilesToGenerate so `atBuildStart == false`
returns null. Ctor surface (atBuildStart, onlyRequired) is unchanged so
Scenario_Required.cs is unaffected.
* In Scenario_Standard.cs, remove the AddEndSteps override — the only
thing it did was schedule the now-empty Step_GenerateFiles(atBuildStart:
false).
Preserved (future slices will address these):
* Get_Configuration_OperatingSystem_props (D1).
* OperatingSystems/*.cs and Context.OS.* surface.
* PrepareWindows.targets, DotNet.targets, Java.Interop's Prepare.targets.
Verification:
* dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug
→ Build succeeded. 0 Warning(s). 0 Error(s).
* build.cmd -t:Prepare -c Debug (Windows, cold tree) → succeeds; the file
external/Java.Interop/bin/BuildDebug/JdkInfo.props exists.
* Compare-Object of the resulting JdkInfo.props before vs after this
change → byte-identical (1493 bytes, SHA256
DE59A8061B7657831788FFED7BC1DEECA442E9181605083A4553DE7AC8C003A1),
confirming Java.Interop's overwrite is what always ends up on disk.
* Grep audit under build-tools/xaprepare/: no remaining references to
Step_GenerateFiles.Windows, JdkInfo.Windows.props.in, or
AddOSSpecificSteps.
Follows previous xaprepare deletion slices #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821,
#11825, #11826.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jul 3, 2026
…xaprepare project (#11959)
Follow-up to #11956, which moved the JDK half of `Configuration.OperatingSystem.props` to Java.Interop's `JdkInfo.props`. The remaining NDK / OS-info half has zero real consumers, so this PR:
1. Deletes the last generator template (`Configuration.OperatingSystem.props.in`).
2. Cascades through `Step_GenerateFiles`, both `Scenario_*` classes (which now had zero steps), and every supporting `OperatingSystems/`, `Context.*OS.cs`, `EssentialTools.*`, `ToolRunners/*`, `Configurables.*`, `Application/*`, and `Main.cs` file that only existed to feed the scenarios.
3. Deletes the whole `build-tools/xaprepare/` project.
4. Patches every integration point (`Makefile`, `PrepareWindows.targets`, `BuildEverything.mk`, CI YAML, docs) so `build.cmd -t:Prepare` and `make prepare` still work end-to-end.
## `Configuration.OperatingSystem.props.in` placeholder audit
| Placeholder | Consumers outside the `.in` file | Action |
| --- | --- | --- |
| `HostOsName` | none | drop |
| `HostOsFlavor` | none | drop |
| `HostOsRelease` | none | drop |
| `HostBits` | none (`ArchiveBase.HostBits` in `src/Xamarin.Installer.AndroidSDK/` is an unrelated C# property) | drop |
| `NdkLlvmTag` | none (the NDK toolchain OS tag is resolved elsewhere via `_NdkToolchainOSTag` in `androidsdk.targets`) | drop |
| `HostCpuCount` | only `Configuration.props:72` via `$(MakeConcurrency)` | drop |
## `$(MakeConcurrency)` audit
The only definition was `Configuration.props:72`. A repo-wide grep of `.targets`, `.props`, `.projitems`, `Makefile`, and `.mk` files found zero consumers of the MSBuild property. The `MakeConcurrency` hits under `build-tools/xaprepare/` were an unrelated C# `Context.MakeConcurrency` property.
**Result:** dropped the `MakeConcurrency` MSBuild property entirely (no `$([System.Environment]::ProcessorCount)` replacement needed) and removed the `$(MakeConcurrency)` bullet in `Documentation/building/configuration.md`.
## xaprepare integration audit (grep-confirmed, patched here)
| Location | Change |
| --- | --- |
| `build-tools/xaprepare/` (entire tree) | **deleted** — 86 tracked files |
| `Configuration.props` | dropped `<Import>` of the generated OS props, dropped `MakeConcurrency`, tidied the "between xaprepare and package creation tools" comment |
| `.gitignore` | dropped `Configuration.OperatingSystem.props` |
| `build-tools/scripts/PrepareWindows.targets` | removed `_XAPrepareExe`, `_XAPrepareStandardArgs`, `_BuildXAPrepare` target, and the `Exec dotnet $(_XAPrepareExe)` line. Repointed `Prepare` at `_InstallDotNet`. Kept the space-in-path guard, BootstrapTasks / workloads MSBuilds, and `PrepareJavaInterop` |
| `Makefile` | dropped `PREPARE_PROJECT`, `PREPARE_NET_FX`, `PREPARE_ARGS`, `PREPARE_MSBUILD_FLAGS`, `PREPARE_SCENARIO`, `PREPARE_CI_PR`, `PREPARE_CI`, `_PREPARE_CI_MODE_*`, `_PREPARE_ARGS`, and all their conditionals. Dropped the `dotnet run --project xaprepare.csproj` line from `prepare`. Deleted the `prepare-help` target |
| `build-tools/scripts/BuildEverything.mk` | `jenkins` no longer branches on `PREPARE_CI_PR`/`PREPARE_CI`; just `$(MAKE) prepare && $(MAKE) leeroy` |
| `.github/workflows/copilot-setup-steps.yml` | dropped now-unused `PREPARE_CI=1` |
| `build-tools/automation/azure-pipelines-apidocs.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-linux-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-macos-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/commercial-build.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/copy-extra-result-files.yaml` | dropped `**/Configuration.OperatingSystem.props` glob and the stale `Step_CopyExtraResultFilesForCI` xaprepare-step comment |
| `build-tools/automation/yaml-templates/generate-cgmanifest.yaml` | dropped the stale `Step_GenerateCGManifest` xaprepare-step comment |
| `build-tools/automation/yaml-templates/setup-jdk-variables.yaml` | renamed `$xaPrepareJdkPath` → `$xaJdkPath` for hygiene |
| `Documentation/workflow/HowToAddNewApiLevel.md` | rewrote the "Add New Platform" section to point at `<_PlatformPackage>` entries in `src/androidsdk/androidsdk.targets` instead of `AndroidToolchain.cs`; updated the `--android-sdk-platforms=all` recipe to `dotnet-local build src/androidsdk/androidsdk.csproj -p:AndroidSdkPlatforms=all` |
| `Documentation/building/unix/dependencies.md` | JDK-version link now points at `$(MicrosoftOpenJDKVersion)` in `/Configuration.props` instead of the deleted `Configurables.cs` |
| `Documentation/building/configuration.md` | removed the `$(MakeConcurrency)` bullet |
**Historical breadcrumb comments left as-is** (still accurate and useful for git-archaeology):
- `.github/skills/update-tpn/SKILL.md`
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
- `src/androidsdk/androidsdk.targets`
- `src/native/cmake-config/cmake-config.csproj`
- `src/workloads/workloads.csproj`
## Verification
- `build.cmd Prepare` — succeeded end-to-end on Windows (0 warnings, 0 errors). The trimmed `Prepare` target ran through `_InstallDotNet`, the space-in-path guard, `Xamarin.Android.BootstrapTasks.sln`, `src/workloads/workloads.csproj`, and `PrepareJavaInterop`.
- `dotnet build src\Xamarin.Android.Build.Tasks\Xamarin.Android.Build.Tasks.csproj -c Debug` — 0 errors (93 pre-existing warnings from `src/Mono.Android/` and generated MCW, unrelated to this change).
- Repo-wide grep for `HostOsName`, `HostOsFlavor`, `HostOsRelease`, `HostCpuCount`, `NdkLlvmTag`, and the MSBuild `MakeConcurrency` property — clean.
- Repo-wide grep for `xaprepare` — clean apart from the five intentional historical breadcrumb comments listed above.
## Diff stat
102 files changed, 25 insertions(+), 7891 deletions(-).
## Precedent chain
Continues the multi-slice teardown started by #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821, #11825, #11826, #11945, #11946, #11956.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 31, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

ready-to-reviewThis PR is ready to review/merge, I think any CI failures are just flaky (ignorable).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@jonathanpeppers@simonrozsival
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

[xaprepare] Use Microsoft.SourceLink.GitHub instead of hand-rolled SourceLink.json - #11821

Merged
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-adopt-sourcelink-github
Jun 30, 2026
Merged

[xaprepare] Use Microsoft.SourceLink.GitHub instead of hand-rolled SourceLink.json#11821
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-adopt-sourcelink-github

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Member

Summary

Stop generating bin/Build$(Configuration)/SourceLink.json from xaprepare and stop overriding $(SourceLink) in Configuration.props. Let Microsoft.SourceLink.GitHub (which is already pinned at 8.0.0 in Directory.Build.targets, but until now only Included in one project) produce SourceLink the canonical Arcade way for every project.

Changes

  • Directory.Build.targets — promoted Microsoft.SourceLink.GitHub 8.0.0 from a PackageReference Update to a broad PackageReference Include with PrivateAssets="All" so every project in the repo picks it up.
  • src/Microsoft.Android.Run/Microsoft.Android.Run.csproj — dropped the now-redundant explicit <PackageReference Include="Microsoft.SourceLink.GitHub" />.
  • Configuration.props — deleted the <PropertyGroup> that overrode $(SourceLink) with the path to the generated json file. The canonical package now sets $(SourceLink) itself.
  • build-tools/xaprepare/xaprepare/Application/GeneratedSourceLinkJsonFile.cs — deleted.
  • build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs — removed Get_SourceLink_Json, both references in GetFilesToGenerate, and the gitSubmodules / xaCommit fields plus the git/submodule prelude in Execute (no other generator in this file used them). Switched Execute from async back to a synchronous Task.FromResult since the only await was the deleted submodule walk.
  • build-tools/xaprepare/xaprepare/Application/GeneratedFile.cs — deleted the now-orphaned SkipGeneratedFile class (only caller was Get_SourceLink_Json).

Net: -99/+8 lines, one file deleted.

Verification

Built Mono.Android.csproj, Xamarin.Android.Build.Tasks.csproj, and xaprepare.csproj in Debug after a clean build.cmd Prepare. All succeeded with 0 errors.

Ran sourcelink print-json on bin\Debug\lib\packs\Microsoft.Android.Runtime.37.android\37.0.0\runtimes\android\lib\net11.0\Mono.Android.pdb:

{"documents":{
"<repo>\\*": "https://raw.githubusercontent.com/dotnet/android/138c93d5a5b369e5d9b6867607afefa7502cd787/*",
"<repo>\\external\\android-api-docs\\*": "https://raw.githubusercontent.com/dotnet/android-api-docs/d382c5bd406432083901e51a4e87cd677b8759d8/*",
"<repo>\\external\\constexpr-xxh3\\*": "https://raw.githubusercontent.com/chys87/constexpr-xxh3/aebcee75c8b6c2458fa8ae151754a8ba833bd697/*",
"<repo>\\external\\debugger-libs\\*": "https://raw.githubusercontent.com/mono/debugger-libs/e7fbb713d156d11193ed404783ad6fe9c4042a6d/*",
"<repo>\\external\\Java.Interop\\*": "https://raw.githubusercontent.com/dotnet/java-interop/8d544738ad294b4faf13d189eeeb02f0313e00b3/*",
"<repo>\\external\\libunwind\\*": "https://raw.githubusercontent.com/libunwind/libunwind/e97c9ef82f8b48d0c7f713be4fa7b15e634d76b8/*",
"<repo>\\external\\lz4\\*": "https://raw.githubusercontent.com/lz4/lz4/ebb370ca83af193212df4dcbadcc5d87bc0de2f0/*",
"<repo>\\external\\robin-map\\*": "https://raw.githubusercontent.com/xamarin/robin-map/d37a41003bfbc7e12e34601f93c18ca2ff6d7c07/*",
"<repo>\\external\\termux-elf-cleaner\\*": "https://raw.githubusercontent.com/termux/termux-elf-cleaner/ee5385e004a9d67bdc289e43939691b260e06b03/*",
"<repo>\\external\\xamarin-android-tools\\*": "https://raw.githubusercontent.com/dotnet/android-tools/367724d6ba93db20294681769de97b9cdecb58a0/*",
"<repo>\\external\\xxHash\\*": "https://raw.githubusercontent.com/Cyan4973/xxHash/bbb27a5efb85b92a0486cf361a8635715a53f6ba/*"
}}

Every submodule from .gitmodules is mapped to its correct upstream raw.githubusercontent.com URL — full parity with what GeneratedSourceLinkJsonFile produced before.

Out of scope

Step_GenerateCGManifest, GitSubmoduleInfo, GitRunner, and the GitCommit* prep tasks are still used by cgmanifest generation and XAVersionInfo.targets; they're intentionally left for a follow-up PR.

Precedent

Continues the xaprepare slim-down work in #11568, #11580, #11608, #11613, #11631, #11657, #11658, #11731, #11732, #11733, #11737, #11740, #11760, #11803.

…urceLink.json
Stop generating bin/Build$(Configuration)/SourceLink.json from xaprepare and stop overriding $(SourceLink) in Configuration.props. Promote Microsoft.SourceLink.GitHub from a PackageReference Update to a broad PackageReference Include in Directory.Build.targets so every project picks it up, then drop the explicit Include from Microsoft.Android.Run.csproj.
Verified with 'sourcelink print-json' on bin\Debug\lib\packs\Microsoft.Android.Runtime.37.android\37.0.0\runtimes\android\lib\net11.0\Mono.Android.pdb: the canonical package produces a documents map covering dotnet/android plus every submodule (Java.Interop, xamarin-android-tools, android-api-docs, constexpr-xxh3, debugger-libs, libunwind, lz4, robin-map, termux-elf-cleaner, xxHash) pointing at the correct upstream raw.githubusercontent.com URLs.
Step_GenerateCGManifest and GitSubmoduleInfo / GitRunner are intentionally left for a follow-up.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 30, 2026 14:07

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR switches the repo’s SourceLink generation to the standard Arcade/MSBuild approach by enabling Microsoft.SourceLink.GitHub repo-wide, and removes the now-redundant xaprepare-generated SourceLink.json plumbing.

Changes:

  • Add a repo-wide PackageReference to Microsoft.SourceLink.GitHub (PrivateAssets=All) via Directory.Build.targets, and remove the per-project reference from Microsoft.Android.Run.
  • Stop overriding $(SourceLink) in Configuration.props, letting the SourceLink package set it canonically.
  • Remove xaprepare’s SourceLink.json generator and related scaffolding (including the SkipGeneratedFile helper).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
Directory.Build.targetsAdds global Microsoft.SourceLink.GitHub package reference for SourceLink across the repo.
src/Microsoft.Android.Run/Microsoft.Android.Run.csprojRemoves redundant explicit SourceLink package reference.
Configuration.propsRemoves $(SourceLink) override pointing to generated SourceLink.json.
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.csRemoves SourceLink.json generation path and simplifies execution flow.
build-tools/xaprepare/xaprepare/Application/GeneratedSourceLinkJsonFile.csDeletes the hand-rolled SourceLink.json generator implementation.
build-tools/xaprepare/xaprepare/Application/GeneratedFile.csRemoves the now-orphaned SkipGeneratedFile helper type.
Comments suppressed due to low confidence (1)

build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs:52

  • Scenario_Required still adds new Step_GenerateFiles (atBuildStart: true, onlyRequired: true), but GetFilesToGenerate() now returns null for that case, so the step generates no files at all. That seems to contradict the scenario description (“generate build files”) and makes the scenario effectively a no-op after this PR.
 if (atBuildStart) {
if (onlyRequired) {
return null;
} else {
return new List <GeneratedFile> {
Get_Configuration_OperatingSystem_props (context),
Get_XABuildConfig_cs (context),
};
}

@jonathanpeppersjonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 30, 2026
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

Verified the CI build artifacts for this PR (build 1487951).

Downloaded nuget-unsigned-symbols, extracted the symbols .nupkgs, and ran sourcelink print-json on representative PDBs from across the SDK / Runtime / Ref packages. Every assembly's SourceLink covers dotnet/android plus all submodules:

Mono.Android.pdb (Microsoft.Android.Runtime.37.android symbols package):

{"documents":{
"/Users/cloudtest/vss/_work/1/s/android/*":"https://raw.githubusercontent.com/dotnet/android/917981be97def8f5d046c8b1b28dca25771d8198/*",
"/Users/cloudtest/vss/_work/1/s/android/external/android-api-docs/*":"https://raw.githubusercontent.com/dotnet/android-api-docs/d382c5bd406432083901e51a4e87cd677b8759d8/*",
"/Users/cloudtest/vss/_work/1/s/android/external/constexpr-xxh3/*":"https://raw.githubusercontent.com/chys87/constexpr-xxh3/aebcee75c8b6c2458fa8ae151754a8ba833bd697/*",
"/Users/cloudtest/vss/_work/1/s/android/external/debugger-libs/*":"https://raw.githubusercontent.com/mono/debugger-libs/e7fbb713d156d11193ed404783ad6fe9c4042a6d/*",
"/Users/cloudtest/vss/_work/1/s/android/external/Java.Interop/*":"https://raw.githubusercontent.com/dotnet/java-interop/8d544738ad294b4faf13d189eeeb02f0313e00b3/*",
"/Users/cloudtest/vss/_work/1/s/android/external/libunwind/*":"https://raw.githubusercontent.com/libunwind/libunwind/e97c9ef82f8b48d0c7f713be4fa7b15e634d76b8/*",
"/Users/cloudtest/vss/_work/1/s/android/external/lz4/*":"https://raw.githubusercontent.com/dotnet/lz4/ebb370ca83af193212df4dcbadcc5d87bc0de2f0/*",
"/Users/cloudtest/vss/_work/1/s/android/external/robin-map/*":"https://raw.githubusercontent.com/xamarin/robin-map/d37a41003bfbc7e12e34601f93c18ca2ff6d7c07/*",
"/Users/cloudtest/vss/_work/1/s/android/external/termux-elf-cleaner/*":"https://raw.githubusercontent.com/termux/termux-elf-cleaner/ee5385e004a9d67bdc289e43939691b260e06b03/*",
"/Users/cloudtest/vss/_work/1/s/android/external/xamarin-android-tools/*":"https://raw.githubusercontent.com/dotnet/android-tools/367724d6ba93db20294681769de97b9cdecb58a0/*",
"/Users/cloudtest/vss/_work/1/s/android/external/xxHash/*":"https://raw.githubusercontent.com/Cyan4973/xxHash/bbb27a5efb85b92a0486cf361a8635715a53f6ba/*"
}}

Same coverage on:

  • Xamarin.Android.Build.Tasks.pdb (Microsoft.Android.Sdk.Windows symbols) — repo + all 10 submodule mappings.
  • Microsoft.Android.Sdk.ILLink.pdb (Microsoft.Android.Sdk.Windows symbols) — repo + all 10 submodule mappings.
  • Java.Interop.pdb — own Java.Interop repo + its nested xamarin-android-tools submodule.

All URLs match .gitmodules exactly (including the dotnet/lz4 upstream). Microsoft.Android.Ref.37 produces a reference-only assembly with no embedded source link section, which is expected for ref assemblies.

@jonathanpeppers
jonathanpeppers merged commit b0fe694 into mainJun 30, 2026
41 checks passed
@jonathanpeppers
jonathanpeppers deleted the jonathanpeppers-adopt-sourcelink-github branch June 30, 2026 19:45
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11826)
## Summary
Moves `XABuildConfig.cs` generation out of `xaprepare` and into a new strong-named class library at `src/AndroidBuildConfig/AndroidBuildConfig.csproj` that produces `AndroidBuildConfig.dll`.
This continues the incremental removal of `xaprepare`, following the precedent set by `cmake-config.csproj` (#11760) and the recent batch #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11803, #11821, #11825.
It also fixes a long-standing wart: previously `XABuildConfig.cs` was `<Compile Include>`'d into three different assemblies (`Xamarin.Android.Build.Tasks`, `Xamarin.ProjectTools`, and `Xamarin.Android.Build.Tests`), so every test that mentioned `XABuildConfig` produced a `CS0436` "type conflicts with imported type" warning — about **22** of them.
Wrapping the type in its own assembly collapses it to a single definition that every consumer references normally. After this change `Xamarin.Android.Build.Tests` builds with **7** warnings (none for `XABuildConfig`).
## How it works
`src/AndroidBuildConfig/AndroidBuildConfig.csproj`:
- `Microsoft.NET.Sdk` / `netstandard2.0`, strong-named with `product.snk`.
- `ProjectReference`s `Xamarin.Android.Tools.AndroidSdk` (for the `AndroidTargetArch` enum used by the template).
- `<UsingTask>`s `ReplaceFileContents`, `GitCommitHash`, and `GitBranch` from `$(PrepTasksAssembly)`, all with `TaskFactory="TaskHostFactory" Runtime="NET"` per repo convention.
- The `_GenerateXABuildConfig` target runs `BeforeTargets="BeforeCompile;CoreCompile"`, computes every substitution from MSBuild properties already exposed by `Configuration.props` (NDK major/minor/micro via `$(_XAAndroidNdkPkgRevision.Split('.'))`, API levels via `Split`/`Contains`, full commit hash via `GitCommitHash.CommitHash`, branch via `GitBranch.Branch`), and writes the file to `$(IntermediateOutputPath)XABuildConfig.cs`. The `<Compile Include>` lives inside the target so it resolves at execution time, when `IntermediateOutputPath` is final.
- `XABuildConfig` is now `public static class` instead of `internal static class`.
The three consumer csprojs lose their `<Compile Include="…XABuildConfig.cs" />` and now have a normal `<ProjectReference Include="…AndroidBuildConfig.csproj" />` (no `ReferenceOutputAssembly="False"`).
`build-tools/installers/create-installers.targets` ships `AndroidBuildConfig.dll` + `.pdb` alongside `Xamarin.Android.Build.Tasks.dll`.
## xaprepare cleanup
Removed dead code that only existed to feed the old `Get_XABuildConfig_cs` step:
- `Step_GenerateFiles.Get_XABuildConfig_cs` and its `GetMajor` / `GetMinor` locals
- `BuildInfo`: `NDKRevision`, `NDKVersionMajor`, `NDKVersionMinor`, `NDKVersionMicro`, `NDKVersion`, `XACommitHash`, `XABranch`, `GatherGitInfo`, `DetermineXACommitInfo`, `cachedNdkVersion`
- `Context`: the `if (SelectedScenario.NeedsGitBuildInfo) { await BuildInfo.GatherGitInfo … }` block
- `Scenario.NeedsGitBuildInfo` (and the `NeedsGitBuildInfo = true;` setters in `Scenario_Standard` and `Scenario_Required`)
- `BuildAndroidPlatforms.cs` — entire file (only contained constants used by the deleted code)
- `Utilities.ParseAndroidPkgRevision`
- `GitRunner.GetTopCommitHash` and `GitRunner.GetBranchName` (class retained — still used by `BuildInfo.DetermineLastVersionChangeCommit`)
## Files
**Added**
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
**Renamed/moved**
- `build-tools/scripts/XABuildConfig.cs.in` → `src/AndroidBuildConfig/XABuildConfig.cs.in` (`static class` → `public static class`)
**Modified**
- `src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Xamarin.ProjectTools.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj`
- `build-tools/installers/create-installers.targets`
- `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs`
- `build-tools/xaprepare/xaprepare/Application/BuildInfo.cs`
- `build-tools/xaprepare/xaprepare/Application/Context.cs`
- `build-tools/xaprepare/xaprepare/Application/Scenario.cs`
- `build-tools/xaprepare/xaprepare/Application/Utilities.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Required.cs`
- `build-tools/xaprepare/xaprepare/ToolRunners/GitRunner.cs`
- `build-tools/xaprepare/README.md`
**Deleted**
- `build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs`
## Verification
- `AndroidBuildConfig.csproj`: 0 warnings, 0 errors.
- `Xamarin.Android.Build.Tasks.csproj`: 0 errors, 85 pre-existing unrelated warnings (none for `XABuildConfig`).
- `Xamarin.Android.Build.Tests.csproj`: 0 errors, **7** warnings — down from ~22; all `CS0436 XABuildConfig` conflicts eliminated.
- `xaprepare.csproj`: 0 warnings, 0 errors.
- Generated `XABuildConfig.cs` is semantically identical to the pre-change xaprepare output. The only token difference is the intentional `static class` → `public static class`; everything else (NDK split, API-level major/minor split, supported-ABIs semicolon list, full commit hash, branch name, etc.) matches the previous baseline byte-for-byte.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11825)
Continues the incremental removal of `xaprepare` by moving the
`cgmanifest.json` generator out of the C# step
`Step_GenerateCGManifest` and into a YAML `pwsh:` step that runs only
on CI.
The file is consumed exclusively by the Azure DevOps Component
Governance Detection task (auto-injected on internal pipelines by
`eng/common/core-templates/job/job.yml`). It is not consumed by any
in-repo build target, so generating it from the C# Prepare step is no
longer necessary.
We cannot drop the file outright: `eng/common` ships CG infrastructure
but it is not yet wired to auto-discover submodules in our pipelines,
so the explicit `cgmanifest.json` is still the source of truth.
Files:
* Added: `build-tools/automation/yaml-templates/generate-cgmanifest.yaml`
* Modified: `build-windows-steps.yaml`, `build-macos-steps.yaml`,
`build-linux-steps.yaml`, `commercial-build.yaml` (call the new
template after the Prepare/`make jenkins` step)
* Modified: `Scenario_Standard.cs` (drop registration)
* Modified: `GitRunner.cs` (remove now-unused `ConfigList` and
`SubmoduleStatus` methods)
* Deleted: `Step_GenerateCGManifest.cs`
Verification: byte-for-byte diff of the YAML-generated
`cgmanifest.json` against the previous C# output on Debug:
Baseline=3144 New=3144
Total byte differences: 0
Precedent PRs in this stream: #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803,
#11821.
### Simplify generate-cgmanifest.yaml using ConvertTo-Json
Replace the hand-rolled StringBuilder JSON emission with PowerShell's
`ConvertTo-Json`. The output is no longer byte-identical to the
previous C# output (2-space indent instead of 4, and slightly
different whitespace), but it is still valid JSON matching the
component-detection-manifest schema. The Azure DevOps Component
Governance Detection task parses the file, so formatting does not
matter.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
On Windows, xaprepare's Step_GenerateFiles.Windows.cs writes
external/Java.Interop/bin/Build$(Configuration)/JdkInfo.props from
build-tools/xaprepare/xaprepare/Resources/JdkInfo.Windows.props.in.
But this file is immediately overwritten. The PrepareWindows.targets
Prepare flow runs, in order:
1. `dotnet xaprepare -a` — writes JdkInfo.props (this code).
2. `MSBuild Xamarin.Android.BootstrapTasks.sln` — does not read JdkInfo.props.
3. `MSBuild src/workloads/workloads.csproj` — does not read JdkInfo.props.
4. `CallTarget PrepareJavaInterop` → `dotnet build -t:Prepare Java.Interop.sln`
→ external/Java.Interop/build-tools/scripts/Prepare.targets → runs the
`JdkInfo` MSBuild task → overwrites JdkInfo.props with its own generated
content.
Nothing between step 1 and step 4 reads the file, and Java.Interop's Prepare
always regenerates it. Now that external/Java.Interop is in-tree, we can
safely delete the redundant write.
This is the smallest-diff removal:
* Delete Step_GenerateFiles.Windows.cs (the AddOSSpecificSteps partial).
* Delete Resources/JdkInfo.Windows.props.in.
* In Step_GenerateFiles.cs, drop the `partial void AddOSSpecificSteps`
declaration and collapse GetFilesToGenerate so `atBuildStart == false`
returns null. Ctor surface (atBuildStart, onlyRequired) is unchanged so
Scenario_Required.cs is unaffected.
* In Scenario_Standard.cs, remove the AddEndSteps override — the only
thing it did was schedule the now-empty Step_GenerateFiles(atBuildStart:
false).
Preserved (future slices will address these):
* Get_Configuration_OperatingSystem_props (D1).
* OperatingSystems/*.cs and Context.OS.* surface.
* PrepareWindows.targets, DotNet.targets, Java.Interop's Prepare.targets.
Verification:
* dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug
→ Build succeeded. 0 Warning(s). 0 Error(s).
* build.cmd -t:Prepare -c Debug (Windows, cold tree) → succeeds; the file
external/Java.Interop/bin/BuildDebug/JdkInfo.props exists.
* Compare-Object of the resulting JdkInfo.props before vs after this
change → byte-identical (1493 bytes, SHA256
DE59A8061B7657831788FFED7BC1DEECA442E9181605083A4553DE7AC8C003A1),
confirming Java.Interop's overwrite is what always ends up on disk.
* Grep audit under build-tools/xaprepare/: no remaining references to
Step_GenerateFiles.Windows, JdkInfo.Windows.props.in, or
AddOSSpecificSteps.
Follows previous xaprepare deletion slices #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821,
#11825, #11826.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jul 3, 2026
…xaprepare project (#11959)
Follow-up to #11956, which moved the JDK half of `Configuration.OperatingSystem.props` to Java.Interop's `JdkInfo.props`. The remaining NDK / OS-info half has zero real consumers, so this PR:
1. Deletes the last generator template (`Configuration.OperatingSystem.props.in`).
2. Cascades through `Step_GenerateFiles`, both `Scenario_*` classes (which now had zero steps), and every supporting `OperatingSystems/`, `Context.*OS.cs`, `EssentialTools.*`, `ToolRunners/*`, `Configurables.*`, `Application/*`, and `Main.cs` file that only existed to feed the scenarios.
3. Deletes the whole `build-tools/xaprepare/` project.
4. Patches every integration point (`Makefile`, `PrepareWindows.targets`, `BuildEverything.mk`, CI YAML, docs) so `build.cmd -t:Prepare` and `make prepare` still work end-to-end.
## `Configuration.OperatingSystem.props.in` placeholder audit
| Placeholder | Consumers outside the `.in` file | Action |
| --- | --- | --- |
| `HostOsName` | none | drop |
| `HostOsFlavor` | none | drop |
| `HostOsRelease` | none | drop |
| `HostBits` | none (`ArchiveBase.HostBits` in `src/Xamarin.Installer.AndroidSDK/` is an unrelated C# property) | drop |
| `NdkLlvmTag` | none (the NDK toolchain OS tag is resolved elsewhere via `_NdkToolchainOSTag` in `androidsdk.targets`) | drop |
| `HostCpuCount` | only `Configuration.props:72` via `$(MakeConcurrency)` | drop |
## `$(MakeConcurrency)` audit
The only definition was `Configuration.props:72`. A repo-wide grep of `.targets`, `.props`, `.projitems`, `Makefile`, and `.mk` files found zero consumers of the MSBuild property. The `MakeConcurrency` hits under `build-tools/xaprepare/` were an unrelated C# `Context.MakeConcurrency` property.
**Result:** dropped the `MakeConcurrency` MSBuild property entirely (no `$([System.Environment]::ProcessorCount)` replacement needed) and removed the `$(MakeConcurrency)` bullet in `Documentation/building/configuration.md`.
## xaprepare integration audit (grep-confirmed, patched here)
| Location | Change |
| --- | --- |
| `build-tools/xaprepare/` (entire tree) | **deleted** — 86 tracked files |
| `Configuration.props` | dropped `<Import>` of the generated OS props, dropped `MakeConcurrency`, tidied the "between xaprepare and package creation tools" comment |
| `.gitignore` | dropped `Configuration.OperatingSystem.props` |
| `build-tools/scripts/PrepareWindows.targets` | removed `_XAPrepareExe`, `_XAPrepareStandardArgs`, `_BuildXAPrepare` target, and the `Exec dotnet $(_XAPrepareExe)` line. Repointed `Prepare` at `_InstallDotNet`. Kept the space-in-path guard, BootstrapTasks / workloads MSBuilds, and `PrepareJavaInterop` |
| `Makefile` | dropped `PREPARE_PROJECT`, `PREPARE_NET_FX`, `PREPARE_ARGS`, `PREPARE_MSBUILD_FLAGS`, `PREPARE_SCENARIO`, `PREPARE_CI_PR`, `PREPARE_CI`, `_PREPARE_CI_MODE_*`, `_PREPARE_ARGS`, and all their conditionals. Dropped the `dotnet run --project xaprepare.csproj` line from `prepare`. Deleted the `prepare-help` target |
| `build-tools/scripts/BuildEverything.mk` | `jenkins` no longer branches on `PREPARE_CI_PR`/`PREPARE_CI`; just `$(MAKE) prepare && $(MAKE) leeroy` |
| `.github/workflows/copilot-setup-steps.yml` | dropped now-unused `PREPARE_CI=1` |
| `build-tools/automation/azure-pipelines-apidocs.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-linux-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-macos-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/commercial-build.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/copy-extra-result-files.yaml` | dropped `**/Configuration.OperatingSystem.props` glob and the stale `Step_CopyExtraResultFilesForCI` xaprepare-step comment |
| `build-tools/automation/yaml-templates/generate-cgmanifest.yaml` | dropped the stale `Step_GenerateCGManifest` xaprepare-step comment |
| `build-tools/automation/yaml-templates/setup-jdk-variables.yaml` | renamed `$xaPrepareJdkPath` → `$xaJdkPath` for hygiene |
| `Documentation/workflow/HowToAddNewApiLevel.md` | rewrote the "Add New Platform" section to point at `<_PlatformPackage>` entries in `src/androidsdk/androidsdk.targets` instead of `AndroidToolchain.cs`; updated the `--android-sdk-platforms=all` recipe to `dotnet-local build src/androidsdk/androidsdk.csproj -p:AndroidSdkPlatforms=all` |
| `Documentation/building/unix/dependencies.md` | JDK-version link now points at `$(MicrosoftOpenJDKVersion)` in `/Configuration.props` instead of the deleted `Configurables.cs` |
| `Documentation/building/configuration.md` | removed the `$(MakeConcurrency)` bullet |
**Historical breadcrumb comments left as-is** (still accurate and useful for git-archaeology):
- `.github/skills/update-tpn/SKILL.md`
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
- `src/androidsdk/androidsdk.targets`
- `src/native/cmake-config/cmake-config.csproj`
- `src/workloads/workloads.csproj`
## Verification
- `build.cmd Prepare` — succeeded end-to-end on Windows (0 warnings, 0 errors). The trimmed `Prepare` target ran through `_InstallDotNet`, the space-in-path guard, `Xamarin.Android.BootstrapTasks.sln`, `src/workloads/workloads.csproj`, and `PrepareJavaInterop`.
- `dotnet build src\Xamarin.Android.Build.Tasks\Xamarin.Android.Build.Tasks.csproj -c Debug` — 0 errors (93 pre-existing warnings from `src/Mono.Android/` and generated MCW, unrelated to this change).
- Repo-wide grep for `HostOsName`, `HostOsFlavor`, `HostOsRelease`, `HostCpuCount`, `NdkLlvmTag`, and the MSBuild `MakeConcurrency` property — clean.
- Repo-wide grep for `xaprepare` — clean apart from the five intentional historical breadcrumb comments listed above.
## Diff stat
102 files changed, 25 insertions(+), 7891 deletions(-).
## Precedent chain
Continues the multi-slice teardown started by #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821, #11825, #11826, #11945, #11946, #11956.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 31, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

ready-to-reviewThis PR is ready to review/merge, I think any CI failures are just flaky (ignorable).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@jonathanpeppers@simonrozsival