[build] android-platform-support repo consolidation - #11529

Merged
jonathanpeppers merged 6 commits into
mainfrom
jonathanpeppers/inline-android-platform-support
Jun 4, 2026
Merged

[build] android-platform-support repo consolidation#11529
jonathanpeppers merged 6 commits into
mainfrom
jonathanpeppers/inline-android-platform-support

Conversation

@jonathanpeppers

@jonathanpeppersjonathanpeppers commented May 28, 2026

Copy link
Copy Markdown
Member

Inlines the contents of the DevDiv/android-platform-support repo into
dotnet/android, removes the BuildExternal MSBuild target that used to
clone it, and prunes dead code carried over with the migration. The
shipped SDK pack DLLs are unchanged.

What moved in from external/android-platform-support:

  • src/Xamarin.AndroidTools/ - SDK probing helpers (AndroidSdk,
    MonoDroidSdk, ProcessUtils, etc.) used by the debugging tasks
    and the installer.
  • src/Mono.AndroidTools/ - AndroidDevice / adb client used by
    fast deployment and the debugging task assembly.
  • src/Xamarin.Android.Build.Debugging.Tasks/ - the
    Xamarin.Android.Common.Debugging.targets MSBuild tasks (FastDeploy,
    RunActivity, RunTests, GetGdbSymbols, ...).
  • src/Xamarin.Installer.AndroidSDK/,
    src/Xamarin.Installer.Build.Tasks/,
    src/Xamarin.Installer.Common/ - Android SDK installer used by the
    standalone Xamarin Installer / VS Mac Android workload acquisition.
  • tools/fastdev/ - native xamarin.{sync,cp,find,stat} helper
    binaries plus the fastdevtools packaging project consumed during
    fast deployment.
  • external/termux-elf-cleaner - submodule consumed only as a
    build-time tool by the fastdev native binaries.
  • build-tools/android-platform-support/ - version/commit metadata
    for the above projects, kept under this path to preserve legacy
    file names.

Build wiring:

  • Xamarin.Android.sln now references the inlined projects directly.
  • Directory.Build.props, build-tools/scripts/DotNet.targets, and
    build-tools/installers/create-installers.targets lose their
    BuildExternal clone/build of external/android-platform-support
    and pick the assemblies up from the in-tree build instead.
  • installer-files.projitems is inlined into the installer targets
    rather than imported across the submodule boundary.
  • tools/workload-dependencies/WorkloadDependencies.proj reads its
    feed XML from a copy under src/Xamarin.Installer.Build.Tasks/.

Cleanup carried out as part of the migration: removed code, resources,
and tooling files that only existed to serve the standalone
android-platform-support build system and have no consumers in
dotnet/android.

THIRD-PARTY-NOTICES.TXT: added the Apache 2.0 notice for
Kajabity/Kajabity.Tools.Java, which is vendored under
src/Xamarin.Installer.AndroidSDK/ and consumed by the
JavaDependencyInstaller.

Build artifact comparison vs main

Compared nuget-unsigned artifacts from this PR against a recent successful
PR build of main (build 14260748).

Same:

  • All 17 nupkgs shipped (Ref, Runtime.* per-ABI, Sdk.Darwin/Windows,
    Templates, Manifest, etc.)
  • Same file structure (363 vs 367 files in Microsoft.Android.Sdk.Darwin)
  • Common file sizes virtually identical (-64 KB total across all common
    files)

Missing (intentional, safe):

  • tools/lib/{arm64-v8a,armeabi-v7a,x86,x86_64}/installer — 4 ELF
    binaries totaling ~15.6 MB uncompressed (~6 MB compressed, exactly
    accounting for the SDK pack size delta below). These are AOSP
    tools/base/deploy/installer binaries (Android Studio's "Apply Changes"
    fast-deploy helper). Strings analysis confirmed the
    tools/base/deploy/proto/deploy.pb.cc and protobuf symbols.
  • Nothing in dotnet/android invokes them — verified by searching the
    tree for the path and for "ApplyChanges"/"deploy.installer". APS shipped
    them but had no source either; they were pre-built blobs inherited from
    upstream.

Pack size delta:

  • Microsoft.Android.Sdk.Darwin: 145.5 MB vs 151.6 MB (-6.16 MB)
  • Microsoft.Android.Sdk.Windows: 129.1 MB vs 135.3 MB (-6.16 MB)

Ref pack, runtime packs, manifest, and templates are bit-for-bit equivalent
in size. No concerning regressions in the shipped product.

@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from c7fe2d6 to 48ce158CompareMay 28, 2026 17:16
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch 2 times, most recently from 653f3e9 to 2d58ed9CompareMay 28, 2026 18:26
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch 2 times, most recently from b03e93b to 3e04b58CompareMay 28, 2026 19:51
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Inlines the contents of the `DevDiv/android-platform-support` repo into
dotnet/android, removes the `BuildExternal` MSBuild target that used to
clone it, and prunes dead code carried over with the migration. The
shipped SDK pack DLLs are unchanged.
What moved in from `external/android-platform-support`:
* `src/Xamarin.AndroidTools/` - SDK probing helpers (`AndroidSdk`,
`MonoDroidSdk`, `ProcessUtils`, etc.) used by the debugging tasks
and the installer.
* `src/Mono.AndroidTools/` - `AndroidDevice` / `adb` client used by
fast deployment and the debugging task assembly.
* `src/Xamarin.Android.Build.Debugging.Tasks/` - the
`Xamarin.Android.Common.Debugging.targets` MSBuild tasks (FastDeploy,
RunActivity, RunTests, GetGdbSymbols, ...).
* `src/Xamarin.Installer.AndroidSDK/`,
`src/Xamarin.Installer.Build.Tasks/`,
`src/Xamarin.Installer.Common/` - Android SDK installer used by the
standalone Xamarin Installer / VS Mac Android workload acquisition.
* `tools/fastdev/` - native `xamarin.{sync,cp,find,stat}` helper
binaries plus the `fastdevtools` packaging project consumed during
fast deployment.
* `external/termux-elf-cleaner` - submodule consumed only as a
build-time tool by the fastdev native binaries.
* `build-tools/android-platform-support/` - version/commit metadata
for the above projects, kept under this path to preserve legacy
file names.
Build wiring:
* `Xamarin.Android.sln` now references the inlined projects directly.
* `Directory.Build.props`, `build-tools/scripts/DotNet.targets`, and
`build-tools/installers/create-installers.targets` lose their
`BuildExternal` clone/build of `external/android-platform-support`
and pick the assemblies up from the in-tree build instead.
* `installer-files.projitems` is inlined into the installer targets
rather than imported across the submodule boundary.
* `tools/workload-dependencies/WorkloadDependencies.proj` reads its
feed XML from a copy under `src/Xamarin.Installer.Build.Tasks/`.
Cleanup carried out as part of the migration: removed code, resources,
and tooling files that only existed to serve the standalone
`android-platform-support` build system and have no consumers in
dotnet/android.
THIRD-PARTY-NOTICES.TXT: added the Apache 2.0 notice for
`Kajabity/Kajabity.Tools.Java`, which is vendored under
`src/Xamarin.Installer.AndroidSDK/` and consumed by the
`JavaDependencyInstaller`.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 3e04b58 to 51f61b1CompareMay 28, 2026 20:18
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

The only entry in `.external` was `DevDiv/android-platform-support`,
which is now inlined into the tree, so the whole "prepare external git
dependencies" pipeline is dead. Removes:
* The `.external` file consumer (`ExternalGitDependency`,
`Step_PrepareExternalGitDependencies`,
`Scenario_PrepareExternalGitDependencies`,
`CommercialExternalDependencies`,
`ExternalGitDepsFilePath` / `ExternalGitDepsDestDir`).
* `make prepare-external-git-dependencies` and its callers in
`build.sh`, `build.cmd`, and the Linux/macOS CI yaml templates.
* The `PrepareExternal` MSBuild target in `PrepareWindows.targets`
and its `vscode-support.md` documentation entries.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 627d28c to 3d5286fCompareMay 28, 2026 21:43
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

PoliCheck uses signature-based suppressions in .gdnsuppress files (not
PoliCheck.Exclusions.xml). Add the three signatures surfaced by the
PoliCheck build stage:
* source.gdnsuppress: 'country' parameter in KeyManagement.cs (X.509
distinguished-name field, required by the spec).
* CHT.gdnsuppress: false-positive 'PK' from the Cantonese term table
inside a machine-translated zh-Hant resource string.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 58bd369 to f667453CompareJune 2, 2026 17:35
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

…abity
Add signature suppressions for the 17 PoliCheck Notes in the inlined
installer content:
* 16 hits in src/Xamarin.Installer.AndroidSDK/Feeds/AndroidManifestFeed_d18.0.xml
for 'country' / 'countries' (rules 79569/79570). These are verbatim
text from Google's Android SDK, Google TV Add-on, and GDK license
agreements and must not be modified.
* 1 hit in src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/
Kajabity.Tools.Java/JavaPropertyReader.cs (rule 92197 'Hong Kong')
in a third-party doc comment showing sample data with embedded spaces.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppers marked this pull request as ready for review June 3, 2026 13:59
CopilotAI review requested due to automatic review settings June 3, 2026 13:59
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/review

CopilotAI reviewed Jun 3, 2026

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.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@github-actions

github-actionsBot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

@github-actionsgithub-actionsBot 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.

✅ LGTM — Minor issues only

PR: android-platform-support repo consolidation

Well-structured consolidation that inlines DevDiv/android-platform-support into dotnet/android, removes the BuildExternal clone/build flow, and replaces it with a new Step_Android_SDK_NDK xaprepare step. The build artifact comparison in the PR description is thorough and reassuring — the shipped SDK pack DLLs are functionally unchanged and the only delta is the intentional removal of unused AOSP installer ELF binaries.

Summary

SeverityCount
❌ Error1
💡 Suggestion3

Positive callouts:

  • Excellent artifact comparison analysis documenting exactly what changed and what was removed
  • Clean removal of PrepareExternalGitDependencies flow — all references in Makefile, build scripts, YAML pipelines, xaprepare scenarios, and docs are consistently removed
  • The new AndroidToolchain / Step_Android_SDK_NDK code is well-organized with clear separation of per-platform OS tags
  • Good addition of the Kajabity Apache 2.0 notice to THIRD-PARTY-NOTICES.TXT

CI Status

  • dotnet-android — passed
  • 🟡 Xamarin.Android-PR — [in progress]((devdiv.visualstudio.com/redacted)

Generated by Android PR Reviewer for issue #11529 · ● 70.6M

@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Without a ProjectReference to androidsdk.csproj, fastdevtools.csproj
can race against the SDK extraction and find a partially-extracted
cmake (binary present at /sdk/cmake/3.30.3/bin/cmake but share/ not
yet populated), resulting in:
CMake error: File .../share/cmake-3.30/Modules/CMakeCXXCompiler.cmake.in does not exist.
Other native-build projects (proguard-android, bundletool, r8,
java-runtime, manifestmerger) already use this pattern.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppersjonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 4, 2026
@jonathanpeppers
jonathanpeppers merged commit c22cdcf into mainJun 4, 2026
3 checks passed
@jonathanpeppers
jonathanpeppers deleted the jonathanpeppers/inline-android-platform-support branch June 4, 2026 14:23
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
## Why
`bin/configuration.mk` exists only to persist `CONFIGURATION=<value>` between Unix `make` invocations. Removing it lets us delete the only meaningful contents of `Step_GenerateFiles.Unix.cs`, continuing the slow removal of `xaprepare` (see precedent: #11568, #11529).
## What
- Drop `-include bin/configuration.mk` from the top of `Makefile`. The `CONFIGURATION ?= Debug` fallback at the top of the file is unchanged.
- Delete `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.Unix.cs` entirely (it contained `GeneratedConfigurationFile` and a one-line `AddUnixPostBuildSteps` partial that registered it).
The `partial void AddUnixPostBuildSteps (Context context, List<GeneratedFile> steps);` declaration in `Step_GenerateFiles.cs` is intentionally left in place — partial methods without an implementation are legal in C#, and the call site becomes a zero-cost no-op. `Step_GenerateFiles.Windows.cs` implements a *different* partial (`AddOSSpecificSteps`) and is unaffected.
## Why this is safe
| Caller | Pre-change behavior | Post-change behavior |
| --- | --- | --- |
| All CI YAML (`build-linux-steps.yaml`, `build-macos-steps.yaml`, `commercial-build.yaml`, `azure-pipelines-apidocs.yaml`) | Passes `CONFIGURATION=$(XA.Build.Configuration)` on every `make` call | Same — explicit value still wins |
| `build.sh` (`make prepare && make jenkins && make pack-dotnet`) | First `make prepare` runs against an empty `bin/`, so the `-include` no-ops and `?= Debug` takes effect | Identical — `?= Debug` still takes effect |
| Fresh local checkout, bare `make all` | `?= Debug` (no `bin/configuration.mk` yet) | Same |
| Local dev who runs `make prepare CONFIGURATION=Release` then bare `make all` | Persisted Release via `bin/configuration.mk` | Now defaults back to Debug — must pass `CONFIGURATION=Release` on every invocation |
That last case is the only behavior change. It was never documented as a contract anywhere in `Documentation/` or `README.md`, and developers building Release locally should be passing the flag explicitly anyway.
## Verification
- `git grep "configuration\.mk"` and `git grep "GeneratedConfigurationFile"`: zero matches after this change.
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj`: 0 warnings, 0 errors.
- Rubber-duck review: no remaining `Path.Combine(..., "configuration.mk")` references, no Makefile target depends on `bin/configuration.mk` as a prerequisite, and the leftover partial-method declaration is benign.
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
…vailable (#11577)
### Context
PR #11529 inlined `external/android-platform-support` into dotnet/android. `Xamarin.Android.Common.Debugging.targets` is now always built and shipped, so `TestEnvironment.CommercialBuildAvailable` is always `true` and `AssertCommercialBuild()` is a no-op.
### Changes
- Removed `TestEnvironment.CommercialBuildAvailable` property.
- Removed `BaseTest.AssertCommercialBuild()` helper.
- Dropped every `AssertCommercialBuild ();` callsite (~40 lines across 19 files).
- Simplified all `CommercialBuildAvailable` predicate usages, since the value is always `true`:
- `if (TestEnvironment.CommercialBuildAvailable) { X }` → unwrapped to `X`
- `if (!TestEnvironment.CommercialBuildAvailable) { X }` → block deleted
- `if (isRelease || !TestEnvironment.CommercialBuildAvailable)` → `if (isRelease)`
- `TestEnvironment.CommercialBuildAvailable ? "debug" : "release"` → `"debug"`
- `!(TestEnvironment.CommercialBuildAvailable && !isRelease)` → `isRelease`
- `!TestEnvironment.CommercialBuildAvailable && !isRelease` → `false`
- In `InstallAndRunTests.cs`, the `if (TestEnvironment.CommercialBuildAvailable) { ... } else { ... }` block keeps only the (now always-taken) true branch.
### Out of scope
The MSBuild gates (`_HasCommercialFiles`, `_AndroidFastDeploymentSupported`, etc.) are intentionally left alone — those will follow in a separate PR.
### Verification
- `git grep -n AssertCommercialBuild` → 0 hits
- `git grep -n CommercialBuildAvailable` → 0 hits
- Brace-balance check on every modified `.cs` file matches the baseline (HEAD) delta exactly.
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
…Supported gates (#11576)
Follow-up to #11529, which inlined the `external/android-platform-support` repo into dotnet/android. The Debugging.targets/props files and supporting assemblies (`Mono.AndroidTools`, `Xamarin.AndroidTools`, `Xamarin.Installer.*`, `Xamarin.Android.Build.Debugging.Tasks`, `fastdevtools`) are now always built in-tree by `Xamarin.Android.sln`, so several `Exists(...)` MSBuild gates are always true.
This PR removes those dead gates and their dead branches:
- **`build-tools/installers/create-installers.targets`** – drop `_HasCommercialFiles` and make the commercial `_MSBuildFiles` `ItemGroup` unconditional.
- **`Microsoft.Android.Sdk.DefaultProperties.targets`** – drop `_AndroidFastDeploymentSupported`.
- **`Microsoft.Android.Sdk.BuildOrder.targets`** – drop the `'$(_AndroidFastDeploymentSupported)' == 'true'` condition on `DeployToDeviceDependsOnTargets`; delete the dead `!= 'true'` branch.
- **`Microsoft.Android.Sdk.Application.targets`** – same treatment for `_RunDependsOn`; remove the now-stale comment.
- **`Xamarin.Android.Common.targets`** – drop `Exists(...)` from the `Xamarin.Android.Common.Debugging.targets` and `Xamarin.Installer.Common.targets` imports (keep the `'$(DesignTimeBuild)' != 'true'` guards); simplify the two dead `_AndroidFastDeploymentSupported` conditions on `EmbedAssembliesIntoApk`.
- **`Microsoft.Android.Sdk.targets`** – drop `Exists(...)` from the `Xamarin.Android.Common.Debugging.props` import (keep DTB guard).
- **Tests** – drop the now-defensive `proj.SetProperty ("_AndroidFastDeploymentSupported", "true")` calls (and the stale `//NOTE` comment) from `BuildTest.cs` and `InvalidConfigTests.cs`.
`TestEnvironment.CommercialBuildAvailable` / `BaseTest.AssertCommercialBuild()` are intentionally left for a follow-up PR.
After this change `git grep _HasCommercialFiles` and `git grep _AndroidFastDeploymentSupported` both return zero hits.
jonathanpeppers added a commit that referenced this pull request Jun 8, 2026
…11592)
PR #11529 inlined `Mono.AndroidTools` from android-platform-support, which carried PackageReferences to `protobuf-net` 3.2.26 and `protobuf-net.Core` 3.2.26. The original consumer of these packages was the native `tools/base/deploy/installer` binary, which was removed in the same PR. None of the inlined managed code (`Mono.AndroidTools`, `Xamarin.AndroidTools`, `Xamarin.Installer.*`, `Xamarin.Android.Build.Debugging.Tasks`) actually uses the `ProtoBuf` namespace, `[ProtoContract]` / `[ProtoMember]` attributes, or `Serializer.*` calls — so the references are dead weight.
More importantly, they were actively breaking `class-parse`'s Kotlin metadata parsing. `Mono.AndroidTools.csproj` outputs to `MicrosoftAndroidSdkOutDir`, where it dropped a v3 `protobuf-net.dll` (a thin facade) that overwrote the v2 self-contained DLL shipped by Java.Interop's `Xamarin.Android.Tools.Bytecode`. Because `protobuf-net.Core.dll` is not packed into the SDK pack, `class-parse` failed at runtime with `FileNotFoundException: Could not load file or assembly 'protobuf-net.Core, Version=3.0.0.0...'`, and `KotlinFixups.Fixup` silently skipped Kotlin metadata. Bindings then regenerated unsigned types as their signed counterparts, breaking `KotlinUnsignedTypesTests.cs` with CS1503/CS0266 errors.
Drop the v3 references from `Mono.AndroidTools.csproj` and the now-unused `ProtobufNetVersion` / `ProtobufNetCoreVersion` properties from `Directory.Build.props`. The v2 `protobuf-net.dll` from Java.Interop's class-parse becomes the only one in `MicrosoftAndroidSdkOutDir`, restoring Kotlin metadata parsing. The existing `_MSBuildFiles Include=...protobuf-net.dll` and `SignList.xml` `ThirdParty` entry (added in #5529) continue to ship the v2 DLL into the SDK pack.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jun 11, 2026
…#11613)
Continues the slow `xaprepare` removal. Recent precedent: #11568 (CopyExtraResultFilesForCI → YAML), #11580 (configuration.mk removal), #11529 (android-platform-support consolidation, which also dropped `Step_PrepareExternalGitDependencies`).
## What
`Step_PrepareProps` generated `external/Java.Interop/Configuration.Override.props` (inside the submodule) by substituting two placeholders into `build-tools/scripts/Configuration.Java.Interop.Override.in.props`. The substituted properties (`_XamarinAndroidCecilVersion`, `UtilityOutputFullPathCoreApps`, `XamarinAndroidToolsDirectory`) are now supplied directly via the checked-in static file `external/Java.Interop.override.props`, which Java.Interop's own `Directory.Build.props` already auto-imports via the parent-dir convention added in dotnet/java-interop#872.
The shared version values (`MonoCecilVersion`, `AndroidPackVersion`, `AndroidPackVersionSuffix`) move into `eng/Versions.props`. `Directory.Build.props` and `external/Java.Interop.override.props` both `<Import>` it. No duplicate-import sentinel is needed because every code path that imports `Configuration.props` has already loaded `Directory.Build.props` (either via MSBuild auto-load or via the explicit `<Import>` in `external/xamarin-android-tools.override.props`).
`MicrosoftAndroidSdkPackName` stays in `Configuration.props` (it is OS-conditioned, not version-shaped, so it doesn't belong in `Versions.props`). The same 3-line OS-conditioned block is mirrored privately in `external/Java.Interop.override.props` as `_MicrosoftAndroidSdkPackName`, used only to compute `UtilityOutputFullPathCoreApps` for the Java.Interop build.
Also dropped:
- `Configurables.Paths.InstallMSBuildDir` and its backing field — the only consumer was `Step_PrepareProps`.
- The dead `UtilityOutputFullPath` line in the old template — Java.Interop's `TargetFrameworkDependentValues.props` unconditionally routes it to `$(UtilityOutputFullPathCoreApps)` anyway, so it was a no-op.
Updated `build-tools/scripts/XAVersionInfo.targets` (the `GitBlame` for `<AndroidPackVersion>` now points at `eng/Versions.props`) and `Documentation/guides/HowToBranch.md` to reflect the moves.
## Why not just `<Import>` `Directory.Build.props` from the Java.Interop override?
That was the original idea. I prototyped it: importing dotnet/android's full props chain from `external/Java.Interop.override.props` flips `DotNetTargetFrameworkVersion` from `10.0` to `11.0` inside Java.Interop, and `dotnet restore Java.Interop.csproj` then fails with:
```
NETSDK1045: The current .NET SDK does not support targeting .NET 11.0
```
`xamarin-android-tools.override.props` gets away with the same trick only because its sole csproj sets `AndroidToolsDisableMultiTargeting=true`, which makes the TFM-clobber harmless. Java.Interop has no equivalent escape hatch.
`eng/Versions.props` is collision-free with Java.Interop (verified against the submodule sources — none of the existing entries collide), has no `<Import>` of its own, and is the safe minimal shared file.
## Verification
On Windows:
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj` — 0 warnings, 0 errors.
- From `src/Xamarin.Android.Build.Tasks/`: `dotnet msbuild --getProperty:MonoCecilVersion,AndroidPackVersion,AndroidPackVersionSuffix,MicrosoftAndroidSdkPackName,MicrosoftAndroidSdkOutDir` — values unchanged from baseline.
- From `external/Java.Interop/src/Java.Interop/`:
- `dotnet msbuild --getProperty:DotNetTargetFramework,_XamarinAndroidCecilVersion,UtilityOutputFullPathCoreApps` returns `net10.0`, `0.11.5`, the expected packs/tools path.
- `dotnet restore Java.Interop.csproj` succeeds (no `NETSDK1045`).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 5, 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.

4 participants

@jonathanpeppers@simonrozsival@jonpryor
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e 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

[build] android-platform-support repo consolidation - #11529

Merged
jonathanpeppers merged 6 commits into
mainfrom
jonathanpeppers/inline-android-platform-support
Jun 4, 2026
Merged

[build] android-platform-support repo consolidation#11529
jonathanpeppers merged 6 commits into
mainfrom
jonathanpeppers/inline-android-platform-support

Conversation

@jonathanpeppers

@jonathanpeppersjonathanpeppers commented May 28, 2026

Copy link
Copy Markdown
Member

Inlines the contents of the DevDiv/android-platform-support repo into
dotnet/android, removes the BuildExternal MSBuild target that used to
clone it, and prunes dead code carried over with the migration. The
shipped SDK pack DLLs are unchanged.

What moved in from external/android-platform-support:

  • src/Xamarin.AndroidTools/ - SDK probing helpers (AndroidSdk,
    MonoDroidSdk, ProcessUtils, etc.) used by the debugging tasks
    and the installer.
  • src/Mono.AndroidTools/ - AndroidDevice / adb client used by
    fast deployment and the debugging task assembly.
  • src/Xamarin.Android.Build.Debugging.Tasks/ - the
    Xamarin.Android.Common.Debugging.targets MSBuild tasks (FastDeploy,
    RunActivity, RunTests, GetGdbSymbols, ...).
  • src/Xamarin.Installer.AndroidSDK/,
    src/Xamarin.Installer.Build.Tasks/,
    src/Xamarin.Installer.Common/ - Android SDK installer used by the
    standalone Xamarin Installer / VS Mac Android workload acquisition.
  • tools/fastdev/ - native xamarin.{sync,cp,find,stat} helper
    binaries plus the fastdevtools packaging project consumed during
    fast deployment.
  • external/termux-elf-cleaner - submodule consumed only as a
    build-time tool by the fastdev native binaries.
  • build-tools/android-platform-support/ - version/commit metadata
    for the above projects, kept under this path to preserve legacy
    file names.

Build wiring:

  • Xamarin.Android.sln now references the inlined projects directly.
  • Directory.Build.props, build-tools/scripts/DotNet.targets, and
    build-tools/installers/create-installers.targets lose their
    BuildExternal clone/build of external/android-platform-support
    and pick the assemblies up from the in-tree build instead.
  • installer-files.projitems is inlined into the installer targets
    rather than imported across the submodule boundary.
  • tools/workload-dependencies/WorkloadDependencies.proj reads its
    feed XML from a copy under src/Xamarin.Installer.Build.Tasks/.

Cleanup carried out as part of the migration: removed code, resources,
and tooling files that only existed to serve the standalone
android-platform-support build system and have no consumers in
dotnet/android.

THIRD-PARTY-NOTICES.TXT: added the Apache 2.0 notice for
Kajabity/Kajabity.Tools.Java, which is vendored under
src/Xamarin.Installer.AndroidSDK/ and consumed by the
JavaDependencyInstaller.

Build artifact comparison vs main

Compared nuget-unsigned artifacts from this PR against a recent successful
PR build of main (build 14260748).

Same:

  • All 17 nupkgs shipped (Ref, Runtime.* per-ABI, Sdk.Darwin/Windows,
    Templates, Manifest, etc.)
  • Same file structure (363 vs 367 files in Microsoft.Android.Sdk.Darwin)
  • Common file sizes virtually identical (-64 KB total across all common
    files)

Missing (intentional, safe):

  • tools/lib/{arm64-v8a,armeabi-v7a,x86,x86_64}/installer — 4 ELF
    binaries totaling ~15.6 MB uncompressed (~6 MB compressed, exactly
    accounting for the SDK pack size delta below). These are AOSP
    tools/base/deploy/installer binaries (Android Studio's "Apply Changes"
    fast-deploy helper). Strings analysis confirmed the
    tools/base/deploy/proto/deploy.pb.cc and protobuf symbols.
  • Nothing in dotnet/android invokes them — verified by searching the
    tree for the path and for "ApplyChanges"/"deploy.installer". APS shipped
    them but had no source either; they were pre-built blobs inherited from
    upstream.

Pack size delta:

  • Microsoft.Android.Sdk.Darwin: 145.5 MB vs 151.6 MB (-6.16 MB)
  • Microsoft.Android.Sdk.Windows: 129.1 MB vs 135.3 MB (-6.16 MB)

Ref pack, runtime packs, manifest, and templates are bit-for-bit equivalent
in size. No concerning regressions in the shipped product.

@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from c7fe2d6 to 48ce158CompareMay 28, 2026 17:16
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch 2 times, most recently from 653f3e9 to 2d58ed9CompareMay 28, 2026 18:26
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch 2 times, most recently from b03e93b to 3e04b58CompareMay 28, 2026 19:51
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Inlines the contents of the `DevDiv/android-platform-support` repo into
dotnet/android, removes the `BuildExternal` MSBuild target that used to
clone it, and prunes dead code carried over with the migration. The
shipped SDK pack DLLs are unchanged.
What moved in from `external/android-platform-support`:
* `src/Xamarin.AndroidTools/` - SDK probing helpers (`AndroidSdk`,
`MonoDroidSdk`, `ProcessUtils`, etc.) used by the debugging tasks
and the installer.
* `src/Mono.AndroidTools/` - `AndroidDevice` / `adb` client used by
fast deployment and the debugging task assembly.
* `src/Xamarin.Android.Build.Debugging.Tasks/` - the
`Xamarin.Android.Common.Debugging.targets` MSBuild tasks (FastDeploy,
RunActivity, RunTests, GetGdbSymbols, ...).
* `src/Xamarin.Installer.AndroidSDK/`,
`src/Xamarin.Installer.Build.Tasks/`,
`src/Xamarin.Installer.Common/` - Android SDK installer used by the
standalone Xamarin Installer / VS Mac Android workload acquisition.
* `tools/fastdev/` - native `xamarin.{sync,cp,find,stat}` helper
binaries plus the `fastdevtools` packaging project consumed during
fast deployment.
* `external/termux-elf-cleaner` - submodule consumed only as a
build-time tool by the fastdev native binaries.
* `build-tools/android-platform-support/` - version/commit metadata
for the above projects, kept under this path to preserve legacy
file names.
Build wiring:
* `Xamarin.Android.sln` now references the inlined projects directly.
* `Directory.Build.props`, `build-tools/scripts/DotNet.targets`, and
`build-tools/installers/create-installers.targets` lose their
`BuildExternal` clone/build of `external/android-platform-support`
and pick the assemblies up from the in-tree build instead.
* `installer-files.projitems` is inlined into the installer targets
rather than imported across the submodule boundary.
* `tools/workload-dependencies/WorkloadDependencies.proj` reads its
feed XML from a copy under `src/Xamarin.Installer.Build.Tasks/`.
Cleanup carried out as part of the migration: removed code, resources,
and tooling files that only existed to serve the standalone
`android-platform-support` build system and have no consumers in
dotnet/android.
THIRD-PARTY-NOTICES.TXT: added the Apache 2.0 notice for
`Kajabity/Kajabity.Tools.Java`, which is vendored under
`src/Xamarin.Installer.AndroidSDK/` and consumed by the
`JavaDependencyInstaller`.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 3e04b58 to 51f61b1CompareMay 28, 2026 20:18
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

The only entry in `.external` was `DevDiv/android-platform-support`,
which is now inlined into the tree, so the whole "prepare external git
dependencies" pipeline is dead. Removes:
* The `.external` file consumer (`ExternalGitDependency`,
`Step_PrepareExternalGitDependencies`,
`Scenario_PrepareExternalGitDependencies`,
`CommercialExternalDependencies`,
`ExternalGitDepsFilePath` / `ExternalGitDepsDestDir`).
* `make prepare-external-git-dependencies` and its callers in
`build.sh`, `build.cmd`, and the Linux/macOS CI yaml templates.
* The `PrepareExternal` MSBuild target in `PrepareWindows.targets`
and its `vscode-support.md` documentation entries.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 627d28c to 3d5286fCompareMay 28, 2026 21:43
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

PoliCheck uses signature-based suppressions in .gdnsuppress files (not
PoliCheck.Exclusions.xml). Add the three signatures surfaced by the
PoliCheck build stage:
* source.gdnsuppress: 'country' parameter in KeyManagement.cs (X.509
distinguished-name field, required by the spec).
* CHT.gdnsuppress: false-positive 'PK' from the Cantonese term table
inside a machine-translated zh-Hant resource string.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 58bd369 to f667453CompareJune 2, 2026 17:35
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

…abity
Add signature suppressions for the 17 PoliCheck Notes in the inlined
installer content:
* 16 hits in src/Xamarin.Installer.AndroidSDK/Feeds/AndroidManifestFeed_d18.0.xml
for 'country' / 'countries' (rules 79569/79570). These are verbatim
text from Google's Android SDK, Google TV Add-on, and GDK license
agreements and must not be modified.
* 1 hit in src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/
Kajabity.Tools.Java/JavaPropertyReader.cs (rule 92197 'Hong Kong')
in a third-party doc comment showing sample data with embedded spaces.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppers marked this pull request as ready for review June 3, 2026 13:59
CopilotAI review requested due to automatic review settings June 3, 2026 13:59
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/review

CopilotAI reviewed Jun 3, 2026

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.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@github-actions

github-actionsBot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

@github-actionsgithub-actionsBot 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.

✅ LGTM — Minor issues only

PR: android-platform-support repo consolidation

Well-structured consolidation that inlines DevDiv/android-platform-support into dotnet/android, removes the BuildExternal clone/build flow, and replaces it with a new Step_Android_SDK_NDK xaprepare step. The build artifact comparison in the PR description is thorough and reassuring — the shipped SDK pack DLLs are functionally unchanged and the only delta is the intentional removal of unused AOSP installer ELF binaries.

Summary

SeverityCount
❌ Error1
💡 Suggestion3

Positive callouts:

  • Excellent artifact comparison analysis documenting exactly what changed and what was removed
  • Clean removal of PrepareExternalGitDependencies flow — all references in Makefile, build scripts, YAML pipelines, xaprepare scenarios, and docs are consistently removed
  • The new AndroidToolchain / Step_Android_SDK_NDK code is well-organized with clear separation of per-platform OS tags
  • Good addition of the Kajabity Apache 2.0 notice to THIRD-PARTY-NOTICES.TXT

CI Status

  • dotnet-android — passed
  • 🟡 Xamarin.Android-PR — [in progress]((devdiv.visualstudio.com/redacted)

Generated by Android PR Reviewer for issue #11529 · ● 70.6M

@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Without a ProjectReference to androidsdk.csproj, fastdevtools.csproj
can race against the SDK extraction and find a partially-extracted
cmake (binary present at /sdk/cmake/3.30.3/bin/cmake but share/ not
yet populated), resulting in:
CMake error: File .../share/cmake-3.30/Modules/CMakeCXXCompiler.cmake.in does not exist.
Other native-build projects (proguard-android, bundletool, r8,
java-runtime, manifestmerger) already use this pattern.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppersjonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 4, 2026
@jonathanpeppers
jonathanpeppers merged commit c22cdcf into mainJun 4, 2026
3 checks passed
@jonathanpeppers
jonathanpeppers deleted the jonathanpeppers/inline-android-platform-support branch June 4, 2026 14:23
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
## Why
`bin/configuration.mk` exists only to persist `CONFIGURATION=<value>` between Unix `make` invocations. Removing it lets us delete the only meaningful contents of `Step_GenerateFiles.Unix.cs`, continuing the slow removal of `xaprepare` (see precedent: #11568, #11529).
## What
- Drop `-include bin/configuration.mk` from the top of `Makefile`. The `CONFIGURATION ?= Debug` fallback at the top of the file is unchanged.
- Delete `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.Unix.cs` entirely (it contained `GeneratedConfigurationFile` and a one-line `AddUnixPostBuildSteps` partial that registered it).
The `partial void AddUnixPostBuildSteps (Context context, List<GeneratedFile> steps);` declaration in `Step_GenerateFiles.cs` is intentionally left in place — partial methods without an implementation are legal in C#, and the call site becomes a zero-cost no-op. `Step_GenerateFiles.Windows.cs` implements a *different* partial (`AddOSSpecificSteps`) and is unaffected.
## Why this is safe
| Caller | Pre-change behavior | Post-change behavior |
| --- | --- | --- |
| All CI YAML (`build-linux-steps.yaml`, `build-macos-steps.yaml`, `commercial-build.yaml`, `azure-pipelines-apidocs.yaml`) | Passes `CONFIGURATION=$(XA.Build.Configuration)` on every `make` call | Same — explicit value still wins |
| `build.sh` (`make prepare && make jenkins && make pack-dotnet`) | First `make prepare` runs against an empty `bin/`, so the `-include` no-ops and `?= Debug` takes effect | Identical — `?= Debug` still takes effect |
| Fresh local checkout, bare `make all` | `?= Debug` (no `bin/configuration.mk` yet) | Same |
| Local dev who runs `make prepare CONFIGURATION=Release` then bare `make all` | Persisted Release via `bin/configuration.mk` | Now defaults back to Debug — must pass `CONFIGURATION=Release` on every invocation |
That last case is the only behavior change. It was never documented as a contract anywhere in `Documentation/` or `README.md`, and developers building Release locally should be passing the flag explicitly anyway.
## Verification
- `git grep "configuration\.mk"` and `git grep "GeneratedConfigurationFile"`: zero matches after this change.
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj`: 0 warnings, 0 errors.
- Rubber-duck review: no remaining `Path.Combine(..., "configuration.mk")` references, no Makefile target depends on `bin/configuration.mk` as a prerequisite, and the leftover partial-method declaration is benign.
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
…vailable (#11577)
### Context
PR #11529 inlined `external/android-platform-support` into dotnet/android. `Xamarin.Android.Common.Debugging.targets` is now always built and shipped, so `TestEnvironment.CommercialBuildAvailable` is always `true` and `AssertCommercialBuild()` is a no-op.
### Changes
- Removed `TestEnvironment.CommercialBuildAvailable` property.
- Removed `BaseTest.AssertCommercialBuild()` helper.
- Dropped every `AssertCommercialBuild ();` callsite (~40 lines across 19 files).
- Simplified all `CommercialBuildAvailable` predicate usages, since the value is always `true`:
- `if (TestEnvironment.CommercialBuildAvailable) { X }` → unwrapped to `X`
- `if (!TestEnvironment.CommercialBuildAvailable) { X }` → block deleted
- `if (isRelease || !TestEnvironment.CommercialBuildAvailable)` → `if (isRelease)`
- `TestEnvironment.CommercialBuildAvailable ? "debug" : "release"` → `"debug"`
- `!(TestEnvironment.CommercialBuildAvailable && !isRelease)` → `isRelease`
- `!TestEnvironment.CommercialBuildAvailable && !isRelease` → `false`
- In `InstallAndRunTests.cs`, the `if (TestEnvironment.CommercialBuildAvailable) { ... } else { ... }` block keeps only the (now always-taken) true branch.
### Out of scope
The MSBuild gates (`_HasCommercialFiles`, `_AndroidFastDeploymentSupported`, etc.) are intentionally left alone — those will follow in a separate PR.
### Verification
- `git grep -n AssertCommercialBuild` → 0 hits
- `git grep -n CommercialBuildAvailable` → 0 hits
- Brace-balance check on every modified `.cs` file matches the baseline (HEAD) delta exactly.
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
…Supported gates (#11576)
Follow-up to #11529, which inlined the `external/android-platform-support` repo into dotnet/android. The Debugging.targets/props files and supporting assemblies (`Mono.AndroidTools`, `Xamarin.AndroidTools`, `Xamarin.Installer.*`, `Xamarin.Android.Build.Debugging.Tasks`, `fastdevtools`) are now always built in-tree by `Xamarin.Android.sln`, so several `Exists(...)` MSBuild gates are always true.
This PR removes those dead gates and their dead branches:
- **`build-tools/installers/create-installers.targets`** – drop `_HasCommercialFiles` and make the commercial `_MSBuildFiles` `ItemGroup` unconditional.
- **`Microsoft.Android.Sdk.DefaultProperties.targets`** – drop `_AndroidFastDeploymentSupported`.
- **`Microsoft.Android.Sdk.BuildOrder.targets`** – drop the `'$(_AndroidFastDeploymentSupported)' == 'true'` condition on `DeployToDeviceDependsOnTargets`; delete the dead `!= 'true'` branch.
- **`Microsoft.Android.Sdk.Application.targets`** – same treatment for `_RunDependsOn`; remove the now-stale comment.
- **`Xamarin.Android.Common.targets`** – drop `Exists(...)` from the `Xamarin.Android.Common.Debugging.targets` and `Xamarin.Installer.Common.targets` imports (keep the `'$(DesignTimeBuild)' != 'true'` guards); simplify the two dead `_AndroidFastDeploymentSupported` conditions on `EmbedAssembliesIntoApk`.
- **`Microsoft.Android.Sdk.targets`** – drop `Exists(...)` from the `Xamarin.Android.Common.Debugging.props` import (keep DTB guard).
- **Tests** – drop the now-defensive `proj.SetProperty ("_AndroidFastDeploymentSupported", "true")` calls (and the stale `//NOTE` comment) from `BuildTest.cs` and `InvalidConfigTests.cs`.
`TestEnvironment.CommercialBuildAvailable` / `BaseTest.AssertCommercialBuild()` are intentionally left for a follow-up PR.
After this change `git grep _HasCommercialFiles` and `git grep _AndroidFastDeploymentSupported` both return zero hits.
jonathanpeppers added a commit that referenced this pull request Jun 8, 2026
…11592)
PR #11529 inlined `Mono.AndroidTools` from android-platform-support, which carried PackageReferences to `protobuf-net` 3.2.26 and `protobuf-net.Core` 3.2.26. The original consumer of these packages was the native `tools/base/deploy/installer` binary, which was removed in the same PR. None of the inlined managed code (`Mono.AndroidTools`, `Xamarin.AndroidTools`, `Xamarin.Installer.*`, `Xamarin.Android.Build.Debugging.Tasks`) actually uses the `ProtoBuf` namespace, `[ProtoContract]` / `[ProtoMember]` attributes, or `Serializer.*` calls — so the references are dead weight.
More importantly, they were actively breaking `class-parse`'s Kotlin metadata parsing. `Mono.AndroidTools.csproj` outputs to `MicrosoftAndroidSdkOutDir`, where it dropped a v3 `protobuf-net.dll` (a thin facade) that overwrote the v2 self-contained DLL shipped by Java.Interop's `Xamarin.Android.Tools.Bytecode`. Because `protobuf-net.Core.dll` is not packed into the SDK pack, `class-parse` failed at runtime with `FileNotFoundException: Could not load file or assembly 'protobuf-net.Core, Version=3.0.0.0...'`, and `KotlinFixups.Fixup` silently skipped Kotlin metadata. Bindings then regenerated unsigned types as their signed counterparts, breaking `KotlinUnsignedTypesTests.cs` with CS1503/CS0266 errors.
Drop the v3 references from `Mono.AndroidTools.csproj` and the now-unused `ProtobufNetVersion` / `ProtobufNetCoreVersion` properties from `Directory.Build.props`. The v2 `protobuf-net.dll` from Java.Interop's class-parse becomes the only one in `MicrosoftAndroidSdkOutDir`, restoring Kotlin metadata parsing. The existing `_MSBuildFiles Include=...protobuf-net.dll` and `SignList.xml` `ThirdParty` entry (added in #5529) continue to ship the v2 DLL into the SDK pack.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jun 11, 2026
…#11613)
Continues the slow `xaprepare` removal. Recent precedent: #11568 (CopyExtraResultFilesForCI → YAML), #11580 (configuration.mk removal), #11529 (android-platform-support consolidation, which also dropped `Step_PrepareExternalGitDependencies`).
## What
`Step_PrepareProps` generated `external/Java.Interop/Configuration.Override.props` (inside the submodule) by substituting two placeholders into `build-tools/scripts/Configuration.Java.Interop.Override.in.props`. The substituted properties (`_XamarinAndroidCecilVersion`, `UtilityOutputFullPathCoreApps`, `XamarinAndroidToolsDirectory`) are now supplied directly via the checked-in static file `external/Java.Interop.override.props`, which Java.Interop's own `Directory.Build.props` already auto-imports via the parent-dir convention added in dotnet/java-interop#872.
The shared version values (`MonoCecilVersion`, `AndroidPackVersion`, `AndroidPackVersionSuffix`) move into `eng/Versions.props`. `Directory.Build.props` and `external/Java.Interop.override.props` both `<Import>` it. No duplicate-import sentinel is needed because every code path that imports `Configuration.props` has already loaded `Directory.Build.props` (either via MSBuild auto-load or via the explicit `<Import>` in `external/xamarin-android-tools.override.props`).
`MicrosoftAndroidSdkPackName` stays in `Configuration.props` (it is OS-conditioned, not version-shaped, so it doesn't belong in `Versions.props`). The same 3-line OS-conditioned block is mirrored privately in `external/Java.Interop.override.props` as `_MicrosoftAndroidSdkPackName`, used only to compute `UtilityOutputFullPathCoreApps` for the Java.Interop build.
Also dropped:
- `Configurables.Paths.InstallMSBuildDir` and its backing field — the only consumer was `Step_PrepareProps`.
- The dead `UtilityOutputFullPath` line in the old template — Java.Interop's `TargetFrameworkDependentValues.props` unconditionally routes it to `$(UtilityOutputFullPathCoreApps)` anyway, so it was a no-op.
Updated `build-tools/scripts/XAVersionInfo.targets` (the `GitBlame` for `<AndroidPackVersion>` now points at `eng/Versions.props`) and `Documentation/guides/HowToBranch.md` to reflect the moves.
## Why not just `<Import>` `Directory.Build.props` from the Java.Interop override?
That was the original idea. I prototyped it: importing dotnet/android's full props chain from `external/Java.Interop.override.props` flips `DotNetTargetFrameworkVersion` from `10.0` to `11.0` inside Java.Interop, and `dotnet restore Java.Interop.csproj` then fails with:
```
NETSDK1045: The current .NET SDK does not support targeting .NET 11.0
```
`xamarin-android-tools.override.props` gets away with the same trick only because its sole csproj sets `AndroidToolsDisableMultiTargeting=true`, which makes the TFM-clobber harmless. Java.Interop has no equivalent escape hatch.
`eng/Versions.props` is collision-free with Java.Interop (verified against the submodule sources — none of the existing entries collide), has no `<Import>` of its own, and is the safe minimal shared file.
## Verification
On Windows:
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj` — 0 warnings, 0 errors.
- From `src/Xamarin.Android.Build.Tasks/`: `dotnet msbuild --getProperty:MonoCecilVersion,AndroidPackVersion,AndroidPackVersionSuffix,MicrosoftAndroidSdkPackName,MicrosoftAndroidSdkOutDir` — values unchanged from baseline.
- From `external/Java.Interop/src/Java.Interop/`:
- `dotnet msbuild --getProperty:DotNetTargetFramework,_XamarinAndroidCecilVersion,UtilityOutputFullPathCoreApps` returns `net10.0`, `0.11.5`, the expected packs/tools path.
- `dotnet restore Java.Interop.csproj` succeeds (no `NETSDK1045`).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 5, 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.

4 participants

@jonathanpeppers@simonrozsival@jonpryor
, '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

[build] android-platform-support repo consolidation - #11529

Merged
jonathanpeppers merged 6 commits into
mainfrom
jonathanpeppers/inline-android-platform-support
Jun 4, 2026
Merged

[build] android-platform-support repo consolidation#11529
jonathanpeppers merged 6 commits into
mainfrom
jonathanpeppers/inline-android-platform-support

Conversation

@jonathanpeppers

@jonathanpeppersjonathanpeppers commented May 28, 2026

Copy link
Copy Markdown
Member

Inlines the contents of the DevDiv/android-platform-support repo into
dotnet/android, removes the BuildExternal MSBuild target that used to
clone it, and prunes dead code carried over with the migration. The
shipped SDK pack DLLs are unchanged.

What moved in from external/android-platform-support:

  • src/Xamarin.AndroidTools/ - SDK probing helpers (AndroidSdk,
    MonoDroidSdk, ProcessUtils, etc.) used by the debugging tasks
    and the installer.
  • src/Mono.AndroidTools/ - AndroidDevice / adb client used by
    fast deployment and the debugging task assembly.
  • src/Xamarin.Android.Build.Debugging.Tasks/ - the
    Xamarin.Android.Common.Debugging.targets MSBuild tasks (FastDeploy,
    RunActivity, RunTests, GetGdbSymbols, ...).
  • src/Xamarin.Installer.AndroidSDK/,
    src/Xamarin.Installer.Build.Tasks/,
    src/Xamarin.Installer.Common/ - Android SDK installer used by the
    standalone Xamarin Installer / VS Mac Android workload acquisition.
  • tools/fastdev/ - native xamarin.{sync,cp,find,stat} helper
    binaries plus the fastdevtools packaging project consumed during
    fast deployment.
  • external/termux-elf-cleaner - submodule consumed only as a
    build-time tool by the fastdev native binaries.
  • build-tools/android-platform-support/ - version/commit metadata
    for the above projects, kept under this path to preserve legacy
    file names.

Build wiring:

  • Xamarin.Android.sln now references the inlined projects directly.
  • Directory.Build.props, build-tools/scripts/DotNet.targets, and
    build-tools/installers/create-installers.targets lose their
    BuildExternal clone/build of external/android-platform-support
    and pick the assemblies up from the in-tree build instead.
  • installer-files.projitems is inlined into the installer targets
    rather than imported across the submodule boundary.
  • tools/workload-dependencies/WorkloadDependencies.proj reads its
    feed XML from a copy under src/Xamarin.Installer.Build.Tasks/.

Cleanup carried out as part of the migration: removed code, resources,
and tooling files that only existed to serve the standalone
android-platform-support build system and have no consumers in
dotnet/android.

THIRD-PARTY-NOTICES.TXT: added the Apache 2.0 notice for
Kajabity/Kajabity.Tools.Java, which is vendored under
src/Xamarin.Installer.AndroidSDK/ and consumed by the
JavaDependencyInstaller.

Build artifact comparison vs main

Compared nuget-unsigned artifacts from this PR against a recent successful
PR build of main (build 14260748).

Same:

  • All 17 nupkgs shipped (Ref, Runtime.* per-ABI, Sdk.Darwin/Windows,
    Templates, Manifest, etc.)
  • Same file structure (363 vs 367 files in Microsoft.Android.Sdk.Darwin)
  • Common file sizes virtually identical (-64 KB total across all common
    files)

Missing (intentional, safe):

  • tools/lib/{arm64-v8a,armeabi-v7a,x86,x86_64}/installer — 4 ELF
    binaries totaling ~15.6 MB uncompressed (~6 MB compressed, exactly
    accounting for the SDK pack size delta below). These are AOSP
    tools/base/deploy/installer binaries (Android Studio's "Apply Changes"
    fast-deploy helper). Strings analysis confirmed the
    tools/base/deploy/proto/deploy.pb.cc and protobuf symbols.
  • Nothing in dotnet/android invokes them — verified by searching the
    tree for the path and for "ApplyChanges"/"deploy.installer". APS shipped
    them but had no source either; they were pre-built blobs inherited from
    upstream.

Pack size delta:

  • Microsoft.Android.Sdk.Darwin: 145.5 MB vs 151.6 MB (-6.16 MB)
  • Microsoft.Android.Sdk.Windows: 129.1 MB vs 135.3 MB (-6.16 MB)

Ref pack, runtime packs, manifest, and templates are bit-for-bit equivalent
in size. No concerning regressions in the shipped product.

@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from c7fe2d6 to 48ce158CompareMay 28, 2026 17:16
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch 2 times, most recently from 653f3e9 to 2d58ed9CompareMay 28, 2026 18:26
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch 2 times, most recently from b03e93b to 3e04b58CompareMay 28, 2026 19:51
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Inlines the contents of the `DevDiv/android-platform-support` repo into
dotnet/android, removes the `BuildExternal` MSBuild target that used to
clone it, and prunes dead code carried over with the migration. The
shipped SDK pack DLLs are unchanged.
What moved in from `external/android-platform-support`:
* `src/Xamarin.AndroidTools/` - SDK probing helpers (`AndroidSdk`,
`MonoDroidSdk`, `ProcessUtils`, etc.) used by the debugging tasks
and the installer.
* `src/Mono.AndroidTools/` - `AndroidDevice` / `adb` client used by
fast deployment and the debugging task assembly.
* `src/Xamarin.Android.Build.Debugging.Tasks/` - the
`Xamarin.Android.Common.Debugging.targets` MSBuild tasks (FastDeploy,
RunActivity, RunTests, GetGdbSymbols, ...).
* `src/Xamarin.Installer.AndroidSDK/`,
`src/Xamarin.Installer.Build.Tasks/`,
`src/Xamarin.Installer.Common/` - Android SDK installer used by the
standalone Xamarin Installer / VS Mac Android workload acquisition.
* `tools/fastdev/` - native `xamarin.{sync,cp,find,stat}` helper
binaries plus the `fastdevtools` packaging project consumed during
fast deployment.
* `external/termux-elf-cleaner` - submodule consumed only as a
build-time tool by the fastdev native binaries.
* `build-tools/android-platform-support/` - version/commit metadata
for the above projects, kept under this path to preserve legacy
file names.
Build wiring:
* `Xamarin.Android.sln` now references the inlined projects directly.
* `Directory.Build.props`, `build-tools/scripts/DotNet.targets`, and
`build-tools/installers/create-installers.targets` lose their
`BuildExternal` clone/build of `external/android-platform-support`
and pick the assemblies up from the in-tree build instead.
* `installer-files.projitems` is inlined into the installer targets
rather than imported across the submodule boundary.
* `tools/workload-dependencies/WorkloadDependencies.proj` reads its
feed XML from a copy under `src/Xamarin.Installer.Build.Tasks/`.
Cleanup carried out as part of the migration: removed code, resources,
and tooling files that only existed to serve the standalone
`android-platform-support` build system and have no consumers in
dotnet/android.
THIRD-PARTY-NOTICES.TXT: added the Apache 2.0 notice for
`Kajabity/Kajabity.Tools.Java`, which is vendored under
`src/Xamarin.Installer.AndroidSDK/` and consumed by the
`JavaDependencyInstaller`.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 3e04b58 to 51f61b1CompareMay 28, 2026 20:18
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

The only entry in `.external` was `DevDiv/android-platform-support`,
which is now inlined into the tree, so the whole "prepare external git
dependencies" pipeline is dead. Removes:
* The `.external` file consumer (`ExternalGitDependency`,
`Step_PrepareExternalGitDependencies`,
`Scenario_PrepareExternalGitDependencies`,
`CommercialExternalDependencies`,
`ExternalGitDepsFilePath` / `ExternalGitDepsDestDir`).
* `make prepare-external-git-dependencies` and its callers in
`build.sh`, `build.cmd`, and the Linux/macOS CI yaml templates.
* The `PrepareExternal` MSBuild target in `PrepareWindows.targets`
and its `vscode-support.md` documentation entries.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 627d28c to 3d5286fCompareMay 28, 2026 21:43
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

PoliCheck uses signature-based suppressions in .gdnsuppress files (not
PoliCheck.Exclusions.xml). Add the three signatures surfaced by the
PoliCheck build stage:
* source.gdnsuppress: 'country' parameter in KeyManagement.cs (X.509
distinguished-name field, required by the spec).
* CHT.gdnsuppress: false-positive 'PK' from the Cantonese term table
inside a machine-translated zh-Hant resource string.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 58bd369 to f667453CompareJune 2, 2026 17:35
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

…abity
Add signature suppressions for the 17 PoliCheck Notes in the inlined
installer content:
* 16 hits in src/Xamarin.Installer.AndroidSDK/Feeds/AndroidManifestFeed_d18.0.xml
for 'country' / 'countries' (rules 79569/79570). These are verbatim
text from Google's Android SDK, Google TV Add-on, and GDK license
agreements and must not be modified.
* 1 hit in src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/
Kajabity.Tools.Java/JavaPropertyReader.cs (rule 92197 'Hong Kong')
in a third-party doc comment showing sample data with embedded spaces.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppers marked this pull request as ready for review June 3, 2026 13:59
CopilotAI review requested due to automatic review settings June 3, 2026 13:59
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/review

CopilotAI reviewed Jun 3, 2026

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.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@github-actions

github-actionsBot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

@github-actionsgithub-actionsBot 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.

✅ LGTM — Minor issues only

PR: android-platform-support repo consolidation

Well-structured consolidation that inlines DevDiv/android-platform-support into dotnet/android, removes the BuildExternal clone/build flow, and replaces it with a new Step_Android_SDK_NDK xaprepare step. The build artifact comparison in the PR description is thorough and reassuring — the shipped SDK pack DLLs are functionally unchanged and the only delta is the intentional removal of unused AOSP installer ELF binaries.

Summary

SeverityCount
❌ Error1
💡 Suggestion3

Positive callouts:

  • Excellent artifact comparison analysis documenting exactly what changed and what was removed
  • Clean removal of PrepareExternalGitDependencies flow — all references in Makefile, build scripts, YAML pipelines, xaprepare scenarios, and docs are consistently removed
  • The new AndroidToolchain / Step_Android_SDK_NDK code is well-organized with clear separation of per-platform OS tags
  • Good addition of the Kajabity Apache 2.0 notice to THIRD-PARTY-NOTICES.TXT

CI Status

  • dotnet-android — passed
  • 🟡 Xamarin.Android-PR — [in progress]((devdiv.visualstudio.com/redacted)

Generated by Android PR Reviewer for issue #11529 · ● 70.6M

@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Without a ProjectReference to androidsdk.csproj, fastdevtools.csproj
can race against the SDK extraction and find a partially-extracted
cmake (binary present at /sdk/cmake/3.30.3/bin/cmake but share/ not
yet populated), resulting in:
CMake error: File .../share/cmake-3.30/Modules/CMakeCXXCompiler.cmake.in does not exist.
Other native-build projects (proguard-android, bundletool, r8,
java-runtime, manifestmerger) already use this pattern.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppersjonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 4, 2026
@jonathanpeppers
jonathanpeppers merged commit c22cdcf into mainJun 4, 2026
3 checks passed
@jonathanpeppers
jonathanpeppers deleted the jonathanpeppers/inline-android-platform-support branch June 4, 2026 14:23
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
## Why
`bin/configuration.mk` exists only to persist `CONFIGURATION=<value>` between Unix `make` invocations. Removing it lets us delete the only meaningful contents of `Step_GenerateFiles.Unix.cs`, continuing the slow removal of `xaprepare` (see precedent: #11568, #11529).
## What
- Drop `-include bin/configuration.mk` from the top of `Makefile`. The `CONFIGURATION ?= Debug` fallback at the top of the file is unchanged.
- Delete `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.Unix.cs` entirely (it contained `GeneratedConfigurationFile` and a one-line `AddUnixPostBuildSteps` partial that registered it).
The `partial void AddUnixPostBuildSteps (Context context, List<GeneratedFile> steps);` declaration in `Step_GenerateFiles.cs` is intentionally left in place — partial methods without an implementation are legal in C#, and the call site becomes a zero-cost no-op. `Step_GenerateFiles.Windows.cs` implements a *different* partial (`AddOSSpecificSteps`) and is unaffected.
## Why this is safe
| Caller | Pre-change behavior | Post-change behavior |
| --- | --- | --- |
| All CI YAML (`build-linux-steps.yaml`, `build-macos-steps.yaml`, `commercial-build.yaml`, `azure-pipelines-apidocs.yaml`) | Passes `CONFIGURATION=$(XA.Build.Configuration)` on every `make` call | Same — explicit value still wins |
| `build.sh` (`make prepare && make jenkins && make pack-dotnet`) | First `make prepare` runs against an empty `bin/`, so the `-include` no-ops and `?= Debug` takes effect | Identical — `?= Debug` still takes effect |
| Fresh local checkout, bare `make all` | `?= Debug` (no `bin/configuration.mk` yet) | Same |
| Local dev who runs `make prepare CONFIGURATION=Release` then bare `make all` | Persisted Release via `bin/configuration.mk` | Now defaults back to Debug — must pass `CONFIGURATION=Release` on every invocation |
That last case is the only behavior change. It was never documented as a contract anywhere in `Documentation/` or `README.md`, and developers building Release locally should be passing the flag explicitly anyway.
## Verification
- `git grep "configuration\.mk"` and `git grep "GeneratedConfigurationFile"`: zero matches after this change.
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj`: 0 warnings, 0 errors.
- Rubber-duck review: no remaining `Path.Combine(..., "configuration.mk")` references, no Makefile target depends on `bin/configuration.mk` as a prerequisite, and the leftover partial-method declaration is benign.
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
…vailable (#11577)
### Context
PR #11529 inlined `external/android-platform-support` into dotnet/android. `Xamarin.Android.Common.Debugging.targets` is now always built and shipped, so `TestEnvironment.CommercialBuildAvailable` is always `true` and `AssertCommercialBuild()` is a no-op.
### Changes
- Removed `TestEnvironment.CommercialBuildAvailable` property.
- Removed `BaseTest.AssertCommercialBuild()` helper.
- Dropped every `AssertCommercialBuild ();` callsite (~40 lines across 19 files).
- Simplified all `CommercialBuildAvailable` predicate usages, since the value is always `true`:
- `if (TestEnvironment.CommercialBuildAvailable) { X }` → unwrapped to `X`
- `if (!TestEnvironment.CommercialBuildAvailable) { X }` → block deleted
- `if (isRelease || !TestEnvironment.CommercialBuildAvailable)` → `if (isRelease)`
- `TestEnvironment.CommercialBuildAvailable ? "debug" : "release"` → `"debug"`
- `!(TestEnvironment.CommercialBuildAvailable && !isRelease)` → `isRelease`
- `!TestEnvironment.CommercialBuildAvailable && !isRelease` → `false`
- In `InstallAndRunTests.cs`, the `if (TestEnvironment.CommercialBuildAvailable) { ... } else { ... }` block keeps only the (now always-taken) true branch.
### Out of scope
The MSBuild gates (`_HasCommercialFiles`, `_AndroidFastDeploymentSupported`, etc.) are intentionally left alone — those will follow in a separate PR.
### Verification
- `git grep -n AssertCommercialBuild` → 0 hits
- `git grep -n CommercialBuildAvailable` → 0 hits
- Brace-balance check on every modified `.cs` file matches the baseline (HEAD) delta exactly.
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
…Supported gates (#11576)
Follow-up to #11529, which inlined the `external/android-platform-support` repo into dotnet/android. The Debugging.targets/props files and supporting assemblies (`Mono.AndroidTools`, `Xamarin.AndroidTools`, `Xamarin.Installer.*`, `Xamarin.Android.Build.Debugging.Tasks`, `fastdevtools`) are now always built in-tree by `Xamarin.Android.sln`, so several `Exists(...)` MSBuild gates are always true.
This PR removes those dead gates and their dead branches:
- **`build-tools/installers/create-installers.targets`** – drop `_HasCommercialFiles` and make the commercial `_MSBuildFiles` `ItemGroup` unconditional.
- **`Microsoft.Android.Sdk.DefaultProperties.targets`** – drop `_AndroidFastDeploymentSupported`.
- **`Microsoft.Android.Sdk.BuildOrder.targets`** – drop the `'$(_AndroidFastDeploymentSupported)' == 'true'` condition on `DeployToDeviceDependsOnTargets`; delete the dead `!= 'true'` branch.
- **`Microsoft.Android.Sdk.Application.targets`** – same treatment for `_RunDependsOn`; remove the now-stale comment.
- **`Xamarin.Android.Common.targets`** – drop `Exists(...)` from the `Xamarin.Android.Common.Debugging.targets` and `Xamarin.Installer.Common.targets` imports (keep the `'$(DesignTimeBuild)' != 'true'` guards); simplify the two dead `_AndroidFastDeploymentSupported` conditions on `EmbedAssembliesIntoApk`.
- **`Microsoft.Android.Sdk.targets`** – drop `Exists(...)` from the `Xamarin.Android.Common.Debugging.props` import (keep DTB guard).
- **Tests** – drop the now-defensive `proj.SetProperty ("_AndroidFastDeploymentSupported", "true")` calls (and the stale `//NOTE` comment) from `BuildTest.cs` and `InvalidConfigTests.cs`.
`TestEnvironment.CommercialBuildAvailable` / `BaseTest.AssertCommercialBuild()` are intentionally left for a follow-up PR.
After this change `git grep _HasCommercialFiles` and `git grep _AndroidFastDeploymentSupported` both return zero hits.
jonathanpeppers added a commit that referenced this pull request Jun 8, 2026
…11592)
PR #11529 inlined `Mono.AndroidTools` from android-platform-support, which carried PackageReferences to `protobuf-net` 3.2.26 and `protobuf-net.Core` 3.2.26. The original consumer of these packages was the native `tools/base/deploy/installer` binary, which was removed in the same PR. None of the inlined managed code (`Mono.AndroidTools`, `Xamarin.AndroidTools`, `Xamarin.Installer.*`, `Xamarin.Android.Build.Debugging.Tasks`) actually uses the `ProtoBuf` namespace, `[ProtoContract]` / `[ProtoMember]` attributes, or `Serializer.*` calls — so the references are dead weight.
More importantly, they were actively breaking `class-parse`'s Kotlin metadata parsing. `Mono.AndroidTools.csproj` outputs to `MicrosoftAndroidSdkOutDir`, where it dropped a v3 `protobuf-net.dll` (a thin facade) that overwrote the v2 self-contained DLL shipped by Java.Interop's `Xamarin.Android.Tools.Bytecode`. Because `protobuf-net.Core.dll` is not packed into the SDK pack, `class-parse` failed at runtime with `FileNotFoundException: Could not load file or assembly 'protobuf-net.Core, Version=3.0.0.0...'`, and `KotlinFixups.Fixup` silently skipped Kotlin metadata. Bindings then regenerated unsigned types as their signed counterparts, breaking `KotlinUnsignedTypesTests.cs` with CS1503/CS0266 errors.
Drop the v3 references from `Mono.AndroidTools.csproj` and the now-unused `ProtobufNetVersion` / `ProtobufNetCoreVersion` properties from `Directory.Build.props`. The v2 `protobuf-net.dll` from Java.Interop's class-parse becomes the only one in `MicrosoftAndroidSdkOutDir`, restoring Kotlin metadata parsing. The existing `_MSBuildFiles Include=...protobuf-net.dll` and `SignList.xml` `ThirdParty` entry (added in #5529) continue to ship the v2 DLL into the SDK pack.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jun 11, 2026
…#11613)
Continues the slow `xaprepare` removal. Recent precedent: #11568 (CopyExtraResultFilesForCI → YAML), #11580 (configuration.mk removal), #11529 (android-platform-support consolidation, which also dropped `Step_PrepareExternalGitDependencies`).
## What
`Step_PrepareProps` generated `external/Java.Interop/Configuration.Override.props` (inside the submodule) by substituting two placeholders into `build-tools/scripts/Configuration.Java.Interop.Override.in.props`. The substituted properties (`_XamarinAndroidCecilVersion`, `UtilityOutputFullPathCoreApps`, `XamarinAndroidToolsDirectory`) are now supplied directly via the checked-in static file `external/Java.Interop.override.props`, which Java.Interop's own `Directory.Build.props` already auto-imports via the parent-dir convention added in dotnet/java-interop#872.
The shared version values (`MonoCecilVersion`, `AndroidPackVersion`, `AndroidPackVersionSuffix`) move into `eng/Versions.props`. `Directory.Build.props` and `external/Java.Interop.override.props` both `<Import>` it. No duplicate-import sentinel is needed because every code path that imports `Configuration.props` has already loaded `Directory.Build.props` (either via MSBuild auto-load or via the explicit `<Import>` in `external/xamarin-android-tools.override.props`).
`MicrosoftAndroidSdkPackName` stays in `Configuration.props` (it is OS-conditioned, not version-shaped, so it doesn't belong in `Versions.props`). The same 3-line OS-conditioned block is mirrored privately in `external/Java.Interop.override.props` as `_MicrosoftAndroidSdkPackName`, used only to compute `UtilityOutputFullPathCoreApps` for the Java.Interop build.
Also dropped:
- `Configurables.Paths.InstallMSBuildDir` and its backing field — the only consumer was `Step_PrepareProps`.
- The dead `UtilityOutputFullPath` line in the old template — Java.Interop's `TargetFrameworkDependentValues.props` unconditionally routes it to `$(UtilityOutputFullPathCoreApps)` anyway, so it was a no-op.
Updated `build-tools/scripts/XAVersionInfo.targets` (the `GitBlame` for `<AndroidPackVersion>` now points at `eng/Versions.props`) and `Documentation/guides/HowToBranch.md` to reflect the moves.
## Why not just `<Import>` `Directory.Build.props` from the Java.Interop override?
That was the original idea. I prototyped it: importing dotnet/android's full props chain from `external/Java.Interop.override.props` flips `DotNetTargetFrameworkVersion` from `10.0` to `11.0` inside Java.Interop, and `dotnet restore Java.Interop.csproj` then fails with:
```
NETSDK1045: The current .NET SDK does not support targeting .NET 11.0
```
`xamarin-android-tools.override.props` gets away with the same trick only because its sole csproj sets `AndroidToolsDisableMultiTargeting=true`, which makes the TFM-clobber harmless. Java.Interop has no equivalent escape hatch.
`eng/Versions.props` is collision-free with Java.Interop (verified against the submodule sources — none of the existing entries collide), has no `<Import>` of its own, and is the safe minimal shared file.
## Verification
On Windows:
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj` — 0 warnings, 0 errors.
- From `src/Xamarin.Android.Build.Tasks/`: `dotnet msbuild --getProperty:MonoCecilVersion,AndroidPackVersion,AndroidPackVersionSuffix,MicrosoftAndroidSdkPackName,MicrosoftAndroidSdkOutDir` — values unchanged from baseline.
- From `external/Java.Interop/src/Java.Interop/`:
- `dotnet msbuild --getProperty:DotNetTargetFramework,_XamarinAndroidCecilVersion,UtilityOutputFullPathCoreApps` returns `net10.0`, `0.11.5`, the expected packs/tools path.
- `dotnet restore Java.Interop.csproj` succeeds (no `NETSDK1045`).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 5, 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.

4 participants

@jonathanpeppers@simonrozsival@jonpryor
, '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 \u003e 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

[build] android-platform-support repo consolidation - #11529

Merged
jonathanpeppers merged 6 commits into
mainfrom
jonathanpeppers/inline-android-platform-support
Jun 4, 2026
Merged

[build] android-platform-support repo consolidation#11529
jonathanpeppers merged 6 commits into
mainfrom
jonathanpeppers/inline-android-platform-support

Conversation

@jonathanpeppers

@jonathanpeppersjonathanpeppers commented May 28, 2026

Copy link
Copy Markdown
Member

Inlines the contents of the DevDiv/android-platform-support repo into
dotnet/android, removes the BuildExternal MSBuild target that used to
clone it, and prunes dead code carried over with the migration. The
shipped SDK pack DLLs are unchanged.

What moved in from external/android-platform-support:

  • src/Xamarin.AndroidTools/ - SDK probing helpers (AndroidSdk,
    MonoDroidSdk, ProcessUtils, etc.) used by the debugging tasks
    and the installer.
  • src/Mono.AndroidTools/ - AndroidDevice / adb client used by
    fast deployment and the debugging task assembly.
  • src/Xamarin.Android.Build.Debugging.Tasks/ - the
    Xamarin.Android.Common.Debugging.targets MSBuild tasks (FastDeploy,
    RunActivity, RunTests, GetGdbSymbols, ...).
  • src/Xamarin.Installer.AndroidSDK/,
    src/Xamarin.Installer.Build.Tasks/,
    src/Xamarin.Installer.Common/ - Android SDK installer used by the
    standalone Xamarin Installer / VS Mac Android workload acquisition.
  • tools/fastdev/ - native xamarin.{sync,cp,find,stat} helper
    binaries plus the fastdevtools packaging project consumed during
    fast deployment.
  • external/termux-elf-cleaner - submodule consumed only as a
    build-time tool by the fastdev native binaries.
  • build-tools/android-platform-support/ - version/commit metadata
    for the above projects, kept under this path to preserve legacy
    file names.

Build wiring:

  • Xamarin.Android.sln now references the inlined projects directly.
  • Directory.Build.props, build-tools/scripts/DotNet.targets, and
    build-tools/installers/create-installers.targets lose their
    BuildExternal clone/build of external/android-platform-support
    and pick the assemblies up from the in-tree build instead.
  • installer-files.projitems is inlined into the installer targets
    rather than imported across the submodule boundary.
  • tools/workload-dependencies/WorkloadDependencies.proj reads its
    feed XML from a copy under src/Xamarin.Installer.Build.Tasks/.

Cleanup carried out as part of the migration: removed code, resources,
and tooling files that only existed to serve the standalone
android-platform-support build system and have no consumers in
dotnet/android.

THIRD-PARTY-NOTICES.TXT: added the Apache 2.0 notice for
Kajabity/Kajabity.Tools.Java, which is vendored under
src/Xamarin.Installer.AndroidSDK/ and consumed by the
JavaDependencyInstaller.

Build artifact comparison vs main

Compared nuget-unsigned artifacts from this PR against a recent successful
PR build of main (build 14260748).

Same:

  • All 17 nupkgs shipped (Ref, Runtime.* per-ABI, Sdk.Darwin/Windows,
    Templates, Manifest, etc.)
  • Same file structure (363 vs 367 files in Microsoft.Android.Sdk.Darwin)
  • Common file sizes virtually identical (-64 KB total across all common
    files)

Missing (intentional, safe):

  • tools/lib/{arm64-v8a,armeabi-v7a,x86,x86_64}/installer — 4 ELF
    binaries totaling ~15.6 MB uncompressed (~6 MB compressed, exactly
    accounting for the SDK pack size delta below). These are AOSP
    tools/base/deploy/installer binaries (Android Studio's "Apply Changes"
    fast-deploy helper). Strings analysis confirmed the
    tools/base/deploy/proto/deploy.pb.cc and protobuf symbols.
  • Nothing in dotnet/android invokes them — verified by searching the
    tree for the path and for "ApplyChanges"/"deploy.installer". APS shipped
    them but had no source either; they were pre-built blobs inherited from
    upstream.

Pack size delta:

  • Microsoft.Android.Sdk.Darwin: 145.5 MB vs 151.6 MB (-6.16 MB)
  • Microsoft.Android.Sdk.Windows: 129.1 MB vs 135.3 MB (-6.16 MB)

Ref pack, runtime packs, manifest, and templates are bit-for-bit equivalent
in size. No concerning regressions in the shipped product.

@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from c7fe2d6 to 48ce158CompareMay 28, 2026 17:16
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch 2 times, most recently from 653f3e9 to 2d58ed9CompareMay 28, 2026 18:26
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch 2 times, most recently from b03e93b to 3e04b58CompareMay 28, 2026 19:51
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Inlines the contents of the `DevDiv/android-platform-support` repo into
dotnet/android, removes the `BuildExternal` MSBuild target that used to
clone it, and prunes dead code carried over with the migration. The
shipped SDK pack DLLs are unchanged.
What moved in from `external/android-platform-support`:
* `src/Xamarin.AndroidTools/` - SDK probing helpers (`AndroidSdk`,
`MonoDroidSdk`, `ProcessUtils`, etc.) used by the debugging tasks
and the installer.
* `src/Mono.AndroidTools/` - `AndroidDevice` / `adb` client used by
fast deployment and the debugging task assembly.
* `src/Xamarin.Android.Build.Debugging.Tasks/` - the
`Xamarin.Android.Common.Debugging.targets` MSBuild tasks (FastDeploy,
RunActivity, RunTests, GetGdbSymbols, ...).
* `src/Xamarin.Installer.AndroidSDK/`,
`src/Xamarin.Installer.Build.Tasks/`,
`src/Xamarin.Installer.Common/` - Android SDK installer used by the
standalone Xamarin Installer / VS Mac Android workload acquisition.
* `tools/fastdev/` - native `xamarin.{sync,cp,find,stat}` helper
binaries plus the `fastdevtools` packaging project consumed during
fast deployment.
* `external/termux-elf-cleaner` - submodule consumed only as a
build-time tool by the fastdev native binaries.
* `build-tools/android-platform-support/` - version/commit metadata
for the above projects, kept under this path to preserve legacy
file names.
Build wiring:
* `Xamarin.Android.sln` now references the inlined projects directly.
* `Directory.Build.props`, `build-tools/scripts/DotNet.targets`, and
`build-tools/installers/create-installers.targets` lose their
`BuildExternal` clone/build of `external/android-platform-support`
and pick the assemblies up from the in-tree build instead.
* `installer-files.projitems` is inlined into the installer targets
rather than imported across the submodule boundary.
* `tools/workload-dependencies/WorkloadDependencies.proj` reads its
feed XML from a copy under `src/Xamarin.Installer.Build.Tasks/`.
Cleanup carried out as part of the migration: removed code, resources,
and tooling files that only existed to serve the standalone
`android-platform-support` build system and have no consumers in
dotnet/android.
THIRD-PARTY-NOTICES.TXT: added the Apache 2.0 notice for
`Kajabity/Kajabity.Tools.Java`, which is vendored under
`src/Xamarin.Installer.AndroidSDK/` and consumed by the
`JavaDependencyInstaller`.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 3e04b58 to 51f61b1CompareMay 28, 2026 20:18
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

The only entry in `.external` was `DevDiv/android-platform-support`,
which is now inlined into the tree, so the whole "prepare external git
dependencies" pipeline is dead. Removes:
* The `.external` file consumer (`ExternalGitDependency`,
`Step_PrepareExternalGitDependencies`,
`Scenario_PrepareExternalGitDependencies`,
`CommercialExternalDependencies`,
`ExternalGitDepsFilePath` / `ExternalGitDepsDestDir`).
* `make prepare-external-git-dependencies` and its callers in
`build.sh`, `build.cmd`, and the Linux/macOS CI yaml templates.
* The `PrepareExternal` MSBuild target in `PrepareWindows.targets`
and its `vscode-support.md` documentation entries.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 627d28c to 3d5286fCompareMay 28, 2026 21:43
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

PoliCheck uses signature-based suppressions in .gdnsuppress files (not
PoliCheck.Exclusions.xml). Add the three signatures surfaced by the
PoliCheck build stage:
* source.gdnsuppress: 'country' parameter in KeyManagement.cs (X.509
distinguished-name field, required by the spec).
* CHT.gdnsuppress: false-positive 'PK' from the Cantonese term table
inside a machine-translated zh-Hant resource string.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 58bd369 to f667453CompareJune 2, 2026 17:35
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

…abity
Add signature suppressions for the 17 PoliCheck Notes in the inlined
installer content:
* 16 hits in src/Xamarin.Installer.AndroidSDK/Feeds/AndroidManifestFeed_d18.0.xml
for 'country' / 'countries' (rules 79569/79570). These are verbatim
text from Google's Android SDK, Google TV Add-on, and GDK license
agreements and must not be modified.
* 1 hit in src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/
Kajabity.Tools.Java/JavaPropertyReader.cs (rule 92197 'Hong Kong')
in a third-party doc comment showing sample data with embedded spaces.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppers marked this pull request as ready for review June 3, 2026 13:59
CopilotAI review requested due to automatic review settings June 3, 2026 13:59
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/review

CopilotAI reviewed Jun 3, 2026

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.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@github-actions

github-actionsBot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

@github-actionsgithub-actionsBot 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.

✅ LGTM — Minor issues only

PR: android-platform-support repo consolidation

Well-structured consolidation that inlines DevDiv/android-platform-support into dotnet/android, removes the BuildExternal clone/build flow, and replaces it with a new Step_Android_SDK_NDK xaprepare step. The build artifact comparison in the PR description is thorough and reassuring — the shipped SDK pack DLLs are functionally unchanged and the only delta is the intentional removal of unused AOSP installer ELF binaries.

Summary

SeverityCount
❌ Error1
💡 Suggestion3

Positive callouts:

  • Excellent artifact comparison analysis documenting exactly what changed and what was removed
  • Clean removal of PrepareExternalGitDependencies flow — all references in Makefile, build scripts, YAML pipelines, xaprepare scenarios, and docs are consistently removed
  • The new AndroidToolchain / Step_Android_SDK_NDK code is well-organized with clear separation of per-platform OS tags
  • Good addition of the Kajabity Apache 2.0 notice to THIRD-PARTY-NOTICES.TXT

CI Status

  • dotnet-android — passed
  • 🟡 Xamarin.Android-PR — [in progress]((devdiv.visualstudio.com/redacted)

Generated by Android PR Reviewer for issue #11529 · ● 70.6M

@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Without a ProjectReference to androidsdk.csproj, fastdevtools.csproj
can race against the SDK extraction and find a partially-extracted
cmake (binary present at /sdk/cmake/3.30.3/bin/cmake but share/ not
yet populated), resulting in:
CMake error: File .../share/cmake-3.30/Modules/CMakeCXXCompiler.cmake.in does not exist.
Other native-build projects (proguard-android, bundletool, r8,
java-runtime, manifestmerger) already use this pattern.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppersjonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 4, 2026
@jonathanpeppers
jonathanpeppers merged commit c22cdcf into mainJun 4, 2026
3 checks passed
@jonathanpeppers
jonathanpeppers deleted the jonathanpeppers/inline-android-platform-support branch June 4, 2026 14:23
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
## Why
`bin/configuration.mk` exists only to persist `CONFIGURATION=<value>` between Unix `make` invocations. Removing it lets us delete the only meaningful contents of `Step_GenerateFiles.Unix.cs`, continuing the slow removal of `xaprepare` (see precedent: #11568, #11529).
## What
- Drop `-include bin/configuration.mk` from the top of `Makefile`. The `CONFIGURATION ?= Debug` fallback at the top of the file is unchanged.
- Delete `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.Unix.cs` entirely (it contained `GeneratedConfigurationFile` and a one-line `AddUnixPostBuildSteps` partial that registered it).
The `partial void AddUnixPostBuildSteps (Context context, List<GeneratedFile> steps);` declaration in `Step_GenerateFiles.cs` is intentionally left in place — partial methods without an implementation are legal in C#, and the call site becomes a zero-cost no-op. `Step_GenerateFiles.Windows.cs` implements a *different* partial (`AddOSSpecificSteps`) and is unaffected.
## Why this is safe
| Caller | Pre-change behavior | Post-change behavior |
| --- | --- | --- |
| All CI YAML (`build-linux-steps.yaml`, `build-macos-steps.yaml`, `commercial-build.yaml`, `azure-pipelines-apidocs.yaml`) | Passes `CONFIGURATION=$(XA.Build.Configuration)` on every `make` call | Same — explicit value still wins |
| `build.sh` (`make prepare && make jenkins && make pack-dotnet`) | First `make prepare` runs against an empty `bin/`, so the `-include` no-ops and `?= Debug` takes effect | Identical — `?= Debug` still takes effect |
| Fresh local checkout, bare `make all` | `?= Debug` (no `bin/configuration.mk` yet) | Same |
| Local dev who runs `make prepare CONFIGURATION=Release` then bare `make all` | Persisted Release via `bin/configuration.mk` | Now defaults back to Debug — must pass `CONFIGURATION=Release` on every invocation |
That last case is the only behavior change. It was never documented as a contract anywhere in `Documentation/` or `README.md`, and developers building Release locally should be passing the flag explicitly anyway.
## Verification
- `git grep "configuration\.mk"` and `git grep "GeneratedConfigurationFile"`: zero matches after this change.
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj`: 0 warnings, 0 errors.
- Rubber-duck review: no remaining `Path.Combine(..., "configuration.mk")` references, no Makefile target depends on `bin/configuration.mk` as a prerequisite, and the leftover partial-method declaration is benign.
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
…vailable (#11577)
### Context
PR #11529 inlined `external/android-platform-support` into dotnet/android. `Xamarin.Android.Common.Debugging.targets` is now always built and shipped, so `TestEnvironment.CommercialBuildAvailable` is always `true` and `AssertCommercialBuild()` is a no-op.
### Changes
- Removed `TestEnvironment.CommercialBuildAvailable` property.
- Removed `BaseTest.AssertCommercialBuild()` helper.
- Dropped every `AssertCommercialBuild ();` callsite (~40 lines across 19 files).
- Simplified all `CommercialBuildAvailable` predicate usages, since the value is always `true`:
- `if (TestEnvironment.CommercialBuildAvailable) { X }` → unwrapped to `X`
- `if (!TestEnvironment.CommercialBuildAvailable) { X }` → block deleted
- `if (isRelease || !TestEnvironment.CommercialBuildAvailable)` → `if (isRelease)`
- `TestEnvironment.CommercialBuildAvailable ? "debug" : "release"` → `"debug"`
- `!(TestEnvironment.CommercialBuildAvailable && !isRelease)` → `isRelease`
- `!TestEnvironment.CommercialBuildAvailable && !isRelease` → `false`
- In `InstallAndRunTests.cs`, the `if (TestEnvironment.CommercialBuildAvailable) { ... } else { ... }` block keeps only the (now always-taken) true branch.
### Out of scope
The MSBuild gates (`_HasCommercialFiles`, `_AndroidFastDeploymentSupported`, etc.) are intentionally left alone — those will follow in a separate PR.
### Verification
- `git grep -n AssertCommercialBuild` → 0 hits
- `git grep -n CommercialBuildAvailable` → 0 hits
- Brace-balance check on every modified `.cs` file matches the baseline (HEAD) delta exactly.
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
…Supported gates (#11576)
Follow-up to #11529, which inlined the `external/android-platform-support` repo into dotnet/android. The Debugging.targets/props files and supporting assemblies (`Mono.AndroidTools`, `Xamarin.AndroidTools`, `Xamarin.Installer.*`, `Xamarin.Android.Build.Debugging.Tasks`, `fastdevtools`) are now always built in-tree by `Xamarin.Android.sln`, so several `Exists(...)` MSBuild gates are always true.
This PR removes those dead gates and their dead branches:
- **`build-tools/installers/create-installers.targets`** – drop `_HasCommercialFiles` and make the commercial `_MSBuildFiles` `ItemGroup` unconditional.
- **`Microsoft.Android.Sdk.DefaultProperties.targets`** – drop `_AndroidFastDeploymentSupported`.
- **`Microsoft.Android.Sdk.BuildOrder.targets`** – drop the `'$(_AndroidFastDeploymentSupported)' == 'true'` condition on `DeployToDeviceDependsOnTargets`; delete the dead `!= 'true'` branch.
- **`Microsoft.Android.Sdk.Application.targets`** – same treatment for `_RunDependsOn`; remove the now-stale comment.
- **`Xamarin.Android.Common.targets`** – drop `Exists(...)` from the `Xamarin.Android.Common.Debugging.targets` and `Xamarin.Installer.Common.targets` imports (keep the `'$(DesignTimeBuild)' != 'true'` guards); simplify the two dead `_AndroidFastDeploymentSupported` conditions on `EmbedAssembliesIntoApk`.
- **`Microsoft.Android.Sdk.targets`** – drop `Exists(...)` from the `Xamarin.Android.Common.Debugging.props` import (keep DTB guard).
- **Tests** – drop the now-defensive `proj.SetProperty ("_AndroidFastDeploymentSupported", "true")` calls (and the stale `//NOTE` comment) from `BuildTest.cs` and `InvalidConfigTests.cs`.
`TestEnvironment.CommercialBuildAvailable` / `BaseTest.AssertCommercialBuild()` are intentionally left for a follow-up PR.
After this change `git grep _HasCommercialFiles` and `git grep _AndroidFastDeploymentSupported` both return zero hits.
jonathanpeppers added a commit that referenced this pull request Jun 8, 2026
…11592)
PR #11529 inlined `Mono.AndroidTools` from android-platform-support, which carried PackageReferences to `protobuf-net` 3.2.26 and `protobuf-net.Core` 3.2.26. The original consumer of these packages was the native `tools/base/deploy/installer` binary, which was removed in the same PR. None of the inlined managed code (`Mono.AndroidTools`, `Xamarin.AndroidTools`, `Xamarin.Installer.*`, `Xamarin.Android.Build.Debugging.Tasks`) actually uses the `ProtoBuf` namespace, `[ProtoContract]` / `[ProtoMember]` attributes, or `Serializer.*` calls — so the references are dead weight.
More importantly, they were actively breaking `class-parse`'s Kotlin metadata parsing. `Mono.AndroidTools.csproj` outputs to `MicrosoftAndroidSdkOutDir`, where it dropped a v3 `protobuf-net.dll` (a thin facade) that overwrote the v2 self-contained DLL shipped by Java.Interop's `Xamarin.Android.Tools.Bytecode`. Because `protobuf-net.Core.dll` is not packed into the SDK pack, `class-parse` failed at runtime with `FileNotFoundException: Could not load file or assembly 'protobuf-net.Core, Version=3.0.0.0...'`, and `KotlinFixups.Fixup` silently skipped Kotlin metadata. Bindings then regenerated unsigned types as their signed counterparts, breaking `KotlinUnsignedTypesTests.cs` with CS1503/CS0266 errors.
Drop the v3 references from `Mono.AndroidTools.csproj` and the now-unused `ProtobufNetVersion` / `ProtobufNetCoreVersion` properties from `Directory.Build.props`. The v2 `protobuf-net.dll` from Java.Interop's class-parse becomes the only one in `MicrosoftAndroidSdkOutDir`, restoring Kotlin metadata parsing. The existing `_MSBuildFiles Include=...protobuf-net.dll` and `SignList.xml` `ThirdParty` entry (added in #5529) continue to ship the v2 DLL into the SDK pack.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jun 11, 2026
…#11613)
Continues the slow `xaprepare` removal. Recent precedent: #11568 (CopyExtraResultFilesForCI → YAML), #11580 (configuration.mk removal), #11529 (android-platform-support consolidation, which also dropped `Step_PrepareExternalGitDependencies`).
## What
`Step_PrepareProps` generated `external/Java.Interop/Configuration.Override.props` (inside the submodule) by substituting two placeholders into `build-tools/scripts/Configuration.Java.Interop.Override.in.props`. The substituted properties (`_XamarinAndroidCecilVersion`, `UtilityOutputFullPathCoreApps`, `XamarinAndroidToolsDirectory`) are now supplied directly via the checked-in static file `external/Java.Interop.override.props`, which Java.Interop's own `Directory.Build.props` already auto-imports via the parent-dir convention added in dotnet/java-interop#872.
The shared version values (`MonoCecilVersion`, `AndroidPackVersion`, `AndroidPackVersionSuffix`) move into `eng/Versions.props`. `Directory.Build.props` and `external/Java.Interop.override.props` both `<Import>` it. No duplicate-import sentinel is needed because every code path that imports `Configuration.props` has already loaded `Directory.Build.props` (either via MSBuild auto-load or via the explicit `<Import>` in `external/xamarin-android-tools.override.props`).
`MicrosoftAndroidSdkPackName` stays in `Configuration.props` (it is OS-conditioned, not version-shaped, so it doesn't belong in `Versions.props`). The same 3-line OS-conditioned block is mirrored privately in `external/Java.Interop.override.props` as `_MicrosoftAndroidSdkPackName`, used only to compute `UtilityOutputFullPathCoreApps` for the Java.Interop build.
Also dropped:
- `Configurables.Paths.InstallMSBuildDir` and its backing field — the only consumer was `Step_PrepareProps`.
- The dead `UtilityOutputFullPath` line in the old template — Java.Interop's `TargetFrameworkDependentValues.props` unconditionally routes it to `$(UtilityOutputFullPathCoreApps)` anyway, so it was a no-op.
Updated `build-tools/scripts/XAVersionInfo.targets` (the `GitBlame` for `<AndroidPackVersion>` now points at `eng/Versions.props`) and `Documentation/guides/HowToBranch.md` to reflect the moves.
## Why not just `<Import>` `Directory.Build.props` from the Java.Interop override?
That was the original idea. I prototyped it: importing dotnet/android's full props chain from `external/Java.Interop.override.props` flips `DotNetTargetFrameworkVersion` from `10.0` to `11.0` inside Java.Interop, and `dotnet restore Java.Interop.csproj` then fails with:
```
NETSDK1045: The current .NET SDK does not support targeting .NET 11.0
```
`xamarin-android-tools.override.props` gets away with the same trick only because its sole csproj sets `AndroidToolsDisableMultiTargeting=true`, which makes the TFM-clobber harmless. Java.Interop has no equivalent escape hatch.
`eng/Versions.props` is collision-free with Java.Interop (verified against the submodule sources — none of the existing entries collide), has no `<Import>` of its own, and is the safe minimal shared file.
## Verification
On Windows:
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj` — 0 warnings, 0 errors.
- From `src/Xamarin.Android.Build.Tasks/`: `dotnet msbuild --getProperty:MonoCecilVersion,AndroidPackVersion,AndroidPackVersionSuffix,MicrosoftAndroidSdkPackName,MicrosoftAndroidSdkOutDir` — values unchanged from baseline.
- From `external/Java.Interop/src/Java.Interop/`:
- `dotnet msbuild --getProperty:DotNetTargetFramework,_XamarinAndroidCecilVersion,UtilityOutputFullPathCoreApps` returns `net10.0`, `0.11.5`, the expected packs/tools path.
- `dotnet restore Java.Interop.csproj` succeeds (no `NETSDK1045`).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 5, 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.

4 participants

@jonathanpeppers@simonrozsival@jonpryor
, '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

[build] android-platform-support repo consolidation - #11529

Merged
jonathanpeppers merged 6 commits into
mainfrom
jonathanpeppers/inline-android-platform-support
Jun 4, 2026
Merged

[build] android-platform-support repo consolidation#11529
jonathanpeppers merged 6 commits into
mainfrom
jonathanpeppers/inline-android-platform-support

Conversation

@jonathanpeppers

@jonathanpeppersjonathanpeppers commented May 28, 2026

Copy link
Copy Markdown
Member

Inlines the contents of the DevDiv/android-platform-support repo into
dotnet/android, removes the BuildExternal MSBuild target that used to
clone it, and prunes dead code carried over with the migration. The
shipped SDK pack DLLs are unchanged.

What moved in from external/android-platform-support:

  • src/Xamarin.AndroidTools/ - SDK probing helpers (AndroidSdk,
    MonoDroidSdk, ProcessUtils, etc.) used by the debugging tasks
    and the installer.
  • src/Mono.AndroidTools/ - AndroidDevice / adb client used by
    fast deployment and the debugging task assembly.
  • src/Xamarin.Android.Build.Debugging.Tasks/ - the
    Xamarin.Android.Common.Debugging.targets MSBuild tasks (FastDeploy,
    RunActivity, RunTests, GetGdbSymbols, ...).
  • src/Xamarin.Installer.AndroidSDK/,
    src/Xamarin.Installer.Build.Tasks/,
    src/Xamarin.Installer.Common/ - Android SDK installer used by the
    standalone Xamarin Installer / VS Mac Android workload acquisition.
  • tools/fastdev/ - native xamarin.{sync,cp,find,stat} helper
    binaries plus the fastdevtools packaging project consumed during
    fast deployment.
  • external/termux-elf-cleaner - submodule consumed only as a
    build-time tool by the fastdev native binaries.
  • build-tools/android-platform-support/ - version/commit metadata
    for the above projects, kept under this path to preserve legacy
    file names.

Build wiring:

  • Xamarin.Android.sln now references the inlined projects directly.
  • Directory.Build.props, build-tools/scripts/DotNet.targets, and
    build-tools/installers/create-installers.targets lose their
    BuildExternal clone/build of external/android-platform-support
    and pick the assemblies up from the in-tree build instead.
  • installer-files.projitems is inlined into the installer targets
    rather than imported across the submodule boundary.
  • tools/workload-dependencies/WorkloadDependencies.proj reads its
    feed XML from a copy under src/Xamarin.Installer.Build.Tasks/.

Cleanup carried out as part of the migration: removed code, resources,
and tooling files that only existed to serve the standalone
android-platform-support build system and have no consumers in
dotnet/android.

THIRD-PARTY-NOTICES.TXT: added the Apache 2.0 notice for
Kajabity/Kajabity.Tools.Java, which is vendored under
src/Xamarin.Installer.AndroidSDK/ and consumed by the
JavaDependencyInstaller.

Build artifact comparison vs main

Compared nuget-unsigned artifacts from this PR against a recent successful
PR build of main (build 14260748).

Same:

  • All 17 nupkgs shipped (Ref, Runtime.* per-ABI, Sdk.Darwin/Windows,
    Templates, Manifest, etc.)
  • Same file structure (363 vs 367 files in Microsoft.Android.Sdk.Darwin)
  • Common file sizes virtually identical (-64 KB total across all common
    files)

Missing (intentional, safe):

  • tools/lib/{arm64-v8a,armeabi-v7a,x86,x86_64}/installer — 4 ELF
    binaries totaling ~15.6 MB uncompressed (~6 MB compressed, exactly
    accounting for the SDK pack size delta below). These are AOSP
    tools/base/deploy/installer binaries (Android Studio's "Apply Changes"
    fast-deploy helper). Strings analysis confirmed the
    tools/base/deploy/proto/deploy.pb.cc and protobuf symbols.
  • Nothing in dotnet/android invokes them — verified by searching the
    tree for the path and for "ApplyChanges"/"deploy.installer". APS shipped
    them but had no source either; they were pre-built blobs inherited from
    upstream.

Pack size delta:

  • Microsoft.Android.Sdk.Darwin: 145.5 MB vs 151.6 MB (-6.16 MB)
  • Microsoft.Android.Sdk.Windows: 129.1 MB vs 135.3 MB (-6.16 MB)

Ref pack, runtime packs, manifest, and templates are bit-for-bit equivalent
in size. No concerning regressions in the shipped product.

@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from c7fe2d6 to 48ce158CompareMay 28, 2026 17:16
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch 2 times, most recently from 653f3e9 to 2d58ed9CompareMay 28, 2026 18:26
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch 2 times, most recently from b03e93b to 3e04b58CompareMay 28, 2026 19:51
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Inlines the contents of the `DevDiv/android-platform-support` repo into
dotnet/android, removes the `BuildExternal` MSBuild target that used to
clone it, and prunes dead code carried over with the migration. The
shipped SDK pack DLLs are unchanged.
What moved in from `external/android-platform-support`:
* `src/Xamarin.AndroidTools/` - SDK probing helpers (`AndroidSdk`,
`MonoDroidSdk`, `ProcessUtils`, etc.) used by the debugging tasks
and the installer.
* `src/Mono.AndroidTools/` - `AndroidDevice` / `adb` client used by
fast deployment and the debugging task assembly.
* `src/Xamarin.Android.Build.Debugging.Tasks/` - the
`Xamarin.Android.Common.Debugging.targets` MSBuild tasks (FastDeploy,
RunActivity, RunTests, GetGdbSymbols, ...).
* `src/Xamarin.Installer.AndroidSDK/`,
`src/Xamarin.Installer.Build.Tasks/`,
`src/Xamarin.Installer.Common/` - Android SDK installer used by the
standalone Xamarin Installer / VS Mac Android workload acquisition.
* `tools/fastdev/` - native `xamarin.{sync,cp,find,stat}` helper
binaries plus the `fastdevtools` packaging project consumed during
fast deployment.
* `external/termux-elf-cleaner` - submodule consumed only as a
build-time tool by the fastdev native binaries.
* `build-tools/android-platform-support/` - version/commit metadata
for the above projects, kept under this path to preserve legacy
file names.
Build wiring:
* `Xamarin.Android.sln` now references the inlined projects directly.
* `Directory.Build.props`, `build-tools/scripts/DotNet.targets`, and
`build-tools/installers/create-installers.targets` lose their
`BuildExternal` clone/build of `external/android-platform-support`
and pick the assemblies up from the in-tree build instead.
* `installer-files.projitems` is inlined into the installer targets
rather than imported across the submodule boundary.
* `tools/workload-dependencies/WorkloadDependencies.proj` reads its
feed XML from a copy under `src/Xamarin.Installer.Build.Tasks/`.
Cleanup carried out as part of the migration: removed code, resources,
and tooling files that only existed to serve the standalone
`android-platform-support` build system and have no consumers in
dotnet/android.
THIRD-PARTY-NOTICES.TXT: added the Apache 2.0 notice for
`Kajabity/Kajabity.Tools.Java`, which is vendored under
`src/Xamarin.Installer.AndroidSDK/` and consumed by the
`JavaDependencyInstaller`.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 3e04b58 to 51f61b1CompareMay 28, 2026 20:18
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

The only entry in `.external` was `DevDiv/android-platform-support`,
which is now inlined into the tree, so the whole "prepare external git
dependencies" pipeline is dead. Removes:
* The `.external` file consumer (`ExternalGitDependency`,
`Step_PrepareExternalGitDependencies`,
`Scenario_PrepareExternalGitDependencies`,
`CommercialExternalDependencies`,
`ExternalGitDepsFilePath` / `ExternalGitDepsDestDir`).
* `make prepare-external-git-dependencies` and its callers in
`build.sh`, `build.cmd`, and the Linux/macOS CI yaml templates.
* The `PrepareExternal` MSBuild target in `PrepareWindows.targets`
and its `vscode-support.md` documentation entries.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 627d28c to 3d5286fCompareMay 28, 2026 21:43
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

PoliCheck uses signature-based suppressions in .gdnsuppress files (not
PoliCheck.Exclusions.xml). Add the three signatures surfaced by the
PoliCheck build stage:
* source.gdnsuppress: 'country' parameter in KeyManagement.cs (X.509
distinguished-name field, required by the spec).
* CHT.gdnsuppress: false-positive 'PK' from the Cantonese term table
inside a machine-translated zh-Hant resource string.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 58bd369 to f667453CompareJune 2, 2026 17:35
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

…abity
Add signature suppressions for the 17 PoliCheck Notes in the inlined
installer content:
* 16 hits in src/Xamarin.Installer.AndroidSDK/Feeds/AndroidManifestFeed_d18.0.xml
for 'country' / 'countries' (rules 79569/79570). These are verbatim
text from Google's Android SDK, Google TV Add-on, and GDK license
agreements and must not be modified.
* 1 hit in src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/
Kajabity.Tools.Java/JavaPropertyReader.cs (rule 92197 'Hong Kong')
in a third-party doc comment showing sample data with embedded spaces.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppers marked this pull request as ready for review June 3, 2026 13:59
CopilotAI review requested due to automatic review settings June 3, 2026 13:59
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/review

CopilotAI reviewed Jun 3, 2026

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.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@github-actions

github-actionsBot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

@github-actionsgithub-actionsBot 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.

✅ LGTM — Minor issues only

PR: android-platform-support repo consolidation

Well-structured consolidation that inlines DevDiv/android-platform-support into dotnet/android, removes the BuildExternal clone/build flow, and replaces it with a new Step_Android_SDK_NDK xaprepare step. The build artifact comparison in the PR description is thorough and reassuring — the shipped SDK pack DLLs are functionally unchanged and the only delta is the intentional removal of unused AOSP installer ELF binaries.

Summary

SeverityCount
❌ Error1
💡 Suggestion3

Positive callouts:

  • Excellent artifact comparison analysis documenting exactly what changed and what was removed
  • Clean removal of PrepareExternalGitDependencies flow — all references in Makefile, build scripts, YAML pipelines, xaprepare scenarios, and docs are consistently removed
  • The new AndroidToolchain / Step_Android_SDK_NDK code is well-organized with clear separation of per-platform OS tags
  • Good addition of the Kajabity Apache 2.0 notice to THIRD-PARTY-NOTICES.TXT

CI Status

  • dotnet-android — passed
  • 🟡 Xamarin.Android-PR — [in progress]((devdiv.visualstudio.com/redacted)

Generated by Android PR Reviewer for issue #11529 · ● 70.6M

@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Without a ProjectReference to androidsdk.csproj, fastdevtools.csproj
can race against the SDK extraction and find a partially-extracted
cmake (binary present at /sdk/cmake/3.30.3/bin/cmake but share/ not
yet populated), resulting in:
CMake error: File .../share/cmake-3.30/Modules/CMakeCXXCompiler.cmake.in does not exist.
Other native-build projects (proguard-android, bundletool, r8,
java-runtime, manifestmerger) already use this pattern.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppersjonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 4, 2026
@jonathanpeppers
jonathanpeppers merged commit c22cdcf into mainJun 4, 2026
3 checks passed
@jonathanpeppers
jonathanpeppers deleted the jonathanpeppers/inline-android-platform-support branch June 4, 2026 14:23
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
## Why
`bin/configuration.mk` exists only to persist `CONFIGURATION=<value>` between Unix `make` invocations. Removing it lets us delete the only meaningful contents of `Step_GenerateFiles.Unix.cs`, continuing the slow removal of `xaprepare` (see precedent: #11568, #11529).
## What
- Drop `-include bin/configuration.mk` from the top of `Makefile`. The `CONFIGURATION ?= Debug` fallback at the top of the file is unchanged.
- Delete `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.Unix.cs` entirely (it contained `GeneratedConfigurationFile` and a one-line `AddUnixPostBuildSteps` partial that registered it).
The `partial void AddUnixPostBuildSteps (Context context, List<GeneratedFile> steps);` declaration in `Step_GenerateFiles.cs` is intentionally left in place — partial methods without an implementation are legal in C#, and the call site becomes a zero-cost no-op. `Step_GenerateFiles.Windows.cs` implements a *different* partial (`AddOSSpecificSteps`) and is unaffected.
## Why this is safe
| Caller | Pre-change behavior | Post-change behavior |
| --- | --- | --- |
| All CI YAML (`build-linux-steps.yaml`, `build-macos-steps.yaml`, `commercial-build.yaml`, `azure-pipelines-apidocs.yaml`) | Passes `CONFIGURATION=$(XA.Build.Configuration)` on every `make` call | Same — explicit value still wins |
| `build.sh` (`make prepare && make jenkins && make pack-dotnet`) | First `make prepare` runs against an empty `bin/`, so the `-include` no-ops and `?= Debug` takes effect | Identical — `?= Debug` still takes effect |
| Fresh local checkout, bare `make all` | `?= Debug` (no `bin/configuration.mk` yet) | Same |
| Local dev who runs `make prepare CONFIGURATION=Release` then bare `make all` | Persisted Release via `bin/configuration.mk` | Now defaults back to Debug — must pass `CONFIGURATION=Release` on every invocation |
That last case is the only behavior change. It was never documented as a contract anywhere in `Documentation/` or `README.md`, and developers building Release locally should be passing the flag explicitly anyway.
## Verification
- `git grep "configuration\.mk"` and `git grep "GeneratedConfigurationFile"`: zero matches after this change.
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj`: 0 warnings, 0 errors.
- Rubber-duck review: no remaining `Path.Combine(..., "configuration.mk")` references, no Makefile target depends on `bin/configuration.mk` as a prerequisite, and the leftover partial-method declaration is benign.
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
…vailable (#11577)
### Context
PR #11529 inlined `external/android-platform-support` into dotnet/android. `Xamarin.Android.Common.Debugging.targets` is now always built and shipped, so `TestEnvironment.CommercialBuildAvailable` is always `true` and `AssertCommercialBuild()` is a no-op.
### Changes
- Removed `TestEnvironment.CommercialBuildAvailable` property.
- Removed `BaseTest.AssertCommercialBuild()` helper.
- Dropped every `AssertCommercialBuild ();` callsite (~40 lines across 19 files).
- Simplified all `CommercialBuildAvailable` predicate usages, since the value is always `true`:
- `if (TestEnvironment.CommercialBuildAvailable) { X }` → unwrapped to `X`
- `if (!TestEnvironment.CommercialBuildAvailable) { X }` → block deleted
- `if (isRelease || !TestEnvironment.CommercialBuildAvailable)` → `if (isRelease)`
- `TestEnvironment.CommercialBuildAvailable ? "debug" : "release"` → `"debug"`
- `!(TestEnvironment.CommercialBuildAvailable && !isRelease)` → `isRelease`
- `!TestEnvironment.CommercialBuildAvailable && !isRelease` → `false`
- In `InstallAndRunTests.cs`, the `if (TestEnvironment.CommercialBuildAvailable) { ... } else { ... }` block keeps only the (now always-taken) true branch.
### Out of scope
The MSBuild gates (`_HasCommercialFiles`, `_AndroidFastDeploymentSupported`, etc.) are intentionally left alone — those will follow in a separate PR.
### Verification
- `git grep -n AssertCommercialBuild` → 0 hits
- `git grep -n CommercialBuildAvailable` → 0 hits
- Brace-balance check on every modified `.cs` file matches the baseline (HEAD) delta exactly.
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
…Supported gates (#11576)
Follow-up to #11529, which inlined the `external/android-platform-support` repo into dotnet/android. The Debugging.targets/props files and supporting assemblies (`Mono.AndroidTools`, `Xamarin.AndroidTools`, `Xamarin.Installer.*`, `Xamarin.Android.Build.Debugging.Tasks`, `fastdevtools`) are now always built in-tree by `Xamarin.Android.sln`, so several `Exists(...)` MSBuild gates are always true.
This PR removes those dead gates and their dead branches:
- **`build-tools/installers/create-installers.targets`** – drop `_HasCommercialFiles` and make the commercial `_MSBuildFiles` `ItemGroup` unconditional.
- **`Microsoft.Android.Sdk.DefaultProperties.targets`** – drop `_AndroidFastDeploymentSupported`.
- **`Microsoft.Android.Sdk.BuildOrder.targets`** – drop the `'$(_AndroidFastDeploymentSupported)' == 'true'` condition on `DeployToDeviceDependsOnTargets`; delete the dead `!= 'true'` branch.
- **`Microsoft.Android.Sdk.Application.targets`** – same treatment for `_RunDependsOn`; remove the now-stale comment.
- **`Xamarin.Android.Common.targets`** – drop `Exists(...)` from the `Xamarin.Android.Common.Debugging.targets` and `Xamarin.Installer.Common.targets` imports (keep the `'$(DesignTimeBuild)' != 'true'` guards); simplify the two dead `_AndroidFastDeploymentSupported` conditions on `EmbedAssembliesIntoApk`.
- **`Microsoft.Android.Sdk.targets`** – drop `Exists(...)` from the `Xamarin.Android.Common.Debugging.props` import (keep DTB guard).
- **Tests** – drop the now-defensive `proj.SetProperty ("_AndroidFastDeploymentSupported", "true")` calls (and the stale `//NOTE` comment) from `BuildTest.cs` and `InvalidConfigTests.cs`.
`TestEnvironment.CommercialBuildAvailable` / `BaseTest.AssertCommercialBuild()` are intentionally left for a follow-up PR.
After this change `git grep _HasCommercialFiles` and `git grep _AndroidFastDeploymentSupported` both return zero hits.
jonathanpeppers added a commit that referenced this pull request Jun 8, 2026
…11592)
PR #11529 inlined `Mono.AndroidTools` from android-platform-support, which carried PackageReferences to `protobuf-net` 3.2.26 and `protobuf-net.Core` 3.2.26. The original consumer of these packages was the native `tools/base/deploy/installer` binary, which was removed in the same PR. None of the inlined managed code (`Mono.AndroidTools`, `Xamarin.AndroidTools`, `Xamarin.Installer.*`, `Xamarin.Android.Build.Debugging.Tasks`) actually uses the `ProtoBuf` namespace, `[ProtoContract]` / `[ProtoMember]` attributes, or `Serializer.*` calls — so the references are dead weight.
More importantly, they were actively breaking `class-parse`'s Kotlin metadata parsing. `Mono.AndroidTools.csproj` outputs to `MicrosoftAndroidSdkOutDir`, where it dropped a v3 `protobuf-net.dll` (a thin facade) that overwrote the v2 self-contained DLL shipped by Java.Interop's `Xamarin.Android.Tools.Bytecode`. Because `protobuf-net.Core.dll` is not packed into the SDK pack, `class-parse` failed at runtime with `FileNotFoundException: Could not load file or assembly 'protobuf-net.Core, Version=3.0.0.0...'`, and `KotlinFixups.Fixup` silently skipped Kotlin metadata. Bindings then regenerated unsigned types as their signed counterparts, breaking `KotlinUnsignedTypesTests.cs` with CS1503/CS0266 errors.
Drop the v3 references from `Mono.AndroidTools.csproj` and the now-unused `ProtobufNetVersion` / `ProtobufNetCoreVersion` properties from `Directory.Build.props`. The v2 `protobuf-net.dll` from Java.Interop's class-parse becomes the only one in `MicrosoftAndroidSdkOutDir`, restoring Kotlin metadata parsing. The existing `_MSBuildFiles Include=...protobuf-net.dll` and `SignList.xml` `ThirdParty` entry (added in #5529) continue to ship the v2 DLL into the SDK pack.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jun 11, 2026
…#11613)
Continues the slow `xaprepare` removal. Recent precedent: #11568 (CopyExtraResultFilesForCI → YAML), #11580 (configuration.mk removal), #11529 (android-platform-support consolidation, which also dropped `Step_PrepareExternalGitDependencies`).
## What
`Step_PrepareProps` generated `external/Java.Interop/Configuration.Override.props` (inside the submodule) by substituting two placeholders into `build-tools/scripts/Configuration.Java.Interop.Override.in.props`. The substituted properties (`_XamarinAndroidCecilVersion`, `UtilityOutputFullPathCoreApps`, `XamarinAndroidToolsDirectory`) are now supplied directly via the checked-in static file `external/Java.Interop.override.props`, which Java.Interop's own `Directory.Build.props` already auto-imports via the parent-dir convention added in dotnet/java-interop#872.
The shared version values (`MonoCecilVersion`, `AndroidPackVersion`, `AndroidPackVersionSuffix`) move into `eng/Versions.props`. `Directory.Build.props` and `external/Java.Interop.override.props` both `<Import>` it. No duplicate-import sentinel is needed because every code path that imports `Configuration.props` has already loaded `Directory.Build.props` (either via MSBuild auto-load or via the explicit `<Import>` in `external/xamarin-android-tools.override.props`).
`MicrosoftAndroidSdkPackName` stays in `Configuration.props` (it is OS-conditioned, not version-shaped, so it doesn't belong in `Versions.props`). The same 3-line OS-conditioned block is mirrored privately in `external/Java.Interop.override.props` as `_MicrosoftAndroidSdkPackName`, used only to compute `UtilityOutputFullPathCoreApps` for the Java.Interop build.
Also dropped:
- `Configurables.Paths.InstallMSBuildDir` and its backing field — the only consumer was `Step_PrepareProps`.
- The dead `UtilityOutputFullPath` line in the old template — Java.Interop's `TargetFrameworkDependentValues.props` unconditionally routes it to `$(UtilityOutputFullPathCoreApps)` anyway, so it was a no-op.
Updated `build-tools/scripts/XAVersionInfo.targets` (the `GitBlame` for `<AndroidPackVersion>` now points at `eng/Versions.props`) and `Documentation/guides/HowToBranch.md` to reflect the moves.
## Why not just `<Import>` `Directory.Build.props` from the Java.Interop override?
That was the original idea. I prototyped it: importing dotnet/android's full props chain from `external/Java.Interop.override.props` flips `DotNetTargetFrameworkVersion` from `10.0` to `11.0` inside Java.Interop, and `dotnet restore Java.Interop.csproj` then fails with:
```
NETSDK1045: The current .NET SDK does not support targeting .NET 11.0
```
`xamarin-android-tools.override.props` gets away with the same trick only because its sole csproj sets `AndroidToolsDisableMultiTargeting=true`, which makes the TFM-clobber harmless. Java.Interop has no equivalent escape hatch.
`eng/Versions.props` is collision-free with Java.Interop (verified against the submodule sources — none of the existing entries collide), has no `<Import>` of its own, and is the safe minimal shared file.
## Verification
On Windows:
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj` — 0 warnings, 0 errors.
- From `src/Xamarin.Android.Build.Tasks/`: `dotnet msbuild --getProperty:MonoCecilVersion,AndroidPackVersion,AndroidPackVersionSuffix,MicrosoftAndroidSdkPackName,MicrosoftAndroidSdkOutDir` — values unchanged from baseline.
- From `external/Java.Interop/src/Java.Interop/`:
- `dotnet msbuild --getProperty:DotNetTargetFramework,_XamarinAndroidCecilVersion,UtilityOutputFullPathCoreApps` returns `net10.0`, `0.11.5`, the expected packs/tools path.
- `dotnet restore Java.Interop.csproj` succeeds (no `NETSDK1045`).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 5, 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.

4 participants

@jonathanpeppers@simonrozsival@jonpryor
, '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

[build] android-platform-support repo consolidation - #11529

Merged
jonathanpeppers merged 6 commits into
mainfrom
jonathanpeppers/inline-android-platform-support
Jun 4, 2026
Merged

[build] android-platform-support repo consolidation#11529
jonathanpeppers merged 6 commits into
mainfrom
jonathanpeppers/inline-android-platform-support

Conversation

@jonathanpeppers

@jonathanpeppersjonathanpeppers commented May 28, 2026

Copy link
Copy Markdown
Member

Inlines the contents of the DevDiv/android-platform-support repo into
dotnet/android, removes the BuildExternal MSBuild target that used to
clone it, and prunes dead code carried over with the migration. The
shipped SDK pack DLLs are unchanged.

What moved in from external/android-platform-support:

  • src/Xamarin.AndroidTools/ - SDK probing helpers (AndroidSdk,
    MonoDroidSdk, ProcessUtils, etc.) used by the debugging tasks
    and the installer.
  • src/Mono.AndroidTools/ - AndroidDevice / adb client used by
    fast deployment and the debugging task assembly.
  • src/Xamarin.Android.Build.Debugging.Tasks/ - the
    Xamarin.Android.Common.Debugging.targets MSBuild tasks (FastDeploy,
    RunActivity, RunTests, GetGdbSymbols, ...).
  • src/Xamarin.Installer.AndroidSDK/,
    src/Xamarin.Installer.Build.Tasks/,
    src/Xamarin.Installer.Common/ - Android SDK installer used by the
    standalone Xamarin Installer / VS Mac Android workload acquisition.
  • tools/fastdev/ - native xamarin.{sync,cp,find,stat} helper
    binaries plus the fastdevtools packaging project consumed during
    fast deployment.
  • external/termux-elf-cleaner - submodule consumed only as a
    build-time tool by the fastdev native binaries.
  • build-tools/android-platform-support/ - version/commit metadata
    for the above projects, kept under this path to preserve legacy
    file names.

Build wiring:

  • Xamarin.Android.sln now references the inlined projects directly.
  • Directory.Build.props, build-tools/scripts/DotNet.targets, and
    build-tools/installers/create-installers.targets lose their
    BuildExternal clone/build of external/android-platform-support
    and pick the assemblies up from the in-tree build instead.
  • installer-files.projitems is inlined into the installer targets
    rather than imported across the submodule boundary.
  • tools/workload-dependencies/WorkloadDependencies.proj reads its
    feed XML from a copy under src/Xamarin.Installer.Build.Tasks/.

Cleanup carried out as part of the migration: removed code, resources,
and tooling files that only existed to serve the standalone
android-platform-support build system and have no consumers in
dotnet/android.

THIRD-PARTY-NOTICES.TXT: added the Apache 2.0 notice for
Kajabity/Kajabity.Tools.Java, which is vendored under
src/Xamarin.Installer.AndroidSDK/ and consumed by the
JavaDependencyInstaller.

Build artifact comparison vs main

Compared nuget-unsigned artifacts from this PR against a recent successful
PR build of main (build 14260748).

Same:

  • All 17 nupkgs shipped (Ref, Runtime.* per-ABI, Sdk.Darwin/Windows,
    Templates, Manifest, etc.)
  • Same file structure (363 vs 367 files in Microsoft.Android.Sdk.Darwin)
  • Common file sizes virtually identical (-64 KB total across all common
    files)

Missing (intentional, safe):

  • tools/lib/{arm64-v8a,armeabi-v7a,x86,x86_64}/installer — 4 ELF
    binaries totaling ~15.6 MB uncompressed (~6 MB compressed, exactly
    accounting for the SDK pack size delta below). These are AOSP
    tools/base/deploy/installer binaries (Android Studio's "Apply Changes"
    fast-deploy helper). Strings analysis confirmed the
    tools/base/deploy/proto/deploy.pb.cc and protobuf symbols.
  • Nothing in dotnet/android invokes them — verified by searching the
    tree for the path and for "ApplyChanges"/"deploy.installer". APS shipped
    them but had no source either; they were pre-built blobs inherited from
    upstream.

Pack size delta:

  • Microsoft.Android.Sdk.Darwin: 145.5 MB vs 151.6 MB (-6.16 MB)
  • Microsoft.Android.Sdk.Windows: 129.1 MB vs 135.3 MB (-6.16 MB)

Ref pack, runtime packs, manifest, and templates are bit-for-bit equivalent
in size. No concerning regressions in the shipped product.

@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from c7fe2d6 to 48ce158CompareMay 28, 2026 17:16
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch 2 times, most recently from 653f3e9 to 2d58ed9CompareMay 28, 2026 18:26
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch 2 times, most recently from b03e93b to 3e04b58CompareMay 28, 2026 19:51
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Inlines the contents of the `DevDiv/android-platform-support` repo into
dotnet/android, removes the `BuildExternal` MSBuild target that used to
clone it, and prunes dead code carried over with the migration. The
shipped SDK pack DLLs are unchanged.
What moved in from `external/android-platform-support`:
* `src/Xamarin.AndroidTools/` - SDK probing helpers (`AndroidSdk`,
`MonoDroidSdk`, `ProcessUtils`, etc.) used by the debugging tasks
and the installer.
* `src/Mono.AndroidTools/` - `AndroidDevice` / `adb` client used by
fast deployment and the debugging task assembly.
* `src/Xamarin.Android.Build.Debugging.Tasks/` - the
`Xamarin.Android.Common.Debugging.targets` MSBuild tasks (FastDeploy,
RunActivity, RunTests, GetGdbSymbols, ...).
* `src/Xamarin.Installer.AndroidSDK/`,
`src/Xamarin.Installer.Build.Tasks/`,
`src/Xamarin.Installer.Common/` - Android SDK installer used by the
standalone Xamarin Installer / VS Mac Android workload acquisition.
* `tools/fastdev/` - native `xamarin.{sync,cp,find,stat}` helper
binaries plus the `fastdevtools` packaging project consumed during
fast deployment.
* `external/termux-elf-cleaner` - submodule consumed only as a
build-time tool by the fastdev native binaries.
* `build-tools/android-platform-support/` - version/commit metadata
for the above projects, kept under this path to preserve legacy
file names.
Build wiring:
* `Xamarin.Android.sln` now references the inlined projects directly.
* `Directory.Build.props`, `build-tools/scripts/DotNet.targets`, and
`build-tools/installers/create-installers.targets` lose their
`BuildExternal` clone/build of `external/android-platform-support`
and pick the assemblies up from the in-tree build instead.
* `installer-files.projitems` is inlined into the installer targets
rather than imported across the submodule boundary.
* `tools/workload-dependencies/WorkloadDependencies.proj` reads its
feed XML from a copy under `src/Xamarin.Installer.Build.Tasks/`.
Cleanup carried out as part of the migration: removed code, resources,
and tooling files that only existed to serve the standalone
`android-platform-support` build system and have no consumers in
dotnet/android.
THIRD-PARTY-NOTICES.TXT: added the Apache 2.0 notice for
`Kajabity/Kajabity.Tools.Java`, which is vendored under
`src/Xamarin.Installer.AndroidSDK/` and consumed by the
`JavaDependencyInstaller`.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 3e04b58 to 51f61b1CompareMay 28, 2026 20:18
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

The only entry in `.external` was `DevDiv/android-platform-support`,
which is now inlined into the tree, so the whole "prepare external git
dependencies" pipeline is dead. Removes:
* The `.external` file consumer (`ExternalGitDependency`,
`Step_PrepareExternalGitDependencies`,
`Scenario_PrepareExternalGitDependencies`,
`CommercialExternalDependencies`,
`ExternalGitDepsFilePath` / `ExternalGitDepsDestDir`).
* `make prepare-external-git-dependencies` and its callers in
`build.sh`, `build.cmd`, and the Linux/macOS CI yaml templates.
* The `PrepareExternal` MSBuild target in `PrepareWindows.targets`
and its `vscode-support.md` documentation entries.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 627d28c to 3d5286fCompareMay 28, 2026 21:43
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

PoliCheck uses signature-based suppressions in .gdnsuppress files (not
PoliCheck.Exclusions.xml). Add the three signatures surfaced by the
PoliCheck build stage:
* source.gdnsuppress: 'country' parameter in KeyManagement.cs (X.509
distinguished-name field, required by the spec).
* CHT.gdnsuppress: false-positive 'PK' from the Cantonese term table
inside a machine-translated zh-Hant resource string.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 58bd369 to f667453CompareJune 2, 2026 17:35
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

…abity
Add signature suppressions for the 17 PoliCheck Notes in the inlined
installer content:
* 16 hits in src/Xamarin.Installer.AndroidSDK/Feeds/AndroidManifestFeed_d18.0.xml
for 'country' / 'countries' (rules 79569/79570). These are verbatim
text from Google's Android SDK, Google TV Add-on, and GDK license
agreements and must not be modified.
* 1 hit in src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/
Kajabity.Tools.Java/JavaPropertyReader.cs (rule 92197 'Hong Kong')
in a third-party doc comment showing sample data with embedded spaces.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppers marked this pull request as ready for review June 3, 2026 13:59
CopilotAI review requested due to automatic review settings June 3, 2026 13:59
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/review

CopilotAI reviewed Jun 3, 2026

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.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@github-actions

github-actionsBot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

@github-actionsgithub-actionsBot 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.

✅ LGTM — Minor issues only

PR: android-platform-support repo consolidation

Well-structured consolidation that inlines DevDiv/android-platform-support into dotnet/android, removes the BuildExternal clone/build flow, and replaces it with a new Step_Android_SDK_NDK xaprepare step. The build artifact comparison in the PR description is thorough and reassuring — the shipped SDK pack DLLs are functionally unchanged and the only delta is the intentional removal of unused AOSP installer ELF binaries.

Summary

SeverityCount
❌ Error1
💡 Suggestion3

Positive callouts:

  • Excellent artifact comparison analysis documenting exactly what changed and what was removed
  • Clean removal of PrepareExternalGitDependencies flow — all references in Makefile, build scripts, YAML pipelines, xaprepare scenarios, and docs are consistently removed
  • The new AndroidToolchain / Step_Android_SDK_NDK code is well-organized with clear separation of per-platform OS tags
  • Good addition of the Kajabity Apache 2.0 notice to THIRD-PARTY-NOTICES.TXT

CI Status

  • dotnet-android — passed
  • 🟡 Xamarin.Android-PR — [in progress]((devdiv.visualstudio.com/redacted)

Generated by Android PR Reviewer for issue #11529 · ● 70.6M

@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Without a ProjectReference to androidsdk.csproj, fastdevtools.csproj
can race against the SDK extraction and find a partially-extracted
cmake (binary present at /sdk/cmake/3.30.3/bin/cmake but share/ not
yet populated), resulting in:
CMake error: File .../share/cmake-3.30/Modules/CMakeCXXCompiler.cmake.in does not exist.
Other native-build projects (proguard-android, bundletool, r8,
java-runtime, manifestmerger) already use this pattern.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppersjonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 4, 2026
@jonathanpeppers
jonathanpeppers merged commit c22cdcf into mainJun 4, 2026
3 checks passed
@jonathanpeppers
jonathanpeppers deleted the jonathanpeppers/inline-android-platform-support branch June 4, 2026 14:23
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
## Why
`bin/configuration.mk` exists only to persist `CONFIGURATION=<value>` between Unix `make` invocations. Removing it lets us delete the only meaningful contents of `Step_GenerateFiles.Unix.cs`, continuing the slow removal of `xaprepare` (see precedent: #11568, #11529).
## What
- Drop `-include bin/configuration.mk` from the top of `Makefile`. The `CONFIGURATION ?= Debug` fallback at the top of the file is unchanged.
- Delete `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.Unix.cs` entirely (it contained `GeneratedConfigurationFile` and a one-line `AddUnixPostBuildSteps` partial that registered it).
The `partial void AddUnixPostBuildSteps (Context context, List<GeneratedFile> steps);` declaration in `Step_GenerateFiles.cs` is intentionally left in place — partial methods without an implementation are legal in C#, and the call site becomes a zero-cost no-op. `Step_GenerateFiles.Windows.cs` implements a *different* partial (`AddOSSpecificSteps`) and is unaffected.
## Why this is safe
| Caller | Pre-change behavior | Post-change behavior |
| --- | --- | --- |
| All CI YAML (`build-linux-steps.yaml`, `build-macos-steps.yaml`, `commercial-build.yaml`, `azure-pipelines-apidocs.yaml`) | Passes `CONFIGURATION=$(XA.Build.Configuration)` on every `make` call | Same — explicit value still wins |
| `build.sh` (`make prepare && make jenkins && make pack-dotnet`) | First `make prepare` runs against an empty `bin/`, so the `-include` no-ops and `?= Debug` takes effect | Identical — `?= Debug` still takes effect |
| Fresh local checkout, bare `make all` | `?= Debug` (no `bin/configuration.mk` yet) | Same |
| Local dev who runs `make prepare CONFIGURATION=Release` then bare `make all` | Persisted Release via `bin/configuration.mk` | Now defaults back to Debug — must pass `CONFIGURATION=Release` on every invocation |
That last case is the only behavior change. It was never documented as a contract anywhere in `Documentation/` or `README.md`, and developers building Release locally should be passing the flag explicitly anyway.
## Verification
- `git grep "configuration\.mk"` and `git grep "GeneratedConfigurationFile"`: zero matches after this change.
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj`: 0 warnings, 0 errors.
- Rubber-duck review: no remaining `Path.Combine(..., "configuration.mk")` references, no Makefile target depends on `bin/configuration.mk` as a prerequisite, and the leftover partial-method declaration is benign.
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
…vailable (#11577)
### Context
PR #11529 inlined `external/android-platform-support` into dotnet/android. `Xamarin.Android.Common.Debugging.targets` is now always built and shipped, so `TestEnvironment.CommercialBuildAvailable` is always `true` and `AssertCommercialBuild()` is a no-op.
### Changes
- Removed `TestEnvironment.CommercialBuildAvailable` property.
- Removed `BaseTest.AssertCommercialBuild()` helper.
- Dropped every `AssertCommercialBuild ();` callsite (~40 lines across 19 files).
- Simplified all `CommercialBuildAvailable` predicate usages, since the value is always `true`:
- `if (TestEnvironment.CommercialBuildAvailable) { X }` → unwrapped to `X`
- `if (!TestEnvironment.CommercialBuildAvailable) { X }` → block deleted
- `if (isRelease || !TestEnvironment.CommercialBuildAvailable)` → `if (isRelease)`
- `TestEnvironment.CommercialBuildAvailable ? "debug" : "release"` → `"debug"`
- `!(TestEnvironment.CommercialBuildAvailable && !isRelease)` → `isRelease`
- `!TestEnvironment.CommercialBuildAvailable && !isRelease` → `false`
- In `InstallAndRunTests.cs`, the `if (TestEnvironment.CommercialBuildAvailable) { ... } else { ... }` block keeps only the (now always-taken) true branch.
### Out of scope
The MSBuild gates (`_HasCommercialFiles`, `_AndroidFastDeploymentSupported`, etc.) are intentionally left alone — those will follow in a separate PR.
### Verification
- `git grep -n AssertCommercialBuild` → 0 hits
- `git grep -n CommercialBuildAvailable` → 0 hits
- Brace-balance check on every modified `.cs` file matches the baseline (HEAD) delta exactly.
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
…Supported gates (#11576)
Follow-up to #11529, which inlined the `external/android-platform-support` repo into dotnet/android. The Debugging.targets/props files and supporting assemblies (`Mono.AndroidTools`, `Xamarin.AndroidTools`, `Xamarin.Installer.*`, `Xamarin.Android.Build.Debugging.Tasks`, `fastdevtools`) are now always built in-tree by `Xamarin.Android.sln`, so several `Exists(...)` MSBuild gates are always true.
This PR removes those dead gates and their dead branches:
- **`build-tools/installers/create-installers.targets`** – drop `_HasCommercialFiles` and make the commercial `_MSBuildFiles` `ItemGroup` unconditional.
- **`Microsoft.Android.Sdk.DefaultProperties.targets`** – drop `_AndroidFastDeploymentSupported`.
- **`Microsoft.Android.Sdk.BuildOrder.targets`** – drop the `'$(_AndroidFastDeploymentSupported)' == 'true'` condition on `DeployToDeviceDependsOnTargets`; delete the dead `!= 'true'` branch.
- **`Microsoft.Android.Sdk.Application.targets`** – same treatment for `_RunDependsOn`; remove the now-stale comment.
- **`Xamarin.Android.Common.targets`** – drop `Exists(...)` from the `Xamarin.Android.Common.Debugging.targets` and `Xamarin.Installer.Common.targets` imports (keep the `'$(DesignTimeBuild)' != 'true'` guards); simplify the two dead `_AndroidFastDeploymentSupported` conditions on `EmbedAssembliesIntoApk`.
- **`Microsoft.Android.Sdk.targets`** – drop `Exists(...)` from the `Xamarin.Android.Common.Debugging.props` import (keep DTB guard).
- **Tests** – drop the now-defensive `proj.SetProperty ("_AndroidFastDeploymentSupported", "true")` calls (and the stale `//NOTE` comment) from `BuildTest.cs` and `InvalidConfigTests.cs`.
`TestEnvironment.CommercialBuildAvailable` / `BaseTest.AssertCommercialBuild()` are intentionally left for a follow-up PR.
After this change `git grep _HasCommercialFiles` and `git grep _AndroidFastDeploymentSupported` both return zero hits.
jonathanpeppers added a commit that referenced this pull request Jun 8, 2026
…11592)
PR #11529 inlined `Mono.AndroidTools` from android-platform-support, which carried PackageReferences to `protobuf-net` 3.2.26 and `protobuf-net.Core` 3.2.26. The original consumer of these packages was the native `tools/base/deploy/installer` binary, which was removed in the same PR. None of the inlined managed code (`Mono.AndroidTools`, `Xamarin.AndroidTools`, `Xamarin.Installer.*`, `Xamarin.Android.Build.Debugging.Tasks`) actually uses the `ProtoBuf` namespace, `[ProtoContract]` / `[ProtoMember]` attributes, or `Serializer.*` calls — so the references are dead weight.
More importantly, they were actively breaking `class-parse`'s Kotlin metadata parsing. `Mono.AndroidTools.csproj` outputs to `MicrosoftAndroidSdkOutDir`, where it dropped a v3 `protobuf-net.dll` (a thin facade) that overwrote the v2 self-contained DLL shipped by Java.Interop's `Xamarin.Android.Tools.Bytecode`. Because `protobuf-net.Core.dll` is not packed into the SDK pack, `class-parse` failed at runtime with `FileNotFoundException: Could not load file or assembly 'protobuf-net.Core, Version=3.0.0.0...'`, and `KotlinFixups.Fixup` silently skipped Kotlin metadata. Bindings then regenerated unsigned types as their signed counterparts, breaking `KotlinUnsignedTypesTests.cs` with CS1503/CS0266 errors.
Drop the v3 references from `Mono.AndroidTools.csproj` and the now-unused `ProtobufNetVersion` / `ProtobufNetCoreVersion` properties from `Directory.Build.props`. The v2 `protobuf-net.dll` from Java.Interop's class-parse becomes the only one in `MicrosoftAndroidSdkOutDir`, restoring Kotlin metadata parsing. The existing `_MSBuildFiles Include=...protobuf-net.dll` and `SignList.xml` `ThirdParty` entry (added in #5529) continue to ship the v2 DLL into the SDK pack.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jun 11, 2026
…#11613)
Continues the slow `xaprepare` removal. Recent precedent: #11568 (CopyExtraResultFilesForCI → YAML), #11580 (configuration.mk removal), #11529 (android-platform-support consolidation, which also dropped `Step_PrepareExternalGitDependencies`).
## What
`Step_PrepareProps` generated `external/Java.Interop/Configuration.Override.props` (inside the submodule) by substituting two placeholders into `build-tools/scripts/Configuration.Java.Interop.Override.in.props`. The substituted properties (`_XamarinAndroidCecilVersion`, `UtilityOutputFullPathCoreApps`, `XamarinAndroidToolsDirectory`) are now supplied directly via the checked-in static file `external/Java.Interop.override.props`, which Java.Interop's own `Directory.Build.props` already auto-imports via the parent-dir convention added in dotnet/java-interop#872.
The shared version values (`MonoCecilVersion`, `AndroidPackVersion`, `AndroidPackVersionSuffix`) move into `eng/Versions.props`. `Directory.Build.props` and `external/Java.Interop.override.props` both `<Import>` it. No duplicate-import sentinel is needed because every code path that imports `Configuration.props` has already loaded `Directory.Build.props` (either via MSBuild auto-load or via the explicit `<Import>` in `external/xamarin-android-tools.override.props`).
`MicrosoftAndroidSdkPackName` stays in `Configuration.props` (it is OS-conditioned, not version-shaped, so it doesn't belong in `Versions.props`). The same 3-line OS-conditioned block is mirrored privately in `external/Java.Interop.override.props` as `_MicrosoftAndroidSdkPackName`, used only to compute `UtilityOutputFullPathCoreApps` for the Java.Interop build.
Also dropped:
- `Configurables.Paths.InstallMSBuildDir` and its backing field — the only consumer was `Step_PrepareProps`.
- The dead `UtilityOutputFullPath` line in the old template — Java.Interop's `TargetFrameworkDependentValues.props` unconditionally routes it to `$(UtilityOutputFullPathCoreApps)` anyway, so it was a no-op.
Updated `build-tools/scripts/XAVersionInfo.targets` (the `GitBlame` for `<AndroidPackVersion>` now points at `eng/Versions.props`) and `Documentation/guides/HowToBranch.md` to reflect the moves.
## Why not just `<Import>` `Directory.Build.props` from the Java.Interop override?
That was the original idea. I prototyped it: importing dotnet/android's full props chain from `external/Java.Interop.override.props` flips `DotNetTargetFrameworkVersion` from `10.0` to `11.0` inside Java.Interop, and `dotnet restore Java.Interop.csproj` then fails with:
```
NETSDK1045: The current .NET SDK does not support targeting .NET 11.0
```
`xamarin-android-tools.override.props` gets away with the same trick only because its sole csproj sets `AndroidToolsDisableMultiTargeting=true`, which makes the TFM-clobber harmless. Java.Interop has no equivalent escape hatch.
`eng/Versions.props` is collision-free with Java.Interop (verified against the submodule sources — none of the existing entries collide), has no `<Import>` of its own, and is the safe minimal shared file.
## Verification
On Windows:
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj` — 0 warnings, 0 errors.
- From `src/Xamarin.Android.Build.Tasks/`: `dotnet msbuild --getProperty:MonoCecilVersion,AndroidPackVersion,AndroidPackVersionSuffix,MicrosoftAndroidSdkPackName,MicrosoftAndroidSdkOutDir` — values unchanged from baseline.
- From `external/Java.Interop/src/Java.Interop/`:
- `dotnet msbuild --getProperty:DotNetTargetFramework,_XamarinAndroidCecilVersion,UtilityOutputFullPathCoreApps` returns `net10.0`, `0.11.5`, the expected packs/tools path.
- `dotnet restore Java.Interop.csproj` succeeds (no `NETSDK1045`).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 5, 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.

4 participants

@jonathanpeppers@simonrozsival@jonpryor
, '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

[build] android-platform-support repo consolidation - #11529

Merged
jonathanpeppers merged 6 commits into
mainfrom
jonathanpeppers/inline-android-platform-support
Jun 4, 2026
Merged

[build] android-platform-support repo consolidation#11529
jonathanpeppers merged 6 commits into
mainfrom
jonathanpeppers/inline-android-platform-support

Conversation

@jonathanpeppers

@jonathanpeppersjonathanpeppers commented May 28, 2026

Copy link
Copy Markdown
Member

Inlines the contents of the DevDiv/android-platform-support repo into
dotnet/android, removes the BuildExternal MSBuild target that used to
clone it, and prunes dead code carried over with the migration. The
shipped SDK pack DLLs are unchanged.

What moved in from external/android-platform-support:

  • src/Xamarin.AndroidTools/ - SDK probing helpers (AndroidSdk,
    MonoDroidSdk, ProcessUtils, etc.) used by the debugging tasks
    and the installer.
  • src/Mono.AndroidTools/ - AndroidDevice / adb client used by
    fast deployment and the debugging task assembly.
  • src/Xamarin.Android.Build.Debugging.Tasks/ - the
    Xamarin.Android.Common.Debugging.targets MSBuild tasks (FastDeploy,
    RunActivity, RunTests, GetGdbSymbols, ...).
  • src/Xamarin.Installer.AndroidSDK/,
    src/Xamarin.Installer.Build.Tasks/,
    src/Xamarin.Installer.Common/ - Android SDK installer used by the
    standalone Xamarin Installer / VS Mac Android workload acquisition.
  • tools/fastdev/ - native xamarin.{sync,cp,find,stat} helper
    binaries plus the fastdevtools packaging project consumed during
    fast deployment.
  • external/termux-elf-cleaner - submodule consumed only as a
    build-time tool by the fastdev native binaries.
  • build-tools/android-platform-support/ - version/commit metadata
    for the above projects, kept under this path to preserve legacy
    file names.

Build wiring:

  • Xamarin.Android.sln now references the inlined projects directly.
  • Directory.Build.props, build-tools/scripts/DotNet.targets, and
    build-tools/installers/create-installers.targets lose their
    BuildExternal clone/build of external/android-platform-support
    and pick the assemblies up from the in-tree build instead.
  • installer-files.projitems is inlined into the installer targets
    rather than imported across the submodule boundary.
  • tools/workload-dependencies/WorkloadDependencies.proj reads its
    feed XML from a copy under src/Xamarin.Installer.Build.Tasks/.

Cleanup carried out as part of the migration: removed code, resources,
and tooling files that only existed to serve the standalone
android-platform-support build system and have no consumers in
dotnet/android.

THIRD-PARTY-NOTICES.TXT: added the Apache 2.0 notice for
Kajabity/Kajabity.Tools.Java, which is vendored under
src/Xamarin.Installer.AndroidSDK/ and consumed by the
JavaDependencyInstaller.

Build artifact comparison vs main

Compared nuget-unsigned artifacts from this PR against a recent successful
PR build of main (build 14260748).

Same:

  • All 17 nupkgs shipped (Ref, Runtime.* per-ABI, Sdk.Darwin/Windows,
    Templates, Manifest, etc.)
  • Same file structure (363 vs 367 files in Microsoft.Android.Sdk.Darwin)
  • Common file sizes virtually identical (-64 KB total across all common
    files)

Missing (intentional, safe):

  • tools/lib/{arm64-v8a,armeabi-v7a,x86,x86_64}/installer — 4 ELF
    binaries totaling ~15.6 MB uncompressed (~6 MB compressed, exactly
    accounting for the SDK pack size delta below). These are AOSP
    tools/base/deploy/installer binaries (Android Studio's "Apply Changes"
    fast-deploy helper). Strings analysis confirmed the
    tools/base/deploy/proto/deploy.pb.cc and protobuf symbols.
  • Nothing in dotnet/android invokes them — verified by searching the
    tree for the path and for "ApplyChanges"/"deploy.installer". APS shipped
    them but had no source either; they were pre-built blobs inherited from
    upstream.

Pack size delta:

  • Microsoft.Android.Sdk.Darwin: 145.5 MB vs 151.6 MB (-6.16 MB)
  • Microsoft.Android.Sdk.Windows: 129.1 MB vs 135.3 MB (-6.16 MB)

Ref pack, runtime packs, manifest, and templates are bit-for-bit equivalent
in size. No concerning regressions in the shipped product.

@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from c7fe2d6 to 48ce158CompareMay 28, 2026 17:16
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch 2 times, most recently from 653f3e9 to 2d58ed9CompareMay 28, 2026 18:26
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch 2 times, most recently from b03e93b to 3e04b58CompareMay 28, 2026 19:51
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Inlines the contents of the `DevDiv/android-platform-support` repo into
dotnet/android, removes the `BuildExternal` MSBuild target that used to
clone it, and prunes dead code carried over with the migration. The
shipped SDK pack DLLs are unchanged.
What moved in from `external/android-platform-support`:
* `src/Xamarin.AndroidTools/` - SDK probing helpers (`AndroidSdk`,
`MonoDroidSdk`, `ProcessUtils`, etc.) used by the debugging tasks
and the installer.
* `src/Mono.AndroidTools/` - `AndroidDevice` / `adb` client used by
fast deployment and the debugging task assembly.
* `src/Xamarin.Android.Build.Debugging.Tasks/` - the
`Xamarin.Android.Common.Debugging.targets` MSBuild tasks (FastDeploy,
RunActivity, RunTests, GetGdbSymbols, ...).
* `src/Xamarin.Installer.AndroidSDK/`,
`src/Xamarin.Installer.Build.Tasks/`,
`src/Xamarin.Installer.Common/` - Android SDK installer used by the
standalone Xamarin Installer / VS Mac Android workload acquisition.
* `tools/fastdev/` - native `xamarin.{sync,cp,find,stat}` helper
binaries plus the `fastdevtools` packaging project consumed during
fast deployment.
* `external/termux-elf-cleaner` - submodule consumed only as a
build-time tool by the fastdev native binaries.
* `build-tools/android-platform-support/` - version/commit metadata
for the above projects, kept under this path to preserve legacy
file names.
Build wiring:
* `Xamarin.Android.sln` now references the inlined projects directly.
* `Directory.Build.props`, `build-tools/scripts/DotNet.targets`, and
`build-tools/installers/create-installers.targets` lose their
`BuildExternal` clone/build of `external/android-platform-support`
and pick the assemblies up from the in-tree build instead.
* `installer-files.projitems` is inlined into the installer targets
rather than imported across the submodule boundary.
* `tools/workload-dependencies/WorkloadDependencies.proj` reads its
feed XML from a copy under `src/Xamarin.Installer.Build.Tasks/`.
Cleanup carried out as part of the migration: removed code, resources,
and tooling files that only existed to serve the standalone
`android-platform-support` build system and have no consumers in
dotnet/android.
THIRD-PARTY-NOTICES.TXT: added the Apache 2.0 notice for
`Kajabity/Kajabity.Tools.Java`, which is vendored under
`src/Xamarin.Installer.AndroidSDK/` and consumed by the
`JavaDependencyInstaller`.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 3e04b58 to 51f61b1CompareMay 28, 2026 20:18
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

The only entry in `.external` was `DevDiv/android-platform-support`,
which is now inlined into the tree, so the whole "prepare external git
dependencies" pipeline is dead. Removes:
* The `.external` file consumer (`ExternalGitDependency`,
`Step_PrepareExternalGitDependencies`,
`Scenario_PrepareExternalGitDependencies`,
`CommercialExternalDependencies`,
`ExternalGitDepsFilePath` / `ExternalGitDepsDestDir`).
* `make prepare-external-git-dependencies` and its callers in
`build.sh`, `build.cmd`, and the Linux/macOS CI yaml templates.
* The `PrepareExternal` MSBuild target in `PrepareWindows.targets`
and its `vscode-support.md` documentation entries.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 627d28c to 3d5286fCompareMay 28, 2026 21:43
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

PoliCheck uses signature-based suppressions in .gdnsuppress files (not
PoliCheck.Exclusions.xml). Add the three signatures surfaced by the
PoliCheck build stage:
* source.gdnsuppress: 'country' parameter in KeyManagement.cs (X.509
distinguished-name field, required by the spec).
* CHT.gdnsuppress: false-positive 'PK' from the Cantonese term table
inside a machine-translated zh-Hant resource string.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 58bd369 to f667453CompareJune 2, 2026 17:35
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

…abity
Add signature suppressions for the 17 PoliCheck Notes in the inlined
installer content:
* 16 hits in src/Xamarin.Installer.AndroidSDK/Feeds/AndroidManifestFeed_d18.0.xml
for 'country' / 'countries' (rules 79569/79570). These are verbatim
text from Google's Android SDK, Google TV Add-on, and GDK license
agreements and must not be modified.
* 1 hit in src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/
Kajabity.Tools.Java/JavaPropertyReader.cs (rule 92197 'Hong Kong')
in a third-party doc comment showing sample data with embedded spaces.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppers marked this pull request as ready for review June 3, 2026 13:59
CopilotAI review requested due to automatic review settings June 3, 2026 13:59
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/review

CopilotAI reviewed Jun 3, 2026

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.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@github-actions

github-actionsBot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

@github-actionsgithub-actionsBot 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.

✅ LGTM — Minor issues only

PR: android-platform-support repo consolidation

Well-structured consolidation that inlines DevDiv/android-platform-support into dotnet/android, removes the BuildExternal clone/build flow, and replaces it with a new Step_Android_SDK_NDK xaprepare step. The build artifact comparison in the PR description is thorough and reassuring — the shipped SDK pack DLLs are functionally unchanged and the only delta is the intentional removal of unused AOSP installer ELF binaries.

Summary

SeverityCount
❌ Error1
💡 Suggestion3

Positive callouts:

  • Excellent artifact comparison analysis documenting exactly what changed and what was removed
  • Clean removal of PrepareExternalGitDependencies flow — all references in Makefile, build scripts, YAML pipelines, xaprepare scenarios, and docs are consistently removed
  • The new AndroidToolchain / Step_Android_SDK_NDK code is well-organized with clear separation of per-platform OS tags
  • Good addition of the Kajabity Apache 2.0 notice to THIRD-PARTY-NOTICES.TXT

CI Status

  • dotnet-android — passed
  • 🟡 Xamarin.Android-PR — [in progress]((devdiv.visualstudio.com/redacted)

Generated by Android PR Reviewer for issue #11529 · ● 70.6M

@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Without a ProjectReference to androidsdk.csproj, fastdevtools.csproj
can race against the SDK extraction and find a partially-extracted
cmake (binary present at /sdk/cmake/3.30.3/bin/cmake but share/ not
yet populated), resulting in:
CMake error: File .../share/cmake-3.30/Modules/CMakeCXXCompiler.cmake.in does not exist.
Other native-build projects (proguard-android, bundletool, r8,
java-runtime, manifestmerger) already use this pattern.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppersjonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 4, 2026
@jonathanpeppers
jonathanpeppers merged commit c22cdcf into mainJun 4, 2026
3 checks passed
@jonathanpeppers
jonathanpeppers deleted the jonathanpeppers/inline-android-platform-support branch June 4, 2026 14:23
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
## Why
`bin/configuration.mk` exists only to persist `CONFIGURATION=<value>` between Unix `make` invocations. Removing it lets us delete the only meaningful contents of `Step_GenerateFiles.Unix.cs`, continuing the slow removal of `xaprepare` (see precedent: #11568, #11529).
## What
- Drop `-include bin/configuration.mk` from the top of `Makefile`. The `CONFIGURATION ?= Debug` fallback at the top of the file is unchanged.
- Delete `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.Unix.cs` entirely (it contained `GeneratedConfigurationFile` and a one-line `AddUnixPostBuildSteps` partial that registered it).
The `partial void AddUnixPostBuildSteps (Context context, List<GeneratedFile> steps);` declaration in `Step_GenerateFiles.cs` is intentionally left in place — partial methods without an implementation are legal in C#, and the call site becomes a zero-cost no-op. `Step_GenerateFiles.Windows.cs` implements a *different* partial (`AddOSSpecificSteps`) and is unaffected.
## Why this is safe
| Caller | Pre-change behavior | Post-change behavior |
| --- | --- | --- |
| All CI YAML (`build-linux-steps.yaml`, `build-macos-steps.yaml`, `commercial-build.yaml`, `azure-pipelines-apidocs.yaml`) | Passes `CONFIGURATION=$(XA.Build.Configuration)` on every `make` call | Same — explicit value still wins |
| `build.sh` (`make prepare && make jenkins && make pack-dotnet`) | First `make prepare` runs against an empty `bin/`, so the `-include` no-ops and `?= Debug` takes effect | Identical — `?= Debug` still takes effect |
| Fresh local checkout, bare `make all` | `?= Debug` (no `bin/configuration.mk` yet) | Same |
| Local dev who runs `make prepare CONFIGURATION=Release` then bare `make all` | Persisted Release via `bin/configuration.mk` | Now defaults back to Debug — must pass `CONFIGURATION=Release` on every invocation |
That last case is the only behavior change. It was never documented as a contract anywhere in `Documentation/` or `README.md`, and developers building Release locally should be passing the flag explicitly anyway.
## Verification
- `git grep "configuration\.mk"` and `git grep "GeneratedConfigurationFile"`: zero matches after this change.
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj`: 0 warnings, 0 errors.
- Rubber-duck review: no remaining `Path.Combine(..., "configuration.mk")` references, no Makefile target depends on `bin/configuration.mk` as a prerequisite, and the leftover partial-method declaration is benign.
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
…vailable (#11577)
### Context
PR #11529 inlined `external/android-platform-support` into dotnet/android. `Xamarin.Android.Common.Debugging.targets` is now always built and shipped, so `TestEnvironment.CommercialBuildAvailable` is always `true` and `AssertCommercialBuild()` is a no-op.
### Changes
- Removed `TestEnvironment.CommercialBuildAvailable` property.
- Removed `BaseTest.AssertCommercialBuild()` helper.
- Dropped every `AssertCommercialBuild ();` callsite (~40 lines across 19 files).
- Simplified all `CommercialBuildAvailable` predicate usages, since the value is always `true`:
- `if (TestEnvironment.CommercialBuildAvailable) { X }` → unwrapped to `X`
- `if (!TestEnvironment.CommercialBuildAvailable) { X }` → block deleted
- `if (isRelease || !TestEnvironment.CommercialBuildAvailable)` → `if (isRelease)`
- `TestEnvironment.CommercialBuildAvailable ? "debug" : "release"` → `"debug"`
- `!(TestEnvironment.CommercialBuildAvailable && !isRelease)` → `isRelease`
- `!TestEnvironment.CommercialBuildAvailable && !isRelease` → `false`
- In `InstallAndRunTests.cs`, the `if (TestEnvironment.CommercialBuildAvailable) { ... } else { ... }` block keeps only the (now always-taken) true branch.
### Out of scope
The MSBuild gates (`_HasCommercialFiles`, `_AndroidFastDeploymentSupported`, etc.) are intentionally left alone — those will follow in a separate PR.
### Verification
- `git grep -n AssertCommercialBuild` → 0 hits
- `git grep -n CommercialBuildAvailable` → 0 hits
- Brace-balance check on every modified `.cs` file matches the baseline (HEAD) delta exactly.
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
…Supported gates (#11576)
Follow-up to #11529, which inlined the `external/android-platform-support` repo into dotnet/android. The Debugging.targets/props files and supporting assemblies (`Mono.AndroidTools`, `Xamarin.AndroidTools`, `Xamarin.Installer.*`, `Xamarin.Android.Build.Debugging.Tasks`, `fastdevtools`) are now always built in-tree by `Xamarin.Android.sln`, so several `Exists(...)` MSBuild gates are always true.
This PR removes those dead gates and their dead branches:
- **`build-tools/installers/create-installers.targets`** – drop `_HasCommercialFiles` and make the commercial `_MSBuildFiles` `ItemGroup` unconditional.
- **`Microsoft.Android.Sdk.DefaultProperties.targets`** – drop `_AndroidFastDeploymentSupported`.
- **`Microsoft.Android.Sdk.BuildOrder.targets`** – drop the `'$(_AndroidFastDeploymentSupported)' == 'true'` condition on `DeployToDeviceDependsOnTargets`; delete the dead `!= 'true'` branch.
- **`Microsoft.Android.Sdk.Application.targets`** – same treatment for `_RunDependsOn`; remove the now-stale comment.
- **`Xamarin.Android.Common.targets`** – drop `Exists(...)` from the `Xamarin.Android.Common.Debugging.targets` and `Xamarin.Installer.Common.targets` imports (keep the `'$(DesignTimeBuild)' != 'true'` guards); simplify the two dead `_AndroidFastDeploymentSupported` conditions on `EmbedAssembliesIntoApk`.
- **`Microsoft.Android.Sdk.targets`** – drop `Exists(...)` from the `Xamarin.Android.Common.Debugging.props` import (keep DTB guard).
- **Tests** – drop the now-defensive `proj.SetProperty ("_AndroidFastDeploymentSupported", "true")` calls (and the stale `//NOTE` comment) from `BuildTest.cs` and `InvalidConfigTests.cs`.
`TestEnvironment.CommercialBuildAvailable` / `BaseTest.AssertCommercialBuild()` are intentionally left for a follow-up PR.
After this change `git grep _HasCommercialFiles` and `git grep _AndroidFastDeploymentSupported` both return zero hits.
jonathanpeppers added a commit that referenced this pull request Jun 8, 2026
…11592)
PR #11529 inlined `Mono.AndroidTools` from android-platform-support, which carried PackageReferences to `protobuf-net` 3.2.26 and `protobuf-net.Core` 3.2.26. The original consumer of these packages was the native `tools/base/deploy/installer` binary, which was removed in the same PR. None of the inlined managed code (`Mono.AndroidTools`, `Xamarin.AndroidTools`, `Xamarin.Installer.*`, `Xamarin.Android.Build.Debugging.Tasks`) actually uses the `ProtoBuf` namespace, `[ProtoContract]` / `[ProtoMember]` attributes, or `Serializer.*` calls — so the references are dead weight.
More importantly, they were actively breaking `class-parse`'s Kotlin metadata parsing. `Mono.AndroidTools.csproj` outputs to `MicrosoftAndroidSdkOutDir`, where it dropped a v3 `protobuf-net.dll` (a thin facade) that overwrote the v2 self-contained DLL shipped by Java.Interop's `Xamarin.Android.Tools.Bytecode`. Because `protobuf-net.Core.dll` is not packed into the SDK pack, `class-parse` failed at runtime with `FileNotFoundException: Could not load file or assembly 'protobuf-net.Core, Version=3.0.0.0...'`, and `KotlinFixups.Fixup` silently skipped Kotlin metadata. Bindings then regenerated unsigned types as their signed counterparts, breaking `KotlinUnsignedTypesTests.cs` with CS1503/CS0266 errors.
Drop the v3 references from `Mono.AndroidTools.csproj` and the now-unused `ProtobufNetVersion` / `ProtobufNetCoreVersion` properties from `Directory.Build.props`. The v2 `protobuf-net.dll` from Java.Interop's class-parse becomes the only one in `MicrosoftAndroidSdkOutDir`, restoring Kotlin metadata parsing. The existing `_MSBuildFiles Include=...protobuf-net.dll` and `SignList.xml` `ThirdParty` entry (added in #5529) continue to ship the v2 DLL into the SDK pack.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jun 11, 2026
…#11613)
Continues the slow `xaprepare` removal. Recent precedent: #11568 (CopyExtraResultFilesForCI → YAML), #11580 (configuration.mk removal), #11529 (android-platform-support consolidation, which also dropped `Step_PrepareExternalGitDependencies`).
## What
`Step_PrepareProps` generated `external/Java.Interop/Configuration.Override.props` (inside the submodule) by substituting two placeholders into `build-tools/scripts/Configuration.Java.Interop.Override.in.props`. The substituted properties (`_XamarinAndroidCecilVersion`, `UtilityOutputFullPathCoreApps`, `XamarinAndroidToolsDirectory`) are now supplied directly via the checked-in static file `external/Java.Interop.override.props`, which Java.Interop's own `Directory.Build.props` already auto-imports via the parent-dir convention added in dotnet/java-interop#872.
The shared version values (`MonoCecilVersion`, `AndroidPackVersion`, `AndroidPackVersionSuffix`) move into `eng/Versions.props`. `Directory.Build.props` and `external/Java.Interop.override.props` both `<Import>` it. No duplicate-import sentinel is needed because every code path that imports `Configuration.props` has already loaded `Directory.Build.props` (either via MSBuild auto-load or via the explicit `<Import>` in `external/xamarin-android-tools.override.props`).
`MicrosoftAndroidSdkPackName` stays in `Configuration.props` (it is OS-conditioned, not version-shaped, so it doesn't belong in `Versions.props`). The same 3-line OS-conditioned block is mirrored privately in `external/Java.Interop.override.props` as `_MicrosoftAndroidSdkPackName`, used only to compute `UtilityOutputFullPathCoreApps` for the Java.Interop build.
Also dropped:
- `Configurables.Paths.InstallMSBuildDir` and its backing field — the only consumer was `Step_PrepareProps`.
- The dead `UtilityOutputFullPath` line in the old template — Java.Interop's `TargetFrameworkDependentValues.props` unconditionally routes it to `$(UtilityOutputFullPathCoreApps)` anyway, so it was a no-op.
Updated `build-tools/scripts/XAVersionInfo.targets` (the `GitBlame` for `<AndroidPackVersion>` now points at `eng/Versions.props`) and `Documentation/guides/HowToBranch.md` to reflect the moves.
## Why not just `<Import>` `Directory.Build.props` from the Java.Interop override?
That was the original idea. I prototyped it: importing dotnet/android's full props chain from `external/Java.Interop.override.props` flips `DotNetTargetFrameworkVersion` from `10.0` to `11.0` inside Java.Interop, and `dotnet restore Java.Interop.csproj` then fails with:
```
NETSDK1045: The current .NET SDK does not support targeting .NET 11.0
```
`xamarin-android-tools.override.props` gets away with the same trick only because its sole csproj sets `AndroidToolsDisableMultiTargeting=true`, which makes the TFM-clobber harmless. Java.Interop has no equivalent escape hatch.
`eng/Versions.props` is collision-free with Java.Interop (verified against the submodule sources — none of the existing entries collide), has no `<Import>` of its own, and is the safe minimal shared file.
## Verification
On Windows:
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj` — 0 warnings, 0 errors.
- From `src/Xamarin.Android.Build.Tasks/`: `dotnet msbuild --getProperty:MonoCecilVersion,AndroidPackVersion,AndroidPackVersionSuffix,MicrosoftAndroidSdkPackName,MicrosoftAndroidSdkOutDir` — values unchanged from baseline.
- From `external/Java.Interop/src/Java.Interop/`:
- `dotnet msbuild --getProperty:DotNetTargetFramework,_XamarinAndroidCecilVersion,UtilityOutputFullPathCoreApps` returns `net10.0`, `0.11.5`, the expected packs/tools path.
- `dotnet restore Java.Interop.csproj` succeeds (no `NETSDK1045`).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 5, 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.

4 participants

@jonathanpeppers@simonrozsival@jonpryor
, '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

[build] android-platform-support repo consolidation - #11529

Merged
jonathanpeppers merged 6 commits into
mainfrom
jonathanpeppers/inline-android-platform-support
Jun 4, 2026
Merged

[build] android-platform-support repo consolidation#11529
jonathanpeppers merged 6 commits into
mainfrom
jonathanpeppers/inline-android-platform-support

Conversation

@jonathanpeppers

@jonathanpeppersjonathanpeppers commented May 28, 2026

Copy link
Copy Markdown
Member

Inlines the contents of the DevDiv/android-platform-support repo into
dotnet/android, removes the BuildExternal MSBuild target that used to
clone it, and prunes dead code carried over with the migration. The
shipped SDK pack DLLs are unchanged.

What moved in from external/android-platform-support:

  • src/Xamarin.AndroidTools/ - SDK probing helpers (AndroidSdk,
    MonoDroidSdk, ProcessUtils, etc.) used by the debugging tasks
    and the installer.
  • src/Mono.AndroidTools/ - AndroidDevice / adb client used by
    fast deployment and the debugging task assembly.
  • src/Xamarin.Android.Build.Debugging.Tasks/ - the
    Xamarin.Android.Common.Debugging.targets MSBuild tasks (FastDeploy,
    RunActivity, RunTests, GetGdbSymbols, ...).
  • src/Xamarin.Installer.AndroidSDK/,
    src/Xamarin.Installer.Build.Tasks/,
    src/Xamarin.Installer.Common/ - Android SDK installer used by the
    standalone Xamarin Installer / VS Mac Android workload acquisition.
  • tools/fastdev/ - native xamarin.{sync,cp,find,stat} helper
    binaries plus the fastdevtools packaging project consumed during
    fast deployment.
  • external/termux-elf-cleaner - submodule consumed only as a
    build-time tool by the fastdev native binaries.
  • build-tools/android-platform-support/ - version/commit metadata
    for the above projects, kept under this path to preserve legacy
    file names.

Build wiring:

  • Xamarin.Android.sln now references the inlined projects directly.
  • Directory.Build.props, build-tools/scripts/DotNet.targets, and
    build-tools/installers/create-installers.targets lose their
    BuildExternal clone/build of external/android-platform-support
    and pick the assemblies up from the in-tree build instead.
  • installer-files.projitems is inlined into the installer targets
    rather than imported across the submodule boundary.
  • tools/workload-dependencies/WorkloadDependencies.proj reads its
    feed XML from a copy under src/Xamarin.Installer.Build.Tasks/.

Cleanup carried out as part of the migration: removed code, resources,
and tooling files that only existed to serve the standalone
android-platform-support build system and have no consumers in
dotnet/android.

THIRD-PARTY-NOTICES.TXT: added the Apache 2.0 notice for
Kajabity/Kajabity.Tools.Java, which is vendored under
src/Xamarin.Installer.AndroidSDK/ and consumed by the
JavaDependencyInstaller.

Build artifact comparison vs main

Compared nuget-unsigned artifacts from this PR against a recent successful
PR build of main (build 14260748).

Same:

  • All 17 nupkgs shipped (Ref, Runtime.* per-ABI, Sdk.Darwin/Windows,
    Templates, Manifest, etc.)
  • Same file structure (363 vs 367 files in Microsoft.Android.Sdk.Darwin)
  • Common file sizes virtually identical (-64 KB total across all common
    files)

Missing (intentional, safe):

  • tools/lib/{arm64-v8a,armeabi-v7a,x86,x86_64}/installer — 4 ELF
    binaries totaling ~15.6 MB uncompressed (~6 MB compressed, exactly
    accounting for the SDK pack size delta below). These are AOSP
    tools/base/deploy/installer binaries (Android Studio's "Apply Changes"
    fast-deploy helper). Strings analysis confirmed the
    tools/base/deploy/proto/deploy.pb.cc and protobuf symbols.
  • Nothing in dotnet/android invokes them — verified by searching the
    tree for the path and for "ApplyChanges"/"deploy.installer". APS shipped
    them but had no source either; they were pre-built blobs inherited from
    upstream.

Pack size delta:

  • Microsoft.Android.Sdk.Darwin: 145.5 MB vs 151.6 MB (-6.16 MB)
  • Microsoft.Android.Sdk.Windows: 129.1 MB vs 135.3 MB (-6.16 MB)

Ref pack, runtime packs, manifest, and templates are bit-for-bit equivalent
in size. No concerning regressions in the shipped product.

@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from c7fe2d6 to 48ce158CompareMay 28, 2026 17:16
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch 2 times, most recently from 653f3e9 to 2d58ed9CompareMay 28, 2026 18:26
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch 2 times, most recently from b03e93b to 3e04b58CompareMay 28, 2026 19:51
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Inlines the contents of the `DevDiv/android-platform-support` repo into
dotnet/android, removes the `BuildExternal` MSBuild target that used to
clone it, and prunes dead code carried over with the migration. The
shipped SDK pack DLLs are unchanged.
What moved in from `external/android-platform-support`:
* `src/Xamarin.AndroidTools/` - SDK probing helpers (`AndroidSdk`,
`MonoDroidSdk`, `ProcessUtils`, etc.) used by the debugging tasks
and the installer.
* `src/Mono.AndroidTools/` - `AndroidDevice` / `adb` client used by
fast deployment and the debugging task assembly.
* `src/Xamarin.Android.Build.Debugging.Tasks/` - the
`Xamarin.Android.Common.Debugging.targets` MSBuild tasks (FastDeploy,
RunActivity, RunTests, GetGdbSymbols, ...).
* `src/Xamarin.Installer.AndroidSDK/`,
`src/Xamarin.Installer.Build.Tasks/`,
`src/Xamarin.Installer.Common/` - Android SDK installer used by the
standalone Xamarin Installer / VS Mac Android workload acquisition.
* `tools/fastdev/` - native `xamarin.{sync,cp,find,stat}` helper
binaries plus the `fastdevtools` packaging project consumed during
fast deployment.
* `external/termux-elf-cleaner` - submodule consumed only as a
build-time tool by the fastdev native binaries.
* `build-tools/android-platform-support/` - version/commit metadata
for the above projects, kept under this path to preserve legacy
file names.
Build wiring:
* `Xamarin.Android.sln` now references the inlined projects directly.
* `Directory.Build.props`, `build-tools/scripts/DotNet.targets`, and
`build-tools/installers/create-installers.targets` lose their
`BuildExternal` clone/build of `external/android-platform-support`
and pick the assemblies up from the in-tree build instead.
* `installer-files.projitems` is inlined into the installer targets
rather than imported across the submodule boundary.
* `tools/workload-dependencies/WorkloadDependencies.proj` reads its
feed XML from a copy under `src/Xamarin.Installer.Build.Tasks/`.
Cleanup carried out as part of the migration: removed code, resources,
and tooling files that only existed to serve the standalone
`android-platform-support` build system and have no consumers in
dotnet/android.
THIRD-PARTY-NOTICES.TXT: added the Apache 2.0 notice for
`Kajabity/Kajabity.Tools.Java`, which is vendored under
`src/Xamarin.Installer.AndroidSDK/` and consumed by the
`JavaDependencyInstaller`.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 3e04b58 to 51f61b1CompareMay 28, 2026 20:18
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

The only entry in `.external` was `DevDiv/android-platform-support`,
which is now inlined into the tree, so the whole "prepare external git
dependencies" pipeline is dead. Removes:
* The `.external` file consumer (`ExternalGitDependency`,
`Step_PrepareExternalGitDependencies`,
`Scenario_PrepareExternalGitDependencies`,
`CommercialExternalDependencies`,
`ExternalGitDepsFilePath` / `ExternalGitDepsDestDir`).
* `make prepare-external-git-dependencies` and its callers in
`build.sh`, `build.cmd`, and the Linux/macOS CI yaml templates.
* The `PrepareExternal` MSBuild target in `PrepareWindows.targets`
and its `vscode-support.md` documentation entries.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 627d28c to 3d5286fCompareMay 28, 2026 21:43
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

PoliCheck uses signature-based suppressions in .gdnsuppress files (not
PoliCheck.Exclusions.xml). Add the three signatures surfaced by the
PoliCheck build stage:
* source.gdnsuppress: 'country' parameter in KeyManagement.cs (X.509
distinguished-name field, required by the spec).
* CHT.gdnsuppress: false-positive 'PK' from the Cantonese term table
inside a machine-translated zh-Hant resource string.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppersforce-pushed the jonathanpeppers/inline-android-platform-support branch from 58bd369 to f667453CompareJune 2, 2026 17:35
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

…abity
Add signature suppressions for the 17 PoliCheck Notes in the inlined
installer content:
* 16 hits in src/Xamarin.Installer.AndroidSDK/Feeds/AndroidManifestFeed_d18.0.xml
for 'country' / 'countries' (rules 79569/79570). These are verbatim
text from Google's Android SDK, Google TV Add-on, and GDK license
agreements and must not be modified.
* 1 hit in src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/
Kajabity.Tools.Java/JavaPropertyReader.cs (rule 92197 'Hong Kong')
in a third-party doc comment showing sample data with embedded spaces.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppers
jonathanpeppers marked this pull request as ready for review June 3, 2026 13:59
CopilotAI review requested due to automatic review settings June 3, 2026 13:59
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/review

CopilotAI reviewed Jun 3, 2026

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.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@github-actions

github-actionsBot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

@github-actionsgithub-actionsBot 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.

✅ LGTM — Minor issues only

PR: android-platform-support repo consolidation

Well-structured consolidation that inlines DevDiv/android-platform-support into dotnet/android, removes the BuildExternal clone/build flow, and replaces it with a new Step_Android_SDK_NDK xaprepare step. The build artifact comparison in the PR description is thorough and reassuring — the shipped SDK pack DLLs are functionally unchanged and the only delta is the intentional removal of unused AOSP installer ELF binaries.

Summary

SeverityCount
❌ Error1
💡 Suggestion3

Positive callouts:

  • Excellent artifact comparison analysis documenting exactly what changed and what was removed
  • Clean removal of PrepareExternalGitDependencies flow — all references in Makefile, build scripts, YAML pipelines, xaprepare scenarios, and docs are consistently removed
  • The new AndroidToolchain / Step_Android_SDK_NDK code is well-organized with clear separation of per-platform OS tags
  • Good addition of the Kajabity Apache 2.0 notice to THIRD-PARTY-NOTICES.TXT

CI Status

  • dotnet-android — passed
  • 🟡 Xamarin.Android-PR — [in progress]((devdiv.visualstudio.com/redacted)

Generated by Android PR Reviewer for issue #11529 · ● 70.6M

@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Without a ProjectReference to androidsdk.csproj, fastdevtools.csproj
can race against the SDK extraction and find a partially-extracted
cmake (binary present at /sdk/cmake/3.30.3/bin/cmake but share/ not
yet populated), resulting in:
CMake error: File .../share/cmake-3.30/Modules/CMakeCXXCompiler.cmake.in does not exist.
Other native-build projects (proguard-android, bundletool, r8,
java-runtime, manifestmerger) already use this pattern.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jonathanpeppersjonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 4, 2026
@jonathanpeppers
jonathanpeppers merged commit c22cdcf into mainJun 4, 2026
3 checks passed
@jonathanpeppers
jonathanpeppers deleted the jonathanpeppers/inline-android-platform-support branch June 4, 2026 14:23
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
## Why
`bin/configuration.mk` exists only to persist `CONFIGURATION=<value>` between Unix `make` invocations. Removing it lets us delete the only meaningful contents of `Step_GenerateFiles.Unix.cs`, continuing the slow removal of `xaprepare` (see precedent: #11568, #11529).
## What
- Drop `-include bin/configuration.mk` from the top of `Makefile`. The `CONFIGURATION ?= Debug` fallback at the top of the file is unchanged.
- Delete `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.Unix.cs` entirely (it contained `GeneratedConfigurationFile` and a one-line `AddUnixPostBuildSteps` partial that registered it).
The `partial void AddUnixPostBuildSteps (Context context, List<GeneratedFile> steps);` declaration in `Step_GenerateFiles.cs` is intentionally left in place — partial methods without an implementation are legal in C#, and the call site becomes a zero-cost no-op. `Step_GenerateFiles.Windows.cs` implements a *different* partial (`AddOSSpecificSteps`) and is unaffected.
## Why this is safe
| Caller | Pre-change behavior | Post-change behavior |
| --- | --- | --- |
| All CI YAML (`build-linux-steps.yaml`, `build-macos-steps.yaml`, `commercial-build.yaml`, `azure-pipelines-apidocs.yaml`) | Passes `CONFIGURATION=$(XA.Build.Configuration)` on every `make` call | Same — explicit value still wins |
| `build.sh` (`make prepare && make jenkins && make pack-dotnet`) | First `make prepare` runs against an empty `bin/`, so the `-include` no-ops and `?= Debug` takes effect | Identical — `?= Debug` still takes effect |
| Fresh local checkout, bare `make all` | `?= Debug` (no `bin/configuration.mk` yet) | Same |
| Local dev who runs `make prepare CONFIGURATION=Release` then bare `make all` | Persisted Release via `bin/configuration.mk` | Now defaults back to Debug — must pass `CONFIGURATION=Release` on every invocation |
That last case is the only behavior change. It was never documented as a contract anywhere in `Documentation/` or `README.md`, and developers building Release locally should be passing the flag explicitly anyway.
## Verification
- `git grep "configuration\.mk"` and `git grep "GeneratedConfigurationFile"`: zero matches after this change.
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj`: 0 warnings, 0 errors.
- Rubber-duck review: no remaining `Path.Combine(..., "configuration.mk")` references, no Makefile target depends on `bin/configuration.mk` as a prerequisite, and the leftover partial-method declaration is benign.
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
…vailable (#11577)
### Context
PR #11529 inlined `external/android-platform-support` into dotnet/android. `Xamarin.Android.Common.Debugging.targets` is now always built and shipped, so `TestEnvironment.CommercialBuildAvailable` is always `true` and `AssertCommercialBuild()` is a no-op.
### Changes
- Removed `TestEnvironment.CommercialBuildAvailable` property.
- Removed `BaseTest.AssertCommercialBuild()` helper.
- Dropped every `AssertCommercialBuild ();` callsite (~40 lines across 19 files).
- Simplified all `CommercialBuildAvailable` predicate usages, since the value is always `true`:
- `if (TestEnvironment.CommercialBuildAvailable) { X }` → unwrapped to `X`
- `if (!TestEnvironment.CommercialBuildAvailable) { X }` → block deleted
- `if (isRelease || !TestEnvironment.CommercialBuildAvailable)` → `if (isRelease)`
- `TestEnvironment.CommercialBuildAvailable ? "debug" : "release"` → `"debug"`
- `!(TestEnvironment.CommercialBuildAvailable && !isRelease)` → `isRelease`
- `!TestEnvironment.CommercialBuildAvailable && !isRelease` → `false`
- In `InstallAndRunTests.cs`, the `if (TestEnvironment.CommercialBuildAvailable) { ... } else { ... }` block keeps only the (now always-taken) true branch.
### Out of scope
The MSBuild gates (`_HasCommercialFiles`, `_AndroidFastDeploymentSupported`, etc.) are intentionally left alone — those will follow in a separate PR.
### Verification
- `git grep -n AssertCommercialBuild` → 0 hits
- `git grep -n CommercialBuildAvailable` → 0 hits
- Brace-balance check on every modified `.cs` file matches the baseline (HEAD) delta exactly.
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
…Supported gates (#11576)
Follow-up to #11529, which inlined the `external/android-platform-support` repo into dotnet/android. The Debugging.targets/props files and supporting assemblies (`Mono.AndroidTools`, `Xamarin.AndroidTools`, `Xamarin.Installer.*`, `Xamarin.Android.Build.Debugging.Tasks`, `fastdevtools`) are now always built in-tree by `Xamarin.Android.sln`, so several `Exists(...)` MSBuild gates are always true.
This PR removes those dead gates and their dead branches:
- **`build-tools/installers/create-installers.targets`** – drop `_HasCommercialFiles` and make the commercial `_MSBuildFiles` `ItemGroup` unconditional.
- **`Microsoft.Android.Sdk.DefaultProperties.targets`** – drop `_AndroidFastDeploymentSupported`.
- **`Microsoft.Android.Sdk.BuildOrder.targets`** – drop the `'$(_AndroidFastDeploymentSupported)' == 'true'` condition on `DeployToDeviceDependsOnTargets`; delete the dead `!= 'true'` branch.
- **`Microsoft.Android.Sdk.Application.targets`** – same treatment for `_RunDependsOn`; remove the now-stale comment.
- **`Xamarin.Android.Common.targets`** – drop `Exists(...)` from the `Xamarin.Android.Common.Debugging.targets` and `Xamarin.Installer.Common.targets` imports (keep the `'$(DesignTimeBuild)' != 'true'` guards); simplify the two dead `_AndroidFastDeploymentSupported` conditions on `EmbedAssembliesIntoApk`.
- **`Microsoft.Android.Sdk.targets`** – drop `Exists(...)` from the `Xamarin.Android.Common.Debugging.props` import (keep DTB guard).
- **Tests** – drop the now-defensive `proj.SetProperty ("_AndroidFastDeploymentSupported", "true")` calls (and the stale `//NOTE` comment) from `BuildTest.cs` and `InvalidConfigTests.cs`.
`TestEnvironment.CommercialBuildAvailable` / `BaseTest.AssertCommercialBuild()` are intentionally left for a follow-up PR.
After this change `git grep _HasCommercialFiles` and `git grep _AndroidFastDeploymentSupported` both return zero hits.
jonathanpeppers added a commit that referenced this pull request Jun 8, 2026
…11592)
PR #11529 inlined `Mono.AndroidTools` from android-platform-support, which carried PackageReferences to `protobuf-net` 3.2.26 and `protobuf-net.Core` 3.2.26. The original consumer of these packages was the native `tools/base/deploy/installer` binary, which was removed in the same PR. None of the inlined managed code (`Mono.AndroidTools`, `Xamarin.AndroidTools`, `Xamarin.Installer.*`, `Xamarin.Android.Build.Debugging.Tasks`) actually uses the `ProtoBuf` namespace, `[ProtoContract]` / `[ProtoMember]` attributes, or `Serializer.*` calls — so the references are dead weight.
More importantly, they were actively breaking `class-parse`'s Kotlin metadata parsing. `Mono.AndroidTools.csproj` outputs to `MicrosoftAndroidSdkOutDir`, where it dropped a v3 `protobuf-net.dll` (a thin facade) that overwrote the v2 self-contained DLL shipped by Java.Interop's `Xamarin.Android.Tools.Bytecode`. Because `protobuf-net.Core.dll` is not packed into the SDK pack, `class-parse` failed at runtime with `FileNotFoundException: Could not load file or assembly 'protobuf-net.Core, Version=3.0.0.0...'`, and `KotlinFixups.Fixup` silently skipped Kotlin metadata. Bindings then regenerated unsigned types as their signed counterparts, breaking `KotlinUnsignedTypesTests.cs` with CS1503/CS0266 errors.
Drop the v3 references from `Mono.AndroidTools.csproj` and the now-unused `ProtobufNetVersion` / `ProtobufNetCoreVersion` properties from `Directory.Build.props`. The v2 `protobuf-net.dll` from Java.Interop's class-parse becomes the only one in `MicrosoftAndroidSdkOutDir`, restoring Kotlin metadata parsing. The existing `_MSBuildFiles Include=...protobuf-net.dll` and `SignList.xml` `ThirdParty` entry (added in #5529) continue to ship the v2 DLL into the SDK pack.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jun 11, 2026
…#11613)
Continues the slow `xaprepare` removal. Recent precedent: #11568 (CopyExtraResultFilesForCI → YAML), #11580 (configuration.mk removal), #11529 (android-platform-support consolidation, which also dropped `Step_PrepareExternalGitDependencies`).
## What
`Step_PrepareProps` generated `external/Java.Interop/Configuration.Override.props` (inside the submodule) by substituting two placeholders into `build-tools/scripts/Configuration.Java.Interop.Override.in.props`. The substituted properties (`_XamarinAndroidCecilVersion`, `UtilityOutputFullPathCoreApps`, `XamarinAndroidToolsDirectory`) are now supplied directly via the checked-in static file `external/Java.Interop.override.props`, which Java.Interop's own `Directory.Build.props` already auto-imports via the parent-dir convention added in dotnet/java-interop#872.
The shared version values (`MonoCecilVersion`, `AndroidPackVersion`, `AndroidPackVersionSuffix`) move into `eng/Versions.props`. `Directory.Build.props` and `external/Java.Interop.override.props` both `<Import>` it. No duplicate-import sentinel is needed because every code path that imports `Configuration.props` has already loaded `Directory.Build.props` (either via MSBuild auto-load or via the explicit `<Import>` in `external/xamarin-android-tools.override.props`).
`MicrosoftAndroidSdkPackName` stays in `Configuration.props` (it is OS-conditioned, not version-shaped, so it doesn't belong in `Versions.props`). The same 3-line OS-conditioned block is mirrored privately in `external/Java.Interop.override.props` as `_MicrosoftAndroidSdkPackName`, used only to compute `UtilityOutputFullPathCoreApps` for the Java.Interop build.
Also dropped:
- `Configurables.Paths.InstallMSBuildDir` and its backing field — the only consumer was `Step_PrepareProps`.
- The dead `UtilityOutputFullPath` line in the old template — Java.Interop's `TargetFrameworkDependentValues.props` unconditionally routes it to `$(UtilityOutputFullPathCoreApps)` anyway, so it was a no-op.
Updated `build-tools/scripts/XAVersionInfo.targets` (the `GitBlame` for `<AndroidPackVersion>` now points at `eng/Versions.props`) and `Documentation/guides/HowToBranch.md` to reflect the moves.
## Why not just `<Import>` `Directory.Build.props` from the Java.Interop override?
That was the original idea. I prototyped it: importing dotnet/android's full props chain from `external/Java.Interop.override.props` flips `DotNetTargetFrameworkVersion` from `10.0` to `11.0` inside Java.Interop, and `dotnet restore Java.Interop.csproj` then fails with:
```
NETSDK1045: The current .NET SDK does not support targeting .NET 11.0
```
`xamarin-android-tools.override.props` gets away with the same trick only because its sole csproj sets `AndroidToolsDisableMultiTargeting=true`, which makes the TFM-clobber harmless. Java.Interop has no equivalent escape hatch.
`eng/Versions.props` is collision-free with Java.Interop (verified against the submodule sources — none of the existing entries collide), has no `<Import>` of its own, and is the safe minimal shared file.
## Verification
On Windows:
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj` — 0 warnings, 0 errors.
- From `src/Xamarin.Android.Build.Tasks/`: `dotnet msbuild --getProperty:MonoCecilVersion,AndroidPackVersion,AndroidPackVersionSuffix,MicrosoftAndroidSdkPackName,MicrosoftAndroidSdkOutDir` — values unchanged from baseline.
- From `external/Java.Interop/src/Java.Interop/`:
- `dotnet msbuild --getProperty:DotNetTargetFramework,_XamarinAndroidCecilVersion,UtilityOutputFullPathCoreApps` returns `net10.0`, `0.11.5`, the expected packs/tools path.
- `dotnet restore Java.Interop.csproj` succeeds (no `NETSDK1045`).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jul 5, 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.

4 participants

@jonathanpeppers@simonrozsival@jonpryor