-
Notifications
You must be signed in to change notification settings - Fork 552
[AndroidDotnetToolTask] Use full path to dotnet #7038
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
dotnetPath = processPath; | ||
} | ||
} | ||
return File.Exists (dotnetPath) ? dotnetPath : "dotnet"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should be a task parameter that is passed in instead? It looks like the $(NetCoreRoot)
msbuild property could also be used for this (see dotnet/sdk#20 (comment) and https://github.com/dotnet/sdk/blob/b15a88fb330548bf447d2df4936c4367db346a1a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ILLink.targets#L148-L154)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Microsoft.NET.ILLink.targets
snippet confuses me (aside: what doesn't confuse me today?), because it's setting various properties when $(DOTNET_HOST_PATH)
isn't set. But what happens when $(DOTNET_HOST_PATH)
is set?
<!-- When running from Desktop MSBuild, DOTNET_HOST_PATH is not set.
In this case, explicitly specify the path to the dotnet host. -->
<PropertyGroup Condition=" '$(DOTNET_HOST_PATH)' == '' ">
<_DotNetHostDirectory>$(NetCoreRoot)</_DotNetHostDirectory>
<_DotNetHostFileName>dotnet</_DotNetHostFileName>
<_DotNetHostFileName Condition="$([MSBuild]::IsOSPlatform(`Windows`))">dotnet.exe</_DotNetHostFileName>
</PropertyGroup>
I ask because the above properties are used elsewhere, e.g. https://github.com/dotnet/sdk/blob/b15a88fb330548bf447d2df4936c4367db346a1a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ILLink.targets#L185-L186
<ILLink AssemblyPaths="@(ManagedAssemblyToLink)"
…
ToolExe="$(_DotNetHostFileName)"
ToolPath="$(_DotNetHostDirectory)"
So when $(DOTNET_HOST_PATH)
is set, those properties won't be set, so… shouldn't it just fail horrifically, as ToolExe
and ToolPath
are the empty string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The answer to my confusion appears to be that the <ILLink/>
task doesn't use ToolExe
and ToolPath
:
partial class ILLink {
private const string DotNetHostPathEnvironmentName = "DOTNET_HOST_PATH";
private string _dotnetPath;
private string DotNetPath {
get {
if (!String.IsNullOrEmpty (_dotnetPath))
return _dotnetPath;
_dotnetPath = Environment.GetEnvironmentVariable (DotNetHostPathEnvironmentName);
if (String.IsNullOrEmpty (_dotnetPath))
throw new InvalidOperationException ($"{DotNetHostPathEnvironmentName} is not set");
return _dotnetPath;
}
}
// …
protected override string GenerateFullPathToTool () => DotNetPath;
}
which is differently "horrifying"; this always throws if $(DOTNET_HOST_PATH)
isn't set, and never uses ToolExe
& ToolPath
, so… How does this work when $(DOTNET_HOST_PATH)
isn't set?
The confusion compounds.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By my understanding GenerateFullPathToTool ()
is only called when ToolPath
and ToolExe
do not point to a valid tool: https://github.com/dotnet/msbuild/blob/f1dae6ab690483458d37b8900f1d1e4a5fc72851/src/Utilities/ToolTask.cs#L463-L481
I think what effectively happens here is that $(DOTNET_HOST_PATH)
is used if set, and $(_DotNetHostFileName)
and $(_DotNetHostDirectory)
are set and used as a fallback if not.
77825f1
to
32e0791
Compare
A "vaguely related" "concern" is one of consistency: "Normal" (There are "only" 48 such uses within But then we have I'm not sure if this means anything at all. We previously established that the Alternatively, we could "embrace convention": <PropertyGroup>
<ClassParseToolExe Condition=" … on .NET … ">class-parse.dll</ClassParseToolExe>
<ClassParseToolExe Condition=" '$(ClassParseToolExe)' == '' ">class-parse.exe</ClassParseToolExe>
<ClassParseToolPath>$(MonoAndroidToolsDirectory)</ClassParseToolPath>
</PropertyGroup>
…
<ClassParse
NetCoreRoot="$(NetCoreRoot)"
ToolExe="$(ClassParseToolExe)"
TooPath="$(ClassParseToolPath)"
…
/>
The benefit to "embrace convention" is that if you want to test a custom |
b560032
to
84d51b2
Compare
I've updated tasks which inherit from The |
Context: dotnet/java-interop#988 A recent attempt to update Java.Interop to target net7.0 produced some test failures on the Xamarin.Android side: Using "ClassParse" task from assembly "/Users/runner/work/1/s/xamarin-android/bin/Release/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.0-ci.pr.gh7028.23/tools/Xamarin.Android.Build.Tasks.dll". Task "ClassParse" (TaskId:139) Task Parameter:ToolPath=/Users/runner/work/1/s/xamarin-android/bin/Release/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.0-ci.pr.gh7028.23/tools (TaskId:139) Task Parameter:OutputFile=obj/Debug/api.xml.class-parse (TaskId:139) Task Parameter:SourceJars=/Users/runner/work/1/s/xamarin-android/bin/Release/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.0-ci.pr.gh7028.23/tools/android-support-multidex.jar (TaskId:139) Using: dotnet /Users/runner/work/1/s/xamarin-android/bin/Release/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.0-ci.pr.gh7028.23/tools/class-parse.dll (TaskId:139) [class-parse] response file: obj/Debug/class-parse.rsp (TaskId:139) --o="obj/Debug/api.xml.class-parse" (TaskId:139) "/Users/runner/work/1/s/xamarin-android/bin/Release/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.0-ci.pr.gh7028.23/tools/android-support-multidex.jar" (TaskId:139) /Users/runner/.dotnet/dotnet /Users/runner/work/1/s/xamarin-android/bin/Release/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.0-ci.pr.gh7028.23/tools/class-parse.dll "@obj/Debug/class-parse.rsp" (TaskId:139) It was not possible to find any compatible framework version (TaskId:139) The framework 'Microsoft.NETCore.App', version '7.0.0-preview.5.22271.4' (x64) was not found. (TaskId:139) - The following frameworks were found: (TaskId:139) 3.1.1 at [/Users/runner/.dotnet/shared/Microsoft.NETCore.App] (TaskId:139) 3.1.3 at [/Users/runner/.dotnet/shared/Microsoft.NETCore.App] (TaskId:139) 3.1.6 at [/Users/runner/.dotnet/shared/Microsoft.NETCore.App] (TaskId:139) 3.1.25 at [/Users/runner/.dotnet/shared/Microsoft.NETCore.App] (TaskId:139) 5.0.2 at [/Users/runner/.dotnet/shared/Microsoft.NETCore.App] (TaskId:139) 5.0.5 at [/Users/runner/.dotnet/shared/Microsoft.NETCore.App] (TaskId:139) 5.0.8 at [/Users/runner/.dotnet/shared/Microsoft.NETCore.App] (TaskId:139) 5.0.17 at [/Users/runner/.dotnet/shared/Microsoft.NETCore.App] (TaskId:139) 6.0.5 at [/Users/runner/.dotnet/shared/Microsoft.NETCore.App] (TaskId:139) (TaskId:139) You can resolve the problem by installing the specified framework and/or SDK. (TaskId:139) (TaskId:139) The specified framework can be found at: (TaskId:139) - https://aka.ms/dotnet-core-applaunch?framework=Microsoft.NETCore.App&framework_version=7.0.0-preview.5.22271.4&arch=x64&rid=osx.12-x64 (TaskId:139) 1:7>/Users/runner/work/1/s/xamarin-android/bin/Release/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.0-ci.pr.gh7028.23/tools/Xamarin.Android.Bindings.ClassParse.targets(30,5): error MSB6006: "dotnet" exited with code 150. [/Users/runner/work/1/a/TestRelease/05-25_01.03.40/temp/BuildWithExternalJavaLibrary/BuildWithExternalJavaLibraryBinding/BuildWithExternalJavaLibraryBinding.csproj] Commit ff7f467 removed the need to have a global .NET 7 preview install to build and test Xamarin.Android. This appears to expose an issue in `AndroidDotnetToolTask`, which uses the latest `dotnet` in $PATH to run some of our tools. After upgrading some of these tools (class-parse, generator) to net7.0, we are no longer able to run them as there is no net7.0 runtime installed globally. Improve the `AndroidDotnetToolTask` to better handle "sandboxed" .NET installations by using a full path to `dotnet` if one is found.
84d51b2
to
8cd79a6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was looking at a random .binlog
and I see both:
DOTNET_HOST_PATH = C:\Program Files\dotnet\dotnet.exe
NetCoreRoot = C:\Program Files\dotnet\
So it seems like this should work.
Context: dotnet/java-interop#988
A recent attempt to update Java.Interop to target net7.0 produced some
test failures on the Xamarin.Android side:
Commit ff7f467 removed the need to have a global .NET 7 preview install
to build and test Xamarin.Android. This appears to expose an issue in
AndroidDotnetToolTask
, which uses the latestdotnet
in $PATH to runsome of our tools. After upgrading some of these tools (class-parse,
generator) to net7.0, we are no longer able to run them as there is no
net7.0 runtime installed globally.
Improve the
AndroidDotnetToolTask
to better handle "sandboxed" .NETinstallations by using a full path to
dotnet
if one is found.