Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .github/skills/tests/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Classify the user's request:
| `src/Mono.Android/Xamarin.Android.Net/` | On-device: networking tests in `Mono.Android.NET-Tests.csproj`. Host: `CheckClientHandlerTypeTests`, `LinkerTests` |
| `src/Mono.Android/Android.*/**` | On-device: corresponding namespace tests in `Mono.Android.NET-Tests.csproj` |
| `src/Xamarin.Android.Build.Tasks/Tasks/` | Host: task tests in `Xamarin.Android.Build.Tests.dll` (filter by task name) |
| `src/Microsoft.Android.Build.Tasks/Tasks/` | Standalone: `Microsoft.Android.Build.Tasks.Tests.csproj` |
| `src/Xamarin.Android.Build.Tasks/Utilities/` | Host: `Xamarin.Android.Build.Tests.dll` — grep for test classes referencing the utility |
| `src/Xamarin.Android.Build.Tasks/**/*.targets` | Host: `Xamarin.Android.Build.Tests.dll`. Device: `MSBuildDeviceIntegration.dll` |
| `src/Microsoft.Android.Sdk.TrimmableTypeMap/` | Standalone: `TrimmableTypeMap.Tests.csproj`. Full-build: `TrimmableTypeMap.IntegrationTests` |
Expand Down
1 change: 1 addition & 0 deletions .github/skills/tests/references/test-catalog.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ These tests can be run immediately with `dotnet test` on the `.csproj`, even if
|-----------|---------|---------|
| **assembly store reader** | `.github/skills/read-assembly-store/tests/AssemblyStore.Tests/` | `dotnet test .github/skills/read-assembly-store/tests/AssemblyStore.Tests/AssemblyStore.Tests.csproj -v minimal` |
| **trimmable type map** (unit) | `tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/` | `dotnet test tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests.csproj -v minimal` |
| **modern Android build tasks** | `src/Microsoft.Android.Build.Tasks/Tests/Microsoft.Android.Build.Tasks.Tests/` | `dotnet test src/Microsoft.Android.Build.Tasks/Tests/Microsoft.Android.Build.Tasks.Tests/Microsoft.Android.Build.Tasks.Tests.csproj -v minimal` |
| **aidl** | `tests/Xamarin.Android.Tools.Aidl-Tests/` | `dotnet test tests/Xamarin.Android.Tools.Aidl-Tests/Xamarin.Android.Tools.Aidl-Tests.csproj -v minimal` |
| **source writer** | `external/Java.Interop/tests/Xamarin.SourceWriter-Tests/` | `dotnet test external/Java.Interop/tests/Xamarin.SourceWriter-Tests/Xamarin.SourceWriter-Tests.csproj -v minimal` |
| **java source** | `external/Java.Interop/tests/Java.Interop.Tools.JavaSource-Tests/` | `dotnet test external/Java.Interop/tests/Java.Interop.Tools.JavaSource-Tests/Java.Interop.Tools.JavaSource-Tests.csproj -v minimal` |
Expand Down
1 change: 1 addition & 0 deletions Xamarin.Android.Build.Tasks.slnx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<Solution>
<Folder Name="/tests/">
<Project Path="src/Microsoft.Android.Build.Tasks/Tests/Microsoft.Android.Build.Tasks.Tests/Microsoft.Android.Build.Tasks.Tests.csproj" />
<Project Path="src/Microsoft.Android.Sdk.Analysis/Tests/Microsoft.Android.Sdk.Analysis.Tests.csproj" />
<Project Path="src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj" />
<Project Path="src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Xamarin.ProjectTools.csproj" />
Expand Down
1 change: 1 addition & 0 deletions Xamarin.Android.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
<Project Path="tools/fastdev/fastdevtools.csproj" />
</Folder>
<Folder Name="/Tests/">
<Project Path="src/Microsoft.Android.Build.Tasks/Tests/Microsoft.Android.Build.Tasks.Tests/Microsoft.Android.Build.Tasks.Tests.csproj" />
<Project Path="src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj" />
<Project Path="src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Xamarin.ProjectTools.csproj" />
<Project Path="tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests.csproj" />
Expand Down
15 changes: 15 additions & 0 deletions build-tools/automation/yaml-templates/build-windows-steps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,21 @@ steps:
testResultsFiles: "$(Agent.TempDirectory)/trimmable-typemap-tests/*.trx"
testRunTitle: Microsoft.Android.Sdk.TrimmableTypeMap.Tests

- template: /build-tools/automation/yaml-templates/run-dotnet-preview.yaml@self
parameters:
command: test
project: src/Microsoft.Android.Build.Tasks/Tests/Microsoft.Android.Build.Tasks.Tests/Microsoft.Android.Build.Tasks.Tests.csproj
arguments: -c $(XA.Build.Configuration) --logger trx --results-directory $(Agent.TempDirectory)/microsoft-android-build-tasks-tests
displayName: Test Microsoft.Android.Build.Tasks.Tests $(XA.Build.Configuration)

- task: PublishTestResults@2
displayName: publish Microsoft.Android.Build.Tasks.Tests results
condition: always()
inputs:
testResultsFormat: VSTest
testResultsFiles: "$(Agent.TempDirectory)/microsoft-android-build-tasks-tests/*.trx"
testRunTitle: Microsoft.Android.Build.Tasks.Tests

- template: /build-tools/automation/yaml-templates/run-dotnet-preview.yaml@self
parameters:
command: test
Expand Down
16 changes: 12 additions & 4 deletions build-tools/installers/create-installers.targets
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,18 @@
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)AndroidBuildConfig.pdb" />
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)Xamarin.Android.Build.Tasks.dll" />
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)Xamarin.Android.Build.Tasks.pdb" />
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)Microsoft.Android.Build.Tasks.dll" />
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)Microsoft.Android.Build.Tasks.pdb" />
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)Microsoft.Android.Sdk.TrimmableTypeMap.dll" />
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)Microsoft.Android.Sdk.TrimmableTypeMap.pdb" />
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)net\Microsoft.Android.Build.Tasks.dll" />
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)net\Microsoft.Android.Build.Tasks.pdb" />
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)net\Microsoft.Android.Sdk.TrimmableTypeMap.dll" />
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)net\Microsoft.Android.Sdk.TrimmableTypeMap.pdb" />
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)net\System.IO.Hashing.dll" />
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)net\Microsoft.Android.Build.BaseTasks.dll" />
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)net\Microsoft.Android.Build.BaseTasks.pdb" />
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)net\Java.Interop.Localization.dll" />
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)net\Java.Interop.Localization.pdb" />
<_MSBuildFiles Include="@(_LocalizationLanguages->'$(MicrosoftAndroidSdkOutDir)net\%(Identity)\Microsoft.Android.Build.BaseTasks.resources.dll')" />
<_MSBuildFiles Include="@(_LocalizationLanguages->'$(MicrosoftAndroidSdkOutDir)net\%(Identity)\Microsoft.Android.Build.Tasks.resources.dll')" />
<_MSBuildFiles Include="@(_LocalizationLanguages->'$(MicrosoftAndroidSdkOutDir)net\%(Identity)\Java.Interop.Localization.resources.dll')" />
<_MSBuildFiles Include="@(_LocalizationLanguages->'$(MicrosoftAndroidSdkOutDir)%(Identity)\Microsoft.Android.Build.BaseTasks.resources.dll')" />
<_MSBuildFiles Include="@(_LocalizationLanguages->'$(MicrosoftAndroidSdkOutDir)%(Identity)\Xamarin.Android.Build.Tasks.resources.dll')" />
<_MSBuildFiles Include="@(_LocalizationLanguages->'$(MicrosoftAndroidSdkOutDir)%(Identity)\Xamarin.Android.Tools.AndroidSdk.resources.dll')" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,52 @@
This assembly hosts MSBuild tasks that require .NET (net11.0) APIs that are not available in
netstandard2.0, so they cannot live in Xamarin.Android.Build.Tasks.dll (which multi-targets
netstandard2.0 to run on both .NET Framework and .NET MSBuild). Tasks here are imported with
<UsingTask ... Runtime="NET" TaskFactory="TaskHostFactory" /> so they run out-of-process on .NET.
<UsingTask ... Runtime="NET" /> so they run on .NET.
Keep this assembly small and self-contained: link only the minimal helpers it needs.
-->
<PropertyGroup>
<TargetFramework>$(DotNetTargetFramework)</TargetFramework>
<RootNamespace>Microsoft.Android.Tasks</RootNamespace>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<OutputPath>$(MicrosoftAndroidSdkOutDir)</OutputPath>
<!--
Deliberately *not* the shared tools\ directory. MSBuild probes a task assembly's own
directory before anything else, and tools\ holds the netstandard2.0 flavors of packages
such as System.IO.Hashing that Xamarin.Android.Build.Tasks.dll deposits. Those bind their
Span<T> to System.Memory, so a net11.0 caller resolving them fails with
MissingMethodException. Living in our own directory means this assembly and its
dependencies always resolve to their .NET flavors.
-->
<OutputPath>$(MicrosoftAndroidSdkOutDir)net\</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\product.snk</AssemblyOriginatorKeyFile>
<!--
We share $(OutputPath) with Xamarin.Android.Build.Tasks.csproj. Letting NuGet copy this
project's transitive runtime assets there can overwrite the netstandard2.0 assemblies
Build.Tasks already deposited with incompatible framework-specific implementations.
Only our compiled assembly needs to land in the SDK pack tools folder.
-->
<!-- Microsoft.Build.* must never ship next to a task assembly; copy only what we need. -->
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
</PropertyGroup>

<!--
Package assets are not copied wholesale (see CopyLocalLockFileAssemblies), so deposit the
.NET flavor of System.IO.Hashing that Microsoft.Android.Sdk.TrimmableTypeMap.dll compiles
against alongside it.
-->
<Target Name="_CopyDotNetPackageDependencies" AfterTargets="ResolveAssemblyReferences">
<ItemGroup>
<ReferenceCopyLocalPaths Include="@(ReferencePath)" Condition=" '%(Filename)' == 'System.IO.Hashing' " />
</ItemGroup>
</Target>

<!-- Microsoft.Build.* references flow transitively from Microsoft.Android.Build.BaseTasks. -->
<ItemGroup>
<Compile Remove="Tests\**" />
<ProjectReference Include="..\Microsoft.Android.Build.BaseTasks\Microsoft.Android.Build.BaseTasks.csproj" />
<ProjectReference Include="..\Microsoft.Android.Sdk.TrimmableTypeMap\Microsoft.Android.Sdk.TrimmableTypeMap.csproj" />
<ProjectReference Include="..\..\external\Java.Interop\src\Java.Interop.Localization\Java.Interop.Localization.csproj" />
<InternalsVisibleTo Include="Microsoft.Android.Build.Tasks.Tests" Key="0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf16cbd2b2b47a62762f273df9cb2795ceccdf77d10bf508e69e7a362ea7a45455bbf3ac955e1f2e2814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b2c9733db" />
</ItemGroup>

<ItemGroup>
<Compile Include="..\Xamarin.Android.Build.Tasks\Utilities\NullableExtensions.cs" Link="Utilities\NullableExtensions.cs" />
</ItemGroup>

<!--
Expand All @@ -38,8 +60,8 @@
-->
<ItemGroup>
<Compile Include="..\Xamarin.Android.Build.Tasks\Properties\Resources.Designer.cs" Link="Properties\Resources.Designer.cs" />
<EmbeddedResource Include="..\Xamarin.Android.Build.Tasks\Properties\Resources.resx" Link="Properties\Resources.resx">
<ManifestResourceName>Xamarin.Android.Tasks.Properties.Resources</ManifestResourceName>
<EmbeddedResource Include="..\Xamarin.Android.Build.Tasks\Properties\Resources*.resx" Link="Properties\%(Filename)%(Extension)">
<ManifestResourceName>Xamarin.Android.Tasks.Properties.%(Filename)</ManifestResourceName>
</EmbeddedResource>
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using Microsoft.Android.Build.Tasks;
using Microsoft.Android.Sdk.TrimmableTypeMap;

namespace Xamarin.Android.Tasks;
namespace Microsoft.Android.Tasks;

/// <summary>
/// Emits empty stub assemblies for per-assembly typemaps (<c>_X.TypeMap.dll</c>) that the root
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection.Metadata;
Expand All @@ -10,9 +11,10 @@
using Microsoft.Android.Sdk.TrimmableTypeMap;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Xamarin.Android.Tools;
using Xamarin.Android.Tasks;
using Properties = Xamarin.Android.Tasks.Properties;

namespace Xamarin.Android.Tasks;
namespace Microsoft.Android.Tasks;

public class GenerateTrimmableTypeMap : AndroidTask
{
Expand Down Expand Up @@ -82,9 +84,9 @@ public void LogMissingBaseConstructorError (string managedTypeName, string jniSi
public void LogInvalidSuperArgumentsStringError (string managedTypeName, string superArgumentsString) =>
log.LogCodedError ("XA4262", Properties.Resources.XA4262, managedTypeName, superArgumentsString);
public void LogCustomJavaObjectError (string managedTypeName) =>
log.LogError ("{0}", $"XA4212: {string.Format (Properties.Resources.XA4212, managedTypeName)}");
log.LogError ("{0}", $"XA4212: {string.Format (CultureInfo.CurrentCulture, Properties.Resources.XA4212, managedTypeName)}");
public void LogCustomJavaObjectWarning (string managedTypeName) =>
log.LogWarning ("{0}", $"XA4212: {string.Format (Properties.Resources.XA4212, managedTypeName)}");
log.LogWarning ("{0}", $"XA4212: {string.Format (CultureInfo.CurrentCulture, Properties.Resources.XA4212, managedTypeName)}");
}

public override string TaskPrefix => "GTT";
Expand Down Expand Up @@ -241,7 +243,7 @@ public override bool RunTask ()
}
IReadOnlyCollection<string>? customViewTypeNames = CustomViewMapFile.IsNullOrEmpty ()
? null
: MonoAndroidHelper.LoadCustomViewMapFile (BuildEngine4, CustomViewMapFile).Keys;
: LoadCustomViewTypeNames (CustomViewMapFile);

result = generator.Execute (
assemblies,
Expand Down Expand Up @@ -377,7 +379,29 @@ void WriteTypeMapFingerprints (IReadOnlyDictionary<string, string> fingerprints)

static bool IsFrameworkAssemblyItem (ITaskItem item) =>
string.Equals (item.GetMetadata ("FrameworkAssembly"), bool.TrueString, StringComparison.OrdinalIgnoreCase) ||
MonoAndroidHelper.IsFrameworkAssembly (item);
string.Equals (item.GetMetadata ("FrameworkReferenceName"), "Microsoft.Android", StringComparison.Ordinal) ||
item.GetMetadata ("FrameworkReferenceName").StartsWith ("Microsoft.NETCore.", StringComparison.OrdinalIgnoreCase) ||
item.GetMetadata ("NuGetPackageId").StartsWith ("Microsoft.NETCore.App.Runtime.", StringComparison.OrdinalIgnoreCase) ||
item.GetMetadata ("NuGetPackageId").StartsWith ("Microsoft.Android.Runtime.", StringComparison.OrdinalIgnoreCase);

internal static IReadOnlyCollection<string> LoadCustomViewTypeNames (string mapFile)
{
var typeNames = new HashSet<string> (StringComparer.Ordinal);
if (!File.Exists (mapFile)) {
return typeNames;
}
foreach (var line in File.ReadLines (mapFile)) {
if (line.IsNullOrWhiteSpace ()) {
continue;
}
int separator = line.IndexOf (';');
if (separator <= 0 || separator == line.Length - 1) {
throw new InvalidDataException ($"Invalid custom view map entry '{line}' in '{mapFile}'.");
}
typeNames.Add (line.Substring (0, separator));
}
return typeNames;
}

void WriteGeneratedAssembliesListFile (IReadOnlyList<ITaskItem> assemblies)
{
Expand Down Expand Up @@ -506,7 +530,7 @@ ITaskItem [] DeleteStaleJavaSources (IReadOnlyCollection<ITaskItem> generatedJav
TaskItem CreateDeletedJavaItem (string fullPath)
{
var item = new TaskItem (fullPath);
item.SetMetadata ("RelativePath", PathUtil.GetRelativePath (JavaSourceOutputDirectory, fullPath));
item.SetMetadata ("RelativePath", Path.GetRelativePath (JavaSourceOutputDirectory, fullPath));
return item;
}

Expand All @@ -533,7 +557,7 @@ static string GenerateApplicationRegistrationJava (IReadOnlyList<string> registr
sb.AppendLine ("\tpublic static void registerApplications ()");
sb.AppendLine ("\t{");
foreach (var javaClassName in registrationTypes) {
sb.AppendLine ($"\t\tmono.android.Runtime.registerNatives ({javaClassName}.class);");
sb.AppendLine (CultureInfo.InvariantCulture, $"\t\tmono.android.Runtime.registerNatives ({javaClassName}.class);");
}
sb.AppendLine ("\t}");
sb.AppendLine ("}");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.IO;
using System.Linq;
using NUnit.Framework;

namespace Xamarin.Android.Build.Tests;

public class BaseTest
{
static readonly char [] InvalidChars = ['{', '}', '(', ')', '$', ':', ';', '"', '\'', ',', '=', '|'];

public string Root => Path.Combine (TestContext.CurrentContext.WorkDirectory, "Microsoft.Android.Build.Tasks.Tests");

public string TestName {
get {
var result = TestContext.CurrentContext.Test.Name;
foreach (var c in InvalidChars.Concat (Path.GetInvalidPathChars ()).Concat (Path.GetInvalidFileNameChars ())) {
result = result.Replace (c, '_');
}
return result.Replace ("_", "");
}
}

[TearDown]
public void Cleanup ()
{
var testDirectory = Path.Combine (Root, "temp", TestName);
if (Directory.Exists (testDirectory)) {
Directory.Delete (testDirectory, recursive: true);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using Microsoft.Android.Tasks;
using Microsoft.Build.Framework;
using NUnit.Framework;
using Xamarin.Android.Tasks;
Expand Down
Loading