diff --git a/src/mono/wasm/Wasm.Build.Tests/Common/BuildEnvironment.cs b/src/mono/wasm/Wasm.Build.Tests/Common/BuildEnvironment.cs
index 37a7668b5d099a..facc67c730147f 100644
--- a/src/mono/wasm/Wasm.Build.Tests/Common/BuildEnvironment.cs
+++ b/src/mono/wasm/Wasm.Build.Tests/Common/BuildEnvironment.cs
@@ -37,7 +37,7 @@ public class BuildEnvironment
public static readonly string RelativeTestAssetsPath = @"..\testassets\";
public static readonly string TestAssetsPath = Path.Combine(AppContext.BaseDirectory, "testassets");
public static readonly string TestDataPath = Path.Combine(AppContext.BaseDirectory, "data");
- public static readonly string TmpPath = Path.Combine(AppContext.BaseDirectory, "wbt");
+ public static readonly string TmpPath = Path.Combine(AppContext.BaseDirectory, "wbt artifacts");
public static readonly string DefaultRuntimeIdentifier =
#if TARGET_WASI
diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets
index d9595b16c2eb42..49b1ad7cb4a3c9 100644
--- a/src/mono/wasm/build/WasmApp.Native.targets
+++ b/src/mono/wasm/build/WasmApp.Native.targets
@@ -3,7 +3,7 @@
-
+
<_WasmBuildNativeCoreDependsOn>
@@ -211,7 +211,7 @@
<_EmccCompileBitcodeRsp>$(_WasmIntermediateOutputPath)emcc-compile-bc.rsp
<_EmccLinkRsp>$(_WasmIntermediateOutputPath)emcc-link.rsp
-
+
$(EmccTotalMemory)
5MB
false
@@ -250,7 +250,7 @@
<_EmccCFlags Include="-DGEN_PINVOKE=1" />
<_EmccCFlags Include="-emit-llvm" />
- <_EmccCFlags Include=""-I%(_EmccIncludePaths.Identity)"" />
+ <_EmccCFlags Include="-I"%(_EmccIncludePaths.Identity)"" />
<_EmccLDFlags Include="$(EmccLinkOptimizationFlag)" />
diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets
index b4040156dfeab6..cd2cf82ba6cc65 100644
--- a/src/mono/wasm/build/WasmApp.targets
+++ b/src/mono/wasm/build/WasmApp.targets
@@ -490,7 +490,7 @@
-
+
diff --git a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs
index 9e52322770b04a..7d22da51109fa3 100644
--- a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs
+++ b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs
@@ -951,7 +951,7 @@ private PrecompileArguments GetPrecompileArgumentsFor(ITaskItem assemblyItem, st
if (isDedup)
{
foreach (var aItem in _assembliesToCompile!)
- processArgs.Add(aItem.ItemSpec);
+ processArgs.Add('"' + aItem.ItemSpec + '"');
}
else
{
diff --git a/src/tasks/WasmAppBuilder/CreateResponseFile.cs b/src/tasks/WasmAppBuilder/CreateResponseFile.cs
new file mode 100644
index 00000000000000..c3206b91496294
--- /dev/null
+++ b/src/tasks/WasmAppBuilder/CreateResponseFile.cs
@@ -0,0 +1,99 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+
+namespace Microsoft.WebAssembly.Build.Tasks
+{
+ ///
+ /// This cannot be done with WriteLinesToFile task because we need to parse EmccCFlags before saving to file
+ /// by escaping spaces with backslashes. MsBuild converts all backslashes to forward slashes automatically,
+ /// so it cannot be done directly in the .targets (https://github.com/dotnet/msbuild/issues/3468).
+ ///
+ public class CreateResponseFile : Microsoft.Build.Utilities.Task
+ {
+ [NotNull]
+ [Required]
+ public ITaskItem[]? EmccCFlags { get; set; }
+ [Required]
+ public string? FilePath { get; set; }
+ public bool Overwrite { get; set; } = true;
+ public bool WriteOnlyWhenDifferent{ get; set; } = true;
+ public override bool Execute()
+ {
+ try
+ {
+ return ExecuteActual();
+ }
+ catch (LogAsErrorException laee)
+ {
+ Log.LogError(laee.Message);
+ return false;
+ }
+ }
+
+ private bool ExecuteActual()
+ {
+ if (EmccCFlags.Length == 0)
+ {
+ Log.LogError($"No Emcc flags to write");
+ return false;
+ }
+
+ if (string.IsNullOrEmpty(FilePath))
+ {
+ Log.LogError($"FilePath is empty");
+ return false;
+ }
+
+ if (File.Exists(FilePath))
+ {
+ if (!Overwrite)
+ return true;
+ var lines = File.ReadLines(FilePath);
+ bool isDifferent = lines.Count() != EmccCFlags.Length;
+ if (!isDifferent)
+ {
+ foreach (var element in lines.Zip(EmccCFlags, (line, flag) => new { Line = line, Flag = flag }) )
+ {
+ if (element.Line != element.Flag.ItemSpec)
+ {
+ Log.LogMessage($"Has a different line, element.Line={element.Line}, element.Flag.ItemSpec={element.Flag.ItemSpec}");
+ isDifferent = true;
+ break;
+ }
+ }
+ }
+ if (WriteOnlyWhenDifferent && isDifferent)
+ return true;
+ Write(FilePath, EmccCFlags);
+ }
+ else
+ {
+ Write(FilePath, EmccCFlags);
+ }
+ return !Log.HasLoggedErrors;
+ }
+
+ private static void Write(string path, ITaskItem[] flags)
+ {
+ using (StreamWriter outputFile = new StreamWriter(path))
+ {
+ foreach (ITaskItem flag in flags)
+ {
+ outputFile.WriteLine(flag.ItemSpec.Replace(" ", "\\ "));
+ }
+ }
+ }
+ }
+}