From 463449fae5aff5e85f5e95bbf7f56aac30184af5 Mon Sep 17 00:00:00 2001 From: Mauro Agnoletti Date: Thu, 20 Jul 2023 10:22:24 -0400 Subject: [PATCH] [dotnet][xma] Ensure we don't use DOTNET_ROOT and DOTNET_HOST_PATH in the Build Agent and remote tasks DOTNET_ROOT and DOTNET_HOST_PATH are being deprecated as a mechanism to store the location of dotnet. PATH will be used instead, so we should ensure that the existing code that makes usage of these variables is adapted to the new guidelines. More information: https://github.com/dotnet/roslyn/commit/f454d6960e979b6643f805f66f619650024a3f34 https://github.com/dotnet/runtime/issues/88754#issuecomment-1632957579 Additionally, to avoid confusion, we are using a dedicate DOTNET_CUSTOM_PATH variable with the path of the dotnet used by the XMA Build Agent, so it can be used internally by the tasks without mixing it with the existing dotnet variables --- .../Xamarin.Messaging.Build/TaskRunner.cs | 82 +++++++++++++++---- .../Tasks/BTouchTaskBase.cs | 13 ++- ...omputeRemoteGeneratorPropertiesTaskBase.cs | 2 +- .../Tasks/XamarinBuildTask.cs | 2 +- 4 files changed, 75 insertions(+), 24 deletions(-) diff --git a/msbuild/Messaging/Xamarin.Messaging.Build/TaskRunner.cs b/msbuild/Messaging/Xamarin.Messaging.Build/TaskRunner.cs index 264ac4d15790..1ad4ea1a51f6 100644 --- a/msbuild/Messaging/Xamarin.Messaging.Build/TaskRunner.cs +++ b/msbuild/Messaging/Xamarin.Messaging.Build/TaskRunner.cs @@ -10,24 +10,15 @@ namespace Xamarin.Messaging.Build { internal class TaskRunner : ITaskRunner { - ITaskSerializer serializer; - List tasks = new List (); + static readonly ITracer tracer = Tracer.Get (); + + readonly ITaskSerializer serializer; + readonly List tasks = new List (); internal TaskRunner (ITaskSerializer serializer) { this.serializer = serializer; - - var sdkRootPath = Path.Combine (MessagingContext.GetXmaPath (), "SDKs"); - var dotnetPath = Path.Combine (sdkRootPath, "dotnet", "dotnet"); - - if (File.Exists (dotnetPath)) { - Environment.SetEnvironmentVariable ("DOTNET_CUSTOM_HOME", Path.Combine (sdkRootPath, ".home")); - } else { - //In case the XMA dotnet has not been installed yet - dotnetPath = "/usr/local/share/dotnet/dotnet"; - } - - Environment.SetEnvironmentVariable ("DOTNET_HOST_PATH", dotnetPath); + SetDotNetVariables(); } internal IEnumerable Tasks => tasks.AsReadOnly (); @@ -57,5 +48,68 @@ public ExecuteTaskResult Execute (string taskName, string inputs) return result; } + + void SetDotNetVariables() + { + var xmaSdkRootPath = Path.Combine (MessagingContext.GetXmaPath (), "SDKs"); + var xmaDotNetRootPath = Path.Combine (xmaSdkRootPath, "dotnet"); + var xmaDotNetPath = default(string); + + if (IsValidDotNetInstallation(xmaDotNetRootPath)) { + //If the XMA dotnet is already installed, we use it and also declare a custom home for it (for NuGet restore and caches) + Environment.SetEnvironmentVariable ("DOTNET_CUSTOM_HOME", Path.Combine (xmaSdkRootPath, ".home")); + xmaDotNetPath = GetDotNetPath(xmaDotNetRootPath); + } else { + //In case the XMA dotnet has not been installed yet, we use the default dotnet installation + xmaDotNetPath = GetDefaultDotNetPath(); + xmaDotNetRootPath = Path.GetDirectoryName (xmaDotNetPath); + } + + var pathContent = GetPathContent(); + //We add the XMA dotnet path first so it has priority over the default dotnet installation + var newPathContent = $"{xmaDotNetRootPath}:{pathContent}"; + + //Override the PATH with the XMA dotnet in it, just in case it's used internally by dotnet + Environment.SetEnvironmentVariable ("PATH", newPathContent); + //Deprecated dotnet environment variable. We still preserve ir for backwards compatibility with other components that haven't deprecated it yet (like dotnet ILLink) + Environment.SetEnvironmentVariable ("DOTNET_HOST_PATH", xmaDotNetPath); + //Custom environment variable for internal iOS SDK usage + Environment.SetEnvironmentVariable ("DOTNET_CUSTOM_PATH", xmaDotNetPath); + + tracer.Info ($"Using dotnet: {xmaDotNetPath}"); + } + + string GetDefaultDotNetPath() + { + var dotnetRootPath = "/usr/local/share/dotnet"; + + if (IsValidDotNetInstallation(dotnetRootPath)) { + return GetDotNetPath(dotnetRootPath); + } + + var pathContent = GetPathContent(); + var pathElements = pathContent.Split(':', StringSplitOptions.RemoveEmptyEntries); + + foreach (var pathElement in pathElements) + { + try + { + if (IsValidDotNetInstallation(pathElement)) + { + return GetDotNetPath(pathElement); + } + } + catch + { + //If we can't read a directory for any reason just skip it + } + } + } + + string GetPathContent() => Environment.GetEnvironmentVariable("PATH") ?? ""; + + bool IsValidDotNetInstallation(string rootPath) => File.Exists (GetDotNetPath(rootPath)); + + string GetDotNetPath(string rootPath) => Path.Combine (rootPath, "dotnet"); } } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/BTouchTaskBase.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/BTouchTaskBase.cs index bfc97a58e84d..08eb656b7d45 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/BTouchTaskBase.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/BTouchTaskBase.cs @@ -78,16 +78,13 @@ public abstract class BTouchTaskBase : XamarinToolTask { string DotNetPath { get { // Return the dotnet executable we're executing with. - var dotnet_path = Environment.GetEnvironmentVariable ("DOTNET_HOST_PATH"); - if (!string.IsNullOrEmpty (dotnet_path)) - return dotnet_path; + var dotnetPath = Environment.GetEnvironmentVariable ("DOTNET_CUSTOM_PATH"); - if (Environment.OSVersion.Platform == PlatformID.Win32NT) { - // This might happen when building from inside VS (design-time builds, etc.) - return "dotnet.exe"; + if (!string.IsNullOrEmpty (dotnetPath)) { + return dotnetPath; } - - throw new InvalidOperationException ($"DOTNET_HOST_PATH is not set"); + + return Environment.OSVersion.Platform == PlatformID.Win32NT ? "dotnet.exe" : "dotnet"; } } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/ComputeRemoteGeneratorPropertiesTaskBase.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/ComputeRemoteGeneratorPropertiesTaskBase.cs index 61e0c045ff0e..96c428f05681 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/ComputeRemoteGeneratorPropertiesTaskBase.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/ComputeRemoteGeneratorPropertiesTaskBase.cs @@ -93,7 +93,7 @@ void ComputeProperties () var environment = default (Dictionary); if (IsDotNet) { - executable = Environment.GetEnvironmentVariable ("DOTNET_HOST_PATH"); + executable = Environment.GetEnvironmentVariable ("DOTNET_CUSTOM_PATH"); if (string.IsNullOrEmpty (executable)) executable = "dotnet"; arguments.Add ("build"); diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinBuildTask.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinBuildTask.cs index d6c36ed34481..baa1af2fa0bb 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinBuildTask.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinBuildTask.cs @@ -35,7 +35,7 @@ protected string ComputeValueUsingTarget (string computeValueTarget, string targ "; File.WriteAllText (projectPath, csproj); - var dotnetPath = Environment.GetEnvironmentVariable ("DOTNET_HOST_PATH"); + var dotnetPath = Environment.GetEnvironmentVariable ("DOTNET_CUSTOM_PATH"); if (string.IsNullOrEmpty (dotnetPath)) { dotnetPath = "dotnet";