public void DotNetBuildBinding() { var proj = new XASdkProject(outputType: "Library"); proj.Sources.Add(new AndroidItem.TransformFile("Transforms\\Metadata.xml") { TextContent = () => @"<metadata> <attr path=""/api/package[@name='com.xamarin.android.test.msbuildtest']"" name=""managedName"">MSBuildTest</attr> </metadata>", }); proj.Sources.Add(new AndroidItem.AndroidLibrary("javaclasses.jar") { BinaryContent = () => Convert.FromBase64String(InlineData.JavaClassesJarBase64) }); // TODO: bring back when Xamarin.Android.Bindings.Documentation.targets is working //proj.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javasources.jar") { // BinaryContent = () => Convert.FromBase64String (InlineData.JavaSourcesJarBase64) //}); var dotnet = CreateDotNetBuilder(proj); Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed"); var assemblyPath = Path.Combine(FullProjectDirectory, proj.OutputPath, "UnnamedProject.dll"); FileAssert.Exists(assemblyPath); using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) { var typeName = "MSBuildTest.JavaSourceJarTest"; var type = assembly.MainModule.GetType(typeName); Assert.IsNotNull(type, $"{assemblyPath} should contain {typeName}"); } }
public void XamarinLegacySdk() { var proj = new XASdkProject(outputType: "Library") { Sdk = "Xamarin.Legacy.Sdk/0.1.0-alpha2", Sources = { new AndroidItem.AndroidLibrary("javaclasses.jar") { BinaryContent = () => ResourceData.JavaSourceJarTestJar, } } }; using var b = new Builder(); var dotnetTargetFramework = "net6.0-android30.0"; var legacyTargetFrameworkVersion = b.LatestTargetFrameworkVersion().TrimStart('v'); var legacyTargetFramework = $"monoandroid{legacyTargetFrameworkVersion}"; proj.SetProperty("TargetFramework", value: ""); proj.SetProperty("TargetFrameworks", value: $"{dotnetTargetFramework};{legacyTargetFramework}"); var dotnet = CreateDotNetBuilder(proj); Assert.IsTrue(dotnet.Pack(), "`dotnet pack` should succeed"); var nupkgPath = Path.Combine(FullProjectDirectory, proj.OutputPath, $"{proj.ProjectName}.1.0.0.nupkg"); FileAssert.Exists(nupkgPath); using var nupkg = ZipHelper.OpenZip(nupkgPath); nupkg.AssertContainsEntry(nupkgPath, $"lib/{dotnetTargetFramework}/{proj.ProjectName}.dll"); nupkg.AssertContainsEntry(nupkgPath, $"lib/{legacyTargetFramework}/{proj.ProjectName}.dll"); }
public void DotNetBuildBinding() { var proj = new XASdkProject(outputType: "Library"); proj.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("javaclasses.jar") { MetadataValues = "Bind=true", BinaryContent = () => Convert.FromBase64String(InlineData.JavaClassesJarBase64) }); // TODO: bring back when Xamarin.Android.Bindings.Documentation.targets is working //proj.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javasources.jar") { // BinaryContent = () => Convert.FromBase64String (InlineData.JavaSourcesJarBase64) //}); var dotnet = CreateDotNetBuilder(proj); Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed"); var assemblyPath = Path.Combine(FullProjectDirectory, proj.OutputPath, "UnnamedProject.dll"); FileAssert.Exists(assemblyPath); using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) { var typeName = "Com.Xamarin.Android.Test.Msbuildtest.JavaSourceJarTest"; var type = assembly.MainModule.GetType(typeName); Assert.IsNotNull(type, $"{assemblyPath} should contain {typeName}"); } }
public void DotNetPublish([Values(false, true)] bool isRelease) { const string runtimeIdentifier = "android.21-arm"; var proj = new XASdkProject { IsRelease = isRelease }; proj.SetProperty(KnownProperties.RuntimeIdentifier, runtimeIdentifier); var dotnet = CreateDotNetBuilder(proj); Assert.IsTrue(dotnet.Publish(), "first `dotnet publish` should succeed"); var publishDirectory = Path.Combine(FullProjectDirectory, proj.OutputPath, runtimeIdentifier, "publish"); var apk = Path.Combine(publishDirectory, $"{proj.PackageName}.apk"); var apkSigned = Path.Combine(publishDirectory, $"{proj.PackageName}-Signed.apk"); FileAssert.Exists(apk); FileAssert.Exists(apkSigned); Assert.IsTrue(dotnet.Publish(parameters: new [] { "AndroidPackageFormat=aab" }), $"second `dotnet publish` should succeed"); var aab = Path.Combine(publishDirectory, $"{proj.PackageName}.aab"); var aabSigned = Path.Combine(publishDirectory, $"{proj.PackageName}-Signed.aab"); FileAssert.DoesNotExist(apk); FileAssert.DoesNotExist(apkSigned); FileAssert.Exists(aab); FileAssert.Exists(aabSigned); }
public void SignAndroidPackage() { var proj = new XASdkProject(); var builder = CreateDotNetBuilder(proj); var parameters = new [] { "BuildingInsideVisualStudio=true" }; Assert.IsTrue(builder.Build("SignAndroidPackage", parameters), $"{proj.ProjectName} should succeed"); }
public void DotNetBuild([Values(false, true)] bool isRelease) { var proj = new XASdkProject(SdkVersion) { IsRelease = isRelease }; var dotnet = CreateDotNetBuilder(proj); Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed"); }
public void BuildXASdkProject([Values(false, true)] bool isRelease) { var proj = new XASdkProject("0.0.1") { IsRelease = isRelease }; using (var b = CreateApkBuilder(Path.Combine("temp", TestName))) { Assert.IsTrue(b.Build(proj), "Build should have succeeded."); } }
public void DotNetPublish([Values(false, true)] bool isRelease) { var proj = new XASdkProject(SdkVersion) { IsRelease = isRelease }; proj.SetProperty(KnownProperties.AndroidLinkMode, AndroidLinkMode.None.ToString()); var dotnet = CreateDotNetBuilder(proj); Assert.IsTrue(dotnet.Publish(), "`dotnet publish` should succeed"); }
public void BuildWithLiteSdk() { var proj = new XASdkProject() { Sdk = $"Xamarin.Android.Sdk.Lite/{SdkVersion}", TargetFramework = "monoandroid10.0" }; using (var b = CreateApkBuilder(Path.Combine("temp", TestName))) { Assert.IsTrue(b.Build(proj), "Build should have succeeded."); } }
DotNetCLI CreateDotNetBuilder(XASdkProject project) { var relativeProjDir = Path.Combine("temp", TestName); var fullProjDir = Path.Combine(Root, relativeProjDir); TestOutputDirectories [TestContext.CurrentContext.Test.ID] = fullProjDir; var files = project.Save(); project.Populate(relativeProjDir, files); project.CopyNuGetConfig(relativeProjDir); return(new DotNetCLI(project, Path.Combine(fullProjDir, project.ProjectFilePath))); }
DotNetCLI CreateDotNetBuilder(XASdkProject project, string relativeProjectDir = null) { if (string.IsNullOrEmpty(relativeProjectDir)) { relativeProjectDir = Path.Combine("temp", TestName); } TestOutputDirectories [TestContext.CurrentContext.Test.ID] = FullProjectDirectory = Path.Combine(Root, relativeProjectDir); var files = project.Save(); project.Populate(relativeProjectDir, files); project.CopyNuGetConfig(relativeProjectDir); return(new DotNetCLI(project, Path.Combine(FullProjectDirectory, project.ProjectFilePath))); }
public void DotNetPack([Values("net6.0-android", "net6.0-android30")] string targetFramework) { var proj = new XASdkProject(outputType: "Library") { TargetFramework = targetFramework, IsRelease = true, Sources = { new BuildItem.Source("Foo.cs") { TextContent = () => "public class Foo { }", } } }; proj.OtherBuildItems.Add(new AndroidItem.AndroidResource("Resources\\raw\\bar.txt") { BinaryContent = () => Array.Empty <byte> (), }); proj.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("sub\\directory\\foo.jar") { BinaryContent = () => ResourceData.JavaSourceJarTestJar, }); proj.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("sub\\directory\\arm64-v8a\\libfoo.so") { BinaryContent = () => Array.Empty <byte> (), }); proj.OtherBuildItems.Add(new AndroidItem.AndroidNativeLibrary(default(Func <string>)) { Update = () => "libfoo.so", MetadataValues = "Link=x86\\libfoo.so", BinaryContent = () => Array.Empty <byte> (), }); var dotnet = CreateDotNetBuilder(proj); Assert.IsTrue(dotnet.Pack(), "`dotnet pack` should succeed"); var nupkgPath = Path.Combine(FullProjectDirectory, proj.OutputPath, "..", $"{proj.ProjectName}.1.0.0.nupkg"); FileAssert.Exists(nupkgPath); using (var nupkg = ZipHelper.OpenZip(nupkgPath)) { nupkg.AssertContainsEntry(nupkgPath, $"lib/net6.0-android30.0/{proj.ProjectName}.dll"); nupkg.AssertContainsEntry(nupkgPath, $"lib/net6.0-android30.0/{proj.ProjectName}.aar"); } }
public void DotNetPack() { var proj = new XASdkProject(outputType: "Library") { IsRelease = true, Sources = { new BuildItem.Source("Foo.cs") { TextContent = () => "public class Foo { }", } } }; proj.OtherBuildItems.Add(new AndroidItem.AndroidResource("Resources\\raw\\bar.txt") { BinaryContent = () => Array.Empty <byte> (), }); proj.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("sub\\directory\\foo.jar") { BinaryContent = () => Convert.FromBase64String(InlineData.JavaClassesJarBase64), }); proj.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("sub\\directory\\arm64-v8a\\libfoo.so") { BinaryContent = () => Array.Empty <byte> (), }); proj.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("libfoo.so") { MetadataValues = "Link=x86\\libfoo.so", BinaryContent = () => Array.Empty <byte> (), }); var dotnet = CreateDotNetBuilder(proj); Assert.IsTrue(dotnet.Pack(), "`dotnet pack` should succeed"); var nupkgPath = Path.Combine(FullProjectDirectory, proj.OutputPath, "..", $"{proj.ProjectName}.1.0.0.nupkg"); FileAssert.Exists(nupkgPath); using (var nupkg = ZipHelper.OpenZip(nupkgPath)) { // TODO: should eventually be $"lib/net5.0-android/{proj.ProjectName}.dll" // See: https://github.com/dotnet/sdk/issues/14042 nupkg.AssertContainsEntry(nupkgPath, $"lib/net5.0/{proj.ProjectName}.dll"); nupkg.AssertContainsEntry(nupkgPath, $"lib/net5.0-android/{proj.ProjectName}.aar"); } }
public void DotNetBuild(string runtimeIdentifier, bool isRelease) { var abi = MonoAndroidHelper.RuntimeIdentifierToAbi(runtimeIdentifier); var proj = new XASdkProject { IsRelease = isRelease }; proj.OtherBuildItems.Add(new AndroidItem.InputJar("javaclasses.jar") { BinaryContent = () => Convert.FromBase64String(InlineData.JavaClassesJarBase64) }); // TODO: bring back when Xamarin.Android.Bindings.Documentation.targets is working //proj.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javasources.jar") { // BinaryContent = () => Convert.FromBase64String (InlineData.JavaSourcesJarBase64) //}); proj.SetProperty(KnownProperties.RuntimeIdentifier, runtimeIdentifier); var dotnet = CreateDotNetBuilder(proj); Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed"); // TODO: run for release once illink warnings are gone // context: https://github.com/xamarin/xamarin-android/issues/4708 if (!isRelease) { Assert.IsTrue(StringAssertEx.ContainsText(dotnet.LastBuildOutput, " 0 Warning(s)"), "Should have no MSBuild warnings."); } var outputPath = Path.Combine(Root, dotnet.ProjectDirectory, proj.OutputPath, runtimeIdentifier); var assemblyPath = Path.Combine(outputPath, "UnnamedProject.dll"); FileAssert.Exists(assemblyPath); using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) { var typeName = "Com.Xamarin.Android.Test.Msbuildtest.JavaSourceJarTest"; var type = assembly.MainModule.GetType(typeName); Assert.IsNotNull(type, $"{assemblyPath} should contain {typeName}"); } var apk = Path.Combine(outputPath, "UnnamedProject.UnnamedProject.apk"); FileAssert.Exists(apk); using (var zip = ZipHelper.OpenZip(apk)) { Assert.IsTrue(zip.ContainsEntry($"lib/{abi}/libmonodroid.so"), "libmonodroid.so should exist."); Assert.IsTrue(zip.ContainsEntry($"lib/{abi}/libmonosgen-2.0.so"), "libmonosgen-2.0.so should exist."); } }
public void DotNetLibraryAarChanges() { var proj = new XASdkProject(outputType: "Library"); proj.Sources.Add(new AndroidItem.AndroidResource("Resources\\raw\\foo.txt") { TextContent = () => "foo", }); proj.Sources.Add(new AndroidItem.AndroidResource("Resources\\raw\\bar.txt") { TextContent = () => "bar", }); var dotnet = CreateDotNetBuilder(proj); Assert.IsTrue(dotnet.Build(), "first build should succeed"); var aarPath = Path.Combine(FullProjectDirectory, proj.OutputPath, $"{proj.ProjectName}.aar"); FileAssert.Exists(aarPath); using (var aar = ZipHelper.OpenZip(aarPath)) { aar.AssertEntryContents(aarPath, "res/raw/foo.txt", contents: "foo"); aar.AssertEntryContents(aarPath, "res/raw/bar.txt", contents: "bar"); } // Change res/raw/bar.txt contents WaitFor(1000); var bar_txt = Path.Combine(FullProjectDirectory, "Resources", "raw", "bar.txt"); File.WriteAllText(bar_txt, contents: "baz"); Assert.IsTrue(dotnet.Build(), "second build should succeed"); FileAssert.Exists(aarPath); using (var aar = ZipHelper.OpenZip(aarPath)) { aar.AssertEntryContents(aarPath, "res/raw/foo.txt", contents: "foo"); aar.AssertEntryContents(aarPath, "res/raw/bar.txt", contents: "baz"); } // Delete res/raw/bar.txt File.Delete(bar_txt); Assert.IsTrue(dotnet.Build(), "third build should succeed"); FileAssert.Exists(aarPath); using (var aar = ZipHelper.OpenZip(aarPath)) { aar.AssertEntryContents(aarPath, "res/raw/foo.txt", contents: "foo"); aar.AssertDoesNotContainEntry(aarPath, "res/raw/bar.txt"); } }
public void DotNetInstallAndRun([Values(false, true)] bool isRelease, [Values(false, true)] bool xamarinForms) { if (!HasDevices) { Assert.Ignore("Skipping Test. No devices available."); } XASdkProject proj; if (xamarinForms) { proj = new XamarinFormsXASdkProject(SdkVersion) { IsRelease = isRelease }; } else { proj = new XASdkProject(SdkVersion) { IsRelease = isRelease }; } proj.SetProperty(KnownProperties.AndroidSupportedAbis, DeviceAbi); proj.SetRuntimeIdentifier(DeviceAbi); var relativeProjDir = Path.Combine("temp", TestName); var fullProjDir = Path.Combine(Root, relativeProjDir); TestOutputDirectories [TestContext.CurrentContext.Test.ID] = fullProjDir; var files = proj.Save(); proj.Populate(relativeProjDir, files); proj.CopyNuGetConfig(relativeProjDir); var dotnet = new DotNetCLI(proj, Path.Combine(fullProjDir, proj.ProjectFilePath)); Assert.IsTrue(dotnet.Run(), "`dotnet run` should succeed"); bool didLaunch = WaitForActivityToStart(proj.PackageName, "MainActivity", Path.Combine(fullProjDir, "logcat.log"), 30); RunAdbCommand($"uninstall {proj.PackageName}"); Assert.IsTrue(didLaunch, "Activity should have started."); }
public void DotNetPackageXASdkProject([Values(false, true)] bool isRelease) { var proj = new XASdkProject("0.0.1") { IsRelease = isRelease }; var relativeProjDir = Path.Combine("temp", TestName); var fullProjDir = Path.Combine(Root, relativeProjDir); TestOutputDirectories [TestContext.CurrentContext.Test.ID] = fullProjDir; var files = proj.Save(); proj.Populate(relativeProjDir, files); proj.CopyNuGetConfig(relativeProjDir); var dotnet = new DotNetCLI(); Assert.IsTrue(dotnet.Build(Path.Combine(fullProjDir, proj.ProjectFilePath), proj.Configuration, "SignAndroidPackage")); }
public void DotNetInstallAndRun(bool isRelease, bool xamarinForms, bool?publishTrimmed) { AssertHasDevices(); XASdkProject proj; if (xamarinForms) { proj = new XamarinFormsXASdkProject { IsRelease = isRelease }; } else { proj = new XASdkProject { IsRelease = isRelease }; } if (publishTrimmed != null) { proj.SetProperty(KnownProperties.PublishTrimmed, publishTrimmed.ToString()); } proj.SetRuntimeIdentifier(DeviceAbi); var relativeProjDir = Path.Combine("temp", TestName); var fullProjDir = Path.Combine(Root, relativeProjDir); TestOutputDirectories [TestContext.CurrentContext.Test.ID] = fullProjDir; var files = proj.Save(); proj.Populate(relativeProjDir, files); proj.CopyNuGetConfig(relativeProjDir); var dotnet = new DotNetCLI(proj, Path.Combine(fullProjDir, proj.ProjectFilePath)); Assert.IsTrue(dotnet.Run(), "`dotnet run` should succeed"); WaitForPermissionActivity(Path.Combine(Root, dotnet.ProjectDirectory, "permission-logcat.log")); bool didLaunch = WaitForActivityToStart(proj.PackageName, "MainActivity", Path.Combine(fullProjDir, "logcat.log"), 30); RunAdbCommand($"uninstall {proj.PackageName}"); Assert.IsTrue(didLaunch, "Activity should have started."); }
string PrepareProject(string testName) { string tempRoot = Path.Combine(TestOutputDir, testName, XABuildPaths.Configuration); string temporaryProjectPath = Path.Combine(tempRoot, "project"); var ignore = new HashSet <string> { Path.Combine(TestProjectRootDirectory, "bin"), Path.Combine(TestProjectRootDirectory, "obj"), Path.Combine(CommonSampleLibraryRootDirectory, "bin"), Path.Combine(CommonSampleLibraryRootDirectory, "obj"), }; CopyRecursively(TestProjectRootDirectory, temporaryProjectPath, ignore); CopyRecursively(CommonSampleLibraryRootDirectory, Path.Combine(tempRoot, CommonSampleLibraryName), ignore); if (Builder.UseDotNet) { XASdkProject.SaveNuGetConfig(tempRoot); } return(temporaryProjectPath); }
public void MauiTargetFramework([Values("net6.0-android", "net6.0-android30", "net6.0-android30.0")] string targetFramework) { var library = new XASdkProject(outputType: "Library") { TargetFramework = targetFramework, }; library.ExtraNuGetConfigSources.Add("https://pkgs.dev.azure.com/azure-public/vside/_packaging/xamarin-impl/nuget/v3/index.json"); library.Sources.Clear(); library.Sources.Add(new BuildItem.Source("Foo.cs") { TextContent = () => @"using Microsoft.Maui; using Microsoft.Maui.Handlers; public abstract class Foo<TVirtualView, TNativeView> : AbstractViewHandler<TVirtualView, TNativeView> where TVirtualView : class, IView #if ANDROID where TNativeView : Android.Views.View #else where TNativeView : class #endif { protected Foo (PropertyMapper mapper) : base(mapper) { #if ANDROID var t = this.Context; #endif } }", }); library.PackageReferences.Add(new Package { Id = "Microsoft.Maui.Core", Version = "6.0.100-preview.3.269" }); var dotnet = CreateDotNetBuilder(library); Assert.IsTrue(dotnet.Build(), $"{library.ProjectName} should succeed"); dotnet.AssertHasNoWarnings(); }
public void DotNetBuildBinding() { var proj = new XASdkProject(outputType: "Library"); // Both transform files should be applied proj.Sources.Add(new AndroidItem.TransformFile("Transforms.xml") { TextContent = () => @"<metadata> <attr path=""/api/package[@name='com.xamarin.android.test.msbuildtest']"" name=""managedName"">FooBar</attr> </metadata>", }); proj.Sources.Add(new AndroidItem.TransformFile("Transforms\\Metadata.xml") { TextContent = () => @"<metadata> <attr path=""/api/package[@managedName='FooBar']"" name=""managedName"">MSBuildTest</attr> </metadata>", }); proj.Sources.Add(new AndroidItem.AndroidLibrary("javaclasses.jar") { BinaryContent = () => ResourceData.JavaSourceJarTestJar, }); proj.OtherBuildItems.Add(new BuildItem("JavaSourceJar", "javaclasses-sources.jar") { BinaryContent = () => ResourceData.JavaSourceJarTestSourcesJar, }); var dotnet = CreateDotNetBuilder(proj); Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed"); var assemblyPath = Path.Combine(FullProjectDirectory, proj.OutputPath, "UnnamedProject.dll"); FileAssert.Exists(assemblyPath); using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) { var typeName = "MSBuildTest.JavaSourceJarTest"; var type = assembly.MainModule.GetType(typeName); Assert.IsNotNull(type, $"{assemblyPath} should contain {typeName}"); } }
public void DotNetIncremental() { // Setup dependencies App A -> Lib B var path = Path.Combine("temp", TestName); var libB = new XASdkProject(outputType: "Library") { ProjectName = "LibraryB" }; libB.Sources.Clear(); libB.Sources.Add(new BuildItem.Source("Foo.cs") { TextContent = () => "public class Foo { }", }); // Will save the project, does not need to build it CreateDotNetBuilder(libB, Path.Combine(path, libB.ProjectName)); var appA = new XASdkProject { ProjectName = "AppA", Sources = { new BuildItem.Source("Bar.cs") { TextContent = () => "public class Bar : Foo { }", } } }; appA.AddReference(libB); var appBuilder = CreateDotNetBuilder(appA, Path.Combine(path, appA.ProjectName)); Assert.IsTrue(appBuilder.Build(), $"{appA.ProjectName} should succeed"); appBuilder.AssertTargetIsNotSkipped("CoreCompile"); // Build again, no changes Assert.IsTrue(appBuilder.Build(), $"{appA.ProjectName} should succeed"); appBuilder.AssertTargetIsSkipped("CoreCompile"); }
public void DotNetBuildLibrary([Values(false, true)] bool isRelease) { var proj = new XASdkProject(outputType: "Library") { IsRelease = isRelease }; var dotnet = CreateDotNetBuilder(proj); Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed"); var assemblyPath = Path.Combine(Root, dotnet.ProjectDirectory, proj.OutputPath, "UnnamedProject.dll"); FileAssert.Exists(assemblyPath); using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) { var resourceName = "__AndroidLibraryProjects__.zip"; var resource = assembly.MainModule.Resources.OfType <EmbeddedResource> ().FirstOrDefault(r => r.Name == resourceName); Assert.IsNotNull(resource, $"{assemblyPath} should contain a {resourceName} EmbeddedResource"); using (var zip = ZipArchive.Open(resource.GetResourceStream())) { var entry = "library_project_imports/res/values/strings.xml"; Assert.IsTrue(zip.ContainsEntry(entry), $"{resourceName} should contain {entry}"); } } }
public void DefaultItems() { void CreateEmptyFile(params string [] paths) { var path = Path.Combine(FullProjectDirectory, Path.Combine(paths)); Directory.CreateDirectory(Path.GetDirectoryName(path)); File.WriteAllText(path, contents: ""); } var proj = new XASdkProject(); var dotnet = CreateDotNetBuilder(proj); // Build error -> no nested sub-directories in Resources CreateEmptyFile("Resources", "drawable", "foo", "bar.png"); CreateEmptyFile("Resources", "raw", "foo", "bar.png"); // Build error -> no files/directories that start with . CreateEmptyFile("Resources", "raw", ".DS_Store"); CreateEmptyFile("Assets", ".DS_Store"); CreateEmptyFile("Assets", ".svn", "foo.txt"); // Files that should work CreateEmptyFile("Resources", "raw", "foo.txt"); CreateEmptyFile("Assets", "foo", "bar.txt"); Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed"); var apkPath = Path.Combine(FullProjectDirectory, proj.OutputPath, $"{proj.PackageName}.apk"); FileAssert.Exists(apkPath); using (var apk = ZipHelper.OpenZip(apkPath)) { apk.AssertContainsEntry(apkPath, "res/raw/foo.txt"); apk.AssertContainsEntry(apkPath, "assets/foo/bar.txt"); } }
public void DotNetBuild(string runtimeIdentifiers, bool isRelease) { var proj = new XASdkProject { IsRelease = isRelease, Sources = { new BuildItem("EmbeddedResource", "Foo.resx") { TextContent = () => InlineData.ResxWithContents("<data name=\"CancelButton\"><value>Cancel</value></data>") }, new BuildItem("EmbeddedResource", "Foo.es.resx") { TextContent = () => InlineData.ResxWithContents("<data name=\"CancelButton\"><value>Cancelar</value></data>") }, } }; proj.OtherBuildItems.Add(new AndroidItem.InputJar("javaclasses.jar") { BinaryContent = () => ResourceData.JavaSourceJarTestJar, }); proj.OtherBuildItems.Add(new BuildItem("JavaSourceJar", "javaclasses-sources.jar") { BinaryContent = () => ResourceData.JavaSourceJarTestSourcesJar, }); if (!runtimeIdentifiers.Contains(";")) { proj.SetProperty(KnownProperties.RuntimeIdentifier, runtimeIdentifiers); } else { proj.SetProperty(KnownProperties.RuntimeIdentifiers, runtimeIdentifiers); } var dotnet = CreateDotNetBuilder(proj); Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed"); // TODO: run for release once illink warnings are gone // context: https://github.com/xamarin/xamarin-android/issues/4708 if (!isRelease) { Assert.IsTrue(StringAssertEx.ContainsText(dotnet.LastBuildOutput, " 0 Warning(s)"), "Should have no MSBuild warnings."); } var outputPath = Path.Combine(FullProjectDirectory, proj.OutputPath); if (!runtimeIdentifiers.Contains(";")) { outputPath = Path.Combine(outputPath, runtimeIdentifiers); } var files = Directory.EnumerateFileSystemEntries(outputPath) .Select(Path.GetFileName) .OrderBy(f => f) .ToArray(); var expectedFiles = new[] { "es", $"{proj.ProjectName}.dll", $"{proj.ProjectName}.pdb", $"{proj.PackageName}.apk", $"{proj.PackageName}-Signed.apk", $"{proj.ProjectName}.xml", }; CollectionAssert.AreEqual(expectedFiles, files, $"Expected: {string.Join (";", expectedFiles)}\n Found: {string.Join (";", files)}"); var assemblyPath = Path.Combine(outputPath, $"{proj.ProjectName}.dll"); FileAssert.Exists(assemblyPath); using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) { var typeName = "Com.Xamarin.Android.Test.Msbuildtest.JavaSourceJarTest"; var type = assembly.MainModule.GetType(typeName); Assert.IsNotNull(type, $"{assemblyPath} should contain {typeName}"); } bool expectEmbeddedAssembies = !(CommercialBuildAvailable && !isRelease); var apkPath = Path.Combine(outputPath, "UnnamedProject.UnnamedProject.apk"); FileAssert.Exists(apkPath); using (var apk = ZipHelper.OpenZip(apkPath)) { apk.AssertContainsEntry(apkPath, $"assemblies/{proj.ProjectName}.dll", shouldContainEntry: expectEmbeddedAssembies); apk.AssertContainsEntry(apkPath, $"assemblies/{proj.ProjectName}.pdb", shouldContainEntry: !CommercialBuildAvailable && !isRelease); apk.AssertContainsEntry(apkPath, $"assemblies/System.Linq.dll", shouldContainEntry: expectEmbeddedAssembies); apk.AssertContainsEntry(apkPath, $"assemblies/es/{proj.ProjectName}.resources.dll", shouldContainEntry: expectEmbeddedAssembies); var rids = runtimeIdentifiers.Split(';'); foreach (var abi in rids.Select(AndroidRidAbiHelper.RuntimeIdentifierToAbi)) { apk.AssertContainsEntry(apkPath, $"lib/{abi}/libmonodroid.so"); apk.AssertContainsEntry(apkPath, $"lib/{abi}/libmonosgen-2.0.so"); if (rids.Length > 1) { apk.AssertContainsEntry(apkPath, $"assemblies/{abi}/System.Private.CoreLib.dll", shouldContainEntry: expectEmbeddedAssembies); } else { apk.AssertContainsEntry(apkPath, "assemblies/System.Private.CoreLib.dll", shouldContainEntry: expectEmbeddedAssembies); } } } }
public void DotNetBuildLibrary(bool isRelease, bool duplicateAar) { var path = Path.Combine("temp", TestName); var env_var = "MY_ENVIRONMENT_VAR"; var env_val = "MY_VALUE"; // Setup dependencies App A -> Lib B -> Lib C var libC = new XASdkProject(outputType: "Library") { ProjectName = "LibraryC", IsRelease = isRelease, Sources = { new BuildItem.Source("Bar.cs") { TextContent = () => "public class Bar { }", } } }; libC.OtherBuildItems.Add(new AndroidItem.AndroidAsset("Assets\\bar\\bar.txt") { BinaryContent = () => Array.Empty <byte> (), }); var activity = libC.Sources.FirstOrDefault(s => s.Include() == "MainActivity.cs"); if (activity != null) { libC.Sources.Remove(activity); } var libCBuilder = CreateDotNetBuilder(libC, Path.Combine(path, libC.ProjectName)); Assert.IsTrue(libCBuilder.Build(), $"{libC.ProjectName} should succeed"); var libB = new XASdkProject(outputType: "Library") { ProjectName = "LibraryB", IsRelease = isRelease, Sources = { new BuildItem.Source("Foo.cs") { TextContent = () => "public class Foo : Bar { }", } } }; libB.OtherBuildItems.Add(new AndroidItem.AndroidAsset("Assets\\foo\\foo.txt") { BinaryContent = () => Array.Empty <byte> (), }); libB.OtherBuildItems.Add(new AndroidItem.AndroidResource("Resources\\layout\\MyLayout.axml") { TextContent = () => "<?xml version=\"1.0\" encoding=\"utf-8\" ?><LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\" />" }); libB.OtherBuildItems.Add(new AndroidItem.AndroidResource("Resources\\raw\\bar.txt") { BinaryContent = () => Array.Empty <byte> (), }); libB.OtherBuildItems.Add(new AndroidItem.AndroidEnvironment("env.txt") { TextContent = () => $"{env_var}={env_val}", }); libB.OtherBuildItems.Add(new AndroidItem.AndroidEnvironment("sub\\directory\\env.txt") { TextContent = () => $"{env_var}={env_val}", }); libB.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("sub\\directory\\foo.jar") { BinaryContent = () => Convert.FromBase64String(InlineData.JavaClassesJarBase64), }); libB.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("sub\\directory\\arm64-v8a\\libfoo.so") { BinaryContent = () => Array.Empty <byte> (), }); libB.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("libfoo.so") { MetadataValues = "Link=x86\\libfoo.so", BinaryContent = () => Array.Empty <byte> (), }); libB.AddReference(libC); activity = libB.Sources.FirstOrDefault(s => s.Include() == "MainActivity.cs"); if (activity != null) { libB.Sources.Remove(activity); } var libBBuilder = CreateDotNetBuilder(libB, Path.Combine(path, libB.ProjectName)); Assert.IsTrue(libBBuilder.Build(), $"{libB.ProjectName} should succeed"); // Check .aar file for class library var aarPath = Path.Combine(FullProjectDirectory, libB.OutputPath, $"{libB.ProjectName}.aar"); FileAssert.Exists(aarPath); using (var aar = ZipHelper.OpenZip(aarPath)) { aar.AssertContainsEntry(aarPath, "assets/foo/foo.txt"); aar.AssertContainsEntry(aarPath, "res/layout/mylayout.xml"); aar.AssertContainsEntry(aarPath, "res/raw/bar.txt"); aar.AssertContainsEntry(aarPath, ".net/__res_name_case_map.txt"); aar.AssertContainsEntry(aarPath, ".net/env/190E30B3D205731E.env"); aar.AssertContainsEntry(aarPath, ".net/env/2CBDAB7FEEA94B19.env"); aar.AssertContainsEntry(aarPath, "libs/A1AFA985571E728E.jar"); aar.AssertContainsEntry(aarPath, "jni/arm64-v8a/libfoo.so"); aar.AssertContainsEntry(aarPath, "jni/x86/libfoo.so"); } // Check EmbeddedResource files do not exist var assemblyPath = Path.Combine(FullProjectDirectory, libB.OutputPath, $"{libB.ProjectName}.dll"); FileAssert.Exists(assemblyPath); using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) { Assert.AreEqual(0, assembly.MainModule.Resources.Count); } var appA = new XASdkProject { ProjectName = "AppA", IsRelease = isRelease, Sources = { new BuildItem.Source("Bar.cs") { TextContent = () => "public class Bar : Foo { }", } } }; appA.AddReference(libB); if (duplicateAar) { // Test a duplicate @(AndroidLibrary) item with the same path of LibraryB.aar appA.OtherBuildItems.Add(new AndroidItem.AndroidLibrary(aarPath)); } var appBuilder = CreateDotNetBuilder(appA, Path.Combine(path, appA.ProjectName)); Assert.IsTrue(appBuilder.Build(), $"{appA.ProjectName} should succeed"); // Check .apk for assets, res, and native libraries var apkPath = Path.Combine(FullProjectDirectory, appA.OutputPath, $"{appA.PackageName}.apk"); FileAssert.Exists(apkPath); using (var apk = ZipHelper.OpenZip(apkPath)) { apk.AssertContainsEntry(apkPath, "assets/foo/foo.txt"); apk.AssertContainsEntry(apkPath, "assets/bar/bar.txt"); apk.AssertContainsEntry(aarPath, "res/layout/mylayout.xml"); apk.AssertContainsEntry(apkPath, "res/raw/bar.txt"); apk.AssertContainsEntry(apkPath, "lib/arm64-v8a/libfoo.so"); apk.AssertContainsEntry(apkPath, "lib/x86/libfoo.so"); } // Check classes.dex contains foo.jar var intermediate = Path.Combine(FullProjectDirectory, appA.IntermediateOutputPath); var dexFile = Path.Combine(intermediate, "android", "bin", "classes.dex"); FileAssert.Exists(dexFile); string className = "Lcom/xamarin/android/test/msbuildtest/JavaSourceJarTest;"; Assert.IsTrue(DexUtils.ContainsClass(className, dexFile, AndroidSdkPath), $"`{dexFile}` should include `{className}`!"); // Check environment variable var environmentFiles = EnvironmentHelper.GatherEnvironmentFiles(intermediate, "x86", required: true); var environmentVariables = EnvironmentHelper.ReadEnvironmentVariables(environmentFiles); Assert.IsTrue(environmentVariables.TryGetValue(env_var, out string actual), $"Environment should contain {env_var}"); Assert.AreEqual(env_val, actual, $"{env_var} should be {env_val}"); // Check Resource.designer.cs var resource_designer_cs = Path.Combine(intermediate, "Resource.designer.cs"); FileAssert.Exists(resource_designer_cs); var resource_designer_text = File.ReadAllText(resource_designer_cs); StringAssert.Contains("public const int MyLayout", resource_designer_text); }
public void DotNetBuild(string runtimeIdentifiers, bool isRelease) { var proj = new XASdkProject { IsRelease = isRelease }; proj.OtherBuildItems.Add(new AndroidItem.InputJar("javaclasses.jar") { BinaryContent = () => Convert.FromBase64String(InlineData.JavaClassesJarBase64) }); // TODO: bring back when Xamarin.Android.Bindings.Documentation.targets is working //proj.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javasources.jar") { // BinaryContent = () => Convert.FromBase64String (InlineData.JavaSourcesJarBase64) //}); if (!runtimeIdentifiers.Contains(";")) { proj.SetProperty(KnownProperties.RuntimeIdentifier, runtimeIdentifiers); } else { proj.SetProperty(KnownProperties.RuntimeIdentifiers, runtimeIdentifiers); } var dotnet = CreateDotNetBuilder(proj); Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed"); // TODO: run for release once illink warnings are gone // context: https://github.com/xamarin/xamarin-android/issues/4708 if (!isRelease) { Assert.IsTrue(StringAssertEx.ContainsText(dotnet.LastBuildOutput, " 0 Warning(s)"), "Should have no MSBuild warnings."); } var outputPath = Path.Combine(FullProjectDirectory, proj.OutputPath); if (!runtimeIdentifiers.Contains(";")) { outputPath = Path.Combine(outputPath, runtimeIdentifiers); } var files = Directory.EnumerateFileSystemEntries(outputPath) .Select(Path.GetFileName) .OrderBy(f => f) .ToArray(); CollectionAssert.AreEqual(new [] { $"{proj.ProjectName}.dll", $"{proj.ProjectName}.pdb", $"{proj.PackageName}.apk", $"{proj.PackageName}-Signed.apk", }, files); var assemblyPath = Path.Combine(outputPath, $"{proj.ProjectName}.dll"); FileAssert.Exists(assemblyPath); using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) { var typeName = "Com.Xamarin.Android.Test.Msbuildtest.JavaSourceJarTest"; var type = assembly.MainModule.GetType(typeName); Assert.IsNotNull(type, $"{assemblyPath} should contain {typeName}"); } bool expectEmbeddedAssembies = !(CommercialBuildAvailable && !isRelease); var apkPath = Path.Combine(outputPath, "UnnamedProject.UnnamedProject.apk"); FileAssert.Exists(apkPath); using (var apk = ZipHelper.OpenZip(apkPath)) { apk.AssertContainsEntry(apkPath, $"assemblies/{proj.ProjectName}.dll", shouldContainEntry: expectEmbeddedAssembies); apk.AssertContainsEntry(apkPath, $"assemblies/{proj.ProjectName}.pdb", shouldContainEntry: !CommercialBuildAvailable && !isRelease); apk.AssertContainsEntry(apkPath, $"assemblies/System.Linq.dll", shouldContainEntry: expectEmbeddedAssembies); var rids = runtimeIdentifiers.Split(';'); foreach (var abi in rids.Select(MonoAndroidHelper.RuntimeIdentifierToAbi)) { apk.AssertContainsEntry(apkPath, $"lib/{abi}/libmonodroid.so"); apk.AssertContainsEntry(apkPath, $"lib/{abi}/libmonosgen-2.0.so"); if (rids.Length > 1) { apk.AssertContainsEntry(apkPath, $"assemblies/{abi}/System.Private.CoreLib.dll", shouldContainEntry: expectEmbeddedAssembies); apk.AssertContainsEntry(apkPath, $"assemblies/{abi}/System.Collections.Concurrent.dll", shouldContainEntry: expectEmbeddedAssembies); } else { apk.AssertContainsEntry(apkPath, "assemblies/System.Private.CoreLib.dll", shouldContainEntry: expectEmbeddedAssembies); apk.AssertContainsEntry(apkPath, "assemblies/System.Collections.Concurrent.dll", shouldContainEntry: expectEmbeddedAssembies); } } } }
public void DotNetDebug() { AssertCommercialBuild(); AssertHasDevices(); XASdkProject proj; proj = new XASdkProject { //TODO: targetSdkVersion="30" causes a crash on startup in .NET 5 MinSdkVersion = null, TargetSdkVersion = null, }; proj.SetRuntimeIdentifier(DeviceAbi); var relativeProjDir = Path.Combine("temp", TestName); var fullProjDir = Path.Combine(Root, relativeProjDir); TestOutputDirectories [TestContext.CurrentContext.Test.ID] = fullProjDir; var files = proj.Save(); proj.Populate(relativeProjDir, files); proj.CopyNuGetConfig(relativeProjDir); var dotnet = new DotNetCLI(proj, Path.Combine(fullProjDir, proj.ProjectFilePath)); Assert.IsTrue(dotnet.Build("Install"), "`dotnet build` should succeed"); bool breakpointHit = false; ManualResetEvent resetEvent = new ManualResetEvent(false); var sw = new Stopwatch(); // setup the debugger var session = new SoftDebuggerSession(); session.Breakpoints = new BreakpointStore { { Path.Combine(Root, dotnet.ProjectDirectory, "MainActivity.cs"), 19 }, }; session.TargetHitBreakpoint += (sender, e) => { Console.WriteLine($"BREAK {e.Type}"); breakpointHit = true; session.Continue(); }; var rnd = new Random(); int port = rnd.Next(10000, 20000); TestContext.Out.WriteLine($"{port}"); var args = new SoftDebuggerConnectArgs("", IPAddress.Loopback, port) { MaxConnectionAttempts = 10, }; var startInfo = new SoftDebuggerStartInfo(args) { WorkingDirectory = Path.Combine(dotnet.ProjectDirectory, proj.IntermediateOutputPath, "android", "assets"), }; var options = new DebuggerSessionOptions() { EvaluationOptions = EvaluationOptions.DefaultOptions, }; options.EvaluationOptions.UseExternalTypeResolver = true; ClearAdbLogcat(); Assert.True(dotnet.Build("Run", new string [] { $"AndroidSdbTargetPort={port}", $"AndroidSdbHostPort={port}", "AndroidAttachDebugger=True", }), "Project should have run."); Assert.IsTrue(WaitForDebuggerToStart(Path.Combine(Root, dotnet.ProjectDirectory, "logcat.log")), "Activity should have started"); // we need to give a bit of time for the debug server to start up. WaitFor(2000); session.LogWriter += (isStderr, text) => { Console.WriteLine(text); }; session.OutputWriter += (isStderr, text) => { Console.WriteLine(text); }; session.DebugWriter += (level, category, message) => { Console.WriteLine(message); }; session.Run(startInfo, options); WaitFor(TimeSpan.FromSeconds(30), () => session.IsConnected); Assert.True(session.IsConnected, "Debugger should have connected but it did not."); // we need to wait here for a while to allow the breakpoints to hit // but we need to timeout TimeSpan timeout = TimeSpan.FromSeconds(60); while (session.IsConnected && !breakpointHit && timeout >= TimeSpan.Zero) { Thread.Sleep(10); timeout = timeout.Subtract(TimeSpan.FromMilliseconds(10)); } WaitFor(2000); Assert.IsTrue(breakpointHit, "Should have a breakpoint"); }
public void DotNetBuild(string runtimeIdentifiers, bool isRelease) { var proj = new XASdkProject { IsRelease = isRelease, ExtraNuGetConfigSources = { "https://pkgs.dev.azure.com/azure-public/vside/_packaging/xamarin-impl/nuget/v3/index.json" }, PackageReferences = { new Package { Id = "Xamarin.AndroidX.AppCompat", Version = "1.2.0.7-net6preview01" }, new Package { Id = "Microsoft.AspNetCore.Components.WebView", Version = "6.0.0-preview.5.21301.17" }, new Package { Id = "Microsoft.Extensions.FileProviders.Embedded", Version = "6.0.0-preview.6.21306.3" }, new Package { Id = "Microsoft.JSInterop", Version = "6.0.0-preview.6.21306.3" }, new Package { Id = "System.Text.Json", Version = "6.0.0-preview.7.21323.3" }, }, Sources = { new BuildItem("EmbeddedResource", "Foo.resx") { TextContent = () => InlineData.ResxWithContents("<data name=\"CancelButton\"><value>Cancel</value></data>") }, new BuildItem("EmbeddedResource", "Foo.es.resx") { TextContent = () => InlineData.ResxWithContents("<data name=\"CancelButton\"><value>Cancelar</value></data>") }, } }; proj.MainActivity = proj.DefaultMainActivity.Replace(": Activity", ": AndroidX.AppCompat.App.AppCompatActivity"); proj.OtherBuildItems.Add(new AndroidItem.InputJar("javaclasses.jar") { BinaryContent = () => ResourceData.JavaSourceJarTestJar, }); proj.OtherBuildItems.Add(new BuildItem("JavaSourceJar", "javaclasses-sources.jar") { BinaryContent = () => ResourceData.JavaSourceJarTestSourcesJar, }); if (!runtimeIdentifiers.Contains(";")) { proj.SetProperty(KnownProperties.RuntimeIdentifier, runtimeIdentifiers); } else { proj.SetProperty(KnownProperties.RuntimeIdentifiers, runtimeIdentifiers); } var dotnet = CreateDotNetBuilder(proj); Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed"); dotnet.AssertHasNoWarnings(); var outputPath = Path.Combine(FullProjectDirectory, proj.OutputPath); var intermediateOutputPath = Path.Combine(FullProjectDirectory, proj.IntermediateOutputPath); if (!runtimeIdentifiers.Contains(";")) { outputPath = Path.Combine(outputPath, runtimeIdentifiers); intermediateOutputPath = Path.Combine(intermediateOutputPath, runtimeIdentifiers); } var files = Directory.EnumerateFileSystemEntries(outputPath) .Select(Path.GetFileName) .OrderBy(f => f) .ToArray(); var expectedFiles = new[] { $"{proj.PackageName}.apk", $"{proj.PackageName}-Signed.apk", "es", $"{proj.ProjectName}.dll", $"{proj.ProjectName}.pdb", $"{proj.ProjectName}.runtimeconfig.json", $"{proj.ProjectName}.xml", }; CollectionAssert.AreEqual(expectedFiles, files, $"Expected: {string.Join (";", expectedFiles)}\n Found: {string.Join (";", files)}"); var assemblyPath = Path.Combine(outputPath, $"{proj.ProjectName}.dll"); FileAssert.Exists(assemblyPath); using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) { var typeName = "Com.Xamarin.Android.Test.Msbuildtest.JavaSourceJarTest"; var type = assembly.MainModule.GetType(typeName); Assert.IsNotNull(type, $"{assemblyPath} should contain {typeName}"); } var rids = runtimeIdentifiers.Split(';'); if (isRelease) { // Check for stripped native libraries foreach (var rid in rids) { FileAssert.Exists(Path.Combine(intermediateOutputPath, "native", rid, "libmono-android.release.so")); FileAssert.Exists(Path.Combine(intermediateOutputPath, "native", rid, "libmonosgen-2.0.so")); } } bool expectEmbeddedAssembies = !(CommercialBuildAvailable && !isRelease); var apkPath = Path.Combine(outputPath, $"{proj.PackageName}.apk"); FileAssert.Exists(apkPath); using (var apk = ZipHelper.OpenZip(apkPath)) { apk.AssertContainsEntry(apkPath, $"assemblies/{proj.ProjectName}.dll", shouldContainEntry: expectEmbeddedAssembies); apk.AssertContainsEntry(apkPath, $"assemblies/{proj.ProjectName}.pdb", shouldContainEntry: !CommercialBuildAvailable && !isRelease); apk.AssertContainsEntry(apkPath, $"assemblies/System.Linq.dll", shouldContainEntry: expectEmbeddedAssembies); apk.AssertContainsEntry(apkPath, $"assemblies/es/{proj.ProjectName}.resources.dll", shouldContainEntry: expectEmbeddedAssembies); foreach (var abi in rids.Select(AndroidRidAbiHelper.RuntimeIdentifierToAbi)) { apk.AssertContainsEntry(apkPath, $"lib/{abi}/libmonodroid.so"); apk.AssertContainsEntry(apkPath, $"lib/{abi}/libmonosgen-2.0.so"); if (rids.Length > 1) { apk.AssertContainsEntry(apkPath, $"assemblies/{abi}/System.Private.CoreLib.dll", shouldContainEntry: expectEmbeddedAssembies); } else { apk.AssertContainsEntry(apkPath, "assemblies/System.Private.CoreLib.dll", shouldContainEntry: expectEmbeddedAssembies); } } } }
public void DotNetBuild(string runtimeIdentifiers, bool isRelease) { var proj = new XASdkProject { IsRelease = isRelease }; proj.OtherBuildItems.Add(new AndroidItem.InputJar("javaclasses.jar") { BinaryContent = () => Convert.FromBase64String(InlineData.JavaClassesJarBase64) }); // TODO: bring back when Xamarin.Android.Bindings.Documentation.targets is working //proj.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javasources.jar") { // BinaryContent = () => Convert.FromBase64String (InlineData.JavaSourcesJarBase64) //}); if (!runtimeIdentifiers.Contains(";")) { proj.SetProperty(KnownProperties.RuntimeIdentifier, runtimeIdentifiers); } else { proj.SetProperty(KnownProperties.RuntimeIdentifiers, runtimeIdentifiers); } var dotnet = CreateDotNetBuilder(proj); Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed"); // TODO: run for release once illink warnings are gone // context: https://github.com/xamarin/xamarin-android/issues/4708 if (!isRelease) { Assert.IsTrue(StringAssertEx.ContainsText(dotnet.LastBuildOutput, " 0 Warning(s)"), "Should have no MSBuild warnings."); } var outputPath = Path.Combine(FullProjectDirectory, proj.OutputPath); if (!runtimeIdentifiers.Contains(";")) { outputPath = Path.Combine(outputPath, runtimeIdentifiers); } // TODO: With workloads we don't control the import of Microsoft.NET.Sdk/Sdk.targets. // We can no longer change the default values of `$(GenerateDependencyFile)` and `$(ProduceReferenceAssembly)` as a result. // We should update Microsoft.NET.Sdk to default both of these properties to false when the `$(TargetPlatformIdentifier)` is "mobile" (Android, iOS, etc). // Alternatively, the workload concept could be updated to support some sort of `Before.Microsoft.NET.targets` hook. /* var files = Directory.EnumerateFileSystemEntries (outputPath) * .Select (Path.GetFileName) * .OrderBy (f => f); * CollectionAssert.AreEqual (new [] { * $"{proj.ProjectName}.dll", * $"{proj.ProjectName}.pdb", * $"{proj.PackageName}.apk", * $"{proj.PackageName}-Signed.apk", * }, files); */ var assemblyPath = Path.Combine(outputPath, $"{proj.ProjectName}.dll"); FileAssert.Exists(assemblyPath); using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) { var typeName = "Com.Xamarin.Android.Test.Msbuildtest.JavaSourceJarTest"; var type = assembly.MainModule.GetType(typeName); Assert.IsNotNull(type, $"{assemblyPath} should contain {typeName}"); } bool expectEmbeddedAssembies = !(CommercialBuildAvailable && !isRelease); var apkPath = Path.Combine(outputPath, "UnnamedProject.UnnamedProject.apk"); FileAssert.Exists(apkPath); using (var apk = ZipHelper.OpenZip(apkPath)) { var rids = runtimeIdentifiers.Split(';'); foreach (var abi in rids.Select(MonoAndroidHelper.RuntimeIdentifierToAbi)) { apk.AssertContainsEntry(apkPath, $"lib/{abi}/libmonodroid.so"); apk.AssertContainsEntry(apkPath, $"lib/{abi}/libmonosgen-2.0.so"); if (rids.Length > 1) { apk.AssertContainsEntry(apkPath, $"assemblies/{abi}/System.Private.CoreLib.dll", expectEmbeddedAssembies); } else { apk.AssertContainsEntry(apkPath, "assemblies/System.Private.CoreLib.dll", expectEmbeddedAssembies); } } } }