MSBuildSdkResolver: resolve symlink for 'dotnet' binary
On Linux the dotnet installed by the dotnet packages is a symlink (/usr/bin/dotnet -> ../share/dotnet/dotnet). We need to resolve the symlink so we're passing the path to the actual .NET Core installation to libhostfxr. Fixes https://github.com/dotnet/cli/issues/7125
This commit is contained in:
parent
5a37290f24
commit
747e9fd6ad
2 changed files with 27 additions and 1 deletions
|
@ -7,6 +7,7 @@
|
||||||
// on non-Windows machines.
|
// on non-Windows machines.
|
||||||
#if NETSTANDARD1_5
|
#if NETSTANDARD1_5
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
@ -16,6 +17,14 @@ namespace Microsoft.DotNet.MSBuildSdkResolver
|
||||||
{
|
{
|
||||||
internal static readonly bool RunningOnWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
internal static readonly bool RunningOnWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||||
|
|
||||||
|
internal static string realpath(string path)
|
||||||
|
{
|
||||||
|
var ptr = unix_realpath(path, IntPtr.Zero);
|
||||||
|
var result = Marshal.PtrToStringAnsi(ptr); // uses UTF8 on Unix
|
||||||
|
unix_free(ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private static int hostfxr_resolve_sdk(string exe_dir, string working_dir, [Out] StringBuilder buffer, int buffer_size)
|
private static int hostfxr_resolve_sdk(string exe_dir, string working_dir, [Out] StringBuilder buffer, int buffer_size)
|
||||||
{
|
{
|
||||||
// hostfxr string encoding is platform -specific so dispatch to the
|
// hostfxr string encoding is platform -specific so dispatch to the
|
||||||
|
@ -31,6 +40,13 @@ namespace Microsoft.DotNet.MSBuildSdkResolver
|
||||||
// CharSet.Ansi is UTF8 on Unix
|
// CharSet.Ansi is UTF8 on Unix
|
||||||
[DllImport("hostfxr", EntryPoint = nameof(hostfxr_resolve_sdk), CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("hostfxr", EntryPoint = nameof(hostfxr_resolve_sdk), CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern int unix_hostfxr_resolve_sdk(string exe_dir, string working_dir, [Out] StringBuilder buffer, int buffer_size);
|
private static extern int unix_hostfxr_resolve_sdk(string exe_dir, string working_dir, [Out] StringBuilder buffer, int buffer_size);
|
||||||
|
|
||||||
|
// CharSet.Ansi is UTF8 on Unix
|
||||||
|
[DllImport("libc", EntryPoint = nameof(realpath), CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
private static extern IntPtr unix_realpath(string path, IntPtr buffer);
|
||||||
|
|
||||||
|
[DllImport("libc", EntryPoint = "free", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
private static extern void unix_free(IntPtr ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -174,8 +174,18 @@ namespace Microsoft.DotNet.MSBuildSdkResolver
|
||||||
}
|
}
|
||||||
|
|
||||||
var environmentProvider = new EnvironmentProvider(_getEnvironmentVariable);
|
var environmentProvider = new EnvironmentProvider(_getEnvironmentVariable);
|
||||||
|
var dotnetExe = environmentProvider.GetCommandPath("dotnet");
|
||||||
|
|
||||||
return Path.GetDirectoryName(environmentProvider.GetCommandPath("dotnet"));
|
#if NETSTANDARD1_5
|
||||||
|
if (dotnetExe != null && !Interop.RunningOnWindows)
|
||||||
|
{
|
||||||
|
// e.g. on Linux the 'dotnet' command from PATH is a symlink so we need to
|
||||||
|
// resolve it to get the actual path to the binary
|
||||||
|
dotnetExe = Interop.realpath(dotnetExe) ?? dotnetExe;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return Path.GetDirectoryName(dotnetExe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue