Skip to content

[xaprepare] Check in Ndk.projitems, remove generator#11733

Merged
jonathanpeppers merged 5 commits into
mainfrom
jonathanpeppers-checkin-ndk-projitems
Jun 25, 2026
Merged

[xaprepare] Check in Ndk.projitems, remove generator#11733
jonathanpeppers merged 5 commits into
mainfrom
jonathanpeppers-checkin-ndk-projitems

Conversation

@jonathanpeppers

@jonathanpeppers jonathanpeppers commented Jun 24, 2026

Copy link
Copy Markdown
Member

Mirrors #11608 (which checked in Mono.Android.Apis.projitems the same way). See also #11568, #11580, #11613, #11631, #11657, #11658.

What

build-tools/scripts/Ndk.projitems.in was a template with @NDK_*@ placeholders that the Get_Ndk_projitems generator in xaprepare filled in from constants in BuildAndroidPlatforms.cs. Those substitution values only change on rare NDK bumps, so generating the file on every build adds no value.

This PR checks in the resolved file as a static build-tools/scripts/Ndk.projitems and removes the generator.

Changes

  • Add build-tools/scripts/Ndk.projitems — the static, checked-in file. Rather than hardcoding values, it sources them from the existing properties in Configuration.props (which is imported before Ndk.targets):

    • AndroidNdkVersion$(_XAAndroidNdkRelease)
    • AndroidNdkPkgRevision$(_XAAndroidNdkPkgRevision)
    • the per-ABI AndroidNdkApiLevel_*$(AndroidMinimumDotNetApiLevel)

    So there is nothing to keep in sync on an NDK/API bump.

  • build-tools/scripts/Ndk.targets — point ProjitemsFile at the new in-tree location ($(MSBuildThisFileDirectory)Ndk.projitems) instead of bin/Build$(Configuration)/Ndk.projitems.

  • Delete build-tools/scripts/Ndk.projitems.in.

  • Step_GenerateFiles.cs — remove the Get_Ndk_projitems method and its dispatch entry.

  • Configurables.cs — update a doc comment reference from Ndk.projitems.inNdk.projitems.

Simplifications (from review)

  • Collapsed the dead legacy/NET API-level split. The legacy 32-bit minimum API level used to be lower than the .NET minimum, but they are identical now. Removed the two per-ABI properties that nothing references (AndroidNdkApiLevel_Arm, AndroidNdkApiLevel_X86_Legacy). The arm64-v8a/x86_64 properties are kept because shipped targets (Build.Tasks.targets, Common.props.in, NativeAOT.targets) still consume them by name.
  • Removed the ApiLevelNET item metadata. ApiLevelNET was the .NET (.NET 6+) Android minimum API level vs. the legacy Xamarin.Android/Mono ApiLevel; the two are identical now and this repo is .NET-only. Its only consumer was src/native/common/libunwind/libunwind-xamarin.targets, which now reads ApiLevel. Dropped ApiLevelNET from all four AndroidSupportedTargetJitAbi items.

The NDK constants in BuildAndroidPlatforms.cs are intentionally left untouched — they're still consumed by Get_XABuildConfig_cs and the cmake presets generator.

Verification

  • dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug → 0 errors / 0 warnings.
  • Evaluated the import chain via a standalone MSBuild harness (importing the real Configuration.props); it produces all four AndroidSupportedTargetJitAbi items with ApiLevel=24 and the expected AndroidRID metadata, matching prior generator output (NDK 28c / pkg 28.2.13676358).
  • Audits clean: git grep Ndk.projitems.in, git grep Ndk_projitems, git grep ApiLevelNET, and the old bin/Build$(Configuration)/Ndk.projitems path all return 0 hits.

Mirrors PR #11608 which checked in Mono.Android.Apis.projitems.

Convert `build-tools/scripts/Ndk.projitems.in` into a checked-in
`build-tools/scripts/Ndk.projitems` with the `@NDK_*@` placeholders
resolved from the current constants in BuildAndroidPlatforms.cs, and
remove the `Get_Ndk_projitems` generator from xaprepare.

- Point `Ndk.targets` at the new static, in-tree location.
- Delete `Get_Ndk_projitems` and its dispatch entry in Step_GenerateFiles.cs.
- The NDK constants in BuildAndroidPlatforms.cs are left intact; they are
  still consumed by Get_XABuildConfig_cs and the cmake presets generator.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 24, 2026 18:53
Instead of hardcoding the NDK version (28c), pkg revision (28.2.13676358)
and minimum API level (24) -- which duplicated values already defined in
Configuration.props -- source them from $(_XAAndroidNdkRelease),
$(_XAAndroidNdkPkgRevision) and $(AndroidMinimumDotNetApiLevel). Those are
all set before Configuration.props imports Ndk.targets, so the projitems
file no longer needs to be kept in sync on an NDK/API bump.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI 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 continues the xaprepare cleanup by checking in build-tools/scripts/Ndk.projitems as a static file and removing the Get_Ndk_projitems generator path from Step_GenerateFiles, so builds no longer regenerate a file whose contents only change on NDK bumps.

Changes:

  • Check in a resolved build-tools/scripts/Ndk.projitems (NDK 28c / pkg rev 28.2.13676358 / min API 24) and stop generating it at prepare time.
  • Update build-tools/scripts/Ndk.targets to import the in-tree projitems instead of bin/Build$(Configuration)/....
  • Remove the Get_Ndk_projitems generator method/dispatch and update related documentation references.

Reviewed changes

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

File Description
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs Removes the Ndk.projitems generation step from the xaprepare file-generation list.
build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs Updates doc comment to point at the checked-in projitems file.
build-tools/scripts/Ndk.targets Imports Ndk.projitems from the scripts directory instead of from bin/Build$(Configuration).
build-tools/scripts/Ndk.projitems Adds the resolved, checked-in projitems file that defines NDK version/pkg revision and ABI metadata.
Comments suppressed due to low confidence (2)

build-tools/scripts/Ndk.targets:8

  • Ndk.projitems is now checked in, so the Exists(...) condition on the <Import> can hide a missing/incorrect checkout and lead to confusing downstream MSBuild errors (the items/properties would just not be defined). Consider removing the condition so the build fails fast if the file is missing.
    <ProjitemsFile>$(MSBuildThisFileDirectory)Ndk.projitems</ProjitemsFile>
  </PropertyGroup>
  <Import
      Project="$(ProjitemsFile)"
      Condition="Exists('$(ProjitemsFile)')"/>

build-tools/scripts/Ndk.projitems:6

  • The header comment says to update API-level values when changing NdkMinimumAPI/NdkMinimumAPILegacy32 in BuildAndroidPlatforms.cs, but those values are actually sourced from $(AndroidMinimumDotNetApiLevel) (Configuration.props). To avoid future mismatches, the comment should point at Configuration.props for API-level changes (and at BuildAndroidPlatforms.cs for NDK version/revision).

jonathanpeppers and others added 3 commits June 24, 2026 14:16
The legacy 32-bit minimum API level used to be lower than the .NET minimum
API level, but they are identical now (both $(AndroidMinimumDotNetApiLevel)).

Remove the two redundant per-ABI properties that nothing else references --
AndroidNdkApiLevel_Arm (armeabi-v7a .NET) and AndroidNdkApiLevel_X86_Legacy
(x86 legacy) -- and point each item's ApiLevel/ApiLevelNET metadata at the
single remaining per-ABI property. The arm64-v8a and x86_64 properties are
left in place since shipped targets (Build.Tasks.targets, Common.props.in,
NativeAOT.targets) still consume them by name.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ApiLevelNET was the minimum API level for .NET (.NET 6+) Android, as
opposed to the legacy Xamarin.Android (Mono) ApiLevel. Those values used to
differ but are identical now, and the repo is .NET-only.

The only consumer of the ApiLevelNET metadata was libunwind-xamarin.targets;
point it at ApiLevel instead and drop the now-redundant ApiLevelNET metadata
from all four AndroidSupportedTargetJitAbi items in Ndk.projitems. The
resolved value (24) is unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers jonathanpeppers merged commit dc54c1c into main Jun 25, 2026
40 checks passed
@jonathanpeppers jonathanpeppers deleted the jonathanpeppers-checkin-ndk-projitems branch June 25, 2026 13:48
simonrozsival pushed a commit that referenced this pull request Jun 26, 2026
Many xaprepare provisioning steps have been removed over the past year (#11332, #11348, #11399, #11440, #11441, #11636 and follow-up cleanups in #11568, #11580, #11608, #11613, #11631, #11657, #11658, #11731, #11732, #11733, #11737). The supporting scaffolding around those steps was left behind. This PR removes the verified-dead pieces in two passes.

## Files removed (first pass — original audit)

| File | Justification |
| --- | --- |
| `Application/TestAssembly.cs` | Orphan test infra; only referenced by `TestAssemblyType.cs`. |
| `Application/TestAssemblyType.cs` | Only referenced by `TestAssembly.cs`. |
| `Application/StepWithDownloadProgress.cs` | No subclasses remain. |
| `Application/NDKTool.cs` | NDK provisioning moved to MSBuild in #11440. Last consumer was the also-dead `Configurables.NDKTools` collection (removed below). |
| `ToolRunners/SnRunner.cs` | Strong-naming tool runner; never instantiated. |
| `ToolRunners/SnRunner.OutputSink.cs` | Partial sibling of `SnRunner`. |
| `ToolRunners/CMakeRunner.cs` | Never instantiated. |
| `ToolRunners/CMakeRunner.OutputSink.cs` | Partial sibling of `CMakeRunner`. |

## Files removed (second pass — repo-wide re-audit)

| File | Justification |
| --- | --- |
| `ToolRunners/MakeRunner.Linux.cs` | Partial of `MakeRunner`; type never instantiated. |
| `ToolRunners/MakeRunner.MacOS.cs` | Partial of `MakeRunner`. |
| `ToolRunners/MakeRunner.OutputSink.Unix.cs` | Partial of `MakeRunner`. |
| `ToolRunners/MakeRunner.Unix.cs` | Partial of `MakeRunner`. |
| `ToolRunners/MSBuildRunner.cs` | Never instantiated. |
| `ToolRunners/MSBuildRunner.OutputSink.cs` | Partial sibling of `MSBuildRunner`. |
| `ToolRunners/NinjaRunner.cs` | Never instantiated. |
| `ToolRunners/NinjaRunner.OutputSink.cs` | Partial sibling of `NinjaRunner`. |
| `Application/ScenarioNoStandardEndSteps.cs` | Abstract class with zero subclasses. |

## Cascading cleanup

- `ConfigAndData/Configurables.cs` — removed the dead `NDKTools` `List<NDKTool>` collection (lines 132–145). Rest of the file unchanged.

## Removed from initial deletion list after verification

- `Application/Extensions.DictionaryOfProgramVersionParser.cs` — initial name-only audit flagged it as dead, but its `Add` extension method is consumed via dictionary collection-initializer syntax in `Application/VersionFetchers.cs`. The consumer never references the static class by name, which is why the first audit missed it. The file stays.
- `Scenarios/Scenario_Required.cs` — looks unreferenced by static grep, but `Scenario` subclasses are reflectively discovered via the `[Scenario]` attribute in `Context.cs` (`Utilities.GetTypesWithCustomAttribute<ScenarioAttribute> ()`). Live. The file stays.

## Verification

- `git grep -n -w <TypeName>` for each deleted type now returns 0 real hits (only unrelated `"TestAssembly"` string literals in `tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/` remain — those are assembly-name strings, not the C# type).
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug` → 0 warnings, 0 errors.

## Deferred follow-up

The csproj conditionally excludes `*MacOS*` files from compilation when `HostOS != Darwin`, so static dead-code analysis from a Windows/Linux host can't see whether the macOS-only consumers are themselves live. These candidates need verification on a Mac host (or a build matrix) before deletion:

- `Application/PkgProgram.MacOS.cs`
- `Application/HomebrewProgram.MacOS.cs`
- `ToolRunners/BrewRunner.MacOS.cs`
- `ToolRunners/PkgutilRunner.MacOS.cs`
- `ConfigAndData/Dependencies/MacOS.cs`
jonathanpeppers added a commit that referenced this pull request Jun 27, 2026
…ct (#11760)

Continues the incremental dismantling of `xaprepare` (see #11568, #11580, #11608, #11613, #11631, #11657, #11658, #11731, #11732, #11733, #11737, #11740). Two more generator methods come out, and the work they did moves into a small dedicated MSBuild project.

## What changes

Two xaprepare generators in `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs` are deleted:

* `Get_Cmake_XA_Build_Configuration` — produced `bin/Build$(Configuration)/xa_build_configuration.cmake`, included by `src/native/CMakeLists.txt`.
* `Get_Cmake_Presets` (and its `GetCmakePresetsCommon` helper) — produced `src/native/CMakePresets.json`, consumed by the `cmake` preset invocations in `src/native/native.targets`.

Both are now generated by a new project:

* **`src/native/cmake-config/cmake-config.csproj`** (`Microsoft.Build.NoTargets`) hosts `_GenerateCMakeFiles`, which uses the existing `ReplaceFileContents` MSBuild task to substitute the placeholders in `build-tools/scripts/xa_build_configuration.cmake.in` and `src/native/CMakePresets.json.in`.
* `native-mono.csproj`, `native-clr.csproj`, and `native-nativeaot.csproj` each `<ProjectReference>` this project.

### Why a dedicated project (not just a target in `native.targets`)

The three native csproj share two output files (`bin/Build$(Configuration)/xa_build_configuration.cmake` and `src/native/CMakePresets.json`). Hosting the generator in `native.targets` would either:

* Race on the shared outputs under parallel msbuild (`/m`), or
* Require a `'$(MSBuildProjectName)' == 'native-mono'` gate -- which breaks isolated `dotnet build native-clr.csproj` on a clean tree (the gitignored output files would never get generated).

A dedicated project with three incoming `<ProjectReference>`s solves both: single producer, and project-reference ordering guarantees the outputs exist before any consumer's `cmake` preset call -- including for isolated single-csproj builds.

### Incremental correctness

`_GenerateCMakeFiles` declares fully-anchored `Inputs`:

* `build-tools/scripts/xa_build_configuration.cmake.in`
* `src/native/CMakePresets.json.in`
* `Configuration.props` (`AndroidNdkDirectory`, `NinjaPath`, `MicrosoftAndroidSdkOutDir`, `XAPackagesDir`, `AndroidMinimumDotNetApiLevel`)
* `Directory.Build.props` (`TestOutputDirectory`)
* `eng/Versions.props` (`MicrosoftNETCoreAppRefPackageVersion`)

so editing any of those re-runs the target; a no-change rebuild skips it. (Note: `$(MSBuildAllProjects)` is intentionally **not** used -- it does not include imported `.props` files for SDK-style projects since MSBuild 16.0; verified empirically.)

### Cascading deletions in xaprepare

* `Configurables.NativeSourcesDir` (was used only by `Get_Cmake_Presets`).
* All eight `Configurables.Paths.NetcoreAppRuntimeAndroid*` / `CoreClrAppRuntimeAndroid*` properties (+ backing fields + the `GetNetcoreAppRuntimePath` / `GetCoreClrAppRuntimePath` helpers) -- the new MSBuild target reads `$(XAPackagesDir)` / `$(MicrosoftNETCoreAppRefPackageVersion)` directly.
* The `Get_Cmake_*` entries in `Step_GenerateFiles.GetFilesToGenerate`.

`BuildAndroidPlatforms.NdkMinimumAPI` / `NdkMinimumAPILegacy32` are kept -- still used by `Get_XABuildConfig_cs` (a separate generator for a future PR).

### What stays

The `.in` template files are unchanged and still tracked in git -- the new MSBuild target reads them. The other generators in `Step_GenerateFiles.cs` (`Get_SourceLink_Json`, `Get_Configuration_OperatingSystem_props`, `Get_XABuildConfig_cs`, `AddOSSpecificSteps`) are out of scope and untouched.

## Verification

On Windows:

* `build.cmd Prepare -c Debug`
* `dotnet-local.cmd build src\native\native-mono.csproj -c Debug` -> 0 errors, generates both files
* `dotnet-local.cmd build src\native\native-clr.csproj -c Debug` -> 0 errors (incl. clean-tree isolated build)
* `dotnet-local.cmd build src\native\native-nativeaot.csproj -c Debug` -> 0 errors
* `dotnet-local.cmd build build-tools\xaprepare\xaprepare\xaprepare.csproj -c Debug` -> 0 errors

Incremental behaviour verified by walking through MSBuild diagnostic output:

* No-change rebuild: `Skipping target "_GenerateCMakeFiles" because all output files are up-to-date`.
* `touch eng/Versions.props` + rebuild: `Building target "_GenerateCMakeFiles" completely`, outputs re-written.

The generated `CMakePresets.json` and `xa_build_configuration.cmake` were diffed against the xaprepare baselines captured before the deletion; only the path separator normalisation (forward slashes throughout) differs, which both CMake and JSON accept on every platform.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jun 30, 2026
### Context

After #11636 (dotnet provisioning step removed) and #11731 (test-deps scenarios removed), `Context.AutoProvision` is `false` by default everywhere except hand-run dev provisioning, which is no longer in use. The per-OS package lists are populated at `OS.Init()` time but `EnsureDependencies` is effectively a no-op:

- `OS.EnsureDependencies()` returns early when `AutoProvision` is false (the default),
- nothing else in the codebase reads from the `Program` derivatives' install/uninstall paths,
- the `BuildToolsInventory` writer remains driven only from `EssentialTools.MacOS.cs` (homebrew version detection).

The `OS.Init() / InitializeDependencies() / EnsureDependencies()` machinery on `OS.cs` itself is intentionally **left in place** here — that's a larger refactor for a follow-up PR. This PR only strips the now-vestigial package-list data and the program/runner classes that fed it.

### Files deleted (Phase F — macOS, 4 files)

- `Application/HomebrewProgram.MacOS.cs`
- `Application/PkgProgram.MacOS.cs`
- `ToolRunners/BrewRunner.MacOS.cs`
- `ToolRunners/PkgutilRunner.MacOS.cs`

### Files deleted (Phase G — Linux, 5 files)

- `Application/Program.Linux.cs` (`LinuxProgram` base — orphan after subclasses go)
- `Application/Program.ArchLinux.cs`
- `Application/Program.DebianLinux.cs`
- `Application/Program.FedoraLinux.cs`
- `Application/Program.GentooLinux.cs`

### Files deleted (Phase 3 — orphan)

- `Application/IBuildInventoryItem.cs` (only implementor was `HomebrewProgram`; `BuildToolsInventory` itself stays, populated directly by `EssentialTools.MacOS.cs`).

### Files reduced to empty stubs

`ConfigAndData/Dependencies/`:
- `MacOS.cs` — `InitializeDependencies()` no-op (was Homebrew formula list + git fallback).
- `Linux.Arch.cs` — class kept (referenced by `distroMap`); package list removed.
- `Linux.Fedora.cs` — same.
- `Linux.Gentoo.cs` — same.
- `Linux.DebianCommon.cs` — common Debian/Ubuntu package list removed; `Flavor = "Debian"` kept.
- `Linux.UbuntuCommon.cs` — `libtoolPackages` + `NeedLibtool` virtual + `InitOS` override removed (all dead).
- `Linux.Debian.cs` — all per-version package lists (`packages`, `packagesPre10`, `packagesPreTrixie`, `packagesTrixieAndLater`, `packages10AndNewerBuildBots`) removed; release/codename detection (`EnsureVersionInformation`, `DebianUnstableVersionMap`, `IsDebian10OrNewer`, etc.) preserved as conservative scope.
- `Linux.Ubuntu.cs` — `preCosmicPackages`, `cosmicPackages`, `preDiscoPackages` lists + `NeedLibtool` override removed; `UbuntuRelease` + `EnsureVersionInformation` preserved.
- `Linux.Mint.cs` — `NeedLibtool` override removed (the property is gone from the base).

`ConfigAndData/Dependencies/Windows.cs` was already a no-op stub — no edit.

### Verification

Orphan audit (each `git grep -nw <Type> -- 'build-tools/xaprepare/*'` reports **0 hits**):

- `HomebrewProgram`, `PkgProgram`, `BrewRunner`, `PkgutilRunner`
- `ArchLinuxProgram`, `DebianLinuxProgram`, `FedoraLinuxProgram`, `GentooLinuxProgram`, `LinuxProgram`
- `IBuildInventoryItem`

Build:

```
dotnet build build-tools\xaprepare\xaprepare\xaprepare.csproj -c Debug
Build succeeded.  0 Warning(s)  0 Error(s)
```

### Out of scope (follow-up)

- Removing the abstract `OS.InitializeDependencies()` declaration and the surrounding `EnsureDependencies()` machinery from `OperatingSystems/OS.cs`.
- `VersionFetchers` / `ProgramVersionParser` / `RegexProgramVersionParser` / `SevenZipVersionParser` / `Extensions.DictionaryOfProgramVersionParser.cs` are kept — `Utilities.GetProgramVersion` still queries them from `Program.cs`, `ToolRunner.cs`, `EssentialTools.MacOS.cs`, and `OperatingSystems/MacOS.cs` (brew detection).

### Precedent

#11568, #11580, #11608, #11613, #11631, #11657, #11658, #11731, #11732, #11733, #11737, #11740, #11760
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants