Skip to content

Commit

Permalink
[Xamarin.Android.Build.Tasks] Add new Unit test for AOT
Browse files Browse the repository at this point in the history
Our AOT system needs to work when a user uses
non ASCII characters and spaces. This commit
updates our BuildAotApplication unit test to
use both spaces and UTF8 based characters.
This will make sure that in future versions of
mono we do not regress supporting those kinds
of paths.
  • Loading branch information
dellis1972 committed Sep 4, 2019
1 parent 842dbfe commit fc048c8
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 35 deletions.
2 changes: 2 additions & 0 deletions src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Xml;
using System.Xml.Linq;
Expand Down Expand Up @@ -113,6 +114,7 @@ bool RunAapt (string commandLine, IList<OutputLine> output)
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
StandardOutputEncoding = Encoding.UTF8,
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
WorkingDirectory = WorkingDirectory,
Expand Down
2 changes: 2 additions & 0 deletions src/Xamarin.Android.Build.Tasks/Tasks/Aapt2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Threading;
using System.Xml;
using System.Xml.Linq;
using System.Text;
using Microsoft.Build.Utilities;
using Microsoft.Build.Framework;
using System.Text.RegularExpressions;
Expand Down Expand Up @@ -53,6 +54,7 @@ protected bool RunAapt (string commandLine, IList<OutputLine> output)
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
StandardOutputEncoding = Encoding.UTF8,
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
WorkingDirectory = WorkingDirectory,
Expand Down
72 changes: 42 additions & 30 deletions src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
Expand Down Expand Up @@ -173,14 +174,6 @@ static string GetNdkToolchainLibraryDir (string binDir, AndroidTargetArch arch)
return GetNdkToolchainLibraryDir (binDir, NdkUtil.GetArchDirName (arch));
}

static string GetShortPath (string path)
{
if (Environment.OSVersion.Platform != PlatformID.Win32NT)
return QuoteFileName (path);
var shortPath = KernelEx.GetShortPathName (Path.GetDirectoryName (path));
return Path.Combine (shortPath, Path.GetFileName (path));
}

static string QuoteFileName(string fileName)
{
var builder = new CommandLineBuilder();
Expand Down Expand Up @@ -282,12 +275,15 @@ bool RunParallelAotCompiler (List<string> nativeLibs)
return;
}
if (!RunAotCompiler (config.AssembliesPath, config.AotCompiler, config.AotOptions, config.AssemblyPath)) {
if (!RunAotCompiler (config.AssembliesPath, config.AotCompiler, config.AotOptions, config.AssemblyPath, config.ResponseFile)) {
LogCodedError ("XA3001", "Could not AOT the assembly: {0}", Path.GetFileName (config.AssemblyPath));
Cancel ();
return;
}
if (File.Exists (config.ResponseFile))
File.Delete (config.ResponseFile);
lock (nativeLibs)
nativeLibs.Add (config.OutputFile);
}
Expand Down Expand Up @@ -361,6 +357,11 @@ IEnumerable<Config> GetAotConfigs ()
if (!Directory.Exists (outdir))
Directory.CreateDirectory (outdir);

// dont use a full path if the outdir is withing the WorkingDirectory.
if (outdir.StartsWith (WorkingDirectory, StringComparison.InvariantCultureIgnoreCase)) {
outdir = outdir.Replace (WorkingDirectory + Path.DirectorySeparatorChar, string.Empty);
}

int level = 0;
string toolPrefix = EnableLLVM
? NdkUtil.GetNdkToolPrefix (AndroidNdkDirectory, arch, level = GetNdkApiLevel (AndroidNdkDirectory, AndroidApiLevel, arch))
Expand Down Expand Up @@ -388,19 +389,19 @@ IEnumerable<Config> GetAotConfigs ()

var libs = new List<string>();
if (NdkUtil.UsingClangNDK) {
libs.Add ($"-L{GetShortPath (toolchainLibDir)}");
libs.Add ($"-L{GetShortPath (androidLibPath)}");
libs.Add ($"-L{toolchainLibDir}");
libs.Add ($"-L{androidLibPath}");

if (arch == AndroidTargetArch.Arm) {
// Needed for -lunwind to work
string compilerLibDir = Path.Combine (toolchainPath, "..", "sysroot", "usr", "lib", NdkUtil.GetArchDirName (arch));
libs.Add ($"-L{GetShortPath (compilerLibDir)}");
libs.Add ($"-L{compilerLibDir}");
}
}

libs.Add (GetShortPath (Path.Combine (toolchainLibDir, "libgcc.a")));
libs.Add (GetShortPath (Path.Combine (androidLibPath, "libc.so")));
libs.Add (GetShortPath (Path.Combine (androidLibPath, "libm.so")));
libs.Add (Path.Combine (toolchainLibDir, "libgcc.a"));
libs.Add (Path.Combine (androidLibPath, "libc.so"));
libs.Add (Path.Combine (androidLibPath, "libm.so"));

ldFlags = string.Join(";", libs);
}
Expand All @@ -422,25 +423,28 @@ IEnumerable<Config> GetAotConfigs ()
aotOptions.Add ("profile-only");
foreach (var p in Profiles) {
var fp = Path.GetFullPath (p.ItemSpec);
aotOptions.Add ($"profile={GetShortPath (fp)}");
aotOptions.Add ($"profile={fp}");
}
}
if (!string.IsNullOrEmpty (AotAdditionalArguments))
aotOptions.Add (AotAdditionalArguments);
if (sequencePointsMode == SequencePointsMode.Offline)
aotOptions.Add ("msym-dir=" + GetShortPath (outdir));
aotOptions.Add ($"msym-dir={outdir}");
if (AotMode != AotMode.Normal)
aotOptions.Add (AotMode.ToString ().ToLowerInvariant ());

aotOptions.Add ("outfile=" + GetShortPath (outputFile));
aotOptions.Add ($"outfile={outputFile}");
aotOptions.Add ("asmwriter");
aotOptions.Add ("mtriple=" + mtriple);
aotOptions.Add ("tool-prefix=" + GetShortPath (toolPrefix));
aotOptions.Add ("ld-flags=" + ldFlags);
aotOptions.Add ("llvm-path=" + GetShortPath (sdkBinDirectory));
aotOptions.Add ("temp-path=" + GetShortPath (tempDir));
aotOptions.Add ($"mtriple={mtriple}");
aotOptions.Add ($"tool-prefix={toolPrefix}");
aotOptions.Add ($"ld-flags={ldFlags}");
aotOptions.Add ($"llvm-path={sdkBinDirectory}");
aotOptions.Add ($"temp-path={tempDir}");

string aotOptionsStr = (EnableLLVM ? "--llvm " : "") + "--aot=" + string.Join (",", aotOptions);
// we need to quote the entire --aot arguments here to make sure it is parsed
// on windows as one argument. Otherwise it will be split up into multiple
// values, which wont work.
string aotOptionsStr = (EnableLLVM ? "--llvm " : "") + $"\"--aot={string.Join (",", aotOptions)}\"";

if (!string.IsNullOrEmpty (ExtraAotOptions)) {
aotOptionsStr += (aotOptions.Count > 0 ? "," : "") + ExtraAotOptions;
Expand All @@ -460,23 +464,29 @@ IEnumerable<Config> GetAotConfigs ()
}

var assembliesPath = Path.GetFullPath (Path.GetDirectoryName (resolvedPath));
var assemblyPath = QuoteFileName (Path.GetFullPath (resolvedPath));
var assemblyPath = Path.GetFullPath (resolvedPath);

yield return new Config (assembliesPath, QuoteFileName (aotCompiler), aotOptionsStr, assemblyPath, outputFile);
yield return new Config (assembliesPath, aotCompiler, aotOptionsStr, assemblyPath, outputFile, Path.Combine (tempDir, "response.txt"));
}
}
}

bool RunAotCompiler (string assembliesPath, string aotCompiler, string aotOptions, string assembly)
bool RunAotCompiler (string assembliesPath, string aotCompiler, string aotOptions, string assembly, string responseFile)
{
var stdout_completed = new ManualResetEvent (false);
var stderr_completed = new ManualResetEvent (false);

using (var sw = new StreamWriter (responseFile, append: false, encoding: new UTF8Encoding (encoderShouldEmitUTF8Identifier: false))) {
sw.WriteLine (aotOptions + " " + QuoteFileName (assembly));
}

var psi = new ProcessStartInfo () {
FileName = aotCompiler,
Arguments = aotOptions + " " + assembly,
FileName = QuoteFileName (aotCompiler),
Arguments = $"--response={QuoteFileName (responseFile)}",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
StandardOutputEncoding = Encoding.UTF8,
CreateNoWindow=true,
WindowStyle=ProcessWindowStyle.Hidden,
WorkingDirectory = WorkingDirectory,
Expand Down Expand Up @@ -536,16 +546,18 @@ struct Config {
public string AotOptions { get; }
public string AssemblyPath { get; }
public string OutputFile { get; }
public string ResponseFile { get; }

public bool Valid { get; private set; }

public Config (string assembliesPath, string aotCompiler, string aotOptions, string assemblyPath, string outputFile)
public Config (string assembliesPath, string aotCompiler, string aotOptions, string assemblyPath, string outputFile, string responseFile)
{
AssembliesPath = assembliesPath;
AotCompiler = aotCompiler;
AotOptions = aotOptions;
AssemblyPath = assemblyPath;
OutputFile = outputFile;
ResponseFile = responseFile;
Valid = true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -732,9 +732,9 @@ public void BuildMkBundleApplicationReleaseAllAbi ()
[Test]
[TestCaseSource (nameof (AotChecks))]
[Category ("Minor")]
public void BuildAotApplication (string supportedAbis, bool enableLLVM, bool expectedResult)
public void BuildAotApplicationAndÜmläüts (string supportedAbis, bool enableLLVM, bool expectedResult)
{
var path = Path.Combine ("temp", string.Format ("BuildAotApplication_{0}_{1}_{2}", supportedAbis, enableLLVM, expectedResult));
var path = Path.Combine ("temp", string.Format ("BuildAotApplication AndÜmläüts_{0}_{1}_{2}", supportedAbis, enableLLVM, expectedResult));
var proj = new XamarinAndroidApplicationProject () {
IsRelease = true,
BundleAssemblies = false,
Expand Down Expand Up @@ -768,7 +768,7 @@ public void BuildAotApplication (string supportedAbis, bool enableLLVM, bool exp
// LLVM passes a direct path to libc.so, and we need to use the libc.so
// which corresponds to the *minimum* SDK version specified in AndroidManifest.xml
// Since we overrode minSdkVersion=16, that means we should use libc.so from android-16.
var rightLibc = new Regex (@"^\s*\[AOT\].*cross-.*--llvm.*,ld-flags=.*android-16.arch-.*.usr.lib.libc\.so", RegexOptions.Multiline);
var rightLibc = new Regex (@"\s*\[aot-compiler stdout].*android-16.arch-.*.usr.lib.libc\.so", RegexOptions.Multiline);
var m = rightLibc.Match (string.Join ("\n",b.LastBuildOutput));
Assert.IsTrue (m.Success, "AOT+LLVM should use libc.so from minSdkVersion!");
}
Expand Down Expand Up @@ -803,9 +803,9 @@ public void BuildAotApplication (string supportedAbis, bool enableLLVM, bool exp
[Test]
[TestCaseSource (nameof (AotChecks))]
[Category ("Minor")]
public void BuildAotApplicationAndBundle (string supportedAbis, bool enableLLVM, bool expectedResult)
public void BuildAotApplicationAndBundleAndÜmläüts (string supportedAbis, bool enableLLVM, bool expectedResult)
{
var path = Path.Combine ("temp", string.Format ("BuildAotApplicationAndBundle_{0}_{1}_{2}", supportedAbis, enableLLVM, expectedResult));
var path = Path.Combine ("temp", string.Format ("BuildAotApplicationAndBundle AndÜmläüts_{0}_{1}_{2}", supportedAbis, enableLLVM, expectedResult));
var proj = new XamarinAndroidApplicationProject () {
IsRelease = true,
BundleAssemblies = true,
Expand Down

0 comments on commit fc048c8

Please sign in to comment.