diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index 3ab15dc741e8..0423bed2998c 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -156,7 +156,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. - $(ProjectDir)$(OutputPath)$(AssemblyName).resources + $(OutputPath)$(AssemblyName).resources + + + + $(GenerateNuspecDependsOn); + _RemoveNativeManifestFromPack; + + + + + <_BuildOutputInPackage Remove="@(_BuildOutputInPackage)" Condition="'%(Filename)%(Extension)' == '$(_DeploymentTargetApplicationManifestFileName)'" /> + + + + + + $(TargetsForTfmSpecificContentInPackage);_IncludeBindingResourcesInNuGetPackage + + + + <_HasOldStyleBindingItems Condition="@(ObjcBindingNativeLibrary->Count()) > 0">true + + + + + + + + + + + <_AppleBindingResourceBasePath>$(TargetDir)$(TargetName).resources + + + + + <_AppleBindingResource Include="$(_AppleBindingResourceBasePath)\**\*" PackagePath="lib\$(_NuGetShortFolderName)\$(TargetName).resources" /> + + <_AppleBindingResource Include="$(_AppleBindingResourceBasePath).zip" PackagePath="lib\$(_NuGetShortFolderName)" Condition="Exists('$(_AppleBindingResourceBasePath).zip')" /> + + + + + + + + diff --git a/tests/common/DotNet.cs b/tests/common/DotNet.cs index fda216713643..8656f153819f 100644 --- a/tests/common/DotNet.cs +++ b/tests/common/DotNet.cs @@ -24,6 +24,18 @@ public static string Executable { } } + public static ExecutionResult AssertPack (string project, Dictionary properties = null) + { + return Execute ("pack", project, properties, true); + } + + public static ExecutionResult AssertPackFailure (string project, Dictionary properties = null) + { + var rv = Execute ("pack", project, properties, false); + Assert.AreNotEqual (0, rv.ExitCode, "Unexpected success"); + return rv; + } + public static ExecutionResult AssertPublish (string project, Dictionary properties = null) { return Execute ("publish", project, properties, true); @@ -75,6 +87,7 @@ public static ExecutionResult Execute (string verb, string project, Dictionary (); args.Add (verb); diff --git a/tests/dotnet/MyClassLibrary/MyClassLibrary.csproj b/tests/dotnet/MyClassLibrary/MyClassLibrary.csproj deleted file mode 100644 index 7af2c032af2f..000000000000 --- a/tests/dotnet/MyClassLibrary/MyClassLibrary.csproj +++ /dev/null @@ -1,6 +0,0 @@ - - - - net6.0-ios - - diff --git a/tests/dotnet/UnitTests/ApplePlatformExtensions.cs b/tests/dotnet/UnitTests/ApplePlatformExtensions.cs new file mode 100644 index 000000000000..cd6a7de30c73 --- /dev/null +++ b/tests/dotnet/UnitTests/ApplePlatformExtensions.cs @@ -0,0 +1,22 @@ +using System; + +namespace Xamarin.Utils { + public static class ApplePlatformExtensionsWithVersions { + public static string ToFrameworkWithDefaultVersion (this ApplePlatform @this) + { + var netVersion = "net6.0"; + switch (@this) { + case ApplePlatform.iOS: + return netVersion + "-ios" + SdkVersions.iOS; + case ApplePlatform.MacOSX: + return netVersion + "-macos" + SdkVersions.OSX; + case ApplePlatform.TVOS: + return netVersion + "-tvos" + SdkVersions.TVOS; + case ApplePlatform.MacCatalyst: + return netVersion + "-maccatalyst" + SdkVersions.MacCatalyst; + default: + return "Unknown"; + } + } + } +} diff --git a/tests/dotnet/UnitTests/DotNetUnitTests.csproj b/tests/dotnet/UnitTests/DotNetUnitTests.csproj index 773bd6711704..0c8c920a7cf1 100644 --- a/tests/dotnet/UnitTests/DotNetUnitTests.csproj +++ b/tests/dotnet/UnitTests/DotNetUnitTests.csproj @@ -48,6 +48,9 @@ external\PListObject.cs + + external\SdkVersions.cs + diff --git a/tests/dotnet/UnitTests/PackTest.cs b/tests/dotnet/UnitTests/PackTest.cs new file mode 100644 index 000000000000..0eb62c67ea4d --- /dev/null +++ b/tests/dotnet/UnitTests/PackTest.cs @@ -0,0 +1,175 @@ +#nullable enable + +using System; +using System.IO; +using System.IO.Compression; +using System.Linq; + +using NUnit.Framework; + +using Xamarin.Utils; +using Xamarin.MacDev; + +namespace Xamarin.Tests { + public class PackTest : TestBaseClass { + + + [Test] + [TestCase (ApplePlatform.iOS)] + [TestCase (ApplePlatform.MacCatalyst)] + [TestCase (ApplePlatform.TVOS)] + [TestCase (ApplePlatform.MacOSX)] + public void BindingProject (ApplePlatform platform) + { + var project = "bindings-test"; + Configuration.IgnoreIfIgnoredPlatform (platform); + + var project_path = Path.Combine (Configuration.RootPath, "tests", project, "dotnet", platform.AsString (), $"{project}.csproj"); + Clean (project_path); + Configuration.CopyDotNetSupportingFiles (Path.GetDirectoryName (project_path)); + + var tmpdir = Cache.CreateTemporaryDirectory (); + var outputPath = Path.Combine (tmpdir, "OutputPath"); + var intermediateOutputPath = Path.Combine (tmpdir, "IntermediateOutputPath"); + var properties = GetDefaultProperties (); + properties ["OutputPath"] = outputPath + Path.DirectorySeparatorChar; + properties ["IntermediateOutputPath"] = intermediateOutputPath + Path.DirectorySeparatorChar; + + var rv =DotNet.AssertPackFailure (project_path, properties); + var errors = BinLog.GetBuildLogErrors (rv.BinLogPath).ToArray (); + Assert.AreEqual (1, errors.Length, "Error count"); + Assert.AreEqual ($"Creating a NuGet package is not supported for projects that have ObjcBindingNativeLibrary items. Migrate to use NativeReference items instead.", errors [0].Message, "Error message"); + } + + [Test] + [TestCase (ApplePlatform.iOS, true)] + [TestCase (ApplePlatform.iOS, false)] + [TestCase (ApplePlatform.MacCatalyst, true)] + [TestCase (ApplePlatform.MacCatalyst, false)] + [TestCase (ApplePlatform.TVOS, true)] + [TestCase (ApplePlatform.TVOS, false)] + [TestCase (ApplePlatform.MacOSX, true)] + [TestCase (ApplePlatform.MacOSX, false)] + public void BindingFrameworksProject (ApplePlatform platform, bool noBindingEmbedding) + { + var project = "bindings-framework-test"; + Configuration.IgnoreIfIgnoredPlatform (platform); + + var project_path = Path.Combine (Configuration.RootPath, "tests", project, "dotnet", platform.AsString (), $"{project}.csproj"); + Clean (project_path); + Configuration.CopyDotNetSupportingFiles (Path.GetDirectoryName (project_path)); + + var tmpdir = Cache.CreateTemporaryDirectory (); + var outputPath = Path.Combine (tmpdir, "OutputPath"); + var intermediateOutputPath = Path.Combine (tmpdir, "IntermediateOutputPath"); + var properties = GetDefaultProperties (); + properties ["OutputPath"] = outputPath + Path.DirectorySeparatorChar; + properties ["IntermediateOutputPath"] = intermediateOutputPath + Path.DirectorySeparatorChar; + properties ["NoBindingEmbedding"] = noBindingEmbedding ? "true" : "false"; + + DotNet.AssertPack (project_path, properties); + + var nupkg = Path.Combine (outputPath, project + ".1.0.0.nupkg"); + Assert.That (nupkg, Does.Exist, "nupkg existence"); + + var archive = ZipFile.OpenRead (nupkg); + var files = archive.Entries.Select (v => v.FullName).ToHashSet (); + var hasSymlinks = noBindingEmbedding && (platform == ApplePlatform.MacCatalyst || platform == ApplePlatform.MacOSX); + if (noBindingEmbedding) { + Assert.That (archive.Entries.Count, Is.EqualTo (hasSymlinks ? 6 : 10), $"nupkg file count - {nupkg}"); + } else { + Assert.That (archive.Entries.Count, Is.EqualTo (5), $"nupkg file count - {nupkg}"); + } + Assert.That (files, Does.Contain (project + ".nuspec"), "nuspec"); + Assert.That (files, Does.Contain ("_rels/.rels"), ".rels"); + Assert.That (files, Does.Contain ("[Content_Types].xml"), "[Content_Types].xml"); + Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithDefaultVersion ()}/{project}.dll"), $"{project}.dll"); + Assert.That (files, Has.Some.Matches (v => v.StartsWith ("package/services/metadata/core-properties/", StringComparison.Ordinal) && v.EndsWith (".psmdcp", StringComparison.Ordinal)), "psmdcp"); + if (noBindingEmbedding) { + if (hasSymlinks) { + Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithDefaultVersion ()}/{project}.resources.zip"), $"{project}.resources.zip"); + } else { + Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithDefaultVersion ()}/{project}.resources/XStaticArTest.framework/XStaticArTest"), $"XStaticArTest.framework/XStaticArTest"); + Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithDefaultVersion ()}/{project}.resources/XStaticObjectTest.framework/XStaticObjectTest"), $"XStaticObjectTest.framework/XStaticObjectTest"); + Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithDefaultVersion ()}/{project}.resources/XTest.framework/XTest"), $"XTest.framework/XTest"); + Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithDefaultVersion ()}/{project}.resources/XTest.framework/Info.plist"), $"XTest.framework/Info.plist"); + Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithDefaultVersion ()}/{project}.resources/manifest"), $"manifest"); + } + } + } + + [Test] + [TestCase (ApplePlatform.iOS, true)] + [TestCase (ApplePlatform.iOS, false)] + [TestCase (ApplePlatform.MacCatalyst, true)] + [TestCase (ApplePlatform.MacCatalyst, false)] + [TestCase (ApplePlatform.TVOS, true)] + [TestCase (ApplePlatform.TVOS, false)] + [TestCase (ApplePlatform.MacOSX, true)] + [TestCase (ApplePlatform.MacOSX, false)] + public void BindingXcFrameworksProject (ApplePlatform platform, bool noBindingEmbedding) + { + var project = "bindings-xcframework-test"; + Configuration.IgnoreIfIgnoredPlatform (platform); + + var project_path = Path.Combine (Configuration.RootPath, "tests", project, "dotnet", platform.AsString (), $"{project}.csproj"); + Clean (project_path); + Configuration.CopyDotNetSupportingFiles (Path.GetDirectoryName (project_path)); + + var tmpdir = Cache.CreateTemporaryDirectory (); + var outputPath = Path.Combine (tmpdir, "OutputPath"); + var intermediateOutputPath = Path.Combine (tmpdir, "IntermediateOutputPath"); + var properties = GetDefaultProperties (); + properties ["OutputPath"] = outputPath + Path.DirectorySeparatorChar; + properties ["IntermediateOutputPath"] = intermediateOutputPath + Path.DirectorySeparatorChar; + properties ["NoBindingEmbedding"] = noBindingEmbedding ? "true" : "false"; + properties ["AssemblyName"] = project; + + DotNet.AssertPack (project_path, properties); + + var nupkg = Path.Combine (outputPath, project + ".1.0.0.nupkg"); + Assert.That (nupkg, Does.Exist, "nupkg existence"); + + var archive = ZipFile.OpenRead (nupkg); + var files = archive.Entries.Select (v => v.FullName).ToHashSet (); + Assert.That (archive.Entries.Count, Is.EqualTo (noBindingEmbedding ? 6 : 5), $"nupkg file count - {nupkg}"); + Assert.That (files, Does.Contain (project + ".nuspec"), "nuspec"); + Assert.That (files, Does.Contain ("_rels/.rels"), ".rels"); + Assert.That (files, Does.Contain ("[Content_Types].xml"), "[Content_Types].xml"); + Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithDefaultVersion ()}/{project}.dll"), $"{project}.dll"); + Assert.That (files, Has.Some.Matches (v => v.StartsWith ("package/services/metadata/core-properties/", StringComparison.Ordinal) && v.EndsWith (".psmdcp", StringComparison.Ordinal)), "psmdcp"); + if (noBindingEmbedding) { + Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithDefaultVersion ()}/{project}.resources.zip"), $"{project}.resources.zip"); + } + } + + [Test] + [TestCase (ApplePlatform.iOS)] + [TestCase (ApplePlatform.MacCatalyst)] + [TestCase (ApplePlatform.TVOS)] + [TestCase (ApplePlatform.MacOSX)] + public void LibraryProject (ApplePlatform platform) + { + var project = "MyClassLibrary"; + Configuration.IgnoreIfIgnoredPlatform (platform); + + var project_path = GetProjectPath (project, runtimeIdentifiers: string.Empty, platform: platform, out var appPath); + Clean (project_path); + var properties = GetDefaultProperties (); + + DotNet.AssertPack (project_path, properties); + + var nupkg = Path.Combine (Path.GetDirectoryName (project_path)!, "bin", "Debug", project + ".1.0.0.nupkg"); + Assert.That (nupkg, Does.Exist, "nupkg existence"); + + var archive = ZipFile.OpenRead (nupkg); + var files = archive.Entries.Select (v => v.FullName).ToHashSet (); + Assert.That (archive.Entries.Count, Is.EqualTo (5), "nupkg file count"); + Assert.That (files, Does.Contain (project + ".nuspec"), "nuspec"); + Assert.That (files, Does.Contain ("_rels/.rels"), ".rels"); + Assert.That (files, Does.Contain ("[Content_Types].xml"), "[Content_Types].xml"); + Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithDefaultVersion ()}/{project}.dll"), $"{project}.dll"); + Assert.That (files, Has.Some.Matches (v => v.StartsWith ("package/services/metadata/core-properties/", StringComparison.Ordinal) && v.EndsWith (".psmdcp", StringComparison.Ordinal)), "psmdcp"); + } + } +}