Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.NET 8 RC1 fails to NativeAOT compile when targeting ios-arm64 #91997

Closed
lemonmojo opened this issue Sep 13, 2023 · 8 comments · Fixed by #92114
Closed

.NET 8 RC1 fails to NativeAOT compile when targeting ios-arm64 #91997

lemonmojo opened this issue Sep 13, 2023 · 8 comments · Fixed by #92114
Assignees
Milestone

Comments

@lemonmojo
Copy link

Description

Up until .NET RC1, NativeAOT compilation worked out of the box when targeting ios-arm64.
This requires adding <PublishAotUsingRuntimePack>true</PublishAotUsingRuntimePack> and <LinkerArg Include="-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk" /> to the csproj.
Everything else is pretty much standard fare.

Now, since RC1, dotnet publish fails because of linking errors in libicuuc.a related to C++.

As a workaround, one can add <LinkerArg Include="-lc++" /> to the csproj like in the example below.

Reproduction Steps

Running dotnet publish against the following example csproj works fine because -lc++ was re-added using a LinkerArg flag. Removing this line makes the build fail.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <RuntimeIdentifier>ios-arm64</RuntimeIdentifier>
    <PublishAOT>true</PublishAOT>

    <!-- TODO: Temporary workaround for iOS/iOS Simulator support -->
    <PublishAotUsingRuntimePack>true</PublishAotUsingRuntimePack>
  </PropertyGroup>

  <ItemGroup>
    <!-- TODO: Temporary workaround for iOS support -->
    <LinkerArg Include="-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk" />

    <!-- TODO: Temporary workaround for .NET 8 RC1 which seems to have removed -lc++ from its linker flags -->
    <LinkerArg Include="-lc++" />
  </ItemGroup>
</Project>

Expected behavior

Compiles out of the box.

Actual behavior

Does not compile without adding <LinkerArg Include="-lc++" />.

Regression?

It did work in all .NET 8 previews until RC1.

Known Workarounds

Adding <LinkerArg Include="-lc++" /> to the csproj.

Configuration

.NET 8.0.100-rc.1.23455.8

Other information

No response

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Sep 13, 2023
@ghost
Copy link

ghost commented Sep 13, 2023

Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

Up until .NET RC1, NativeAOT compilation worked out of the box when targeting ios-arm64.
This requires adding <PublishAotUsingRuntimePack>true</PublishAotUsingRuntimePack> and <LinkerArg Include="-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk" /> to the csproj.
Everything else is pretty much standard fare.

Now, since RC1, dotnet publish fails because of linking errors in libicuuc.a related to C++.

As a workaround, one can add <LinkerArg Include="-lc++" /> to the csproj like in the example below.

Reproduction Steps

Running dotnet publish against the following example csproj works fine because -lc++ was re-added using a LinkerArg flag. Removing this line makes the build fail.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <RuntimeIdentifier>ios-arm64</RuntimeIdentifier>
    <PublishAOT>true</PublishAOT>

    <!-- TODO: Temporary workaround for iOS/iOS Simulator support -->
    <PublishAotUsingRuntimePack>true</PublishAotUsingRuntimePack>
  </PropertyGroup>

  <ItemGroup>
    <!-- TODO: Temporary workaround for iOS support -->
    <LinkerArg Include="-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk" />

    <!-- TODO: Temporary workaround for .NET 8 RC1 which seems to have removed -lc++ from its linker flags -->
    <LinkerArg Include="-lc++" />
  </ItemGroup>
</Project>

Expected behavior

Compiles out of the box.

Actual behavior

Does not compile without adding <LinkerArg Include="-lc++" />.

Regression?

It did work in all .NET 8 previews until RC1.

Known Workarounds

Adding <LinkerArg Include="-lc++" /> to the csproj.

Configuration

.NET 8.0.100-rc.1.23455.8

Other information

No response

Author: lemonmojo
Assignees: -
Labels:

area-NativeAOT-coreclr

Milestone: -

@ghost
Copy link

ghost commented Sep 13, 2023

Tagging subscribers to 'os-ios': @steveisok, @akoeplinger, @kotlarmilos
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

Up until .NET RC1, NativeAOT compilation worked out of the box when targeting ios-arm64.
This requires adding <PublishAotUsingRuntimePack>true</PublishAotUsingRuntimePack> and <LinkerArg Include="-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk" /> to the csproj.
Everything else is pretty much standard fare.

Now, since RC1, dotnet publish fails because of linking errors in libicuuc.a related to C++.

As a workaround, one can add <LinkerArg Include="-lc++" /> to the csproj like in the example below.

Reproduction Steps

Running dotnet publish against the following example csproj works fine because -lc++ was re-added using a LinkerArg flag. Removing this line makes the build fail.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <RuntimeIdentifier>ios-arm64</RuntimeIdentifier>
    <PublishAOT>true</PublishAOT>

    <!-- TODO: Temporary workaround for iOS/iOS Simulator support -->
    <PublishAotUsingRuntimePack>true</PublishAotUsingRuntimePack>
  </PropertyGroup>

  <ItemGroup>
    <!-- TODO: Temporary workaround for iOS support -->
    <LinkerArg Include="-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk" />

    <!-- TODO: Temporary workaround for .NET 8 RC1 which seems to have removed -lc++ from its linker flags -->
    <LinkerArg Include="-lc++" />
  </ItemGroup>
</Project>

Expected behavior

Compiles out of the box.

Actual behavior

Does not compile without adding <LinkerArg Include="-lc++" />.

Regression?

It did work in all .NET 8 previews until RC1.

Known Workarounds

Adding <LinkerArg Include="-lc++" /> to the csproj.

Configuration

.NET 8.0.100-rc.1.23455.8

Other information

No response

Author: lemonmojo
Assignees: -
Labels:

untriaged, os-ios, area-NativeAOT-coreclr

Milestone: -

@ivanpovazan
Copy link
Member

Hello @lemonmojo I will look into this.

Just for the clarification, the effort is being made towards creating a NativeAOT library for iOS-like platforms (as reported in: #88737), correct?

@ivanpovazan ivanpovazan removed the untriaged New issue has not been triaged by the area owner label Sep 13, 2023
@ivanpovazan ivanpovazan added this to the 9.0.0 milestone Sep 13, 2023
@lemonmojo
Copy link
Author

Hi @ivanpovazan, yes that's correct.

@ivanpovazan
Copy link
Member

ivanpovazan commented Sep 14, 2023

Thank you for the confirmation.
I managed to reproduce the issue and will open the PR that fixes it soon - the issue is related to recent changes in globalization and ICU support and is reproducible only in library mode, which is currently not officially supported with NativeAOT on iOS.

As a side note: It is also possible to workaround the problem by passing -p:LinkStandardCPlusPlusLibrary=true (or setting this property in the project file) or using invariant globalization via -p:InvariantGlobalization=true

@lemonmojo
Copy link
Author

@ivanpovazan Thx for looking into this.

I'm aware that this is an unsupported scenario at the moment. From what I can tell though, with the unit tests I have in place, everything seems to be working properly. Do you happen to know if this is going to be a supported scenario in the future?

Since I'm already passing custom linker flags, I'll keep the workaround I already have in place. But it's good to know that LinkStandardCPlusPlusLibrary exists. I'll keep that in mind.

Also, I know about InvariantGlobalization but it's not a viable option for Beyond.NET.

Kinda off-topic but since you already mentioned ICU related changes: Is the ICU stuff now embedded automatically when building with NativeAOT in library mode for iOS? Or is it still necessary to include the .dat file in the app/framework bundle?

@ivanpovazan
Copy link
Member

ivanpovazan commented Sep 15, 2023

I'm aware that this is an unsupported scenario at the moment. From what I can tell though, with the unit tests I have in place, everything seems to be working properly. Do you happen to know if this is going to be a supported scenario in the future?

Yes, this is planned to be a supported scenario for .NET9, but at this point, I cannot tell for sure if it is going to be backported to .NET8.

Kinda off-topic but since you already mentioned ICU related changes: Is the ICU stuff now embedded automatically when building with NativeAOT in library mode for iOS? Or is it still necessary to include the .dat file in the app/framework bundle?

It is still necessary to include the data file in the bundle as the file is loaded from a path:

GlobalizationNative_LoadICUData(const char* path)
{
#if defined(TARGET_MACCATALYST) || defined(TARGET_IOS) || defined(TARGET_TVOS)
if (path && path[0] != '/')
{
// if the path is relative, prepend the app bundle root
path = GlobalizationNative_GetICUDataPathRelativeToAppBundleRoot(path);
}
if (!path)
{
// fallback to icudt.dat in the app bundle resources in case the path isn't set
path = GlobalizationNative_GetICUDataPathFallback();
}
#endif

The ICU changes I was referring to were introduced here: https://github.com/dotnet/runtime/pull/90430/files when we started statically linking: icudata, icui18n and icuuc (which depend on standard c++ library) instead of using private APIs when targeting iOS-like platforms. This regression is not visible when building applications, because the app bundlers we are using: AppleAppBuilder and Xamarin are taking care of native linking.

@lemonmojo
Copy link
Author

@ivanpovazan Got you! Thx a lot for explaining the details.

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Sep 15, 2023
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Sep 16, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Oct 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants