Skip to content
60 changes: 4 additions & 56 deletions src/tasks/Common/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,61 +48,6 @@ public static bool IsNewerThan(string inFile, string outFile)
=> !File.Exists(inFile) || !File.Exists(outFile) ||
(File.GetLastWriteTimeUtc(inFile) > File.GetLastWriteTimeUtc(outFile));

public static (int exitCode, string output) RunShellCommand(
TaskLoggingHelper logger,
string command,
IDictionary<string, string> envVars,
string workingDir,
bool silent=false,
bool logStdErrAsMessage=false,
MessageImportance debugMessageImportance=MessageImportance.Low,
string? label=null)
{
string scriptFileName = CreateTemporaryBatchFile(command);
(string shell, string args) = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? ("cmd", $"/c \"{scriptFileName}\"")
: ("/bin/sh", $"\"{scriptFileName}\"");

string msgPrefix = label == null ? string.Empty : $"[{label}] ";
logger.LogMessage(debugMessageImportance, $"{msgPrefix}Running {command} via script {scriptFileName}:", msgPrefix);
logger.LogMessage(debugMessageImportance, File.ReadAllText(scriptFileName), msgPrefix);

return TryRunProcess(logger,
shell,
args,
envVars,
workingDir,
silent: silent,
logStdErrAsMessage: logStdErrAsMessage,
label: label,
debugMessageImportance: debugMessageImportance);

static string CreateTemporaryBatchFile(string command)
{
string extn = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".cmd" : ".sh";
string file = Path.Combine(Path.GetTempPath(), $"tmp{Guid.NewGuid():N}{extn}");

using StreamWriter sw = new(file);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// set encoding to UTF-8 -> full Unicode support is needed for usernames -
// `command` contains tmp dir path with the username
sw.WriteLine(@"%SystemRoot%\System32\chcp.com 65001>nul");
Comment thread
tmds marked this conversation as resolved.
sw.WriteLine("setlocal");
sw.WriteLine("set errorlevel=dummy");
sw.WriteLine("set errorlevel=");
}
else
{
// Use sh rather than bash, as not all 'nix systems necessarily have Bash installed
sw.WriteLine("#!/bin/sh");
}

sw.WriteLine(command);
return file;
}
}

public static string RunProcess(
TaskLoggingHelper logger,
string path,
Expand Down Expand Up @@ -150,7 +95,9 @@ public static (int, string) TryRunProcess(
CreateNoWindow = true,
RedirectStandardError = true,
RedirectStandardOutput = true,
RedirectStandardInput = inputProvider != null,
RedirectStandardInput = true,
StandardOutputEncoding = Encoding.UTF8,
StandardErrorEncoding = Encoding.UTF8,
Arguments = args,
};

Expand Down Expand Up @@ -208,6 +155,7 @@ public static (int, string) TryRunProcess(
process.BeginOutputReadLine();
process.BeginErrorReadLine();
inputProvider?.Invoke(process.StandardInput.BaseStream);
process.StandardInput.Close();
process.WaitForExit();

logger.LogMessage(debugMessageImportance, $"{msgPrefix}Exit code: {process.ExitCode}");
Expand Down
21 changes: 17 additions & 4 deletions src/tasks/WasmAppBuilder/EmccCompile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -209,19 +210,31 @@ bool ProcessSourceFile(string srcFile, string objFile)
string tmpObjFile = Path.GetTempFileName();
try
{
string command = $"\"{CompilerBinaryPath}\" {Arguments} -c -o \"{tmpObjFile}\" \"{srcFile}\"";
string args = $"{Arguments} -c -o \"{tmpObjFile}\" \"{srcFile}\"";
var startTime = DateTime.Now;

// Log the command in a compact format which can be copy pasted
StringBuilder envStr = new StringBuilder(string.Empty);
foreach (var key in envVarsDict.Keys)
envStr.Append($"{key}={envVarsDict[key]} ");
Log.LogMessage(MessageImportance.Low, $"Exec: {envStr}{command}");
(int exitCode, string output) = Utils.RunShellCommand(
Comment thread
maraf marked this conversation as resolved.
Log.LogMessage(MessageImportance.Low, $"Exec: {envStr}\"{CompilerBinaryPath}\" {args}");

// On Windows, the emsdk ships emcc.bat to invoke emcc. Use 'cmd' to execute the batch file.
// Switch to UTF-8 code page to enable cmd to handle non-ASCII paths.
string processPath = CompilerBinaryPath;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
args = $"/S /c \"chcp 65001 > nul && \"{CompilerBinaryPath}\" {args}\"";
processPath = "cmd";
}

(int exitCode, string output) = Utils.TryRunProcess(
Log,
command,
processPath,
args,
envVarsDict,
workingDir: Environment.CurrentDirectory,
silent: false,
logStdErrAsMessage: true,
debugMessageImportance: messageImportance,
label: Path.GetFileName(srcFile));
Expand Down
Loading