Skip to content

Commit

Permalink
[wasm] Use compile rsp instead of link, for compiling native files (d…
Browse files Browse the repository at this point in the history
…otnet#55848)

.. and fix logging that broke recently.

`tasks/Common/Utils.cs`:

TaskLoggingHelper Utils.Logger is a static field, which must be set by
task else any methods in Utils, eg. RunProcess, silently fail to log
any messages. Also, this would be a problem when building multiple
projects in parallel, since the logger is a task-specific one.

Instead, we pass logger as an arg to all the methods.
  • Loading branch information
radical committed Jul 19, 2021
1 parent d574b03 commit 3301e9d
Show file tree
Hide file tree
Showing 11 changed files with 77 additions and 82 deletions.
2 changes: 1 addition & 1 deletion src/mono/wasm/build/WasmApp.Native.targets
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@
<EmccCompile
Condition="@(_BitCodeFile->Count()) > 0"
SourceFiles="@(_BitCodeFile)"
Arguments="&quot;@$(_EmccDefaultFlagsRsp)&quot; @(_EmccLDFlags->'%(Identity)', ' ')"
Arguments="&quot;@$(_EmccDefaultFlagsRsp)&quot; &quot;@$(_EmccCompileRsp)&quot;"
EnvironmentVariables="@(EmscriptenEnvVars)" />

<ItemGroup>
Expand Down
3 changes: 1 addition & 2 deletions src/tasks/AndroidAppBuilder/AndroidApkFileReplacerTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 1 addition & 3 deletions src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
40 changes: 24 additions & 16 deletions src/tasks/AndroidAppBuilder/ApkBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Linq;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

public class ApkBuilder
{
Expand All @@ -32,6 +33,13 @@ public class ApkBuilder
public string? DiagnosticPorts { get; set; }
public ITaskItem[] Assemblies { get; set; } = Array.Empty<ITaskItem>();

private TaskLoggingHelper logger;

public ApkBuilder(TaskLoggingHelper logger)
{
this.logger = logger;
}

public (string apk, string packageId) BuildApk(
string abi,
string mainLibraryFileName,
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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<string>();
dynamicLibs.Add(Path.Combine(OutputDir, "monodroid", "libmonodroid.so"));
Expand Down Expand Up @@ -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);
}
Expand All @@ -460,15 +468,15 @@ 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);
}
else if (Path.GetFullPath(signingKey) != Path.GetFullPath(defaultKey))
{
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);
}

Expand Down Expand Up @@ -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);
Expand Down
18 changes: 13 additions & 5 deletions src/tasks/AotCompilerTask/MonoAOTCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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<string, string> 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}");
Expand Down
5 changes: 2 additions & 3 deletions src/tasks/AppleAppBuilder/AppleAppBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
Expand Down Expand Up @@ -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;

Expand All @@ -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
{
Expand Down
24 changes: 14 additions & 10 deletions src/tasks/AppleAppBuilder/Xcode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,38 @@
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

internal class Xcode
{
private string RuntimeIdentifier { get; set; }
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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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");
}
Expand Down Expand Up @@ -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");
Expand All @@ -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;
}
Expand Down
Loading

0 comments on commit 3301e9d

Please sign in to comment.