diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index 2d89733447d12..375747cd4e6e5 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -269,7 +269,7 @@ diff --git a/src/tasks/AndroidAppBuilder/AndroidApkFileReplacerTask.cs b/src/tasks/AndroidAppBuilder/AndroidApkFileReplacerTask.cs index a0af313aa1e6a..8a8149ef15484 100644 --- a/src/tasks/AndroidAppBuilder/AndroidApkFileReplacerTask.cs +++ b/src/tasks/AndroidAppBuilder/AndroidApkFileReplacerTask.cs @@ -26,8 +26,7 @@ public class AndroidApkFileReplacerTask : Task public override bool Execute() { - Utils.Logger = Log; - var apkBuilder = new ApkBuilder(); + var apkBuilder = new ApkBuilder(Log); apkBuilder.OutputDir = OutputDir; apkBuilder.AndroidSdk = AndroidSdk; apkBuilder.MinApiLevel = MinApiLevel; diff --git a/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs b/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs index 345ad7219998d..fcf71c0e6f68e 100644 --- a/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs +++ b/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs @@ -87,11 +87,9 @@ public class AndroidAppBuilderTask : Task public override bool Execute() { - Utils.Logger = Log; - string abi = DetermineAbi(); - var apkBuilder = new ApkBuilder(); + var apkBuilder = new ApkBuilder(Log); apkBuilder.ProjectName = ProjectName; apkBuilder.AppDir = AppDir; apkBuilder.OutputDir = OutputDir; diff --git a/src/tasks/AndroidAppBuilder/ApkBuilder.cs b/src/tasks/AndroidAppBuilder/ApkBuilder.cs index 23475c9e1e6c2..c69288218d69f 100644 --- a/src/tasks/AndroidAppBuilder/ApkBuilder.cs +++ b/src/tasks/AndroidAppBuilder/ApkBuilder.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Text; using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; public class ApkBuilder { @@ -32,6 +33,13 @@ public class ApkBuilder public string? DiagnosticPorts { get; set; } public ITaskItem[] Assemblies { get; set; } = Array.Empty(); + private TaskLoggingHelper logger; + + public ApkBuilder(TaskLoggingHelper logger) + { + this.logger = logger; + } + public (string apk, string packageId) BuildApk( string abi, string mainLibraryFileName, @@ -209,7 +217,7 @@ public class ApkBuilder string cmake = "cmake"; string zip = "zip"; - Utils.RunProcess(zip, workingDir: assetsToZipDirectory, args: "-q -r ../assets/assets.zip ."); + Utils.RunProcess(logger, zip, workingDir: assetsToZipDirectory, args: "-q -r ../assets/assets.zip ."); Directory.Delete(assetsToZipDirectory, true); if (!File.Exists(androidJar)) @@ -274,7 +282,7 @@ public class ApkBuilder // if lib doesn't exist (primarly due to runtime build without static lib support), fallback linking stub lib. if (!File.Exists(componentLibToLink)) { - Utils.LogInfo($"\nCouldn't find static component library: {componentLibToLink}, linking static component stub library: {staticComponentStubLib}.\n"); + logger.LogMessage(MessageImportance.High, $"\nCouldn't find static component library: {componentLibToLink}, linking static component stub library: {staticComponentStubLib}.\n"); componentLibToLink = staticComponentStubLib; } @@ -339,8 +347,8 @@ public class ApkBuilder cmakeBuildArgs += " --config Debug"; } - Utils.RunProcess(cmake, workingDir: OutputDir, args: cmakeGenArgs); - Utils.RunProcess(cmake, workingDir: OutputDir, args: cmakeBuildArgs); + Utils.RunProcess(logger, cmake, workingDir: OutputDir, args: cmakeGenArgs); + Utils.RunProcess(logger, cmake, workingDir: OutputDir, args: cmakeBuildArgs); // 2. Compile Java files @@ -369,15 +377,15 @@ public class ApkBuilder .Replace("%MinSdkLevel%", MinApiLevel)); string javaCompilerArgs = $"-d obj -classpath src -bootclasspath {androidJar} -source 1.8 -target 1.8 "; - Utils.RunProcess(javac, javaCompilerArgs + javaActivityPath, workingDir: OutputDir); - Utils.RunProcess(javac, javaCompilerArgs + monoRunnerPath, workingDir: OutputDir); - Utils.RunProcess(dx, "--dex --output=classes.dex obj", workingDir: OutputDir); + Utils.RunProcess(logger, javac, javaCompilerArgs + javaActivityPath, workingDir: OutputDir); + Utils.RunProcess(logger, javac, javaCompilerArgs + monoRunnerPath, workingDir: OutputDir); + Utils.RunProcess(logger, dx, "--dex --output=classes.dex obj", workingDir: OutputDir); // 3. Generate APK string debugModeArg = StripDebugSymbols ? string.Empty : "--debug-mode"; string apkFile = Path.Combine(OutputDir, "bin", $"{ProjectName}.unaligned.apk"); - Utils.RunProcess(aapt, $"package -f -m -F {apkFile} -A assets -M AndroidManifest.xml -I {androidJar} {debugModeArg}", workingDir: OutputDir); + Utils.RunProcess(logger, aapt, $"package -f -m -F {apkFile} -A assets -M AndroidManifest.xml -I {androidJar} {debugModeArg}", workingDir: OutputDir); var dynamicLibs = new List(); dynamicLibs.Add(Path.Combine(OutputDir, "monodroid", "libmonodroid.so")); @@ -433,21 +441,21 @@ public class ApkBuilder // NOTE: we can run android-strip tool from NDK to shrink native binaries here even more. File.Copy(dynamicLib, Path.Combine(OutputDir, destRelative), true); - Utils.RunProcess(aapt, $"add {apkFile} {destRelative}", workingDir: OutputDir); + Utils.RunProcess(logger, aapt, $"add {apkFile} {destRelative}", workingDir: OutputDir); } - Utils.RunProcess(aapt, $"add {apkFile} classes.dex", workingDir: OutputDir); + Utils.RunProcess(logger, aapt, $"add {apkFile} classes.dex", workingDir: OutputDir); // 4. Align APK string alignedApk = Path.Combine(OutputDir, "bin", $"{ProjectName}.apk"); - Utils.RunProcess(zipalign, $"-v 4 {apkFile} {alignedApk}", workingDir: OutputDir); + Utils.RunProcess(logger, zipalign, $"-v 4 {apkFile} {alignedApk}", workingDir: OutputDir); // we don't need the unaligned one any more File.Delete(apkFile); // 5. Generate key (if needed) & sign the apk SignApk(alignedApk, apksigner); - Utils.LogInfo($"\nAPK size: {(new FileInfo(alignedApk).Length / 1000_000.0):0.#} Mb.\n"); + logger.LogMessage(MessageImportance.High, $"\nAPK size: {(new FileInfo(alignedApk).Length / 1000_000.0):0.#} Mb.\n"); return (alignedApk, packageId); } @@ -460,7 +468,7 @@ private void SignApk(string apkPath, string apksigner) if (!File.Exists(signingKey)) { - Utils.RunProcess("keytool", "-genkey -v -keystore debug.keystore -storepass android -alias " + + Utils.RunProcess(logger, "keytool", "-genkey -v -keystore debug.keystore -storepass android -alias " + "androiddebugkey -keypass android -keyalg RSA -keysize 2048 -noprompt " + "-dname \"CN=Android Debug,O=Android,C=US\"", workingDir: OutputDir, silent: true); } @@ -468,7 +476,7 @@ private void SignApk(string apkPath, string apksigner) { File.Copy(signingKey, Path.Combine(OutputDir, "debug.keystore")); } - Utils.RunProcess(apksigner, $"sign --min-sdk-version {MinApiLevel} --ks debug.keystore " + + Utils.RunProcess(logger, apksigner, $"sign --min-sdk-version {MinApiLevel} --ks debug.keystore " + $"--ks-pass pass:android --key-pass pass:android {apkPath}", workingDir: OutputDir); } @@ -499,8 +507,8 @@ public void ReplaceFileInApk(string file) if (!File.Exists(apkPath)) throw new Exception($"{apkPath} was not found"); - Utils.RunProcess(aapt, $"remove -v bin/{Path.GetFileName(apkPath)} {file}", workingDir: OutputDir); - Utils.RunProcess(aapt, $"add -v bin/{Path.GetFileName(apkPath)} {file}", workingDir: OutputDir); + Utils.RunProcess(logger, aapt, $"remove -v bin/{Path.GetFileName(apkPath)} {file}", workingDir: OutputDir); + Utils.RunProcess(logger, aapt, $"add -v bin/{Path.GetFileName(apkPath)} {file}", workingDir: OutputDir); // we need to re-sign the apk SignApk(apkPath, apksigner); diff --git a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs index 259622da70785..465c8845209d9 100644 --- a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs +++ b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs @@ -194,8 +194,6 @@ public class MonoAOTCompiler : Microsoft.Build.Utilities.Task public override bool Execute() { - Utils.Logger = Log; - if (string.IsNullOrEmpty(CompilerBinaryPath)) { throw new ArgumentException($"'{nameof(CompilerBinaryPath)}' is required.", nameof(CompilerBinaryPath)); @@ -545,15 +543,25 @@ private bool PrecompileLibrary(ITaskItem assemblyItem, string? monoPaths) Log.LogMessage(MessageImportance.Low, $"AOT compiler arguments: {responseFileContent}"); + string args = $"--response=\"{responseFilePath}\""; + + // Log the command in a compact format which can be copy pasted + StringBuilder envStr = new StringBuilder(string.Empty); + foreach (KeyValuePair kvp in envVariables) + envStr.Append($"{kvp.Key}={kvp.Value} "); + Log.LogMessage(MessageImportance.Low, $"Exec: {envStr}{CompilerBinaryPath} {args}"); + try { // run the AOT compiler - (int exitCode, string output) = Utils.TryRunProcess(CompilerBinaryPath, - $"--response=\"{responseFilePath}\"", + (int exitCode, string output) = Utils.TryRunProcess(Log, + CompilerBinaryPath, + args, envVariables, assemblyDir, silent: false, - debugMessageImportance: MessageImportance.Low); + debugMessageImportance: MessageImportance.Low, + label: assembly); if (exitCode != 0) { Log.LogError($"Precompiling failed for {assembly}: {output}"); diff --git a/src/tasks/AppleAppBuilder/AppleAppBuilder.cs b/src/tasks/AppleAppBuilder/AppleAppBuilder.cs index 0b20d27f38835..a0637d8d8453d 100644 --- a/src/tasks/AppleAppBuilder/AppleAppBuilder.cs +++ b/src/tasks/AppleAppBuilder/AppleAppBuilder.cs @@ -153,7 +153,6 @@ public string TargetOS public override bool Execute() { - Utils.Logger = Log; bool isDevice = (TargetOS == TargetNames.iOS || TargetOS == TargetNames.tvOS); if (!File.Exists(Path.Combine(AppDir, MainLibraryFileName))) @@ -227,7 +226,7 @@ public override bool Execute() if (GenerateXcodeProject) { - Xcode generator = new Xcode(TargetOS, Arch); + Xcode generator = new Xcode(Log, TargetOS, Arch); generator.EnableRuntimeLogging = EnableRuntimeLogging; generator.DiagnosticPorts = DiagnosticPorts; @@ -239,7 +238,7 @@ public override bool Execute() if (isDevice && string.IsNullOrEmpty(DevTeamProvisioning)) { // DevTeamProvisioning shouldn't be empty for arm64 builds - Utils.LogInfo("DevTeamProvisioning is not set, BuildAppBundle step is skipped."); + Log.LogMessage(MessageImportance.High, "DevTeamProvisioning is not set, BuildAppBundle step is skipped."); } else { diff --git a/src/tasks/AppleAppBuilder/Xcode.cs b/src/tasks/AppleAppBuilder/Xcode.cs index b79387da224f8..2e938d8ea0e36 100644 --- a/src/tasks/AppleAppBuilder/Xcode.cs +++ b/src/tasks/AppleAppBuilder/Xcode.cs @@ -6,6 +6,8 @@ using System.IO; using System.Linq; using System.Text; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; internal class Xcode { @@ -13,27 +15,29 @@ internal class Xcode private string SysRoot { get; set; } private string Target { get; set; } private string XcodeArch { get; set; } + private TaskLoggingHelper Logger { get; set; } - public Xcode(string target, string arch) + public Xcode(TaskLoggingHelper logger, string target, string arch) { + Logger = logger; Target = target; XcodeArch = (arch == "x64") ? "x86_64" : arch; switch (Target) { case TargetNames.iOS: - SysRoot = Utils.RunProcess("xcrun", "--sdk iphoneos --show-sdk-path"); + SysRoot = Utils.RunProcess(Logger, "xcrun", "--sdk iphoneos --show-sdk-path"); break; case TargetNames.iOSsim: - SysRoot = Utils.RunProcess("xcrun", "--sdk iphonesimulator --show-sdk-path"); + SysRoot = Utils.RunProcess(Logger, "xcrun", "--sdk iphonesimulator --show-sdk-path"); break; case TargetNames.tvOS: - SysRoot = Utils.RunProcess("xcrun", "--sdk appletvos --show-sdk-path"); + SysRoot = Utils.RunProcess(Logger, "xcrun", "--sdk appletvos --show-sdk-path"); break; case TargetNames.tvOSsim: - SysRoot = Utils.RunProcess("xcrun", "--sdk appletvsimulator --show-sdk-path"); + SysRoot = Utils.RunProcess(Logger, "xcrun", "--sdk appletvsimulator --show-sdk-path"); break; default: - SysRoot = Utils.RunProcess("xcrun", "--sdk macosx --show-sdk-path"); + SysRoot = Utils.RunProcess(Logger, "xcrun", "--sdk macosx --show-sdk-path"); break; } @@ -145,7 +149,7 @@ public string GenerateXCode( // if lib doesn't exist (primarly due to runtime build without static lib support), fallback linking stub lib. if (!File.Exists(componentLibToLink)) { - Utils.LogInfo($"\nCouldn't find static component library: {componentLibToLink}, linking static component stub library: {staticComponentStubLib}.\n"); + Logger.LogMessage(MessageImportance.High, $"\nCouldn't find static component library: {componentLibToLink}, linking static component stub library: {staticComponentStubLib}.\n"); componentLibToLink = staticComponentStubLib; } @@ -298,7 +302,7 @@ public string GenerateXCode( .Replace("//%APPLE_RUNTIME_IDENTIFIER%", RuntimeIdentifier) .Replace("%EntryPointLibName%", Path.GetFileName(entryPointLib))); - Utils.RunProcess("cmake", cmakeArgs.ToString(), workingDir: binDir); + Utils.RunProcess(Logger, "cmake", cmakeArgs.ToString(), workingDir: binDir); return Path.Combine(binDir, projectName, projectName + ".xcodeproj"); } @@ -391,7 +395,7 @@ public string BuildAppBundle( string config = optimized ? "Release" : "Debug"; args.Append(" -configuration ").Append(config); - Utils.RunProcess("xcodebuild", args.ToString(), workingDir: Path.GetDirectoryName(xcodePrjPath)); + Utils.RunProcess(Logger, "xcodebuild", args.ToString(), workingDir: Path.GetDirectoryName(xcodePrjPath)); string appPath = Path.Combine(Path.GetDirectoryName(xcodePrjPath)!, config + "-" + sdk, Path.GetFileNameWithoutExtension(xcodePrjPath) + ".app"); @@ -400,7 +404,7 @@ public string BuildAppBundle( .EnumerateFiles("*", SearchOption.AllDirectories) .Sum(file => file.Length); - Utils.LogInfo($"\nAPP size: {(appSize / 1000_000.0):0.#} Mb.\n"); + Logger.LogMessage(MessageImportance.High, $"\nAPP size: {(appSize / 1000_000.0):0.#} Mb.\n"); return appPath; } diff --git a/src/tasks/Common/Utils.cs b/src/tasks/Common/Utils.cs index 8756a3156c220..3376b4d5e7bdc 100644 --- a/src/tasks/Common/Utils.cs +++ b/src/tasks/Common/Utils.cs @@ -22,10 +22,11 @@ public static string GetEmbeddedResource(string file) return reader.ReadToEnd(); } - public static (int exitCode, string output) RunShellCommand(string command, + public static (int exitCode, string output) RunShellCommand( + TaskLoggingHelper logger, + string command, IDictionary envVars, string workingDir, - TaskLoggingHelper logger, bool silent=false, bool logStdErrAsMessage=false, MessageImportance debugMessageImportance=MessageImportance.Low, @@ -37,16 +38,16 @@ public static (int exitCode, string output) RunShellCommand(string command, : ("/bin/sh", $"\"{scriptFileName}\""); string msgPrefix = label == null ? string.Empty : $"[{label}] "; - LogMessage(debugMessageImportance, $"Running {command} via script {scriptFileName}:", msgPrefix); - LogMessage(debugMessageImportance, File.ReadAllText(scriptFileName), msgPrefix); + logger.LogMessage(debugMessageImportance, $"Running {command} via script {scriptFileName}:", msgPrefix); + logger.LogMessage(debugMessageImportance, File.ReadAllText(scriptFileName), msgPrefix); - return TryRunProcess(shell, + return TryRunProcess(logger, + shell, args, envVars, workingDir, silent: silent, logStdErrAsMessage: logStdErrAsMessage, - logger: logger, label: label, debugMessageImportance: debugMessageImportance); @@ -74,6 +75,7 @@ static string CreateTemporaryBatchFile(string command) } public static string RunProcess( + TaskLoggingHelper logger, string path, string args = "", IDictionary? envVars = null, @@ -83,12 +85,12 @@ public static string RunProcess( MessageImportance debugMessageImportance=MessageImportance.High) { (int exitCode, string output) = TryRunProcess( + logger, path, args, envVars, workingDir, silent: silent, - logger: Logger, debugMessageImportance: debugMessageImportance); if (exitCode != 0 && !ignoreErrors) @@ -98,20 +100,18 @@ public static string RunProcess( } public static (int, string) TryRunProcess( + TaskLoggingHelper logger, string path, string args = "", IDictionary? envVars = null, string? workingDir = null, bool silent = true, bool logStdErrAsMessage = false, - TaskLoggingHelper? logger = null, MessageImportance debugMessageImportance=MessageImportance.High, string? label=null) { - Logger = logger; - string msgPrefix = label == null ? string.Empty : $"[{label}] "; - LogMessage(debugMessageImportance, $"Running: {path} {args}", msgPrefix); + logger.LogMessage(debugMessageImportance, $"Running: {path} {args}", msgPrefix); var outputBuilder = new StringBuilder(); var processStartInfo = new ProcessStartInfo { @@ -126,17 +126,17 @@ public static (int, string) TryRunProcess( if (workingDir != null) processStartInfo.WorkingDirectory = workingDir; - LogMessage(debugMessageImportance, $"Using working directory: {workingDir ?? Environment.CurrentDirectory}", msgPrefix); + logger.LogMessage(debugMessageImportance, $"Using working directory: {workingDir ?? Environment.CurrentDirectory}", msgPrefix); if (envVars != null) { if (envVars.Count > 0) - LogMessage(MessageImportance.Low, $"Setting environment variables for execution:", msgPrefix); + logger.LogMessage(MessageImportance.Low, $"Setting environment variables for execution:", msgPrefix); foreach (KeyValuePair envVar in envVars) { processStartInfo.EnvironmentVariables[envVar.Key] = envVar.Value; - Logger?.LogMessage(MessageImportance.Low, $"{msgPrefix}\t{envVar.Key} = {envVar.Value}"); + logger.LogMessage(MessageImportance.Low, $"{msgPrefix}\t{envVar.Key} = {envVar.Value}"); } } @@ -155,9 +155,9 @@ public static (int, string) TryRunProcess( if (!silent) { if (logStdErrAsMessage) - LogMessage(debugMessageImportance, e.Data, msgPrefix); + logger.LogMessage(debugMessageImportance, e.Data, msgPrefix); else - Logger?.LogWarning(msg); + logger.LogWarning(msg); } outputBuilder.AppendLine(e.Data); } @@ -170,7 +170,7 @@ public static (int, string) TryRunProcess( return; if (!silent) - LogMessage(debugMessageImportance, e.Data, msgPrefix); + logger.LogMessage(debugMessageImportance, e.Data, msgPrefix); outputBuilder.AppendLine(e.Data); } }; @@ -178,7 +178,7 @@ public static (int, string) TryRunProcess( process.BeginErrorReadLine(); process.WaitForExit(); - Logger?.LogMessage(debugMessageImportance, $"{msgPrefix}Exit code: {process.ExitCode}"); + logger.LogMessage(debugMessageImportance, $"{msgPrefix}Exit code: {process.ExitCode}"); return (process.ExitCode, outputBuilder.ToString().Trim('\r', '\n')); } @@ -223,24 +223,4 @@ public static void DirectoryCopy(string sourceDir, string destDir, Func $"{r.Name}/{r.Version}"))}"); string args = $"restore \"{projectPath}\" /p:RestorePackagesPath=\"{_packagesDir}\""; - (int exitCode, string output) = Utils.TryRunProcess("dotnet", args, silent: false, debugMessageImportance: MessageImportance.Low); + (int exitCode, string output) = Utils.TryRunProcess(_logger, "dotnet", args, silent: false, debugMessageImportance: MessageImportance.Low); if (exitCode != 0) { LogErrorOrWarning($"Restoring packages failed with exit code: {exitCode}. Output:{Environment.NewLine}{output}", stopOnMissing);