Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
6543b9c
Add trimmable typemap test plumbing and CI lane
simonrozsival Apr 13, 2026
854c1df
Keep CoreCLR test flavor naming in CI
simonrozsival Apr 13, 2026
4f084ec
[TrimmableTypeMap] Package CoreCLR preserve list in SDK pack
simonrozsival Apr 15, 2026
ce44773
[TrimmableTypeMap] Keep CoreCLR lane on CoreCLR runtime
simonrozsival Apr 15, 2026
7e4a505
[TrimmableTypeMap] Fix CoreCLR preserve list packaging
simonrozsival Apr 15, 2026
1b55202
[TrimmableTypeMap] Fix SDK preserve list test path
simonrozsival Apr 15, 2026
b779469
Include trimmable CoreCLR preserve list in SDK pack
simonrozsival Apr 15, 2026
45b8a33
[TrimmableTypeMap] Fix PreserveLists packaging for both local and CI …
simonrozsival Apr 15, 2026
f6ea0b7
[TrimmableTypeMap] Fix IL1034 by changing root assembly RootMode from…
simonrozsival Apr 15, 2026
70deb30
[TrimmableTypeMap] Default instrumentation targetPackage to app packa…
simonrozsival Apr 16, 2026
f719fb1
[TrimmableTypeMap] Fix stale manifest causing ClassNotFoundException …
simonrozsival Apr 16, 2026
a5a6dd8
[TrimmableTypeMap] Use outer IntermediateOutputPath for typemap/manif…
simonrozsival Apr 16, 2026
1f22129
[TrimmableTypeMap] Rewrite compat JNI names in manifest template to C…
simonrozsival Apr 16, 2026
9082b24
[TrimmableTypeMap] Fix runtime initialization ordering and generic ty…
simonrozsival Apr 16, 2026
306a207
[TrimmableTypeMap] Fix generic type proxy loading in typemap
simonrozsival Apr 16, 2026
883f030
[TrimmableTypeMap] Revert two-phase init — use single Initialize() af…
simonrozsival Apr 16, 2026
2ccf01b
[TrimmableTypeMap] Fix ClassLoader mismatch in RegisterNatives
simonrozsival Apr 16, 2026
d303fde
[TrimmableTypeMap] Fix static initializer ordering for Instrumentatio…
simonrozsival Apr 16, 2026
ce55722
[TrimmableTypeMap] Fix Release build pipeline and ApplicationRegistra…
simonrozsival Apr 16, 2026
1ca7f08
[TrimmableTypeMap] Route registerNatives via C++ function pointer
simonrozsival Apr 16, 2026
bfcbdcc
[TrimmableTypeMap] Use nativeClassHandle for RegisterNatives instead …
simonrozsival Apr 17, 2026
0972cb7
[TrimmableTypeMap] Include abstract Instrumentation/Application subty…
simonrozsival Apr 17, 2026
c7ad90a
[TrimmableTypeMap] Defer registerNatives for classes loaded before ma…
simonrozsival Apr 17, 2026
352df39
[TrimmableTypeMap] Add self-application attribute to proxy types + fi…
simonrozsival Apr 17, 2026
1cf1006
Skip failing JavaCast/JavaAs/JavaObjectArray tests in CoreCLRTrimmable
simonrozsival Apr 17, 2026
4abdc1e
Revert unused C++ registerNatives plumbing and u8 literal change
simonrozsival Apr 17, 2026
d8e8c42
Merge branch 'main' into dev/simonrozsival/trimmable-test-plumbing
simonrozsival Apr 18, 2026
8c33ad0
[TrimmableTypeMap] Drop stale merge leftovers
simonrozsival Apr 18, 2026
0c865e9
Fix trimmable Release test regressions
simonrozsival Apr 18, 2026
a6f8e2a
Make MavenDownload tests tolerate transient network errors
simonrozsival Apr 19, 2026
45872df
Stabilize custom widget global ref test
simonrozsival Apr 19, 2026
225ebf8
Reduce MSBuild perf test flakiness
simonrozsival Apr 19, 2026
713f2a6
Drop Maven test CI hardening
simonrozsival Apr 19, 2026
ce6d279
Drop unrelated CI-only test tweaks
simonrozsival Apr 19, 2026
edf6cee
[tests] Improve trimmable typemap test plumbing
simonrozsival Apr 20, 2026
b56882d
[tests] Move generic runner auditing out of #11091
simonrozsival Apr 20, 2026
4b96133
[tests] Restore trimmable exclusion rationale comments
simonrozsival Apr 20, 2026
57be01d
[tests] Refine trimmable exclusions for review feedback
simonrozsival Apr 20, 2026
41ec29b
[tests] Require successful trimmable build in regressions
simonrozsival Apr 20, 2026
0480ad5
Fix trimmable _GenerateJavaStubs incrementality and skip failing test
simonrozsival Apr 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions build-tools/automation/yaml-templates/stage-package-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,16 @@ stages:
artifactSource: bin/Test$(XA.Build.Configuration)/$(DotNetTargetFramework)-android/Mono.Android.NET_Tests-Signed.aab
artifactFolder: $(DotNetTargetFramework)-CoreCLR

- template: /build-tools/automation/yaml-templates/apk-instrumentation.yaml
parameters:
configuration: $(XA.Build.Configuration)
testName: Mono.Android.NET_Tests-CoreCLRTrimmable
project: tests/Mono.Android-Tests/Mono.Android-Tests/Mono.Android.NET-Tests.csproj
testResultsFiles: TestResult-Mono.Android.NET_Tests-$(XA.Build.Configuration)CoreCLRTrimmable.xml
extraBuildArgs: -p:_AndroidTypeMapImplementation=trimmable -p:UseMonoRuntime=false
artifactSource: bin/Test$(XA.Build.Configuration)/$(DotNetTargetFramework)-android/Mono.Android.NET_Tests-Signed.aab
artifactFolder: $(DotNetTargetFramework)-CoreCLRTrimmable

- template: /build-tools/automation/yaml-templates/apk-instrumentation.yaml
parameters:
configuration: $(XA.Build.Configuration)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,7 @@ static void EmitPeers (TypeMapAssemblyData model, string jniName,

// Emit TypeMapAssociation for all proxy-backed types so managed → proxy
// lookup works even when the final JNI name differs from the type's attributes.
// Generic definitions are included — their proxy types derive from the
// non-generic `JavaPeerProxy` base so the CLR can load them without
// resolving an open generic argument.
// Generic definitions are supported via the non-generic `JavaPeerProxy` base.
var assocProxy = (i > 0 && primaryProxy != null) ? primaryProxy : proxy;
if (assocProxy != null) {
model.Associations.Add (new TypeMapAssociationData {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ public class TrimmableTypeMapGenerator
{
readonly ITrimmableTypeMapLogger logger;

static readonly HashSet<string> RequiredFrameworkDeferredRegistrationTypes = new (StringComparer.Ordinal) {
"android/app/Application",
"android/app/Instrumentation",
};

public TrimmableTypeMapGenerator (ITrimmableTypeMapLogger logger)
{
this.logger = logger ?? throw new ArgumentNullException (nameof (logger));
Expand Down Expand Up @@ -40,6 +45,7 @@ public TrimmableTypeMapResult Execute (

RootManifestReferencedTypes (allPeers, PrepareManifestForRooting (manifestTemplate, manifestConfig));
PropagateDeferredRegistrationToBaseClasses (allPeers);
PropagateCannotRegisterToDescendants (allPeers);

var generatedAssemblies = GenerateTypeMapAssemblies (allPeers, systemRuntimeVersion);
var jcwPeers = allPeers.Where (p =>
Expand All @@ -48,14 +54,7 @@ public TrimmableTypeMapResult Execute (
logger.LogGeneratingJcwFilesInfo (jcwPeers.Count, allPeers.Count);
var generatedJavaSources = GenerateJcwJavaSources (jcwPeers);

// Collect Application/Instrumentation types that need deferred registerNatives
var appRegTypes = allPeers
// Include all deferred-registration peers here: framework MCWs still need
// ApplicationRegistration.java even without generated ACWs, and abstract
// base types can own the native methods that derived types invoke.
.Where (p => p.CannotRegisterInStaticConstructor)
.Select (p => JniSignatureHelper.JniNameToJavaName (p.JavaName))
.ToList ();
var appRegTypes = CollectApplicationRegistrationTypes (allPeers);
if (appRegTypes.Count > 0) {
logger.LogDeferredRegistrationTypesInfo (appRegTypes.Count);
}
Expand All @@ -67,6 +66,33 @@ public TrimmableTypeMapResult Execute (
return new TrimmableTypeMapResult (generatedAssemblies, generatedJavaSources, allPeers, manifest, appRegTypes);
}

internal static List<string> CollectApplicationRegistrationTypes (List<JavaPeerInfo> allPeers)
{
var appRegTypes = new List<string> ();
var seen = new HashSet<string> (StringComparer.Ordinal);

foreach (var peer in allPeers) {
if (!peer.CannotRegisterInStaticConstructor) {
continue;
}

// ApplicationRegistration.java is compiled against the app's target Android API
// surface. Legacy framework descendants such as android.test.* may not exist there,
// so keep only the two framework roots plus app/runtime types that participate in
// the deferred-registration flow.
if (peer.DoNotGenerateAcw && !RequiredFrameworkDeferredRegistrationTypes.Contains (peer.JavaName)) {
continue;
}

var javaName = JniSignatureHelper.JniNameToJavaName (peer.JavaName);
if (seen.Add (javaName)) {
appRegTypes.Add (javaName);
}
}

return appRegTypes;
}

GeneratedManifest GenerateManifest (List<JavaPeerInfo> allPeers, AssemblyManifestInfo assemblyManifestInfo,
ManifestConfig config, XDocument? manifestTemplate)
{
Expand Down Expand Up @@ -217,8 +243,7 @@ internal void RootManifestReferencedTypes (List<JavaPeerInfo> allPeers, XDocumen
/// TestInstrumentation_1 must also defer — otherwise the base class <c>&lt;clinit&gt;</c> will call
/// <c>registerNatives</c> before the managed runtime is ready.
/// </summary>
internal static void PropagateDeferredRegistrationToBaseClasses (List<JavaPeerInfo> allPeers)
{
internal static void PropagateDeferredRegistrationToBaseClasses (List<JavaPeerInfo> allPeers) {
// In practice only 1–2 types need propagation (one Application, maybe one
// Instrumentation), each with a short base-class chain. A linear scan per
// ancestor is simpler and cheaper than building a Dictionary<JavaName, List<Peer>>
Expand Down Expand Up @@ -247,6 +272,43 @@ static void PropagateToAncestors (string? baseJniName, List<JavaPeerInfo> allPee
}
}

/// <summary>
/// Propagates <see cref="JavaPeerInfo.CannotRegisterInStaticConstructor"/> DOWN
/// from Application/Instrumentation types to all their descendants. Any subclass of
/// an Instrumentation/Application type can be loaded by Android before the native
/// library is ready, so it must also use the lazy __md_registerNatives pattern.
/// </summary>
internal static void PropagateCannotRegisterToDescendants (List<JavaPeerInfo> allPeers)
{
// Build a set of JavaNames that have CannotRegisterInStaticConstructor
var cannotRegister = new HashSet<string> (StringComparer.Ordinal);
foreach (var peer in allPeers) {
if (peer.CannotRegisterInStaticConstructor) {
cannotRegister.Add (peer.JavaName);
}
}

// Also include the framework base types
cannotRegister.Add ("android/app/Application");
cannotRegister.Add ("android/app/Instrumentation");

// Propagate to descendants: if your base is in the set, you're in the set too
bool changed = true;
while (changed) {
changed = false;
foreach (var peer in allPeers) {
if (peer.CannotRegisterInStaticConstructor || peer.BaseJavaName is null) {
continue;
}
if (cannotRegister.Contains (peer.BaseJavaName)) {
peer.CannotRegisterInStaticConstructor = true;
cannotRegister.Add (peer.JavaName);
changed = true;
}
}
}
}

static void AddPeerByDotName (Dictionary<string, List<JavaPeerInfo>> peersByDotName, string dotName, JavaPeerInfo peer)
{
if (!peersByDotName.TryGetValue (dotName, out var list)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,35 @@
</ItemGroup>
</Target>

<!--
Populates @(_AdditionalNativeConfigResolvedAssemblies) with the trimmable TypeMap DLLs
so that GenerateNativeApplicationConfigSources (in _GeneratePackageManagerJava) accounts
for them. This must NOT live inside _GenerateJavaStubs because that target can be
skipped on incremental builds, which would leave the item group empty.
-->
<Target Name="_PrepareTrimmableNativeConfigAssemblies"
BeforeTargets="_GeneratePackageManagerJava">
<ItemGroup>
<_AdditionalNativeConfigResolvedAssemblies Remove="@(_AdditionalNativeConfigResolvedAssemblies)" />
<_AdditionalNativeConfigResolvedAssemblies Include="$(_TypeMapOutputDirectory)*.dll" />
</ItemGroup>
</Target>

<!--
_GenerateJavaStubs: overrides the legacy target from BuildOrder.targets.
In the trimmable path, TypeMap generation already happened in _GenerateTrimmableTypeMap,
so this target only handles JCW file copying, manifest, assembly store setup, and native config.
We keep the name _GenerateJavaStubs because BuildOrder.targets references it.

Inputs uses the TypeMap DLL as a focused sentinel — _GenerateTrimmableTypeMap regenerates
the DLL whenever any of its own inputs (assemblies, manifest, etc.) change, so the DLL
timestamp is a reliable proxy for "something changed that requires re-copying".
We keep _GetGenerateJavaStubsInputs in DependsOnTargets so that downstream targets
(_GetGeneratePackageManagerJavaInputs) can still read @(_GenerateJavaStubsInputs).
-->
<Target Name="_GenerateJavaStubs"
DependsOnTargets="_SetLatestTargetFrameworkVersion;_CleanIntermediateIfNeeded;_PrepareAssemblies;_GetGenerateJavaStubsInputs;_DefineBuildTargetAbis;_PrepareNativeAssemblySources"
Inputs="@(_GenerateJavaStubsInputs)"
Inputs="$(_TypeMapOutputDirectory)$(_TypeMapAssemblyName).dll"
Outputs="$(_AndroidStampDirectory)_GenerateJavaStubs.stamp">

<ItemGroup>
Expand All @@ -112,28 +132,6 @@
<FileWrites Include="@(_TypeMapJavaFiles->'$(IntermediateOutputPath)android/src/%(RecursiveDir)%(Filename)%(Extension)')" />
</ItemGroup>

<!-- Set properties for ABI/RID used by CoreCLR _AddTrimmableTypeMapAssembliesToStore fallback -->
<PropertyGroup>
<_TypeMapFirstAbi Condition=" '$(AndroidSupportedAbis)' != '' ">$([System.String]::Copy('$(AndroidSupportedAbis)').Split(';')[0])</_TypeMapFirstAbi>
<_TypeMapFirstAbi Condition=" '$(_TypeMapFirstAbi)' == '' ">arm64-v8a</_TypeMapFirstAbi>
<_TypeMapFirstRid Condition=" '$(_TypeMapFirstAbi)' == 'arm64-v8a' ">android-arm64</_TypeMapFirstRid>
<_TypeMapFirstRid Condition=" '$(_TypeMapFirstAbi)' == 'armeabi-v7a' ">android-arm</_TypeMapFirstRid>
<_TypeMapFirstRid Condition=" '$(_TypeMapFirstAbi)' == 'x86_64' ">android-x64</_TypeMapFirstRid>
<_TypeMapFirstRid Condition=" '$(_TypeMapFirstAbi)' == 'x86' ">android-x86</_TypeMapFirstRid>
</PropertyGroup>

<!-- Add TypeMap DLLs to _ResolvedAssemblies so they are counted by
GenerateNativeApplicationConfigSources (in _GeneratePackageManagerJava)
and included in the assembly store hash table. -->
<ItemGroup>
<_ResolvedAssemblies Include="$(_TypeMapOutputDirectory)*.dll">
<Abi>$(_TypeMapFirstAbi)</Abi>
<RuntimeIdentifier>$(_TypeMapFirstRid)</RuntimeIdentifier>
<DestinationSubPath>$(_TypeMapFirstAbi)/%(Filename)%(Extension)</DestinationSubPath>
<DestinationSubDirectory>$(_TypeMapFirstAbi)/</DestinationSubDirectory>
</_ResolvedAssemblies>
</ItemGroup>

<!-- Copy generated manifest to expected location -->
<Copy SourceFiles="$(_TypeMapBaseOutputDir)AndroidManifest.xml"
DestinationFiles="$(IntermediateOutputPath)AndroidManifest.xml"
Expand Down Expand Up @@ -175,5 +173,4 @@
<FileWrites Include="@(_TypeMapAssemblySource)" />
</ItemGroup>
</Target>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public class GenerateNativeApplicationConfigSources : AndroidTask
[Required]
public ITaskItem[] ResolvedAssemblies { get; set; } = [];

public ITaskItem[]? AdditionalResolvedAssemblies { get; set; }

public ITaskItem[]? NativeLibraries { get; set; }
public ITaskItem[]? NativeLibrariesNoJniPreload { get; set; }
public ITaskItem[]? NativeLibrariesAlwaysJniPreload { get; set; }
Expand Down Expand Up @@ -202,6 +204,13 @@ public override bool RunTask ()
GetRequiredTokens (assembly.ItemSpec, out android_runtime_jnienv_class_token, out jnienv_initialize_method_token, out jnienv_registerjninatives_method_token);
}

if (AdditionalResolvedAssemblies != null) {
foreach (ITaskItem assembly in AdditionalResolvedAssemblies) {
updateNameWidth (assembly);
updateAssemblyCount (assembly);
}
}

if (!UseAssemblyStore) {
int abiNameLength = 0;
foreach (string abi in SupportedAbis) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ public void Execute_ManifestPlaceholdersAreResolvedForRooting ()
var registrationText = File.ReadAllText (applicationRegistration);
StringAssert.Contains ("mono.android.Runtime.registerNatives (android.app.Application.class);", registrationText);
StringAssert.Contains ("mono.android.Runtime.registerNatives (android.app.Instrumentation.class);", registrationText);
StringAssert.DoesNotContain ("android.test.InstrumentationTestRunner.class", registrationText);
StringAssert.DoesNotContain ("android.test.mock.MockApplication.class", registrationText);
Assert.IsFalse (warnings.Any (w => w.Code == "XA4250"), "Resolved placeholder-based manifest references should not log XA4250.");
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using NUnit.Framework;
using Xamarin.Android.Tasks;
using Xamarin.ProjectTools;
Expand All @@ -11,45 +13,101 @@ public class TrimmableTypeMapBuildTests : BaseTest {
[Test]
public void Build_WithTrimmableTypeMap_Succeeds ()
{
var proj = new XamarinAndroidApplicationProject ();
var proj = new XamarinAndroidApplicationProject {
IsRelease = true,
};
proj.SetRuntime (AndroidRuntime.CoreCLR);
proj.SetProperty ("_AndroidTypeMapImplementation", "trimmable");

// Full Build will fail downstream (manifest generation not yet implemented for trimmable path),
// but _GenerateJavaStubs runs and completes before the failure point.
using var builder = CreateApkBuilder ();
builder.ThrowOnBuildFailure = false;
builder.Build (proj);
Assert.IsTrue (builder.Build (proj), "Build should have succeeded.");

// Verify _GenerateJavaStubs ran by checking typemap outputs exist
var intermediateDir = builder.Output.GetIntermediaryPath ("typemap");
DirectoryAssert.Exists (intermediateDir);
}

[Test]
public void Build_WithTrimmableTypeMap_IncrementalBuild ()
{
var proj = new XamarinAndroidApplicationProject ();
var proj = new XamarinAndroidApplicationProject {
IsRelease = true,
};
proj.SetRuntime (AndroidRuntime.CoreCLR);
proj.SetProperty ("_AndroidTypeMapImplementation", "trimmable");

// Full Build will fail downstream (manifest generation not yet implemented for trimmable path),
// but _GenerateJavaStubs runs and completes before the failure point.
using var builder = CreateApkBuilder ();
builder.ThrowOnBuildFailure = false;
builder.Build (proj);
Assert.IsTrue (builder.Build (proj), "First build should have succeeded.");

// Verify _GenerateJavaStubs ran on the first build
var intermediateDir = builder.Output.GetIntermediaryPath ("typemap");
DirectoryAssert.Exists (intermediateDir);

// Second build with no changes — _GenerateJavaStubs should be skipped
builder.Build (proj);
Assert.IsTrue (builder.Build (proj), "Second build should have succeeded.");
Assert.IsTrue (
builder.Output.IsTargetSkipped ("_GenerateJavaStubs"),
"_GenerateJavaStubs should be skipped on incremental build.");
}

[Test]
public void Build_WithTrimmableTypeMap_DoesNotHitCopyIfChangedMismatch ()
{
var proj = new XamarinAndroidApplicationProject {
IsRelease = true,
};
proj.SetRuntime (AndroidRuntime.CoreCLR);
proj.SetProperty ("_AndroidTypeMapImplementation", "trimmable");

using var builder = CreateApkBuilder ();
Assert.IsTrue (builder.Build (proj), "Build should have succeeded.");

Assert.IsFalse (
StringAssertEx.ContainsText (builder.LastBuildOutput, "source and destination count mismatch"),
$"{builder.BuildLogFile} should not fail with XACIC7004.");
Assert.IsFalse (
StringAssertEx.ContainsText (builder.LastBuildOutput, "Internal error: architecture"),
$"{builder.BuildLogFile} should keep trimmable typemap assemblies aligned across ABIs.");
}

[Test]
public void Build_WithTrimmableTypeMap_AssemblyStoreMappingsStayInRange ()
{
var proj = new XamarinAndroidApplicationProject {
IsRelease = true,
};
proj.SetRuntime (AndroidRuntime.CoreCLR);
proj.SetProperty ("_AndroidTypeMapImplementation", "trimmable");

using var builder = CreateApkBuilder ();
Assert.IsTrue (builder.Build (proj), "Build should have succeeded.");

var environmentFiles = Directory.GetFiles (builder.Output.GetIntermediaryPath ("android"), "environment.*.ll");
Assert.IsNotEmpty (environmentFiles, "Expected generated environment.<abi>.ll files.");

foreach (var environmentFile in environmentFiles) {
var abi = Path.GetFileNameWithoutExtension (environmentFile).Substring ("environment.".Length);
var manifestFile = builder.Output.GetIntermediaryPath (Path.Combine ("app_shared_libraries", abi, "assembly-store.so.manifest"));

if (!File.Exists (manifestFile)) {
continue;
}

var environmentText = File.ReadAllText (environmentFile);
var runtimeDataMatch = Regex.Match (environmentText, @"assembly_store_bundled_assemblies.*\[(\d+)\s+x");
Assert.IsTrue (runtimeDataMatch.Success, $"{environmentFile} should declare assembly_store_bundled_assemblies.");

var runtimeDataCount = int.Parse (runtimeDataMatch.Groups [1].Value);
var maxMappingIndex = File.ReadLines (manifestFile)
.Select (line => Regex.Match (line, @"\bmi:(\d+)\b"))
.Where (match => match.Success)
.Select (match => int.Parse (match.Groups [1].Value))
.Max ();

Assert.That (
runtimeDataCount,
Is.GreaterThan (maxMappingIndex),
$"{Path.GetFileName (environmentFile)} should allocate enough runtime slots for {Path.GetFileName (manifestFile)}.");
}
}

[Test]
public void TrimmableTypeMap_PreserveList_IsPackagedInSdk ()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1727,6 +1727,7 @@ because xbuild doesn't support framework reference assemblies.

<GenerateNativeApplicationConfigSources
ResolvedAssemblies="@(_ResolvedAssemblies)"
AdditionalResolvedAssemblies="@(_AdditionalNativeConfigResolvedAssemblies)"
SatelliteAssemblies="@(_AndroidResolvedSatellitePaths)"
NativeLibraries="@(_AllNativeLibraries)"
NativeLibrariesNoJniPreload="@(_AndroidNativeLibraryNeverJniPreload);@(AndroidNativeLibraryNoJniPreload)"
Expand Down
Loading