-
Notifications
You must be signed in to change notification settings - Fork 518
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
Xamarin.iOS linker removes assembly attributes, but large & useful libraries (e.g. EF Core 2.0) rely on such being preserved #3655
Comments
This looks like an issue with the linker since we should be able to use the xml configuration file to state that attributes should be preserved in the case of libraries like EF. |
@spouliot any feedback for this issue? Should we move it to the linker project? |
@mandel-macaque no (moving), it's a XI/XM specific step @cwrea the XML file is used to mark code, not metadata. We'll look to see how we can make this more flexible. |
@marek-safar some time ago we talked about things that could enable EF Core to work better with Xamarin, but I think I did not mention this issue specifically. Having fine-grained control to preserve assembly-level attributes would unblock anyone (us, @cwrea, another contributor, or an application developer) that wants to use EF Core with full linking. |
@spouliot that's bug in the hardcoded override of attributes in https://github.com/xamarin/xamarin-macios/blob/master/tools/linker/MonoTouch.Tuner/RemoveAttributes.cs I think it'd be better to remove that customization completely and rely on original linker to do the work (I am happy to help with that) |
I am using EF7 and was able to enable full linking on Android using a LinkDescription.xml. However, this issue now blocks me enabling full linking on iOS, so I am stuck with a 110 MB app size :( |
What's the current status of this? Don't want to be annoying, but I think this could be a small fix that unblocks & helps a lot of us working with iOS & EF Core |
This is an old step but it removes a lot of unused metadata out of every applications: reducing size and saving build and deploy times. There's a recent mechanism to enable/disable optimizations (using Additional mtouch arguments). That would be an easy, first fix/hack to disable the step (entirely) when needed (i.e. the extra cost being paid only if needed). There's a newer, smarter metadata remover step - which checks if 3rd party code use a feature before removing it (e.g. parameters names are removed from metadata only if I have an upcoming trip to Redmond next week so I'll have a look at it (at least the first part) during the flights. |
Thanks for taking care about this! |
…timization. Fix xamarin#3655 This allows the optimization to be disabled in cases where one, or many, a custom attribute(s) are required by the application at runtime. While not ideal disabling this single step is much better than disabling linking for the whole application. A better approach is described in xamarin#6048 but this configuration optimization makes sense independently of it. Fix xamarin#3655
…timization. Fix xamarin#3655 This allows the optimization to be disabled in cases where one, or many, a custom attribute(s) are required by the application at runtime. While not ideal disabling this single step is much better than disabling linking for the whole application. A better approach is described in xamarin#6048 but this configuration optimization makes sense independently of it. Fix xamarin#3655
…timization. Fix #3655 (#6049) This allows the optimization to be disabled in cases where one, or many, a custom attribute(s) are required by the application at runtime. While not ideal disabling this single step is much better than disabling linking for the whole application. A better approach is described in #6048 but this configuration optimization makes sense independently of it. Fix #3655
…rable optimization. Fix #3655 (#6058) This allows the optimization to be disabled in cases where one, or many, a custom attribute(s) are required by the application at runtime. While not ideal disabling this single step is much better than disabling linking for the whole application. A better approach is described in #6048 but this configuration optimization makes sense independently of it. Fix #3655
I've been attempting to get Microsoft Entity Framework Core 2.0 working in a Xamarin.iOS application with full linking enabled. EF Core is a large library — exactly the kind that could benefit from linking. Discovering all the critical types/methods to preserve in a LinkDescription XML file has been tedious, owing to extensive reflection and use of DI in EF Core 2.0, but I've been making progress, one crash at a time. (There's also hope that ER Core could one day have linker hints built in.)
However, I hit a major blocker: When EF Core creates a database from a model, it reads its own
AssemblyInformationalVersion
attribute to preserve in generated metadata. But the Xamarin.iOS linker strips assembly attributes from an assembly that is not link-skipped. So, in an app with full linking enabled, EF Core is crashing as it gets nothing back from reading the desired attribute value.This behaviour appears to be an intentional linker feature, perhaps desirable and harmless in many cases — but for cases where it is a problem, there exists no fine-grained directive to preserve assembly attributes, as one could do with plain types/methods in a LinkDescription XML file.
The only workaround at present is to go back to link-skipping the large EF Core main assembly, and put up with the resulting bloat. For a small app that doesn't use EF Core's more advanced features, the unnecessary bloat may be considerable. (I haven't measured potential avoidable bloat yet, as I'm blocked from getting to the point where I could compare a working iOS app with full linking vs. one that link-skips EF Core.)
Steps to Reproduce (without EF Core; just the essential issue)
FinishedLaunching()
method, add the following line before the return:System.Diagnostics.Debug.WriteLine("TODO");
[assembly: AssemblyInformationalVersion("1.0.0.0")]
Debug.WriteLine()
call added in step 1 to read:System.Diagnostics.Debug.WriteLine("Version: " + ProductInfo.GetVersion());
.System.NullReferenceException: Object reference not set to an instance of an object
.If you were to expand the one-liner from EF Core's
GetVersion()
method into multiple statements and intermediate values instead, you would see that the null reference is the attribute object from which the InformationalVersion property would have been accessed. If you were to change linking back to "Link SDK Assemblies Only", you would avoid the crash and see the expected output.Expected Behavior
It should be possible to configure the linker to specifically preserve assembly attributes when the need arises — i.e. without completely opting out of linking an assembly.
Developers of .NET Standard class libraries should be able to rely on reading their own assembly's attribute information. Linking should aim to exclude only unnecessary types, methods, and other data from an assembly. Beyond types and methods, when the linker assumes that a kind of thing can safely be excluded, it should provide a fine-grained directive to preserve some or all of the kinds-of-things, for cases where the assumption has been proven unsafe for a specific assembly.
Actual Behavior
Crash. The present workaround requires completely opting out of linking for an assembly that relies on reading its own assembly attributes.
However, linking remains highly desirable for large library dependencies used in mobile applications. The case in point is not only a very large .NET Standard library, but a popular data access framework promoted by Microsoft as cross-platform capable, which ideally would include mobile applications with on-device data access needs.
Environment
Build Logs
The text was updated successfully, but these errors were encountered: