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
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ This file is only used by binding projects.
OutputFile="$(ApiOutputFile).class-parse"
SourceJars="@(EmbeddedJar);@(InputJar)"
DocumentationPaths="@(_AndroidDocumentationPath)"
NetCoreRoot="$(NetCoreRoot)"
ToolPath="$(MonoAndroidToolsDirectory)"
ToolExe="$(ClassParseToolExe)"
/>
<BindingsGenerator
OnlyRunXmlAdjuster="true"
Expand All @@ -41,6 +43,7 @@ This file is only used by binding projects.
ApiXmlInput="$(ApiOutputFile).class-parse"
ReferencedManagedLibraries="@(ReferencePath);@(ReferenceDependencyPaths)"
MonoAndroidFrameworkDirectories="$(_XATargetFrameworkDirectories)"
NetCoreRoot="$(NetCoreRoot)"
ToolPath="$(MonoAndroidToolsDirectory)"
ToolExe="$(BindingsGeneratorToolExe)"
Nullable="$(Nullable)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ It is shared between "legacy" binding projects and .NET 5 projects.
<GeneratedOutputPath Condition=" '$(GeneratedOutputPath)' == '' ">$(IntermediateOutputPath)generated\</GeneratedOutputPath>
<AndroidJavadocVerbosity Condition=" '$(AndroidJavadocVerbosity)' == '' ">intellisense</AndroidJavadocVerbosity>
<ApiOutputFile Condition=" '$(ApiOutputFile)' == '' ">$(IntermediateOutputPath)api.xml</ApiOutputFile>
<ClassParseToolExe Condition=" '$(UsingAndroidNETSdk)' == 'true' ">class-parse.dll</ClassParseToolExe>
<ClassParseToolExe Condition=" '$(ClassParseToolExe)' == '' ">class-parse.exe</ClassParseToolExe>
<BindingsGeneratorToolExe Condition=" '$(UsingAndroidNETSdk)' == 'true' ">generator.dll</BindingsGeneratorToolExe>
<BindingsGeneratorToolExe Condition=" '$(BindingsGeneratorToolExe)' == '' ">generator.exe</BindingsGeneratorToolExe>
<JavadocToMdocToolExe Condition=" '$(UsingAndroidNETSdk)' == 'true' ">javadoc-to-mdoc.dll</JavadocToMdocToolExe>
<JavadocToMdocToolExe Condition=" '$(JavadocToMdocToolExe)' == '' ">javadoc-to-mdoc.exe</JavadocToMdocToolExe>
<_GeneratorStampFile>$(_AndroidStampDirectory)generator.stamp</_GeneratorStampFile>
</PropertyGroup>

Expand Down Expand Up @@ -73,6 +79,7 @@ It is shared between "legacy" binding projects and .NET 5 projects.
ReferencedManagedLibraries="@(ReferencePath);@(ReferenceDependencyPaths)"
MonoAndroidFrameworkDirectories="$(_XATargetFrameworkDirectories)"
TypeMappingReportFile="$(GeneratedOutputPath)type-mapping.txt"
NetCoreRoot="$(NetCoreRoot)"
ToolPath="$(MonoAndroidToolsDirectory)"
ToolExe="$(BindingsGeneratorToolExe)"
LangVersion="$(LangVersion)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ This file is only used by binding projects. .NET 5 can eventually use it, once `
/>
<ImportJavaDoc
ContinueOnError="true"
NetCoreRoot="$(NetCoreRoot)"
ToolPath="$(MonoAndroidToolsDirectory)"
ToolExe="$(JavadocToMdocToolExe)"
JavaDocs="@(JavaDocIndex)"
References="@(ReferencePath);@(ReferenceDependencyPaths)"
Transforms="@(TransformFile)"
Expand Down
49 changes: 29 additions & 20 deletions src/Xamarin.Android.Build.Tasks/Tasks/AndroidDotnetToolTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ namespace Xamarin.Android.Tasks
/// </summary>
public abstract class AndroidDotnetToolTask : AndroidToolTask
{
/// <summary>
/// Path to the folder that contains dotnet / dotnet.exe.
/// </summary>
public string NetCoreRoot { get; set; }

/// <summary>
/// If `true`, this task should run `dotnet foo.dll` and `foo.exe` otherwise.
/// </summary>
Expand All @@ -31,61 +36,65 @@ public abstract class AndroidDotnetToolTask : AndroidToolTask

public override bool Execute ()
{
if (string.IsNullOrEmpty (ToolExe)) {
ToolExe = $"{BaseToolName}.exe";
}

var assemblyPath = Path.Combine (ToolPath, $"{BaseToolName}.dll");
if (File.Exists (assemblyPath)) {
if (Path.GetExtension (ToolExe) == ".dll") {
NeedsDotnet = true;
AssemblyPath = assemblyPath;
AssemblyPath = Path.Combine (ToolPath, ToolExe);
ToolPath = null;
ToolExe = null;

Log.LogDebugMessage ($"Using: dotnet {AssemblyPath}");
Log.LogDebugMessage ($"Using: {FindDotnet ()} {AssemblyPath}");
} else {
if (!RuntimeInformation.IsOSPlatform (OSPlatform.Windows) &&
!RuntimeInformation.FrameworkDescription.StartsWith ("Mono", StringComparison.OrdinalIgnoreCase)) {
// If not Windows and not running under Mono
NeedsMono = true;
AssemblyPath = Path.Combine (ToolPath, $"{BaseToolName}.exe");
AssemblyPath = Path.Combine (ToolPath, ToolExe);
ToolPath = null;
ToolExe = null;

Log.LogDebugMessage ($"Using: mono {AssemblyPath}");
Log.LogDebugMessage ($"Using: {FindMono ()} {AssemblyPath}");
} else {
// Otherwise running the .exe directly should work
Log.LogDebugMessage ($"Using: {GenerateFullPathToTool ()}");
Log.LogDebugMessage ($"Using: {Path.Combine (ToolPath, ToolExe)}");
}
}

return base.Execute ();
}

/// <summary>
/// The base tool name, such as "generator" for `generator.exe` and `dotnet generator.dll`
/// </summary>
protected abstract string BaseToolName {
get;
}

protected override string ToolName {
get {
if (NeedsDotnet)
return "dotnet";
if (NeedsMono)
return "mono";
return $"{BaseToolName}.exe";
return ToolExe;
}
}

protected override string GenerateFullPathToTool ()
{
if (NeedsDotnet)
return "dotnet";
return FindDotnet ();
if (NeedsMono)
return FindMono ();
return Path.Combine (ToolPath, ToolExe);
}

string FindDotnet ()
{
if (Directory.Exists (NetCoreRoot)) {
var dotnetPath = Path.Combine (NetCoreRoot, (RuntimeInformation.IsOSPlatform (OSPlatform.Windows) ? "dotnet.exe" : "dotnet"));
if (File.Exists (dotnetPath))
return dotnetPath;
}

var dotnetHostPath = Environment.GetEnvironmentVariable ("DOTNET_HOST_PATH");
if (File.Exists (dotnetHostPath))
return dotnetHostPath;

return "dotnet";
}

const RegisteredTaskObjectLifetime Lifetime = RegisteredTaskObjectLifetime.Build;
const string MonoKey = nameof (AndroidDotnetToolTask) + "_Mono";
Expand Down
2 changes: 0 additions & 2 deletions src/Xamarin.Android.Build.Tasks/Tasks/ClassParse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ public class ClassParse : AndroidDotnetToolTask
{
public override string TaskPrefix => "CLP";

protected override string BaseToolName => "class-parse";

[Required]
public string OutputFile { get; set; }

Expand Down
2 changes: 0 additions & 2 deletions src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,6 @@ protected override string GenerateCommandLineCommands ()
return cmd.ToString ();
}

protected override string BaseToolName => "generator";

protected override void LogEventsFromTextOutput (string singleLine, MessageImportance messageImportance)
{
base.LogEventsFromTextOutput (singleLine, messageImportance);
Expand Down
2 changes: 0 additions & 2 deletions src/Xamarin.Android.Build.Tasks/Tasks/ImportJavaDoc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ public class ImportJavaDoc : AndroidDotnetToolTask
[Required]
public string OutputDocDirectory { get; set; }

protected override string BaseToolName => "javadoc-to-mdoc";

protected override string GenerateCommandLineCommands ()
{
if (!Directory.Exists (OutputDocDirectory))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

using NUnit.Framework;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Xamarin.Android.Tasks;
using Xamarin.ProjectTools;

namespace Xamarin.Android.Build.Tests
{
[TestFixture]
[Category ("Node-5")]
public class AndroidDotnetToolTests : BaseTest
{
MockBuildEngine engine;
List<BuildErrorEventArgs> errors;
List<BuildWarningEventArgs> warnings;
List<BuildMessageEventArgs> messages;

[SetUp]
public void Setup ()
{
engine = new MockBuildEngine (TestContext.Out,
errors: errors = new List<BuildErrorEventArgs> (),
warnings: warnings = new List<BuildWarningEventArgs> (),
messages: messages = new List<BuildMessageEventArgs> ());
}

[Test]
public void ShouldUseFullToolPath ()
{
var dotnetDir = AndroidSdkResolver.GetDotNetPreviewPath ();
var dotnetPath = Path.Combine (dotnetDir, (TestEnvironment.IsWindows ? "dotnet.exe" : "dotnet"));
var classParseTask = new ClassParseTestTask {
BuildEngine = engine,
NetCoreRoot = dotnetDir,
ToolPath = Builder.UseDotNet ? TestEnvironment.DotNetAndroidSdkToolsDirectory : AndroidMSBuildDirectory,
ToolExe = Builder.UseDotNet ? "class-parse.dll" : "class-parse.exe",
};

Assert.True (classParseTask.Execute (), "Task should have succeeded.");
var expectedTool = Builder.UseDotNet ? dotnetPath : Path.Combine (AndroidMSBuildDirectory, "class-parse.exe");
Assert.IsTrue (messages.Any (m => m.Message.StartsWith (expectedTool)), "Task did not use expected tool path.");
}
}

public class ClassParseTestTask : AndroidDotnetToolTask
{
public override string TaskPrefix => "TEST";
protected override string GenerateCommandLineCommands ()
{
return GetCommandLineBuilder ().ToString ();
}
}
}