Skip to content

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

Closed

Description

@lemonmojo

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

Activity

  1. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Sep 13, 2023
  2. ivanpovazan commented on Sep 13, 2023

    @ivanpovazan
    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?

  3. removed
    untriagedNew issue has not been triaged by the area owner
    on Sep 13, 2023
  4. added this to the 9.0.0 milestone on Sep 13, 2023
  5. lemonmojo commented on Sep 13, 2023

    @lemonmojo
    Author

    Hi @ivanpovazan, yes that's correct.

  6. ivanpovazan commented on Sep 14, 2023

    @ivanpovazan
    Member

    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

  7. lemonmojo commented on Sep 15, 2023

    @lemonmojo
    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?

  8. ivanpovazan commented on Sep 15, 2023

    @ivanpovazan
    Member

    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.

  9. lemonmojo commented on Sep 15, 2023

    @lemonmojo
    Author

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

  10. ghost added
    in-prThere is an active PR which will close this issue when it is merged
    on Sep 15, 2023
  11. ghost removed
    in-prThere is an active PR which will close this issue when it is merged
    on Sep 16, 2023
  12. ghost locked as resolved and limited conversation to collaborators on Oct 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions