diff --git a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs index 87642d8d2fb32b..319ba6280a0dcc 100644 --- a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs +++ b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs @@ -191,12 +191,39 @@ public class MonoAOTCompiler : Microsoft.Build.Utilities.Task /// public string? CacheFilePath { get; set; } + /// + /// Passes additional, custom arguments to --aot + /// + public string? AotArguments { get; set; } + + /// + /// Passes temp-path to the AOT compiler + /// + public string? TempPath { get; set; } + + /// + /// Passes ld-name to the AOT compiler, for use with UseLLVM=true + /// + public string? LdName { get; set; } + + /// + /// Passes ld-flags to the AOT compiler, for use with UseLLVM=true + /// + public string? LdFlags { get; set; } + + /// + /// Specify WorkingDirectory for the AOT compiler + /// + public string? WorkingDirectory { get; set; } + [Required] public string IntermediateOutputPath { get; set; } = string.Empty; [Output] public string[]? FileWrites { get; private set; } + private static readonly Encoding s_utf8Encoding = new UTF8Encoding(false); + private List _fileWrites = new(); private IList? _assembliesToCompile; @@ -225,7 +252,9 @@ private bool ProcessAndValidateArguments() return false; } - if (!Path.IsPathRooted(OutputDir)) + // A relative path might be used along with WorkingDirectory, + // only call Path.GetFullPath() if WorkingDirectory is blank. + if (string.IsNullOrEmpty(WorkingDirectory) && !Path.IsPathRooted(OutputDir)) OutputDir = Path.GetFullPath(OutputDir); if (!Directory.Exists(OutputDir)) @@ -682,6 +711,26 @@ private PrecompileArguments GetPrecompileArgumentsFor(ITaskItem assemblyItem, st } } + if (!string.IsNullOrEmpty(AotArguments)) + { + aotArgs.Add(AotArguments); + } + + if (!string.IsNullOrEmpty(TempPath)) + { + aotArgs.Add($"temp-path={TempPath}"); + } + + if (!string.IsNullOrEmpty(LdName)) + { + aotArgs.Add($"ld-name={LdName}"); + } + + if (!string.IsNullOrEmpty(LdFlags)) + { + aotArgs.Add($"ld-flags={LdFlags}"); + } + // we need to quote the entire --aot arguments here to make sure it is parsed // on Windows as one argument. Otherwise it will be split up into multiple // values, which wont work. @@ -694,7 +743,16 @@ private PrecompileArguments GetPrecompileArgumentsFor(ITaskItem assemblyItem, st } else { - processArgs.Add('"' + assemblyFilename + '"'); + if (string.IsNullOrEmpty(WorkingDirectory)) + { + processArgs.Add('"' + assemblyFilename + '"'); + } + else + { + // If WorkingDirectory is supplied, the caller could be passing in a relative path + // Use the original ItemSpec that was passed in. + processArgs.Add('"' + assemblyItem.ItemSpec + '"'); + } } monoPaths = $"{assemblyDir}{Path.PathSeparator}{monoPaths}"; @@ -706,14 +764,14 @@ private PrecompileArguments GetPrecompileArgumentsFor(ITaskItem assemblyItem, st var responseFileContent = string.Join(" ", processArgs); var responseFilePath = Path.GetTempFileName(); - using (var sw = new StreamWriter(responseFilePath, append: false, encoding: new UTF8Encoding(false))) + using (var sw = new StreamWriter(responseFilePath, append: false, encoding: s_utf8Encoding)) { sw.WriteLine(responseFileContent); } return new PrecompileArguments(ResponseFilePath: responseFilePath, EnvironmentVariables: envVariables, - WorkingDir: assemblyDir, + WorkingDir: string.IsNullOrEmpty(WorkingDirectory) ? assemblyDir : WorkingDirectory, AOTAssembly: aotAssembly, ProxyFiles: proxyFiles); } @@ -741,7 +799,7 @@ private bool PrecompileLibrary(PrecompileArguments args) StringBuilder envStr = new StringBuilder(string.Empty); foreach (KeyValuePair kvp in args.EnvironmentVariables) envStr.Append($"{kvp.Key}={kvp.Value} "); - Log.LogMessage(importance, $"{msgPrefix}Exec (with response file contents expanded) in {args.WorkingDir}: {envStr}{CompilerBinaryPath} {File.ReadAllText(args.ResponseFilePath)}"); + Log.LogMessage(importance, $"{msgPrefix}Exec (with response file contents expanded) in {args.WorkingDir}: {envStr}{CompilerBinaryPath} {File.ReadAllText(args.ResponseFilePath, s_utf8Encoding)}"); } Log.LogMessage(importance, output);