You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
.NET 8 RC1 fails to NativeAOT compile when targeting ios-arm64 #91997
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.
<ProjectSdk="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 -->
<LinkerArgInclude="-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 -->
<LinkerArgInclude="-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.
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
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?
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:
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.
Activity
ivanpovazan commentedon Sep 13, 2023
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?
lemonmojo commentedon Sep 13, 2023
Hi @ivanpovazan, yes that's correct.
ivanpovazan commentedon 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=truelemonmojo commentedon Sep 15, 2023
@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
LinkStandardCPlusPlusLibraryexists. I'll keep that in mind.Also, I know about
InvariantGlobalizationbut 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 commentedon Sep 15, 2023
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.
It is still necessary to include the data file in the bundle as the file is loaded from a path:
runtime/src/native/libs/System.Globalization.Native/pal_icushim_static.c
Lines 171 to 184 in d40f90c
The ICU changes I was referring to were introduced here: https://github.com/dotnet/runtime/pull/90430/files when we started statically linking:
icudata,icui18nandicuuc(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:AppleAppBuilderandXamarinare taking care of native linking.lemonmojo commentedon Sep 15, 2023
@ivanpovazan Got you! Thx a lot for explaining the details.
[NativeAOT] Fix iOS library build by linking standard C++ library by …