[xaprepare] Move XABuildConfig generation to AndroidBuildConfig.dll#11826
Merged
Conversation
Mirrors the cmake-config.csproj precedent (#11760): a new Microsoft.Build.NoTargets project at build-tools/scripts/xabuildconfig/xabuildconfig.csproj generates bin/Build$(Configuration)/XABuildConfig.cs from build-tools/scripts/XABuildConfig.cs.in using the existing ReplaceFileContents, GitCommitHash, and GitBranch prep tasks (all hosted via TaskFactory=TaskHostFactory Runtime=NET, per the internal-prep-task convention). All substitution values come from Configuration.props properties already in scope - no new C# task code required. The three consumers that <Compile Include> XABuildConfig.cs now <ProjectReference> the new csproj with ReferenceOutputAssembly=False, ensuring single-execution and ordering for isolated builds: * 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 The generated file is byte-identical to the prior xaprepare output (verified via fc /b against a baseline captured before the change). xaprepare cleanup (the only consumers of these methods/properties were the deleted Get_XABuildConfig_cs and its helpers): * Step_GenerateFiles.cs: deleted Get_XABuildConfig_cs and its GetMajor/GetMinor helpers; the at-build-start list now contains only Get_Configuration_OperatingSystem_props. * BuildInfo.cs: deleted NDKRevision, NDKVersionMajor/Minor/Micro, NDKVersion, cachedNdkVersion, XACommitHash, XABranch, GatherGitInfo, and DetermineXACommitInfo. * Context.cs: removed the `if (SelectedScenario.NeedsGitBuildInfo)` GatherGitInfo block. * Scenario.cs / Scenario_Required.cs / Scenario_Standard.cs: removed the now-unused NeedsGitBuildInfo property and setters. * ConfigAndData/BuildAndroidPlatforms.cs: entire file deleted - AndroidNdkVersion, AndroidNdkPkgRevision, NdkMinimumAPI, and NdkMinimumAPILegacy32 were all sourced from Configuration.props by way of Get_XABuildConfig_cs. * Utilities.cs: deleted ParseAndroidPkgRevision (sole caller was BuildInfo.NDKVersion). * GitRunner.cs: deleted GetTopCommitHash and GetBranchName (sole caller was BuildInfo.DetermineXACommitInfo). The GitRunner class is retained - other consumers (Blame, SubmoduleUpdate, etc.) remain. * README.md: dropped the BuildAndroidPlatforms.cs bullet. Net diff: +6 / -195 (one new ~120-line csproj, ~175 lines of C# removed). Verification: * xaprepare.csproj: 0 warnings, 0 errors. * Xamarin.Android.Build.Tasks.csproj: builds; consumes the MSBuild-generated XABuildConfig.cs unchanged. * Incremental rebuild of xabuildconfig.csproj reports _GenerateXABuildConfig as up-to-date. * fc /b vs baseline: no differences encountered. Precedent PRs in this incremental xaprepare removal stream: #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821, #11825. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ass library Follow-up to commit f6958e4 on this branch. The previous commit moved XABuildConfig.cs generation out of xaprepare into a NoTargets MSBuild project that produced bin/Build$(Configuration)/XABuildConfig.cs and was <Compile Include>'d into three csprojs (Xamarin.Android.Build.Tasks, Xamarin.ProjectTools, Xamarin.Android.Build.Tests). That preserved byte-equivalence with xaprepare's output but kept the long-standing problem that the same type (Xamarin.Android.Tools.XABuildConfig) ended up compiled into three different assemblies. Because Build.Tests references Build.Tasks (which exposes its internals via InternalsVisibleTo), every use of XABuildConfig in test sources produced CS0436 "type conflicts with imported type" warnings — about 22 of them. This commit collapses XABuildConfig to a single definition by making it a real class library: * New project src/AndroidBuildConfig/AndroidBuildConfig.csproj is a regular Microsoft.NET.Sdk netstandard2.0 strong-named assembly. It generates obj/$(Configuration)/$(TargetFramework)/XABuildConfig.cs from XABuildConfig.cs.in (now living alongside the csproj) using the same GitCommitHash / GitBranch / ReplaceFileContents tasks as before, with the BeforeCompile + Compile-inside-target pattern so the generated file lands under obj/ instead of the source tree. * The XABuildConfig class is now public, so consumers reference the assembly normally (the user explicitly OK'd making it public). * The three consumer csprojs lose their <Compile Include> for XABuildConfig.cs and reference AndroidBuildConfig with a normal ProjectReference (no ReferenceOutputAssembly=False). * build-tools/installers/create-installers.targets ships AndroidBuildConfig.dll and .pdb alongside Xamarin.Android.Build.Tasks so the SDK installer carries the new dll. Verification: * AndroidBuildConfig.csproj: 0 warnings, 0 errors. * Xamarin.Android.Build.Tasks.csproj: 0 errors, 85 pre-existing unrelated warnings (none referencing XABuildConfig). * Xamarin.Android.Build.Tests.csproj: 0 errors, 7 warnings — down from ~22, the ~15 XABuildConfig CS0436 warnings are eliminated. * xaprepare.csproj: 0 warnings, 0 errors. * Generated XABuildConfig.cs matches the previous output exactly apart from "static class" -> "public static class" (the intentional change) and the expected commit-hash / branch drift. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Without this the CI build fails on Windows/Linux because the project reference from Xamarin.Android.Build.Tasks (built via the sln in Release) somehow triggers AndroidBuildConfig with Configuration=Debug, so it looks for bin\BuildDebug\net10.0\xa-prep-tasks.dll -- which doesn't exist yet. Adding the project to the sln with proper Debug/Release configuration mappings (mirroring cmake-config which has the same pattern) ensures the solution build passes Configuration correctly. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
simonrozsival
approved these changes
Jul 1, 2026
This was referenced Jul 1, 2026
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>
jonathanpeppers
added a commit
that referenced
this pull request
Jul 1, 2026
…#11945) Follow-up to #11826. After that PR moved XABuildConfig generation to AndroidBuildConfig.dll and removed instance members from BuildInfo, the entire cascade downstream of `BuildInfo.DetermineLastVersionChangeCommit` became unreachable. Removed: * `Application/BuildInfo.cs` (whole file — all members orphan) * `ToolRunners/GitRunner.BlamePorcelainEntry.cs` (whole file) * `GitRunner` `Blame(...)` overloads (3), `ParseBlameLine`, and now-unused `SetCommandArguments` helper * `Context.BuildInfo` property + assignment in `Init()` * `Utilities.ShortenGitHash` and its only consumer `Configurables.Defaults.AbbreviatedHashLength` `BuildInfo.cs.in` was changed from `partial class` to `static class` since only `XAVersion` remains; `Main.cs` still uses `BuildInfo.XAVersion`. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This was referenced Jul 2, 2026
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Moves
XABuildConfig.csgeneration out ofxaprepareand into a new strong-named class library atsrc/AndroidBuildConfig/AndroidBuildConfig.csprojthat producesAndroidBuildConfig.dll.This continues the incremental removal of
xaprepare, following the precedent set bycmake-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.cswas<Compile Include>'d into three different assemblies (Xamarin.Android.Build.Tasks,Xamarin.ProjectTools, andXamarin.Android.Build.Tests), so every test that mentionedXABuildConfigproduced aCS0436"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.Testsbuilds with 7 warnings (none forXABuildConfig).How it works
src/AndroidBuildConfig/AndroidBuildConfig.csproj:Microsoft.NET.Sdk/netstandard2.0, strong-named withproduct.snk.ProjectReferencesXamarin.Android.Tools.AndroidSdk(for theAndroidTargetArchenum used by the template).<UsingTask>sReplaceFileContents,GitCommitHash, andGitBranchfrom$(PrepTasksAssembly), all withTaskFactory="TaskHostFactory" Runtime="NET"per repo convention._GenerateXABuildConfigtarget runsBeforeTargets="BeforeCompile;CoreCompile", computes every substitution from MSBuild properties already exposed byConfiguration.props(NDK major/minor/micro via$(_XAAndroidNdkPkgRevision.Split('.')), API levels viaSplit/Contains, full commit hash viaGitCommitHash.CommitHash, branch viaGitBranch.Branch), and writes the file to$(IntermediateOutputPath)XABuildConfig.cs. The<Compile Include>lives inside the target so it resolves at execution time, whenIntermediateOutputPathis final.XABuildConfigis nowpublic static classinstead ofinternal static class.The three consumer csprojs lose their
<Compile Include="…XABuildConfig.cs" />and now have a normal<ProjectReference Include="…AndroidBuildConfig.csproj" />(noReferenceOutputAssembly="False").build-tools/installers/create-installers.targetsshipsAndroidBuildConfig.dll+.pdbalongsideXamarin.Android.Build.Tasks.dll.xaprepare cleanup
Removed dead code that only existed to feed the old
Get_XABuildConfig_csstep:Step_GenerateFiles.Get_XABuildConfig_csand itsGetMajor/GetMinorlocalsBuildInfo:NDKRevision,NDKVersionMajor,NDKVersionMinor,NDKVersionMicro,NDKVersion,XACommitHash,XABranch,GatherGitInfo,DetermineXACommitInfo,cachedNdkVersionContext: theif (SelectedScenario.NeedsGitBuildInfo) { await BuildInfo.GatherGitInfo … }blockScenario.NeedsGitBuildInfo(and theNeedsGitBuildInfo = true;setters inScenario_StandardandScenario_Required)BuildAndroidPlatforms.cs— entire file (only contained constants used by the deleted code)Utilities.ParseAndroidPkgRevisionGitRunner.GetTopCommitHashandGitRunner.GetBranchName(class retained — still used byBuildInfo.DetermineLastVersionChangeCommit)Files
Added
src/AndroidBuildConfig/AndroidBuildConfig.csprojRenamed/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.csprojsrc/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Xamarin.ProjectTools.csprojsrc/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csprojbuild-tools/installers/create-installers.targetsbuild-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.csbuild-tools/xaprepare/xaprepare/Application/BuildInfo.csbuild-tools/xaprepare/xaprepare/Application/Context.csbuild-tools/xaprepare/xaprepare/Application/Scenario.csbuild-tools/xaprepare/xaprepare/Application/Utilities.csbuild-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.csbuild-tools/xaprepare/xaprepare/Scenarios/Scenario_Required.csbuild-tools/xaprepare/xaprepare/ToolRunners/GitRunner.csbuild-tools/xaprepare/README.mdDeleted
build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.csVerification
AndroidBuildConfig.csproj: 0 warnings, 0 errors.Xamarin.Android.Build.Tasks.csproj: 0 errors, 85 pre-existing unrelated warnings (none forXABuildConfig).Xamarin.Android.Build.Tests.csproj: 0 errors, 7 warnings — down from ~22; allCS0436 XABuildConfigconflicts eliminated.xaprepare.csproj: 0 warnings, 0 errors.XABuildConfig.csis semantically identical to the pre-change xaprepare output. The only token difference is the intentionalstatic 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.