Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/Xamarin.Android.Build.Tasks/Tasks/D8.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ protected virtual CommandLineBuilder GetCommandLineBuilder ()

// Create response file with all D8/R8 arguments to avoid command line length limits
responseFilePath = CreateResponseFile ();
cmd.AppendSwitch ($"@{responseFilePath}");
cmd.AppendSwitch ($"\"@{responseFilePath}\"");

return cmd;
}
Expand All @@ -91,7 +91,7 @@ protected virtual CommandLineBuilder GetCommandLineBuilder ()
/// </summary>
protected virtual string CreateResponseFile ()
{
var responseFile = Path.GetTempFileName ();
var responseFile = CreateResponseFilePath ();
Log.LogDebugMessage ($"[{MainClass}] response file: {responseFile}");

using var response = new StreamWriter (responseFile, append: false, encoding: Files.UTF8withoutBOM);
Expand Down Expand Up @@ -170,6 +170,8 @@ protected virtual string CreateResponseFile ()
return responseFile;
}

protected virtual string CreateResponseFilePath () => Path.GetTempFileName ();

/// <summary>
/// Writes a single argument to the response file.
/// R8/D8 response files treat each line as a complete argument, so no quoting is needed.
Expand Down
2 changes: 1 addition & 1 deletion src/Xamarin.Android.Build.Tasks/Tasks/JavaSourceUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ protected override string GenerateCommandLineCommands ()
// Arguments sent to java.exe
cmd.AppendSwitchIfNotNull ("-jar ", JavaSourceUtilsJar);

cmd.AppendSwitch ($"@{responseFilePath}");
cmd.AppendSwitch ($"\"@{responseFilePath}\"");


return cmd.ToString ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Microsoft.Build.Utilities;
using NUnit.Framework;
using Xamarin.Android.Tasks;
using Xamarin.Android.Tools;

namespace Xamarin.Android.Build.Tests
{
Expand Down Expand Up @@ -73,7 +74,7 @@ public void ResponseFileContainsLibAndInputJars ()
FileAssert.Exists (responseFilePath, "Response file should exist");

// Verify the response file is referenced in the command line
Assert.IsTrue (commandLine.Contains ($"@{responseFilePath}"), "Command line should reference the response file");
Assert.IsTrue (commandLine.Contains ($"\"@{responseFilePath}\""), "Command line should quote the response file");

// Read and verify response file content
string [] responseFileContent = File.ReadAllLines (responseFilePath);
Expand Down Expand Up @@ -116,16 +117,19 @@ public void ResponseFileHandlesPathsWithSpaces ()
JarPath = "d8.jar",
JavaPlatformJarPath = platformJar,
OutputDirectory = tempDir,
ResponseFileDirectory = pathWithSpaces,
JavaLibrariesToEmbed = new ITaskItem [] {
new TaskItem (inputJar),
},
};

d8Task.TestGenerateCommandLineCommands ();
string commandLine = d8Task.TestGenerateCommandLineCommands ();
string responseFilePath = d8Task.ResponseFilePath;

try {
Assert.IsNotNull (responseFilePath, "Response file path should not be null");
FileAssert.Exists (responseFilePath, "Response file should exist");
Assert.IsTrue (commandLine.Contains ($"\"@{responseFilePath}\""), "Command line should quote a response file path containing spaces");
string responseFileContent = File.ReadAllText (responseFilePath);

// Paths with spaces should NOT be quoted (R8/D8 treats each line as a complete argument)
Expand All @@ -150,30 +154,30 @@ internal class D8TestTask : D8
/// </summary>
public string ResponseFilePath { get; private set; }

public string ResponseFileDirectory { get; set; }

protected override string CreateResponseFilePath ()
{
if (!ResponseFileDirectory.IsNullOrEmpty ()) {
return Path.Combine (ResponseFileDirectory, Path.GetRandomFileName ());
}
return base.CreateResponseFilePath ();
}

protected override string CreateResponseFile ()
{
var responseFile = base.CreateResponseFile ();
ResponseFilePath = responseFile;
return responseFile;
}

/// <summary>
/// Test method that generates command line without actually running the task.
/// </summary>
public string TestGenerateCommandLineCommands ()
{
var cmd = GetCommandLineBuilder ();
// Capture the response file path after command line generation
ResponseFilePath = GetResponseFilePathFromCommandLine (cmd.ToString ());
return cmd.ToString ();
}

private static string GetResponseFilePathFromCommandLine (string commandLine)
{
// Find the @filepath argument
var startIndex = commandLine.IndexOf ("@", StringComparison.Ordinal);
if (startIndex < 0) return null;

// Check if '@' is the last character
if (startIndex + 1 >= commandLine.Length) return null;

var endIndex = commandLine.IndexOf (" ", startIndex, StringComparison.Ordinal);
if (endIndex < 0) endIndex = commandLine.Length;

return commandLine.Substring (startIndex + 1, endIndex - startIndex - 1);
}
}
}