Skip to content

Commit

Permalink
[dotnet][xma] Ensure we don't use DOTNET_ROOT and DOTNET_HOST_PATH in…
Browse files Browse the repository at this point in the history
… 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:

dotnet/roslyn@f454d69

dotnet/runtime#88754 (comment)

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
  • Loading branch information
mauroa committed Jul 20, 2023
1 parent fb147a1 commit 463449f
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 24 deletions.
82 changes: 68 additions & 14 deletions msbuild/Messaging/Xamarin.Messaging.Build/TaskRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,15 @@

namespace Xamarin.Messaging.Build {
internal class TaskRunner : ITaskRunner {
ITaskSerializer serializer;
List<Type> tasks = new List<Type> ();
static readonly ITracer tracer = Tracer.Get<TaskRunner> ();

readonly ITaskSerializer serializer;
readonly List<Type> tasks = new List<Type> ();

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<Type> Tasks => tasks.AsReadOnly ();
Expand Down Expand Up @@ -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");
}
}
13 changes: 5 additions & 8 deletions msbuild/Xamarin.MacDev.Tasks/Tasks/BTouchTaskBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ void ComputeProperties ()
var environment = default (Dictionary<string, string?>);

if (IsDotNet) {
executable = Environment.GetEnvironmentVariable ("DOTNET_HOST_PATH");
executable = Environment.GetEnvironmentVariable ("DOTNET_CUSTOM_PATH");
if (string.IsNullOrEmpty (executable))
executable = "dotnet";
arguments.Add ("build");
Expand Down
2 changes: 1 addition & 1 deletion msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinBuildTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down

0 comments on commit 463449f

Please sign in to comment.