diff --git a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Common/ImportAfter/Xamarin.Android.Windows.targets b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Common/ImportAfter/Xamarin.Android.Windows.targets index 3ddab4d9d50..3f8f240f0a9 100644 --- a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Common/ImportAfter/Xamarin.Android.Windows.targets +++ b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Common/ImportAfter/Xamarin.Android.Windows.targets @@ -14,7 +14,7 @@ Copyright (C) 2014 Xamarin. All rights reserved. - + resource_fixup = new Dictionary (StringComparer.OrdinalIgnoreCase); public override bool Execute () @@ -121,7 +124,13 @@ public override bool Execute () var suffix = assemblyName.ItemSpec.EndsWith (".dll") ? String.Empty : ".dll"; string hintPath = assemblyName.GetMetadata ("HintPath").Replace (Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); string fileName = assemblyName.ItemSpec + suffix; - resolver.Load (Path.GetFullPath (assemblyName.ItemSpec)); + string fullPath = Path.GetFullPath (assemblyName.ItemSpec); + // Skip non existing files in DesignTimeBuild + if (!File.Exists (fullPath) && DesignTimeBuild) { + Log.LogDebugMessage ("Skipping non existant dependancy '{0}' due to design time build.", fullPath); + continue; + } + resolver.Load (fullPath); if (!String.IsNullOrEmpty (hintPath) && !File.Exists (hintPath)) // ignore invalid HintPath hintPath = null; string assemblyPath = String.IsNullOrEmpty (hintPath) ? fileName : hintPath; diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GetAdditionalResourcesFromAssemblies.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GetAdditionalResourcesFromAssemblies.cs index 8968c489de2..8c529f8b35b 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GetAdditionalResourcesFromAssemblies.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GetAdditionalResourcesFromAssemblies.cs @@ -397,10 +397,17 @@ public override bool Execute () using (var resolver = new DirectoryAssemblyResolver (this.CreateTaskLogger (), loadDebugSymbols: false)) { foreach (var assemblyItem in Assemblies) { string fullPath = Path.GetFullPath (assemblyItem.ItemSpec); + if (DesignTimeBuild && !File.Exists (fullPath)) { + LogWarning ("Failed to load '{0}'. Check the file exists or the project has been built.", fullPath); + continue; + } if (assemblies.Contains (fullPath)) { LogDebugMessage (" Skip assembly: {0}, it was already processed", fullPath); continue; } + // don't try to even load mscorlib it will fail. + if (string.Compare (Path.GetFileNameWithoutExtension (fullPath), "mscorlib", StringComparison.OrdinalIgnoreCase) == 0) + continue; assemblies.Add (fullPath); resolver.Load (fullPath); // Append source file name (without the Xamarin. prefix or extension) to the base folder diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveLibraryProjectImports.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveLibraryProjectImports.cs index f68f7b65128..2d83842b14f 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveLibraryProjectImports.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveLibraryProjectImports.cs @@ -37,7 +37,10 @@ public class ResolveLibraryProjectImports : Task [Required] public string AssemblyIdentityMapFile { get; set; } - public string CacheFile { get; set;} + public string CacheFile { get; set; } + + [Required] + public bool DesignTimeBuild { get; set; } [Output] public string [] Jars { get; set; } @@ -207,6 +210,11 @@ void Extract ( continue; } + if (!File.Exists (assemblyPath) && DesignTimeBuild) { + Log.LogDebugMessage ("Skipping non existant dependancy '{0}' due to design time build.", assemblyPath); + continue; + } + Log.LogDebugMessage ("Refreshing {0}", assemblyPath); Directory.CreateDirectory (importsDir); diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs index a4118caf632..ff49b4491b4 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs @@ -28,10 +28,10 @@ public void RepetitiveBuild () b.ThrowOnBuildFailure = false; Assert.IsTrue (b.Build (proj), "first build failed"); Assert.IsTrue (b.Build (proj), "second build failed"); - Assert.IsTrue (b.LastBuildOutput.Contains ("Skipping target \"_Sign\" because"), "failed to skip some build"); + Assert.IsTrue (b.Output.IsTargetSkipped ("_Sign"), "failed to skip some build"); proj.AndroidResources.First ().Timestamp = null; // means "always build" Assert.IsTrue (b.Build (proj), "third build failed"); - Assert.IsFalse (b.LastBuildOutput.Contains ("Skipping target \"_Sign\" because"), "incorrectly skipped some build"); + Assert.IsFalse (b.Output.IsTargetSkipped ("_Sign"), "incorrectly skipped some build"); } } @@ -74,15 +74,18 @@ public void DesignTimeBuild ([Values(false, true)] bool isRelease, [Values (fals }, }; proj.SetProperty ("AndroidUseManagedDesignTimeResourceGenerator", useManagedParser.ToString ()); + if (useManagedParser) + proj.SetProperty ("BuildingInsideVisualStudio", "True"); using (var l = CreateDllBuilder (Path.Combine (path, lib.ProjectName), false, false)) { using (var b = CreateApkBuilder (Path.Combine (path, proj.ProjectName), false, false)) { l.Verbosity = LoggerVerbosity.Diagnostic; + l.Target = "Build"; Assert.IsTrue(l.Clean(lib), "Lib1 should have cleaned successfully"); Assert.IsTrue (l.Build (lib), "Lib1 should have built successfully"); b.Verbosity = LoggerVerbosity.Diagnostic; b.ThrowOnBuildFailure = false; - Assert.IsTrue (b.Clean(proj), "App should have cleaned successfully"); - Assert.IsTrue (b.UpdateAndroidResources (proj, doNotCleanupOnUpdate: true, parameters: new string [] { "DesignTimeBuild=true" }, environmentVariables: envVar), + b.Target = "Compile"; + Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true, parameters: new string [] { "DesignTimeBuild=true" }, environmentVariables: envVar), "first build failed"); Assert.AreEqual (!useManagedParser, b.LastBuildOutput.Contains ("Skipping download of "), "failed to skip the downloading of files."); @@ -156,7 +159,7 @@ public void MoveResource () image.Timestamp = DateTimeOffset.UtcNow.AddMinutes (1); Assert.IsTrue (b.Build (proj), "Second build should have succeeded."); Assert.IsFalse (File.Exists (Path.Combine (b.ProjectDirectory, oldpath)), "XamarinProject.UpdateProjectFiles() failed to delete file"); - Assert.IsFalse (b.LastBuildOutput.Contains ("Skipping target \"_Sign\" because"), "incorrectly skipped some build"); + Assert.IsFalse (b.Output.IsTargetSkipped ("_Sign"), "incorrectly skipped some build"); } } @@ -194,25 +197,23 @@ public void RepetiviteBuildUpdateSingleResource () Assert.IsTrue (b.Build (proj), "Second build was supposed to build without errors"); Assert.IsTrue (firstBuildTime > b.LastBuildTime, "Second build was supposed to be quicker than the first"); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_GenerateAndroidResourceDir\" because"), + b.Output.IsTargetSkipped ("_GenerateAndroidResourceDir"), "The Target _GenerateAndroidResourceDir should have been skipped"); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_CompileJava\" because"), + b.Output.IsTargetSkipped ("_CompileJava"), "The Target _CompileJava should have been skipped"); image1.Timestamp = DateTime.UtcNow; var layout = proj.AndroidResources.First (x => x.Include() == "Resources\\layout\\Main.axml"); layout.Timestamp = DateTime.UtcNow; Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate:true, saveProject: false), "Third build was supposed to build without errors"); - Assert.IsTrue ( - b.LastBuildOutput.Contains ("Target _GenerateAndroidResourceDir needs to be built as input file") || - b.LastBuildOutput.Contains ("Building target \"_GenerateAndroidResourceDir\" completely."), + Assert.IsFalse ( + b.Output.IsTargetSkipped ("_GenerateAndroidResourceDir"), "The Target _GenerateAndroidResourceDir should not have been skipped"); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_CompileJava\" because"), + b.Output.IsTargetSkipped ("_CompileJava"), "The Target _CompileJava (2) should have been skipped"); - Assert.IsTrue ( - b.LastBuildOutput.Contains ("Target _CreateBaseApk needs to be built as input file") || - b.LastBuildOutput.Contains ("Building target \"_CreateBaseApk\" completely."), + Assert.IsFalse ( + b.Output.IsTargetSkipped ("_CreateBaseApk"), "The Target _CreateBaseApk should not have been skipped"); } } @@ -957,7 +958,7 @@ public void BuildAppWithManagedResourceParser() using (var appBuilder = CreateApkBuilder (Path.Combine (path, appProj.ProjectName))) { appBuilder.Verbosity = LoggerVerbosity.Diagnostic; appBuilder.Target = "Compile"; - Assert.IsTrue (appBuilder.Build (appProj, parameters: new string[] { "DesignTimeBuild=true"} ), + Assert.IsTrue (appBuilder.Build (appProj, parameters: new string[] { "DesignTimeBuild=true", "BuildingInsideVisualStudio=true" } ), "DesignTime Application Build should have succeeded."); Assert.IsFalse (appProj.CreateBuildOutput (appBuilder).IsTargetSkipped ("_ManagedUpdateAndroidResgen"), "Target '_ManagedUpdateAndroidResgen' should have run."); @@ -1021,15 +1022,17 @@ public void BuildAppWithManagedResourceParserAndLibraries () appProj.SetProperty ("AndroidUseManagedDesignTimeResourceGenerator", "True"); using (var libBuilder = CreateDllBuilder (Path.Combine (path, libProj.ProjectName), false, false)) { libBuilder.Verbosity = LoggerVerbosity.Diagnostic; + libBuilder.ThrowOnBuildFailure = false; using (var appBuilder = CreateApkBuilder (Path.Combine (path, appProj.ProjectName), false, false)) { appBuilder.Verbosity = LoggerVerbosity.Diagnostic; + appBuilder.ThrowOnBuildFailure = false; libBuilder.Target = "Compile"; - Assert.IsTrue (libBuilder.Build (libProj, parameters: new string [] { "DesignTimeBuild=true" }), "Library project should have built"); + Assert.IsTrue (libBuilder.Build (libProj, parameters: new string [] { "DesignTimeBuild=true", "BuildingInsideVisualStudio=true" }), "Library project should have built"); Assert.LessOrEqual (libBuilder.LastBuildTime.TotalMilliseconds, maxBuildTimeMs, "DesingTime build should be less than 5 seconds."); Assert.IsFalse (libProj.CreateBuildOutput (libBuilder).IsTargetSkipped ("_ManagedUpdateAndroidResgen"), "Target '_ManagedUpdateAndroidResgen' should have run."); appBuilder.Target = "Compile"; - Assert.IsTrue (appBuilder.Build (appProj, parameters: new string [] { "DesignTimeBuild=true" }), "Library project should have built"); + Assert.AreEqual (!appBuilder.RunningMSBuild, appBuilder.Build (appProj, parameters: new string [] { "DesignTimeBuild=true", "BuildingInsideVisualStudio=true" }), "Application project should have built"); Assert.LessOrEqual (appBuilder.LastBuildTime.TotalMilliseconds, maxBuildTimeMs, "DesingTime build should be less than 5 seconds."); Assert.IsFalse (appProj.CreateBuildOutput (appBuilder).IsTargetSkipped ("_ManagedUpdateAndroidResgen"), "Target '_ManagedUpdateAndroidResgen' should have run."); @@ -1049,7 +1052,7 @@ public void BuildAppWithManagedResourceParserAndLibraries () Assert.IsTrue (libProj.CreateBuildOutput (libBuilder).IsTargetSkipped ("_ManagedUpdateAndroidResgen"), "Target '_ManagedUpdateAndroidResgen' should not have run."); appBuilder.Target = "Compile"; - Assert.IsTrue (appBuilder.Build (appProj, parameters: new string [] { "DesignTimeBuild=true" }), "App project should have built"); + Assert.IsTrue (appBuilder.Build (appProj, parameters: new string [] { "DesignTimeBuild=true", "BuildingInsideVisualStudio=true" }), "App project should have built"); Assert.LessOrEqual (appBuilder.LastBuildTime.TotalMilliseconds, maxBuildTimeMs, "DesingTime build should be less than 5 seconds."); Assert.IsFalse (appProj.CreateBuildOutput (appBuilder).IsTargetSkipped ("_ManagedUpdateAndroidResgen"), "Target '_ManagedUpdateAndroidResgen' should have run."); diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.OSS.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.OSS.cs index 4e0567b9acf..566b3858f8f 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.OSS.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.OSS.cs @@ -133,7 +133,7 @@ public partial class BuildTest : BaseTest /* debugType */ "", /* optimize */ true , /* embedassebmlies */ true , - /* expectedResult */ "debug", + /* expectedResult */ "release", }, new object[] { /* supportedAbi */ new string[] { "armeabi-v7a"}, @@ -141,7 +141,7 @@ public partial class BuildTest : BaseTest /* debugType */ "", /* optimize */ true , /* embedassebmlies */ false , - /* expectedResult */ "debug", + /* expectedResult */ "release", }, new object[] { /* supportedAbi */ new string[] { "armeabi-v7a"}, 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 0432bf87f92..573ab506adc 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 @@ -131,12 +131,16 @@ public void BuildApplicationWithLibraryAndClean ([Values (false, true)] bool isR //var fi = new FileInfo (Path.Combine (b.ProjectDirectory, proj.IntermediateOutputPath, // "__library_projects__", "Library1", "library_project_imports", "")); //fi.Attributes != FileAttributes.ReadOnly; + var ignoreFiles = new string [] { + "TemporaryGeneratedFile", + "CopyComplete" + }; Assert.IsTrue (b.Clean (proj), "Clean should have succeeded."); var fileCount = Directory.GetFiles (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath), "*", SearchOption.AllDirectories) - .Where (x => !Path.GetFileName (x).StartsWith ("TemporaryGeneratedFile")).Count (); + .Where (x => !ignoreFiles.Any (i => !Path.GetFileName (x).Contains (i))).Count (); Assert.AreEqual (0, fileCount, "{0} should be Empty", proj.IntermediateOutputPath); fileCount = Directory.GetFiles (Path.Combine (Root, b.ProjectDirectory, proj.OutputPath), "*", SearchOption.AllDirectories) - .Where (x => !Path.GetFileName (x).StartsWith ("TemporaryGeneratedFile")).Count (); + .Where (x => !ignoreFiles.Any (i => !Path.GetFileName (x).Contains (i))).Count (); Assert.AreEqual (0, fileCount, "{0} should be Empty", proj.OutputPath); } } @@ -258,10 +262,10 @@ public void BuildAotApplication (string supportedAbis, bool enableLLVM, bool exp } Assert.AreEqual (expectedResult, b.Build (proj), "Second Build should have {0}.", expectedResult ? "succeeded" : "failed"); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_CompileJava\" because"), + b.Output.IsTargetSkipped ("_CompileJava"), "the _CompileJava target should be skipped"); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_BuildApkEmbed\" because"), + b.Output.IsTargetSkipped ("_BuildApkEmbed"), "the _BuildApkEmbed target should be skipped"); } } @@ -309,10 +313,10 @@ public void BuildAotApplicationAndBundle (string supportedAbis, bool enableLLVM, } Assert.AreEqual (expectedResult, b.Build (proj), "Second Build should have {0}.", expectedResult ? "succeeded" : "failed"); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_CompileJava\" because"), + b.Output.IsTargetSkipped ("_CompileJava"), "the _CompileJava target should be skipped"); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_BuildApkEmbed\" because"), + b.Output.IsTargetSkipped ("_BuildApkEmbed"), "the _BuildApkEmbed target should be skipped"); } } @@ -449,15 +453,15 @@ public void BasicApplicationRepetitiveBuild () b.LastBuildTime, firstBuildTime ); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_Sign\" because"), + b.Output.IsTargetSkipped ("_Sign"), "the _Sign target should not run"); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_StripEmbeddedLibraries\" because"), + b.Output.IsTargetSkipped ("_StripEmbeddedLibraries"), "the _StripEmbeddedLibraries target should not run"); proj.AndroidResources.First ().Timestamp = null; Assert.IsTrue (b.Build (proj), "third build failed"); Assert.IsFalse ( - b.LastBuildOutput.Contains ("Skipping target \"_Sign\" because"), + b.Output.IsTargetSkipped ("_Sign"), "the _Sign target should run"); } } @@ -485,21 +489,20 @@ public class Foo { b.LastBuildTime, firstBuildTime ); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_Sign\" because"), + b.Output.IsTargetSkipped ("_Sign"), "the _Sign target should not run"); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_StripEmbeddedLibraries\" because"), + b.Output.IsTargetSkipped ("_StripEmbeddedLibraries"), "the _StripEmbeddedLibraries target should not run"); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_LinkAssembliesShrink\" because"), + b.Output.IsTargetSkipped ("_LinkAssembliesShrink"), "the _LinkAssembliesShrink target should not run"); foo.Timestamp = DateTime.UtcNow; Assert.IsTrue (b.Build (proj), "third build failed"); - Assert.IsTrue (b.LastBuildOutput.Contains ("Target CoreCompile needs to be built as input file ") || - b.LastBuildOutput.Contains ("Building target \"CoreCompile\" completely."), + Assert.IsFalse (b.Output.IsTargetSkipped ("CoreCompile"), "the Core Compile target should run"); Assert.IsFalse ( - b.LastBuildOutput.Contains ("Skipping target \"_Sign\" because"), + b.Output.IsTargetSkipped ("_Sign"), "the _Sign target should run"); } } @@ -530,8 +533,11 @@ public void BuildBasicApplicationCheckMdbRepeatBuild () "UnnamedProject.dll.mdb must be copied to the Intermediate directory"); Assert.IsTrue (b.Build (proj), "second build failed"); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_CopyMdbFiles\" because"), + b.Output.IsTargetSkipped ("_CopyMdbFiles"), "the _CopyMdbFiles target should be skipped"); + Assert.IsTrue ( + b.Output.IsTargetSkipped ("_CopyPdbFiles"), + "the _CopyPdbFiles target should be skipped"); Assert.IsTrue ( File.Exists (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android/assets/UnnamedProject.dll.mdb")) || File.Exists (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android/assets/UnnamedProject.pdb")), @@ -592,13 +598,31 @@ public Class2 () Assert.IsTrue ( File.Exists (assetsPdb), "Library1.pdb must be copied to Intermediate directory"); - Assert.IsTrue ( + Assert.IsFalse ( File.Exists (linkDst), - "Library1.pdb must be copied to linkdst directory"); + "Library1.pdb should not be copied to linkdst directory because it has no Abstrsact methods to fix up."); Assert.IsTrue ( File.Exists (linkSrc), "Library1.pdb must be copied to linksrc directory"); - FileAssert.AreEqual (linkDst, assetsPdb, $"Library1.pdb in {assetsPdb} should match {linkDst}"); + var outputPath = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath); + using (var apk = ZipHelper.OpenZip (Path.Combine (outputPath, proj.PackageName + ".apk"))) { + var data = ZipHelper.ReadFileFromZip (apk, "assemblies/Library1.pdb"); + var filedata = File.ReadAllBytes (linkSrc); + Assert.AreEqual (filedata.Length, data.Length, "Library1.pdb in the apk should match {0}", linkSrc); + } + linkDst = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "linkdst", "App1.pdb"); + linkSrc = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "linksrc", "App1.pdb"); + Assert.IsTrue ( + File.Exists (linkDst), + "App1.pdb should be copied to linkdst directory because it has Abstrsact methods to fix up."); + Assert.IsTrue ( + File.Exists (linkSrc), + "App1.pdb must be copied to linksrc directory"); + FileAssert.AreEqual (linkSrc, linkDst, "{0} and {1} should not differ.", linkSrc, linkDst); + linkDst = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "linkdst", "App1.dll"); + linkSrc = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "linksrc", "App1.dll"); + FileAssert.AreEqual (linkSrc, linkDst, "{0} and {1} should match.", linkSrc, linkDst); + } } } @@ -648,13 +672,13 @@ public void BuildBasicApplicationCheckMdbAndPortablePdb () "NetStandard16.pdb must be copied to Intermediate directory"); Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true), "second build failed"); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_CopyMdbFiles\" because"), + b.Output.IsTargetSkipped ("_CopyMdbFiles"), "the _CopyMdbFiles target should be skipped"); var lastTime = File.GetLastAccessTimeUtc (pdbToMdbPath); pdb.Timestamp = DateTime.UtcNow; Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true), "third build failed"); Assert.IsFalse ( - b.LastBuildOutput.Contains ("Skipping target \"_CopyMdbFiles\" because"), + b.Output.IsTargetSkipped ("_CopyMdbFiles"), "the _CopyMdbFiles target should not be skipped"); Assert.Less (lastTime, File.GetLastAccessTimeUtc (pdbToMdbPath), @@ -683,7 +707,7 @@ public void BuildBasicApplicationCheckConfigFiles () "UnnamedProject.dll.config was must be copied to Intermediate directory"); Assert.IsTrue (b.Build (proj), "second build failed"); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_CopyConfigFiles\" because"), + b.Output.IsTargetSkipped ("_CopyConfigFiles"), "the _CopyConfigFiles target should be skipped"); } } @@ -717,13 +741,12 @@ public void BuildApplicationCheckThatAddStaticResourcesTargetDoesNotRerun () b.Verbosity = LoggerVerbosity.Diagnostic; b.ThrowOnBuildFailure = false; Assert.IsTrue (b.Build (proj), "Build should not have failed"); - Assert.IsTrue ( - b.LastBuildOutput.Contains ("Target _AddStaticResources needs to be built as output file") || - b.LastBuildOutput.Contains ("Building target \"_AddStaticResources\" completely."), + Assert.IsFalse ( + b.Output.IsTargetSkipped ("_AddStaticResources"), "The _AddStaticResources should have been run"); Assert.IsTrue (b.Build (proj), "Build should not have failed"); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_AddStaticResources\" because"), + b.Output.IsTargetSkipped ("_AddStaticResources"), "The _AddStaticResources should NOT have been run"); } } @@ -1048,6 +1071,8 @@ public void CheckWhichRuntimeIsIncluded (string[] supportedAbi, bool debugSymbol Assert.IsTrue (b.Build (proj), "Build should have succeeded."); var apkPath = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath,"android", "bin", "UnnamedProject.UnnamedProject.apk"); + if (debugSymbols && optimize.HasValue && optimize.Value && debugType == "" && !b.RunningMSBuild) + expectedRuntime = "debug"; using (var apk = ZipHelper.OpenZip (apkPath)) { foreach (var abi in supportedAbi) { var runtime = runtimeInfo.FirstOrDefault (x => x.Abi == abi && x.Runtime == expectedRuntime); @@ -1745,15 +1770,16 @@ public void BuildBasicApplicationCheckPdb () "assemblies/PdbTestLibrary.pdb"), "assemblies/PdbTestLibrary.pdb should not exist in the apk."); } + b.BuildLogFile = "build1.log"; Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true), "second build failed"); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_CopyMdbFiles\" because"), + b.Output.IsTargetSkipped ("_CopyMdbFiles"), "the _CopyMdbFiles target should be skipped"); var lastTime = File.GetLastAccessTimeUtc (pdbToMdbPath); pdb.Timestamp = DateTime.UtcNow; Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true), "third build failed"); Assert.IsFalse ( - b.LastBuildOutput.Contains ("Skipping target \"_CopyMdbFiles\" because"), + b.Output.IsTargetSkipped ("_CopyMdbFiles"), "the _CopyMdbFiles target should not be skipped"); Assert.Less (lastTime, File.GetLastAccessTimeUtc (pdbToMdbPath), 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 f8dcb986d1c..67dfe59a02f 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 @@ -59,20 +59,20 @@ public TestMe createTestMe () { using (var b = CreateApkBuilder (Path.Combine ("temp", "JavacTaskDoesNotRunOnSecondBuild"), false, false)) { Assert.IsTrue (b.Build (app), "First build should have succeeded"); Assert.IsFalse ( - b.LastBuildOutput.Contains ("Skipping target \"_CompileJava\" because"), + b.Output.IsTargetSkipped ("_CompileJava"), "the _CompileJava target should not be skipped"); Assert.IsFalse ( - b.LastBuildOutput.Contains ("Skipping target \"_BuildApkEmbed\" because"), + b.Output.IsTargetSkipped ("_BuildApkEmbed"), "the _BuildApkEmbed target should not be skipped"); var expectedOutput = Path.Combine (Root, b.ProjectDirectory, app.IntermediateOutputPath, "android", "bin", "classes", "com", "android", "test", "TestMe.class"); Assert.IsTrue (File.Exists (expectedOutput), string.Format ("{0} should exist.", expectedOutput)); Assert.IsTrue (b.Build (app), "Second build should have succeeded"); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_CompileJava\" because"), + b.Output.IsTargetSkipped ("_CompileJava"), "the _CompileJava target should be skipped"); Assert.IsTrue ( - b.LastBuildOutput.Contains ("Skipping target \"_BuildApkEmbed\" because"), + b.Output.IsTargetSkipped ("_BuildApkEmbed"), "the _BuildApkEmbed target should be skipped"); Assert.IsTrue (File.Exists (expectedOutput), string.Format ("{0} should exist.", expectedOutput)); } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.OSS.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.OSS.cs index 6e889582ef3..990ae302ad7 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.OSS.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.OSS.cs @@ -17,7 +17,7 @@ public partial class ManifestTest : BaseTest new object[] { "", true, false, }, new object[] { "", false, true, }, new object[] { "None", true, false, }, - new object[] { "None", false, false, }, + new object[] { "None", false, true, }, new object[] { "PdbOnly", true, false, }, new object[] { "PdbOnly", false, true, }, new object[] { "Full", true, false, }, diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs index a188ae03036..b58e07a7526 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs @@ -480,6 +480,8 @@ public void DebuggerAttribute (string debugType, bool isRelease, bool expected) using (var builder = CreateApkBuilder (Path.Combine ("temp", $"DebuggerAttribute_{debugType}_{isRelease}_{expected}"), false, false)) { Assert.IsTrue (builder.Build (proj), "Build should have succeeded"); var manifest = builder.Output.GetIntermediaryAsText (Root, Path.Combine ("android", "AndroidManifest.xml")); + if (!isRelease && debugType == "None" && !builder.RunningMSBuild) + expected = false; Assert.AreEqual (expected, manifest.Contains ("android:debuggable=\"true\""), $"Manifest {(expected ? "should" : "should not")} contain the andorid:debuggable attribute"); } } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs index 5765a2e6010..361e16fccbe 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs @@ -222,7 +222,13 @@ protected virtual void CleanupTest () TestContext.Out.WriteLine ("*************************************************************************"); TestContext.Out.WriteLine (file); TestContext.Out.WriteLine (); - TestContext.Out.WriteLine (File.ReadAllText (file)); + using (StreamReader reader = new StreamReader (file)) { + string line; + while ((line = reader.ReadLine ()) != null) { + TestContext.Out.WriteLine (line); + TestContext.Out.Flush (); + } + } TestContext.Out.WriteLine ("*************************************************************************"); TestContext.Out.Flush (); } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/BuildOutput.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/BuildOutput.cs index 3e00da5bdc7..0bef5cd05c9 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/BuildOutput.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/BuildOutput.cs @@ -49,8 +49,11 @@ public bool IsTargetSkipped (string target) if (!Builder.LastBuildOutput.Contains (target)) throw new ArgumentException (string.Format ("Target '{0}' is not even in the build output.", target)); return Builder.LastBuildOutput.Contains (string.Format ("Target {0} skipped due to ", target)) - || Builder.LastBuildOutput.Contains (string.Format ("Skipping target \"{0}\" because its outputs are up-to-date", target)) - || Builder.LastBuildOutput.Contains ($"Skipping target \"{target}\" because all output files are up-to-date"); + || Builder.LastBuildOutput.Contains (string.Format ("Skipping target \"{0}\" because it has no outputs.", target)) + || Builder.LastBuildOutput.Contains (string.Format ("Target \"{0}\" skipped, due to", target)) + || Builder.LastBuildOutput.Contains (string.Format ("Skipping target \"{0}\" because its outputs are up-to-date", target)) + || Builder.LastBuildOutput.Contains (string.Format ("target {0}, skipping", target)) + || Builder.LastBuildOutput.Contains ($"Skipping target \"{target}\" because all output files are up-to-date"); } public bool IsApkInstalled { diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs index d37a8283740..ad6dd88ab4d 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs @@ -40,8 +40,10 @@ string GetVisualStudio2017Directory () public string XABuildExe { get { if (IsUnix) { - if (!string.IsNullOrEmpty (Environment.GetEnvironmentVariable ("USE_MSBUILD"))) { - RunningMSBuild = true; + RunningMSBuild = true; + var useMSBuild = Environment.GetEnvironmentVariable ("USE_MSBUILD"); + if (string.IsNullOrEmpty (useMSBuild) || useMSBuild == "0") { + RunningMSBuild = false; } return Path.GetFullPath (Path.Combine (Root, "..", "..", "tools", "scripts", "xabuild")); } @@ -167,9 +169,12 @@ protected bool BuildInternal (string projectOrSolution, string target, string [] var start = DateTime.UtcNow; var args = new StringBuilder (); var psi = new ProcessStartInfo (XABuildExe); - args.AppendFormat ("{0} /t:{1} {2} /p:UseHostCompilerIfAvailable=false /p:BuildingInsideVisualStudio=true", + args.AppendFormat ("{0} /t:{1} {2}", QuoteFileName(Path.Combine (Root, projectOrSolution)), target, logger); - + if (RunningMSBuild) + args.Append (" /p:BuildingOutOfProcess=true"); + else + args.Append (" /p:UseHostCompilerIfAvailable=false /p:BuildingInsideVisualStudio=true"); if (parameters != null) { foreach (var param in parameters) { args.AppendFormat (" /p:{0}", param); 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 3abae105911..92248712d62 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 @@ -24,31 +24,43 @@ public void Save () foreach (var p in Projects) { using (var pb = new ProjectBuilder (Path.Combine (SolutionPath, p.ProjectName))) { pb.Save (p); + p.NuGetRestore (Path.Combine (SolutionPath, p.ProjectName), Path.Combine (SolutionPath, "packages")); } } // write a sln. var sb = new StringBuilder (); - sb.AppendFormat ("Microsoft Visual Studio Solution File, Format Version {0}\n", "12.00"); - sb.AppendFormat ("# Visual Studio {0}\n", "2012"); + sb.AppendFormat ("Microsoft Visual Studio Solution File, Format Version {0}\r\n", "12.00"); + sb.AppendFormat ("# Visual Studio {0}\r\n", "2012"); foreach (var p in Projects) { - sb.AppendFormat ("Project(\"{{{0}}}\") = \"{1}\", \"{2}\", \"{{{3}}}\"\n", p.ProjectTypeGuid, p.ProjectName, + sb.AppendFormat ("Project(\"{{{0}}}\") = \"{1}\", \"{2}\", \"{{{3}}}\"\r\n", p.ProjectTypeGuid, p.ProjectName, Path.Combine(p.ProjectName,p.ProjectFilePath), p.ProjectGuid); - sb.Append ("EndProject\n"); + sb.Append ("EndProject\r\n"); } - sb.Append ("Global\n"); - sb.Append ("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n"); - sb.Append ("\t\tDebug|AnyCPU = Debug|AnyCPU\n"); - sb.Append ("\t\tRelease|AnyCPU = Release|AnyCPU\n"); - sb.Append ("\tEndGlobalSection\n"); - sb.Append ("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n"); + sb.Append ("Global\r\n"); + sb.Append ("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n"); + sb.Append ("\t\tDebug|AnyCPU = Debug|AnyCPU\r\n"); + sb.Append ("\t\tRelease|AnyCPU = Release|AnyCPU\r\n"); + sb.Append ("\tEndGlobalSection\r\n"); + sb.Append ("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n"); foreach (var p in Projects) { - sb.AppendFormat ("{{{0}}}.Debug|AnyCPU.ActiveCfg = Debug|AnyCPU\n", p.ProjectGuid); - sb.AppendFormat ("{{{0}}}.Debug|AnyCPU.Build.0 = Debug|AnyCPU\n", p.ProjectGuid); - sb.AppendFormat ("{{{0}}}.Release|AnyCPU.ActiveCfg = Release|AnyCPU\n", p.ProjectGuid); - sb.AppendFormat ("{{{0}}}.Release|AnyCPU.Build.0 = Release|AnyCPU\n", p.ProjectGuid); + sb.AppendFormat ("\t\t{{{0}}}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU\r\n", p.ProjectGuid); + sb.AppendFormat ("\t\t{{{0}}}.Debug|AnyCPU.Build.0 = Debug|Any CPU\r\n", p.ProjectGuid); + if (p is XamarinAndroidApplicationProject) + sb.AppendFormat ("\t\t{{{0}}}.Debug|AnyCPU.Deploy.0 = Debug|Any CPU\r\n", p.ProjectGuid); + sb.AppendFormat ("\t\t{{{0}}}.Release|AnyCPU.ActiveCfg = Release|Any CPU\r\n", p.ProjectGuid); + sb.AppendFormat ("\t\t{{{0}}}.Release|AnyCPU.Build.0 = Release|Any CPU\r\n", p.ProjectGuid); + if (p is XamarinAndroidApplicationProject) + sb.AppendFormat ("\t\t{{{0}}}.Release|AnyCPU.Deploy.0 = Release|Any CPU\r\n", p.ProjectGuid); + } - sb.Append ("\tEndGlobalSection\n"); - sb.Append ("EndGlobal\n"); + sb.Append ("\tEndGlobalSection\r\n"); + sb.Append ("\tGlobalSection (SolutionProperties) = preSolution\r\n"); + sb.Append ("\t\tHideSolutionNode = FALSE\r\n"); + sb.Append ("\tEndGlobalSection\r\n"); + sb.Append ("\tGlobalSection (ExtensibilityGlobals) = postSolution\r\n"); + sb.Append ("\t\tSolutionGuid = { BA9651E4 - A332 - 4729 - 9FB4 - 24520221DC3C}\r\n"); + sb.Append ("\tEndGlobalSection\r\n"); + sb.Append ("EndGlobal\r\n"); File.WriteAllText (Path.Combine (SolutionPath, SolutionName), sb.ToString ()); } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs index 97e915db0a0..e9cd7a10b2d 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs @@ -61,7 +61,6 @@ protected XamarinProject (string debugConfigurationName = "Debug", string releas SetProperty ("ConsolePause", "false"); SetProperty ("RootNamespace", () => RootNamespace ?? ProjectName); SetProperty ("AssemblyName", () => AssemblyName ?? ProjectName); - SetProperty ("BuildingInsideVisualStudio", "True"); SetProperty ("BaseIntermediateOutputPath", "obj\\", " '$(BaseIntermediateOutputPath)' == '' "); SetProperty (DebugProperties, "DebugSymbols", "true"); @@ -257,7 +256,7 @@ public virtual List Save (bool saveProject = true) Timestamp = ItemGroupList.SelectMany (ig => ig).Where (i => i.Timestamp != null).Select (i => (DateTimeOffset)i.Timestamp).Max (), Path = ProjectFilePath, Content = SaveProject (), - Encoding = System.Text.Encoding.Unicode + Encoding = System.Text.Encoding.UTF8, }); } diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Bindings.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Bindings.targets index 3bf10950e5f..44b4f527ece 100755 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Bindings.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Bindings.targets @@ -297,6 +297,7 @@ Copyright (C) 2012 Xamarin Inc. All rights reserved. + + + false + portable + + @@ -456,7 +462,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. + DependsOnTargets="_CopyIntermediateAssemblies;_CopyPdbFiles;_CopyMdbFiles"> @@ -1079,6 +1085,7 @@ because xbuild doesn't support framework reference assemblies. IsApplication="$(AndroidApplication)" References="@(ReferencePath)" UseManagedResourceGenerator="True" + DesignTimeBuild="$(DesignTimeBuild)" /> @@ -1148,6 +1155,7 @@ because xbuild doesn't support framework reference assemblies. @@ -1644,25 +1653,49 @@ because xbuild doesn't support framework reference assemblies. Overwrite="false" /> + + + + + + + + + + + + + + Inputs="@(_ResolvedMdbFiles)" + Outputs="@(_ResolvedMdbFiles->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension)')" + DependsOnTargets="_CollectMdbFiles" > + SourceFiles="@(_ResolvedMdbFiles)" + DestinationFiles="@(_ResolvedMdbFiles->'$(OutputPath)%(Filename)%(Extension)')"> - + diff --git a/tools/scripts/xabuild b/tools/scripts/xabuild index b9c1509127e..d057c449a21 100755 --- a/tools/scripts/xabuild +++ b/tools/scripts/xabuild @@ -83,7 +83,7 @@ else fi if [[ "$MSBUILD" == "msbuild" ]] ; then - exec mono "$prefix/bin/xabuild.exe" "$@" + exec mono "$prefix/bin/xabuild.exe" "$@" "/p:MonoDroidInstallDirectory=$prefix" exit $? fi @@ -129,7 +129,7 @@ export MSBuildExtensionsPath="$TARGETS_DIR" case "$MSBUILD" in *msbuild*) - XABUILD_FLAGS+=(/p:TargetFrameworkRootPath="$TARGETS_DIR-frameworks") + XABUILD_FLAGS+=(/p:TargetFrameworkRootPath="$TARGETS_DIR-frameworks/") ;; *xbuild*) export XBUILD_FRAMEWORK_FOLDERS_PATH="$TARGETS_DIR-frameworks"