diff --git a/build-tools/unix-distribution-setup/unix-distribution-setup.targets b/build-tools/unix-distribution-setup/unix-distribution-setup.targets
index edca94d5465..d7535d1c5d1 100644
--- a/build-tools/unix-distribution-setup/unix-distribution-setup.targets
+++ b/build-tools/unix-distribution-setup/unix-distribution-setup.targets
@@ -9,6 +9,14 @@
Condition=" '$(HostOS)' != 'Windows' "
Command="chmod +x $(OutputPath)bin\generator"
/>
+
+
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs
index 6e08e31f75a..de9ff551bd8 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs
@@ -99,36 +99,37 @@ bool RunAapt (string commandLine)
WindowStyle = ProcessWindowStyle.Hidden,
};
- var proc = new Process ();
- proc.OutputDataReceived += (sender, e) => {
- if (e.Data != null)
- LogEventsFromTextOutput (e.Data, MessageImportance.Normal);
- else
- stdout_completed.Set ();
- };
- proc.ErrorDataReceived += (sender, e) => {
- if (e.Data != null)
- LogEventsFromTextOutput (e.Data, MessageImportance.Normal);
- else
- stderr_completed.Set ();
- };
- proc.StartInfo = psi;
- proc.Start ();
- proc.BeginOutputReadLine ();
- proc.BeginErrorReadLine ();
- Token.Register (() => {
- try {
- proc.Kill ();
- } catch (Exception) {
- }
- });
- LogDebugMessage ("Executing {0}", commandLine);
- proc.WaitForExit ();
- if (psi.RedirectStandardError)
- stderr_completed.WaitOne (TimeSpan.FromSeconds (30));
- if (psi.RedirectStandardOutput)
- stdout_completed.WaitOne (TimeSpan.FromSeconds (30));
- return proc.ExitCode == 0;
+ using (var proc = new Process ()) {
+ proc.OutputDataReceived += (sender, e) => {
+ if (e.Data != null)
+ LogEventsFromTextOutput (e.Data, MessageImportance.Normal);
+ else
+ stdout_completed.Set ();
+ };
+ proc.ErrorDataReceived += (sender, e) => {
+ if (e.Data != null)
+ LogEventsFromTextOutput (e.Data, MessageImportance.Normal);
+ else
+ stderr_completed.Set ();
+ };
+ proc.StartInfo = psi;
+ proc.Start ();
+ proc.BeginOutputReadLine ();
+ proc.BeginErrorReadLine ();
+ Token.Register (() => {
+ try {
+ proc.Kill ();
+ } catch (Exception) {
+ }
+ });
+ LogDebugMessage ("Executing {0}", commandLine);
+ proc.WaitForExit ();
+ if (psi.RedirectStandardError)
+ stderr_completed.WaitOne (TimeSpan.FromSeconds (30));
+ if (psi.RedirectStandardOutput)
+ stdout_completed.WaitOne (TimeSpan.FromSeconds (30));
+ return proc.ExitCode == 0;
+ }
}
bool ExecuteForAbi (string cmd, string currentResourceOutputFile)
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs
index 6411dec6b70..4f00d3507cf 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs
@@ -434,6 +434,8 @@ IEnumerable GetAotConfigs ()
bool RunAotCompiler (string assembliesPath, string aotCompiler, string aotOptions, string assembly, CancellationToken token)
{
+ var stdout_completed = new ManualResetEvent (false);
+ var stderr_completed = new ManualResetEvent (false);
var psi = new ProcessStartInfo () {
FileName = aotCompiler,
Arguments = aotOptions + " \"" + assembly + "\"",
@@ -453,16 +455,32 @@ bool RunAotCompiler (string assembliesPath, string aotCompiler, string aotOption
LogDebugMessage ("[AOT] MONO_PATH=\"{0}\" MONO_ENV_OPTIONS=\"{1}\" {2} {3}",
psi.EnvironmentVariables ["MONO_PATH"], psi.EnvironmentVariables ["MONO_ENV_OPTIONS"], psi.FileName, psi.Arguments);
- var proc = new Process ();
- proc.OutputDataReceived += OnAotOutputData;
- proc.ErrorDataReceived += OnAotErrorData;
- proc.StartInfo = psi;
- proc.Start ();
- proc.BeginOutputReadLine ();
- proc.BeginErrorReadLine ();
- token.Register (() => { try { proc.Kill (); } catch (Exception) {} });
- proc.WaitForExit ();
- return proc.ExitCode == 0;
+ using (var proc = new Process ()) {
+ proc.OutputDataReceived += (s, e) => {
+ if (e.Data != null)
+ OnAotOutputData (s, e);
+ else
+ stdout_completed.Set ();
+ };
+ proc.ErrorDataReceived += (s, e) => {
+ if (e.Data != null)
+ OnAotErrorData (s, e);
+ else
+ stderr_completed.Set ();
+ };
+ proc.StartInfo = psi;
+ proc.Start ();
+ proc.BeginOutputReadLine ();
+ proc.BeginErrorReadLine ();
+ token.Register (() => { try { proc.Kill (); } catch (Exception) { } });
+ proc.WaitForExit ();
+ if (psi.RedirectStandardError)
+ stderr_completed.WaitOne (TimeSpan.FromSeconds (30));
+ if (psi.RedirectStandardOutput)
+ stdout_completed.WaitOne (TimeSpan.FromSeconds (30));
+ return proc.ExitCode == 0;
+ }
+ GC.Collect ();
}
void OnAotOutputData (object sender, DataReceivedEventArgs e)
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs b/src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs
index 2246b7c75a7..54d2d6fbe85 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs
@@ -116,34 +116,44 @@ void ExecuteWithAbi (string supportedAbis, string apkInputPath, string apkOutput
ArchiveFileList files = new ArchiveFileList ();
if (apkInputPath != null)
File.Copy (apkInputPath, apkOutputPath + "new", overwrite: true);
- using (var apk = ZipArchive.Open (apkOutputPath + "new", apkInputPath != null ? FileMode.Open : FileMode.Create )) {
- apk.AddEntry ("NOTICE",
+ using (var apk = new ZipArchiveEx (apkOutputPath + "new", apkInputPath != null ? FileMode.Open : FileMode.Create )) {
+ apk.Archive.AddEntry ("NOTICE",
Assembly.GetExecutingAssembly ().GetManifestResourceStream ("NOTICE.txt"));
// Add classes.dx
- apk.AddFiles (DalvikClasses, useFileDirectories: false);
+ apk.Archive.AddFiles (DalvikClasses, useFileDirectories: false);
if (EmbedAssemblies && !BundleAssemblies)
AddAssemblies (apk);
AddEnvironment (apk);
AddRuntimeLibraries (apk, supportedAbis);
+ apk.Flush();
AddNativeLibraries (files, supportedAbis);
+ apk.Flush();
AddAdditionalNativeLibraries (files, supportedAbis);
+ apk.Flush();
AddNativeLibrariesFromAssemblies (apk, supportedAbis);
+ apk.Flush();
foreach (ITaskItem typemap in TypeMappings) {
- apk.AddFile (typemap.ItemSpec, Path.GetFileName(typemap.ItemSpec), compressionMethod: CompressionMethod.Store);
+ apk.Archive.AddFile (typemap.ItemSpec, Path.GetFileName(typemap.ItemSpec), compressionMethod: CompressionMethod.Store);
}
+ int count = 0;
foreach (var file in files) {
var item = Path.Combine (file.Item2, Path.GetFileName (file.Item1))
.Replace (Path.DirectorySeparatorChar, '/');
- if (apk.ContainsEntry (item)) {
+ if (apk.Archive.ContainsEntry (item)) {
Log.LogWarning (null, "XA4301", null, file.Item1, 0, 0, 0, 0, "Apk already contains the item {0}; ignoring.", item);
continue;
}
- apk.AddFile (file.Item1, item);
+ apk.Archive.AddFile (file.Item1, item);
+ count++;
+ if (count == ZipArchiveEx.ZipFlushLimit) {
+ apk.Flush();
+ count = 0;
+ }
}
if (_Debug)
AddGdbservers (apk, files, supportedAbis, debugServer);
@@ -160,6 +170,7 @@ void ExecuteWithAbi (string supportedAbis, string apkInputPath, string apkOutput
var jarFilePaths = libraryProjectJars.Concat (jarFiles != null ? jarFiles.Select (j => j.ItemSpec) : Enumerable.Empty ());
jarFilePaths = MonoAndroidHelper.DistinctFilesByContent (jarFilePaths);
+ count = 0;
foreach (var jarFile in jarFilePaths) {
using (var jar = ZipArchive.Open (File.OpenRead (jarFile))) {
foreach (var jarItem in jar.Where (ze => !ze.IsDirectory && !ze.FullName.StartsWith ("META-INF") && !ze.FullName.EndsWith (".class") && !ze.FullName.EndsWith (".java") && !ze.FullName.EndsWith ("MANIFEST.MF"))) {
@@ -168,15 +179,20 @@ void ExecuteWithAbi (string supportedAbis, string apkInputPath, string apkOutput
jarItem.Extract (d);
data = d.ToArray ();
}
- if (apk.Any (e => e.FullName == jarItem.FullName))
+ if (apk.Archive.Any (e => e.FullName == jarItem.FullName))
Log.LogMessage ("Warning: failed to add jar entry {0} from {1}: the same file already exists in the apk", jarItem.FullName, Path.GetFileName (jarFile));
else
- apk.AddEntry (data, jarItem.FullName);
+ apk.Archive.AddEntry (data, jarItem.FullName);
}
}
+ count++;
+ if (count == ZipArchiveEx.ZipFlushLimit) {
+ apk.Flush();
+ count = 0;
+ }
}
if (StubApplicationDataFile != null && File.Exists (StubApplicationDataFile))
- apk.AddFile (StubApplicationDataFile, Path.GetFileName (StubApplicationDataFile));
+ apk.Archive.AddFile (StubApplicationDataFile, Path.GetFileName (StubApplicationDataFile));
}
MonoAndroidHelper.CopyIfZipChanged (apkOutputPath + "new", apkOutputPath);
File.Delete (apkOutputPath + "new");
@@ -249,14 +265,15 @@ public override bool Execute ()
return !Log.HasLoggedErrors;
}
- private void AddAssemblies (ZipArchive apk)
+ private void AddAssemblies (ZipArchiveEx apk)
{
bool debug = _Debug;
bool use_shared_runtime = String.Equals (UseSharedRuntime, "true", StringComparison.OrdinalIgnoreCase);
+ int count = 0;
foreach (ITaskItem assembly in ResolvedUserAssemblies) {
// Add assembly
- apk.AddFile (assembly.ItemSpec, GetTargetDirectory (assembly.ItemSpec) + "/" + Path.GetFileName (assembly.ItemSpec), compressionMethod: CompressionMethod.Store);
+ apk.Archive.AddFile (assembly.ItemSpec, GetTargetDirectory (assembly.ItemSpec) + "/" + Path.GetFileName (assembly.ItemSpec), compressionMethod: CompressionMethod.Store);
// Try to add config if exists
var config = Path.ChangeExtension (assembly.ItemSpec, "dll.config");
@@ -267,21 +284,27 @@ private void AddAssemblies (ZipArchive apk)
var symbols = Path.ChangeExtension (assembly.ItemSpec, "dll.mdb");
if (File.Exists (symbols))
- apk.AddFile (symbols, "assemblies/" + Path.GetFileName (symbols), compressionMethod: CompressionMethod.Store);
+ apk.Archive.AddFile (symbols, "assemblies/" + Path.GetFileName (symbols), compressionMethod: CompressionMethod.Store);
symbols = Path.ChangeExtension (assembly.ItemSpec, "pdb");
if (File.Exists (symbols))
- apk.AddFile (symbols, "assemblies/" + Path.GetFileName (symbols), compressionMethod: CompressionMethod.Store);
+ apk.Archive.AddFile (symbols, "assemblies/" + Path.GetFileName (symbols), compressionMethod: CompressionMethod.Store);
+ }
+ count++;
+ if (count == ZipArchiveEx.ZipFlushLimit) {
+ apk.Flush();
+ count = 0;
}
}
if (use_shared_runtime)
return;
+ count = 0;
// Add framework assemblies
foreach (ITaskItem assembly in ResolvedFrameworkAssemblies) {
- apk.AddFile (assembly.ItemSpec, "assemblies/" + Path.GetFileName (assembly.ItemSpec), compressionMethod: CompressionMethod.Store);
+ apk.Archive.AddFile (assembly.ItemSpec, "assemblies/" + Path.GetFileName (assembly.ItemSpec), compressionMethod: CompressionMethod.Store);
var config = Path.ChangeExtension (assembly.ItemSpec, "dll.config");
AddAssemblyConfigEntry (apk, config);
// Try to add symbols if Debug
@@ -289,17 +312,22 @@ private void AddAssemblies (ZipArchive apk)
var symbols = Path.ChangeExtension (assembly.ItemSpec, "dll.mdb");
if (File.Exists (symbols))
- apk.AddFile (symbols, "assemblies/" + Path.GetFileName (symbols), compressionMethod: CompressionMethod.Store);
+ apk.Archive.AddFile (symbols, "assemblies/" + Path.GetFileName (symbols), compressionMethod: CompressionMethod.Store);
symbols = Path.ChangeExtension (assembly.ItemSpec, "pdb");
if (File.Exists (symbols))
- apk.AddFile (symbols, "assemblies/" + Path.GetFileName (symbols), compressionMethod: CompressionMethod.Store);
+ apk.Archive.AddFile (symbols, "assemblies/" + Path.GetFileName (symbols), compressionMethod: CompressionMethod.Store);
+ }
+ count++;
+ if (count == ZipArchiveEx.ZipFlushLimit) {
+ apk.Flush();
+ count = 0;
}
}
}
- void AddAssemblyConfigEntry (ZipArchive apk, string configFile)
+ void AddAssemblyConfigEntry (ZipArchiveEx apk, string configFile)
{
if (!File.Exists (configFile))
return;
@@ -309,7 +337,7 @@ void AddAssemblyConfigEntry (ZipArchive apk, string configFile)
source.CopyTo (dest);
dest.WriteByte (0);
dest.Position = 0;
- apk.AddEntry ("assemblies/" + Path.GetFileName (configFile), dest, compressionMethod: CompressionMethod.Store);
+ apk.Archive.AddEntry ("assemblies/" + Path.GetFileName (configFile), dest, compressionMethod: CompressionMethod.Store);
}
}
@@ -322,7 +350,7 @@ static string GetTargetDirectory (string path)
return "assemblies";
}
- void AddEnvironment (ZipArchive apk)
+ void AddEnvironment (ZipArchiveEx apk)
{
var environment = new StringWriter () {
NewLine = "\n",
@@ -395,7 +423,7 @@ void AddEnvironment (ZipArchive apk)
environment.WriteLine ("MONO_GC_PARAMS=major=marksweep");
}
- apk.AddEntry ("environment", environment.ToString (),
+ apk.Archive.AddEntry ("environment", environment.ToString (),
new UTF8Encoding (encoderShouldEmitUTF8Identifier:false));
}
@@ -431,13 +459,13 @@ HashSet ParseProfilers (string value)
return results;
}
- void AddNativeLibrary (ZipArchive apk, string abi, string filename)
+ void AddNativeLibrary (ZipArchiveEx apk, string abi, string filename)
{
var path = Path.Combine (MSBuildXamarinAndroidDirectory, "lib", abi, filename);
- apk.AddEntry (string.Format ("lib/{0}/{1}", abi, filename), File.OpenRead (path));
+ apk.Archive.AddEntry (string.Format ("lib/{0}/{1}", abi, filename), File.OpenRead (path));
}
- void AddProfilers (ZipArchive apk, string abi)
+ void AddProfilers (ZipArchiveEx apk, string abi)
{
if (!string.IsNullOrEmpty (AndroidEmbedProfilers)) {
foreach (var profiler in ParseProfilers (AndroidEmbedProfilers)) {
@@ -447,7 +475,7 @@ void AddProfilers (ZipArchive apk, string abi)
}
}
- void AddBtlsLibs (ZipArchive apk, string abi)
+ void AddBtlsLibs (ZipArchiveEx apk, string abi)
{
if (string.Compare ("btls", TlsProvider, StringComparison.OrdinalIgnoreCase) == 0) {
AddNativeLibrary (apk, abi, "libmono-btls-shared.so");
@@ -457,14 +485,14 @@ void AddBtlsLibs (ZipArchive apk, string abi)
// * "legacy":
}
- void AddRuntimeLibraries (ZipArchive apk, string supportedAbis)
+ void AddRuntimeLibraries (ZipArchiveEx apk, string supportedAbis)
{
bool use_shared_runtime = String.Equals (UseSharedRuntime, "true", StringComparison.OrdinalIgnoreCase);
var abis = supportedAbis.Split (new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var abi in abis) {
string library = string.Format ("libmono-android.{0}.so", _Debug ? "debug" : "release");
var path = Path.Combine (MSBuildXamarinAndroidDirectory, "lib", abi, library);
- apk.AddEntry (string.Format ("lib/{0}/libmonodroid.so", abi), File.OpenRead (path));
+ apk.Archive.AddEntry (string.Format ("lib/{0}/libmonodroid.so", abi), File.OpenRead (path));
if (!use_shared_runtime) {
// include the sgen
AddNativeLibrary (apk, abi, "libmonosgen-2.0.so");
@@ -474,8 +502,9 @@ void AddRuntimeLibraries (ZipArchive apk, string supportedAbis)
}
}
- void AddNativeLibrariesFromAssemblies (ZipArchive apk, string supportedAbis)
+ void AddNativeLibrariesFromAssemblies (ZipArchiveEx apk, string supportedAbis)
{
+ int count = 0;
var abis = supportedAbis.Split (new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
using (var res = new DirectoryAssemblyResolver (Console.WriteLine, loadDebugSymbols: false)) {
foreach (var assembly in EmbeddedNativeLibraryAssemblies)
@@ -493,19 +522,24 @@ void AddNativeLibrariesFromAssemblies (ZipArchive apk, string supportedAbis)
if (e.IsDirectory)
continue;
var key = e.FullName.Replace ("native_library_imports", "lib");
- if (apk.Any (k => k.FullName == key)) {
+ if (apk.Archive.Any (k => k.FullName == key)) {
Log.LogCodedWarning ("4301", "Apk already contains the item {0}; ignoring.", key);
continue;
}
using (var s = new MemoryStream ()) {
e.Extract (s);
s.Position = 0;
- apk.AddEntry (s.ToArray (), key);
+ apk.Archive.AddEntry (s.ToArray (), key);
}
}
}
}
}
+ count++;
+ if (count == ZipArchiveEx.ZipFlushLimit) {
+ apk.Flush();
+ count = 0;
+ }
}
}
}
@@ -566,11 +600,12 @@ void AddNativeLibrary (ArchiveFileList files, string path, string abi)
files.Add (new Tuple (path, string.Format ("lib/{0}", abi)));
}
- private void AddGdbservers (ZipArchive apk, ArchiveFileList files, string supportedAbis, AndroidDebugServer debugServer)
+ private void AddGdbservers (ZipArchiveEx apk, ArchiveFileList files, string supportedAbis, AndroidDebugServer debugServer)
{
if (string.IsNullOrEmpty (AndroidNdkDirectory))
return;
+ int count = 0;
foreach (var sabi in supportedAbis.Split (new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)) {
var arch = GdbPaths.GetArchFromAbi (sabi);
var abi = GdbPaths.GetAbiFromArch (arch);
@@ -585,7 +620,12 @@ private void AddGdbservers (ZipArchive apk, ArchiveFileList files, string suppor
if (!File.Exists (debugServerPath))
continue;
Log.LogDebugMessage ("Adding {0} debug server '{1}' to the APK as '{2}'", sabi, debugServerPath, entryName);
- apk.AddEntry (entryName, File.OpenRead (debugServerPath));
+ apk.Archive.AddEntry (entryName, File.OpenRead (debugServerPath));
+ count++;
+ if (count == ZipArchiveEx.ZipFlushLimit) {
+ apk.Flush();
+ count = 0;
+ }
}
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs
index a86d63ac458..70a4545bec9 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Linq;
+using System.Text;
using System.Xml.Linq;
using Microsoft.Build.Framework;
using NUnit.Framework;
@@ -195,6 +196,101 @@ public void BuildInDesignTimeMode ()
Assert.IsTrue (builder.Output.IsTargetSkipped ("_ResolveLibraryProjectImports"), "target \"_ResolveLibraryProjectImports\' should have been skipped.");
}
}
+
+ [Test]
+ public void BuildAMassiveApp()
+ {
+ var testPath = Path.Combine("temp", "BuildAMassiveApp");
+ TestContext.CurrentContext.Test.Properties ["Output"] = new string [] { Path.Combine (Root, testPath) };
+ var sb = new SolutionBuilder("BuildAMassiveApp.sln") {
+ SolutionPath = Path.Combine(Root, testPath),
+ Verbosity = LoggerVerbosity.Diagnostic,
+ };
+ var app1 = new XamarinAndroidApplicationProject() {
+ ProjectName = "App1",
+ AotAssemblies = true,
+ IsRelease = true,
+ Packages = {
+ KnownPackages.AndroidSupportV4_21_0_3_0,
+ KnownPackages.GooglePlayServices_22_0_0_2,
+ },
+ };
+ app1.Imports.Add (new Import ("foo.targets") {
+ TextContent = () => @"
+
+
+
+ armeabi-v7a;x86
+ $(AndroidSupportedAbis);armeabi
+ $(AndroidSupportedAbis);arm64-v8a
+ $(AndroidSupportedAbis);x86_64
+
+
+
+
+
+ False
+
+
+
+
+",
+ });
+ app1.SetProperty(KnownProperties.AndroidUseSharedRuntime, "False");
+ sb.Projects.Add(app1);
+ var code = new StringBuilder();
+ code.AppendLine("using System;");
+ code.AppendLine("namespace App1 {");
+ code.AppendLine("\tpublic class AppCode {");
+ code.AppendLine("\t\tpublic void Foo () {");
+ for (int i = 0; i < 128; i++) {
+ var libName = $"Lib{i}";
+ var lib = new XamarinAndroidLibraryProject() {
+ ProjectName = libName,
+ IsRelease = true,
+ OtherBuildItems = {
+ new AndroidItem.AndroidAsset ($"Assets\\{libName}.txt") {
+ TextContent = () => "Asset1",
+ Encoding = Encoding.ASCII,
+ },
+ new AndroidItem.AndroidAsset ($"Assets\\subfolder\\{libName}.txt") {
+ TextContent = () => "Asset2",
+ Encoding = Encoding.ASCII,
+ },
+ },
+ Sources = {
+ new BuildItem.Source ($"{libName}.cs") {
+ TextContent = () => @"using System;
+
+namespace "+ libName + @" {
+
+ public class " + libName + @" {
+ public static void Foo () {
+ }
+ }
+}"
+ },
+ }
+ };
+ var strings = lib.AndroidResources.First(x => x.Include() == "Resources\\values\\Strings.xml");
+ strings.TextContent = () => @"
+
+ " + libName + @"
+";
+ sb.Projects.Add(lib);
+ app1.References.Add(new BuildItem.ProjectReference($"..\\{libName}\\{libName}.csproj", libName, lib.ProjectGuid));
+ code.AppendLine($"\t\t\t{libName}.{libName}.Foo ();");
+ }
+ code.AppendLine("\t\t}");
+ code.AppendLine("\t}");
+ code.AppendLine("}");
+ app1.Sources.Add(new BuildItem.Source("Code.cs") {
+ TextContent = ()=> code.ToString (),
+ });
+ Assert.IsTrue(sb.Build(new string[] { "Configuration=Release" }), "Solution should have built.");
+ Assert.IsTrue(sb.BuildProject(app1, "SignAndroidPackage"), "Build of project should have succeeded");
+ sb.Dispose();
+ }
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs
index 865556fb88f..3c35dea1417 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs
@@ -17,8 +17,8 @@ public class IncrementalBuildTest : BaseTest
public void AllProjectsHaveSameOutputDirectory()
{
var testPath = Path.Combine ("temp", "AllProjectsHaveSameOutputDirectory");
- var sb = new SolutionBuilder () {
- SolutionPath = Path.Combine (Root, testPath, "AllProjectsHaveSameOutputDirectory.sln"),
+ var sb = new SolutionBuilder("AllProjectsHaveSameOutputDirectory.sln") {
+ SolutionPath = Path.Combine (Root, testPath),
Verbosity = LoggerVerbosity.Diagnostic,
};
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/SolutionBuilder.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/SolutionBuilder.cs
index 22d9556f77e..3abae105911 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/SolutionBuilder.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/SolutionBuilder.cs
@@ -10,17 +10,19 @@ public class SolutionBuilder : Builder
{
public IList Projects { get; }
public string SolutionPath { get; set; }
+ public string SolutionName { get; set; }
public bool BuildSucceeded { get; set; }
- public SolutionBuilder () : base()
+ public SolutionBuilder (string solutionName) : base()
{
+ SolutionName = solutionName;
Projects = new List ();
}
public void Save ()
{
foreach (var p in Projects) {
- using (var pb = new ProjectBuilder (Path.Combine (Path.GetDirectoryName (SolutionPath), p.ProjectName))) {
+ using (var pb = new ProjectBuilder (Path.Combine (SolutionPath, p.ProjectName))) {
pb.Save (p);
}
}
@@ -47,27 +49,33 @@ public void Save ()
}
sb.Append ("\tEndGlobalSection\n");
sb.Append ("EndGlobal\n");
- File.WriteAllText (SolutionPath, sb.ToString ());
+ File.WriteAllText (Path.Combine (SolutionPath, SolutionName), sb.ToString ());
}
- public bool Build ()
+ public bool BuildProject(XamarinProject project, string target = "Build")
+ {
+ BuildSucceeded = BuildInternal(Path.Combine (SolutionPath, project.ProjectName, project.ProjectFilePath), target);
+ return BuildSucceeded;
+ }
+
+ public bool Build (params string[] parameters)
{
Save ();
- BuildSucceeded = BuildInternal (SolutionPath, "Build");
+ BuildSucceeded = BuildInternal (Path.Combine (SolutionPath, SolutionName), "Build", parameters);
return BuildSucceeded;
}
- public bool ReBuild ()
+ public bool ReBuild(params string[] parameters)
{
Save ();
- BuildSucceeded = BuildInternal (SolutionPath, "ReBuild");
+ BuildSucceeded = BuildInternal(Path.Combine(SolutionPath, SolutionName), "ReBuild", parameters);
return BuildSucceeded;
}
- public bool Clean ()
+ public bool Clean(params string[] parameters)
{
Save ();
- BuildSucceeded = BuildInternal (SolutionPath, "Clean");
+ BuildSucceeded = BuildInternal(Path.Combine(SolutionPath, SolutionName), "Clean", parameters);
return BuildSucceeded;
}
@@ -75,7 +83,7 @@ protected override void Dispose (bool disposing)
{
if (disposing)
if (BuildSucceeded)
- Directory.Delete (Path.GetDirectoryName (SolutionPath), recursive: true);
+ Directory.Delete (SolutionPath, recursive: true);
}
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/ZipArchiveEx.cs b/src/Xamarin.Android.Build.Tasks/Utilities/ZipArchiveEx.cs
index 80aa16f051e..b9c7d3571b2 100644
--- a/src/Xamarin.Android.Build.Tasks/Utilities/ZipArchiveEx.cs
+++ b/src/Xamarin.Android.Build.Tasks/Utilities/ZipArchiveEx.cs
@@ -1,21 +1,33 @@
using System;
using System.IO;
+using System.Linq;
using Xamarin.Tools.Zip;
namespace Xamarin.Android.Tasks
{
public class ZipArchiveEx : IDisposable
{
+
+ public static int ZipFlushLimit = 50;
+
ZipArchive zip;
string archive;
- public ZipArchiveEx (string archive)
+ public ZipArchive Archive {
+ get { return zip; }
+ }
+
+ public ZipArchiveEx (string archive) : this (archive, FileMode.CreateNew)
+ {
+ }
+
+ public ZipArchiveEx(string archive, FileMode filemode)
{
this.archive = archive;
- zip = ZipArchive.Open (archive, FileMode.CreateNew);
+ zip = ZipArchive.Open(archive, filemode);
}
- void Flush ()
+ public void Flush ()
{
if (zip != null) {
zip.Close ();
@@ -51,7 +63,7 @@ void AddFiles (string folder, string folderInArchive)
continue;
zip.AddFile (fileName, ArchiveNameForFile (fileName, folderInArchive));
count++;
- if (count == 50) {
+ if (count == ZipArchiveEx.ZipFlushLimit) {
Flush ();
count = 0;
}