-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Use unix as the parent for the Android RID graph #45927
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
Conversation
Fixes: dotnet/sdk#14908 In a .NET 6 Android project, adding a NuGet package such as: <PackageReference Include="akavache" Version="6.0.30"/> ...would include Linux native libraries from dependencies, such as: packages\sqlitepclraw.lib.e_sqlite3.linux\1.1.11\runtimes\linux-arm64\native\libe_sqlite3.so Comparing the RID graph for iOS and Android in `dotnet\sdk\*\RuntimeIdentifierGraph.json`: "ios": { "#import": [ "unix" ] }, ... "android": { "#import": [ "linux" ] }, It seems like Android graph should match iOS here, as changing `linux` -> `unix` solved this issue for me locally. Based on the changes in dotnet#45442, I updated `runtimeGroups.props` to specify `linux` instead of `unix` for Android. Then I ran this command to update the checked-in `.json` files: > dotnet build .\src\libraries\pkg\Microsoft.NETCore.Platforms -p:UpdateRuntimeFiles=true
|
Yep, parenting android to unix was rejected. We need agreement first on how we want to address this problem. @ericstj what do you suggest as the next steps? |
I don't think it will, at least not if we follow the And if we don't do it then we're back to essentially the same situation with this PR where we're reparenting android to unix. I think the underlying issue is that there are two competing concerns: allowing to reference managed-only |
Do packages need to provide a different native asset in order to work on android? If so they can provide that in the Do packages need to not provide any native asset to work on android? If so they can make that happen by adding an empty There's no promise that a package that specializes for a platform will just work on a brand new platform that they've never considered. RIDs try to do their best to represent useful reuse, so that more often than not folks can avoid duplication when they specialize by platform. They can't get it right 100% of the time, but when its wrong there should be a way to make a package specialize for the new platform once the author understands it needs to. We should only be changing RID hierarchy if there is data out there showing that a majority of the time the RID graph leads to duplication rather than reuse. |
|
@ericstj I think the problem is if a user brings in an innocent NuGet package in an Android project: <PackageReference Include="akavache" Version="6.0.30"/>How do we prevent linux Right now we have this workaround, which doesn't seem right: |
|
The fallback RID is not meant to guarantee binary compatibility for any OS. e.g. there are
If we examine the entire RID graph, we will see that it is actually iOS and tvOS that are at odds by not parented by OSX. It does not necessarily mean one approach is right and other one is wrong, it just shows that we are trying to achieve some concrete goals from the thing which does not guarantee them. |
Who are you to violate the contract of the package author? The package author decided to include those files you can't just drop them. What's the library going to do when it tries to load them? This is a case of a package that needs to specialize for the new platform, we cannot do that for them. |
In the example above, the app ends up with both Linux and Android The library author could update the package to support .NET 6, but it seems like this situation will happen frequently for users migrating from Xamarin.Android to .NET 6. We need to do something, maybe all we can do is give a good error message? |
How is this possible? Is more than one package responsible for delivering the same component? Nuget will only ever choose one folder for any asset type. I tried restoring that package for both net5.0 and monoandroid and I only see |
|
I don't know why these packages are split up so much, but I see the Android native library coming from: In this package, the native library is packed as an EmbeddedResource, which is removed and put in the right place in the Android app at build time. This implementation for native libraries was implemented in Xamarin early on. NuGet might not have existed (or hit popularity yet). Either way, let's say the library author added a |
Native assets must be put in one of the native folders, so they'd need to either use If you placed the native SO binary in If the author decided to provide the native binary in a different package, |
|
Sorry, I mistyped, I should have put the RID What should we do here? Emit a nice error message if |
|
I think you would currently hit:
|
|
Will the check be based off of scanning the binary? If so then that seems fine. If the check is based off checking the folder name it seems like it could have false positives. |
I've noticed the `_IncludeNativeSystemLibraries` MSBuild target can
take 40ms because it is running this workaround:
<!-- HACK remove any unexpected runtime components -->
<FrameworkNativeLibrary
Remove="@(ResolvedFileToPublish)"
Condition=" $([System.Text.RegularExpressions.Regex]::IsMatch('%(FullPath)', '.*linux-.*')) "
/>
The `_IncludeNativeSystemLibraries` also can be split up between
"legacy" Xamarin.Android and .NET 6. The .NET 6 version can simply
check the `@(ResolvedFileToPublish)` item group, as the other parts
support the intepreter, profiler, etc., which are not available in .NET
6 yet.
I created a new `<ProcessNativeLibraries/>` MSBuild task to simplify
the work in C#:
* We can iterate over all `.so` files from `@(ResolvedFileToPublish)`.
* We can fix up `libmonodroid.so` as needed.
* We can emit a warning if the ABI is unknown without using a `Regex`.
It is possible for Linux `.so` files to be brought in from NuGet
packages as discussed in: dotnet/runtime#45927
The warning is a new alternate message for XA4301, such as:
Cannot determine ABI of native library 'C:\src\xamarin-android\packages\sqlitepclraw.lib.e_sqlite3.linux\1.1.11\runtimes\linux-arm64\native\libe_sqlite3.so'. The RuntimeIdentifier 'linux-arm64' does not target Android platforms.
As part of this change, .NET 6 will no longer need to do:
<PropertyGroup>
<_Assemblies>@(_ResolvedFrameworkAssemblies)</_Assemblies>
So we can avoid creating a ~14K character string.
~~ Results ~~
Timing the project fromm the `DotNetBuild(android.21-arm,false)` test,
in a build with no changes:
Before:
40 ms _IncludeNativeSystemLibraries 1 calls
After:
4 ms _IncludeNativeSystemLibraries 1 calls
This should save ~36ms from all .NET 6 builds.
|
Closing this in favor of the latest changes in dotnet/android#5386 I added a new warning message that reports if |
I've noticed the `_IncludeNativeSystemLibraries` MSBuild target can
take 40ms because it is running this workaround:
<!-- HACK remove any unexpected runtime components -->
<FrameworkNativeLibrary
Remove="@(ResolvedFileToPublish)"
Condition=" $([System.Text.RegularExpressions.Regex]::IsMatch('%(FullPath)', '.*linux-.*')) "
/>
The `_IncludeNativeSystemLibraries` also can be split up between
"legacy" Xamarin.Android and .NET 6. The .NET 6 version can simply
check the `@(ResolvedFileToPublish)` item group, as the other parts
support the intepreter, profiler, etc., which are not available in .NET
6 yet.
I created a new `<ProcessNativeLibraries/>` MSBuild task to simplify
the work in C#:
* We can iterate over all `.so` files from `@(ResolvedFileToPublish)`.
* We can fix up `libmonodroid.so` as needed.
* We can emit a warning if the ABI is unknown without using a `Regex`.
It is possible for Linux `.so` files to be brought in from NuGet
packages as discussed in: dotnet/runtime#45927
The warning is a new alternate message for XA4301, such as:
warning XA4301: Cannot determine ABI of native library 'C:\src\xamarin-android\packages\sqlitepclraw.lib.e_sqlite3.linux\1.1.11\runtimes\linux-arm64\native\libe_sqlite3.so'. Remove the 'SQLitePCLRaw.lib.e_sqlite3.linux' NuGet package, or notify the library author.
As part of this change, .NET 6 will no longer need to do:
<PropertyGroup>
<_Assemblies>@(_ResolvedFrameworkAssemblies)</_Assemblies>
So we can avoid creating a ~14K character string.
~~ Results ~~
Timing the project fromm the `DotNetBuild(android.21-arm,false)` test,
in a build with no changes:
Before:
40 ms _IncludeNativeSystemLibraries 1 calls
After:
4 ms _IncludeNativeSystemLibraries 1 calls
This should save ~36ms from all .NET 6 builds.
I've noticed the `_IncludeNativeSystemLibraries` MSBuild target can
take 40ms because it is running this workaround:
<!-- HACK remove any unexpected runtime components -->
<FrameworkNativeLibrary
Remove="@(ResolvedFileToPublish)"
Condition=" $([System.Text.RegularExpressions.Regex]::IsMatch('%(FullPath)', '.*linux-.*')) "
/>
The `_IncludeNativeSystemLibraries` also can be split up between
"legacy" Xamarin.Android and .NET 6. The .NET 6 version can simply
check the `@(ResolvedFileToPublish)` item group, as the other parts
support the intepreter, profiler, etc., which are not available in .NET
6 yet.
I created a new `<ProcessNativeLibraries/>` MSBuild task to simplify
the work in C#:
* We can iterate over all `.so` files from `@(ResolvedFileToPublish)`.
* We can fix up `libmonodroid.so` as needed.
* We can emit a warning if the ABI is unknown without using a `Regex`.
It is possible for Linux `.so` files to be brought in from NuGet
packages as discussed in: dotnet/runtime#45927
The warning is a new alternate message for XA4301, such as:
warning XA4301: Cannot determine ABI of native library 'C:\src\xamarin-android\packages\sqlitepclraw.lib.e_sqlite3.linux\1.1.11\runtimes\linux-arm64\native\libe_sqlite3.so'. Remove the 'SQLitePCLRaw.lib.e_sqlite3.linux' NuGet package, or notify the library author.
As part of this change, .NET 6 will no longer need to do:
<PropertyGroup>
<_Assemblies>@(_ResolvedFrameworkAssemblies)</_Assemblies>
So we can avoid creating a ~14K character string.
~~ Results ~~
Timing the project fromm the `DotNetBuild(android.21-arm,false)` test,
in a build with no changes:
Before:
40 ms _IncludeNativeSystemLibraries 1 calls
After:
4 ms _IncludeNativeSystemLibraries 1 calls
This should save ~36ms from all .NET 6 builds.
I've noticed that the `_IncludeNativeSystemLibraries` MSBuild target
can take 40ms because it is running this workaround:
<!-- HACK remove any unexpected runtime components -->
<FrameworkNativeLibrary
Remove="@(ResolvedFileToPublish)"
Condition=" $([System.Text.RegularExpressions.Regex]::IsMatch('%(FullPath)', '.*linux-.*')) "
/>
The `_IncludeNativeSystemLibraries` also can be split up between
"legacy" Xamarin.Android and .NET 6. The .NET 6 version can simply
check the `@(ResolvedFileToPublish)` item group, as the other parts
support the interpreter, profiler, etc., which are not available in
.NET 6 yet.
I created a new `<ProcessNativeLibraries/>` MSBuild task to simplify
the work in C#:
* We can iterate over all `.so` files in `@(ResolvedFileToPublish)`.
* We can fix up `libmonodroid.so` as needed.
* We can emit a warning if the ABI is unknown without using a `Regex`.
It is possible for Linux `.so` files to be brought in from NuGet
packages as discussed in: dotnet/runtime#45927
The warning is a new alternate message for XA4301, such as:
warning XA4301: Cannot determine ABI of native library 'C:\src\xamarin-android\packages\sqlitepclraw.lib.e_sqlite3.linux\1.1.11\runtimes\linux-arm64\native\libe_sqlite3.so'.
Remove the 'SQLitePCLRaw.lib.e_sqlite3.linux' NuGet package, or notify the library author.
As part of this change, .NET 6 will no longer need to do:
<PropertyGroup>
<_Assemblies>@(_ResolvedFrameworkAssemblies)</_Assemblies>
So we can also avoid creating a ~14K character string.
~~ Results ~~
Timing the project fromm the `DotNetBuild(android.21-arm,false)`
test, in a build with no changes:
* Before:
40 ms _IncludeNativeSystemLibraries 1 calls
* After:
4 ms _IncludeNativeSystemLibraries 1 calls
This should save ~36ms from all .NET 6 builds.
Fixes: dotnet/sdk#14908
In a .NET 6 Android project, adding a NuGet package such as:
...would include Linux native libraries from dependencies, such as:
Comparing the RID graph for iOS and Android in
dotnet\sdk\*\RuntimeIdentifierGraph.json:It seems like Android graph should match iOS here, as changing
linux->
unixsolved this issue for me locally.Based on the changes in #45442, I updated
runtimeGroups.propstospecify
linuxinstead ofunixfor Android. Then I ran this commandto update the checked-in
.jsonfiles:/cc @marek-safar @steveisok