From 747e9fd6adc189d12a418fd4bac978c4b1582369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Wed, 12 Jul 2017 16:33:29 +0200 Subject: [PATCH 1/2] 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 --- .../Interop.NETStandard.cs | 16 ++++++++++++++++ .../MSBuildSdkResolver.cs | 12 +++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.NETStandard.cs b/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.NETStandard.cs index 272471bd3..74abc2a61 100644 --- a/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.NETStandard.cs +++ b/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.NETStandard.cs @@ -7,6 +7,7 @@ // on non-Windows machines. #if NETSTANDARD1_5 +using System; using System.Runtime.InteropServices; using System.Text; @@ -16,6 +17,14 @@ namespace Microsoft.DotNet.MSBuildSdkResolver { 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) { // hostfxr string encoding is platform -specific so dispatch to the @@ -31,6 +40,13 @@ namespace Microsoft.DotNet.MSBuildSdkResolver // CharSet.Ansi is UTF8 on Unix [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); + + // 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); } } diff --git a/src/Microsoft.DotNet.MSBuildSdkResolver/MSBuildSdkResolver.cs b/src/Microsoft.DotNet.MSBuildSdkResolver/MSBuildSdkResolver.cs index f5195f839..08a552479 100644 --- a/src/Microsoft.DotNet.MSBuildSdkResolver/MSBuildSdkResolver.cs +++ b/src/Microsoft.DotNet.MSBuildSdkResolver/MSBuildSdkResolver.cs @@ -174,8 +174,18 @@ namespace Microsoft.DotNet.MSBuildSdkResolver } 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); } } } From 600946c58b558a72015b56655026af365037902a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Tue, 11 Jul 2017 17:12:26 +0200 Subject: [PATCH 2/2] MSBuildSdkResolver: clarify comment in Interop.NETStandard.cs The .NET Standard build ships with Mono/msbuild. --- .../Interop.NETStandard.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.NETStandard.cs b/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.NETStandard.cs index 74abc2a61..b672a5dfb 100644 --- a/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.NETStandard.cs +++ b/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.NETStandard.cs @@ -1,10 +1,10 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -// NOTE: Currently, only the NET46 build ships (with Visual Studio/desktop msbuild), -// but the netstandard1.5 adaptation here acts a proof-of-concept for cross-platform +// NOTE: the NET46 build ships with Visual Studio/desktop msbuild on Windows. +// The netstandard1.5 adaptation here acts a proof-of-concept for cross-platform // portability of the underlying hostfxr API and gives us build and test coverage -// on non-Windows machines. +// on non-Windows machines. It also ships with msbuild on Mono. #if NETSTANDARD1_5 using System;