diff --git a/docs/building-apps/build-properties.md b/docs/building-apps/build-properties.md index 97525d1af61e..ae4cf7fb95b6 100644 --- a/docs/building-apps/build-properties.md +++ b/docs/building-apps/build-properties.md @@ -300,6 +300,17 @@ This also applies to how native references are stored inside NuGets. > [!NOTE] > In some cases it can be beneficial to force a zip file on iOS as well, especially when there's a framework with files that have long names, because the zip file can sometimes work around MAX_PATH issues on Windows. +## CopyDSYMToPublishDirectory + +A boolean property that specifies whether any generated `*.dSYM` directories should be +copied to the publish directory when publishing (`dotnet publish`). + +The `*.dSYM` directories are generated next to the app bundle (see [NoDSymUtil](#nodsymutil)), +and when this property is `true` they'll also be copied to the publish directory (next to the +generated `.ipa`/`.pkg`). + +The default value is `true`. + ## CopySceneKitAssetsPath The full path to the `copySceneKitAssets` tool. diff --git a/dotnet/targets/Xamarin.Shared.Sdk.Publish.targets b/dotnet/targets/Xamarin.Shared.Sdk.Publish.targets index 8f6dca62905e..e2d66c9fa52c 100644 --- a/dotnet/targets/Xamarin.Shared.Sdk.Publish.targets +++ b/dotnet/targets/Xamarin.Shared.Sdk.Publish.targets @@ -20,8 +20,35 @@ Condition="$(RuntimeIdentifiers.Contains('iossimulator-')) Or $(RuntimeIdentifiers.Contains('tvossimulator-'))" /> - + + + + + + + + + <_DSymFileToPublish Include="%(_DSymDirToPublish.Identity)/**/*"> + %(_DSymDirToPublish.Filename)%(_DSymDirToPublish.Extension) + + + + + + diff --git a/tests/dotnet/UnitTests/PostBuildTest.cs b/tests/dotnet/UnitTests/PostBuildTest.cs index 91c459d8e75e..983fc2ecf744 100644 --- a/tests/dotnet/UnitTests/PostBuildTest.cs +++ b/tests/dotnet/UnitTests/PostBuildTest.cs @@ -541,6 +541,46 @@ public void StaticFrameworksNotInPostProcessing (ApplePlatform platform, string Assert.That (staticFrameworkItems, Is.Empty, $"Static framework XStaticArTest should not be in post-processing items. All items:\n\t{string.Join ("\n\t", postProcessingItems.Select (i => i.ItemSpec))}"); } + [Test] + [TestCase (ApplePlatform.iOS, "ios-arm64", true)] + [TestCase (ApplePlatform.iOS, "ios-arm64", false)] + public void PublishDSymToPublishDirectory (ApplePlatform platform, string runtimeIdentifiers, bool copyDSym) + { + // https://github.com/dotnet/macios/issues/15384 + // When publishing, the generated *.dSYM directories should be copied to the publish + // directory (unless CopyDSYMToPublishDirectory=false). + var project = "MySimpleApp"; + var configuration = "Release"; + Configuration.IgnoreIfIgnoredPlatform (platform); + Configuration.AssertRuntimeIdentifiersAvailable (platform, runtimeIdentifiers); + + var project_path = GetProjectPath (project, runtimeIdentifiers, platform: platform, out var appPath, configuration: configuration); + Clean (project_path); + + var properties = GetDefaultProperties (runtimeIdentifiers); + properties ["Configuration"] = configuration; + if (!copyDSym) + properties ["CopyDSYMToPublishDirectory"] = "false"; + + DotNet.AssertPublish (project_path, properties); + + var appContainerDir = Path.GetDirectoryName (appPath)!; + var appBundleName = Path.GetFileName (appPath); + var publishDir = Path.Combine (appContainerDir, "publish"); + + // The dSYM must have been generated next to the app bundle in the first place. + var sourceDSym = Path.Combine (appContainerDir, appBundleName + ".dSYM"); + Assert.That (sourceDSym, Does.Exist, "Source dSYM"); + + var publishedDSym = Path.Combine (publishDir, appBundleName + ".dSYM"); + if (copyDSym) { + Assert.That (publishedDSym, Does.Exist, "Published dSYM"); + Assert.That (Path.Combine (publishedDSym, "Contents", "Info.plist"), Does.Exist, "Published dSYM Info.plist"); + } else { + Assert.That (publishedDSym, Does.Not.Exist, "Published dSYM (disabled)"); + } + } + static ITaskItem AssertApplicationArtifact (string binLogPath, string path, ApplePlatform platform, string packageFormat, bool isDirectory) { var outputs = GetItems (binLogPath, "ApplicationArtifact");