NativeAOT: Fix output dir path for universal apps built with NativeAOT (#21288)

### Description 

When building universal apps with NativeAOT, the output path for the app bundle (and zipped .ipa) is incorrect when building with NativeAOT.

For example publishing a MAUI template app with NativeAOT gives the following output (notice: `osx-arm64`):
```
Created the package: /Users/ivan/tmp/net9-rc1/MacCatRc1/bin/Release/net9.0-maccatalyst/osx-arm64/publish/MacCatRc1-1.0.pkg
```
and the following output tree:
```
bin/Release 
bin/Release/net9.0-maccatalyst 
bin/Release/net9.0-maccatalyst/maccatalyst-arm64/*
bin/Release/net9.0-maccatalyst/maccatalyst-x64/*
bin/Release/net9.0-maccatalyst/osx-arm64
bin/Release/net9.0-maccatalyst/osx-arm64/MacCatRc1.app/*
bin/Release/net9.0-maccatalyst/osx-arm64/publish/*
```

The problem comes from the fact that .NET SDK for NativeAOT builds will try to resolve `RuntimeIdentifier` when it is not specified in:
58eb155e30/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets (L95-L114)

which resolves to `osx-arm64` and gets later used to setup `IntermediateOutputPath` and `OutputPath` in:
58eb155e30/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets (L343-L346)
 
However, this shouldn't be done in universal builds, as the outer build does not have the runtime identifier specified and should not be altered.

### Changes

In this PR we are disabling the resolution of the `RuntimeIdentifier` when building universal apps with NativeAOT early in SDK in order to fix the output path.

I also included unit tests to verify the existence of .app bundles. 

### Follow-up

There is an additional issue with Debug builds of universal apps with NativeAOT, where merging PDBs fails, which is reported in: https://github.com/xamarin/xamarin-macios/issues/20903

---
Contributes to: https://github.com/xamarin/xamarin-macios/issues/20903

---------

Co-authored-by: Ivan Povazan <ivan.povazan@gmail.com>
This commit is contained in:
Ivan Povazan 2024-09-23 21:18:12 +02:00 коммит произвёл GitHub
Родитель 1fccb419b6
Коммит 5633f4e890
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
2 изменённых файлов: 20 добавлений и 6 удалений

Просмотреть файл

@ -95,6 +95,9 @@
<AllowPublishAotWithoutRuntimeIdentifier Condition="'$(AllowPublishAotWithoutRuntimeIdentifier)' == '' And '$(_UseNativeAot)' == 'true'">true</AllowPublishAotWithoutRuntimeIdentifier>
<AllowSelfContainedWithoutRuntimeIdentifier Condition="'$(AllowSelfContainedWithoutRuntimeIdentifier)' == ''">true</AllowSelfContainedWithoutRuntimeIdentifier>
<!-- Prevent .NET from resolving runtime identifier for NativeAOT builds when building universal apps. -->
<UseCurrentRuntimeIdentifier Condition="'$(_UseNativeAot)' == 'true' And '$(RuntimeIdentifiers)' != '' And '$(RuntimeIdentifier)' == ''">false</UseCurrentRuntimeIdentifier>
</PropertyGroup>
<!-- Set the default RuntimeIdentifier if not already specified. -->

Просмотреть файл

@ -1738,19 +1738,28 @@ namespace Xamarin.Tests {
}
[Test]
[TestCase (ApplePlatform.iOS, "ios-arm64")]
[TestCase (ApplePlatform.MacOSX, "osx-x64")]
[TestCase (ApplePlatform.MacCatalyst, "maccatalyst-arm64")]
[TestCase (ApplePlatform.TVOS, "tvossimulator-x64")]
public void PublishAot (ApplePlatform platform, string runtimeIdentifiers)
[TestCase (ApplePlatform.iOS, "ios-arm64", "Debug")]
[TestCase (ApplePlatform.iOS, "ios-arm64", "Release")]
[TestCase (ApplePlatform.MacOSX, "osx-x64", "Debug")]
[TestCase (ApplePlatform.MacOSX, "osx-x64", "Release")]
// [TestCase (ApplePlatform.MacOSX, "osx-arm64;osx-x64", "Debug")] // See: https://github.com/xamarin/xamarin-macios/issues/20903
[TestCase (ApplePlatform.MacOSX, "osx-arm64;osx-x64", "Release")]
[TestCase (ApplePlatform.MacCatalyst, "maccatalyst-arm64", "Debug")]
[TestCase (ApplePlatform.MacCatalyst, "maccatalyst-arm64", "Release")]
// [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-arm64;maccatalyst-x64", "Debug")] // See: https://github.com/xamarin/xamarin-macios/issues/20903
[TestCase (ApplePlatform.MacCatalyst, "maccatalyst-arm64;maccatalyst-x64", "Release")]
[TestCase (ApplePlatform.TVOS, "tvossimulator-x64", "Debug")]
[TestCase (ApplePlatform.TVOS, "tvossimulator-x64", "Release")]
public void PublishAot (ApplePlatform platform, string runtimeIdentifiers, string configuration)
{
var project = "MySimpleApp";
Configuration.IgnoreIfIgnoredPlatform (platform);
Configuration.AssertRuntimeIdentifiersAvailable (platform, runtimeIdentifiers);
var project_path = GetProjectPath (project, runtimeIdentifiers: runtimeIdentifiers, platform: platform, out var appPath);
var project_path = GetProjectPath (project, runtimeIdentifiers: runtimeIdentifiers, platform: platform, out var appPath, configuration: configuration);
Clean (project_path);
var properties = GetDefaultProperties (runtimeIdentifiers);
properties ["Configuration"] = configuration;
properties ["PublishAot"] = "true";
properties ["_IsPublishing"] = "true"; // quack like "dotnet publish"
properties ["ExcludeNUnitLiteReference"] = "true"; // we're asserting no warnings, and NUnitLite produces a lot of them, so ignore NUnitLite
@ -1758,6 +1767,8 @@ namespace Xamarin.Tests {
properties ["TrimmerSingleWarn"] = "false"; // don't be shy, we want to know what the problem is
var rv = DotNet.AssertBuild (project_path, properties);
Assert.True (Directory.Exists (appPath), $"App file expected at: {appPath}");
// Verify that we have no warnings, but unfortunately we still have some we haven't fixed yet.
// Ignore those, and fail the test if we stop getting them (so that we can update the test to not ignore them anymore).
rv.AssertNoWarnings ((evt) => {