-
Notifications
You must be signed in to change notification settings - Fork 127
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
CopyUsed with new TrimMode #3039
Comments
In .NET 6, this was accomplished by setting If you need a workaround, you can try setting |
Thanks, it worked! Will it be officially supported in .NET 7 (or later)? or is the |
Thanks @adirh3 - I'm adding it to the list. We don't plan to add back support for "copyused" going forward. It's a flaky/hacky approach - if it's needed it means there are almost certainly warnings produced and using "copuysed" is a way to sort of randomly include enough in the app to make it work. For some apps it may work, but it's basically just a guess. We would rather invest in mechanisms which are more predictable in behavior. |
I agree that It is strange that today if you set |
I don't think it is a flaky/hacky approach and it is sometimes a must -- you really want to just account for all the assemblies in so that there is no need to worry about a big list of TrimmerRootAssembly, for example:
This is because I used this for Serilog in appsettings.json:
And this would never be scanned by the trimmer for potential reference. We need to be more conservative here regarding dynamic code. This is just from a toy project of mine who tried to naively include Serilog and I already have to figure a lot of things out to make Native AOT somewhat usable. Consider if I have a project with more than 100 dependencies this quickly becomes a nightmareish burden. I don't care about the compile time or binary size, I just want it to run. |
What benefits are you looking for using NativeAOT for this project? Our general approach in NativeAOT is to heavily rely on the static analysis, meaning that apps are guaranteed to work only if they produce 0 warnings. That obviously comes with lot of limitations and lot of things don't work. On the other hand, it's the only solution we could come up with which is predictable, all of the other solutions can break at any time and diagnosing why they broke was very difficult. |
Maybe give us a suggestion list of assemblies for adding into the TrimmerRootAssembly? It is quite hard to figure out the right combination to add in. In golang you can have a wildcard import* so that we can force add the needed code into the assembler. With dotnet not so much *: import _ "time/tzdata" |
You could root all assemblies if you wanted, but then the binary size and compile time will be really bad. I guess I don't understand the goal here. If you need all this dynamism, why not use normal CoreCLR to run the app? Why do you want NativeAOT? |
Indeed...I used self-contained + single file + compression before to try and achieve a golang like experience...but the performance is terrible. This is for a private CLI application I wrote to convert game music into MP3 and the boot up time is like 3 seconds (alas, still better than NodeJS CLI apps which I used to take 10 seconds to launch but that's not very fair to compare with a scripted language) If I put this solution onto a full-fledged game engine, I bet the boot up time would be even worse. Having NativeAOT also helps with some platform limitation, for example I can export functions as dynamic libraries symbols. |
Also what is the best way to do that without manual cherrypicking? |
Sorry - forgot to answer your other question:
I don't know how. What if you have code like: void Test(object value)
{
value.GetType().GetProperty("Prop");
} Without more info, the only solution to make this work always would be to keep the And that's not even the worst. Some plugin systems (I'm not sure but I think Serilog does something like this): foreach (var asm in GetAllAssemblies())
{
foreach (var t in asm.GetTypes())
{
if (t.IsAssignableTo(typeof(IInteresting)))
DoSomething(t);
}
} The only way to make this work is to preserve everything everywhere, not a solution for trying to make the app small. |
@sbomer - I vaguely remember that there's a point in SDK where we know all the assemblies as input to publish... do you know what it is? |
Note that it's a "private" (by convention since it starts with |
Did you set
I think you'll be best off by just setting When publishing your app you should see feedback in the form of warnings when the library you're using is not compatible with trimming/AOT. Ignoring the warnings and rooting random assemblies is not recommended because unless you know exactly what the code in the library is doing, you're running the risk of either the app being broken off the bat, or being broken in some subtle/non obvious ways (e.g. only in exceptional paths). We have these warnings because it's fundamentally not possible to just take existing .NET code (that has access to many scripting-like facilities) and run trimming/AOT on it. Golang lacks those facilities (there's no |
Previously,
TrimMode
allowed usinglink
orcopyused
modes for assemblies that opted in for trimming.Since .NET 7 Preview 7 (I believe #2856),
TrimMode
now haspartial
orfull
to enable/disable trimming of all assemblies, but now there is no way (unless I missed it) to copy assemblies as is (previouslycopyused
) while not trimming libraries that did not opt in for trimming (currentlypartial
).Is there any way to achieve
copyused
andpartial
mode at the same time?Thanks!
The text was updated successfully, but these errors were encountered: