-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Decide on linker to use in runtime builds #84794
Comments
Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas Issue Details#84148 changed the linker that we use in runtime builds (including when running NativeAOT on our binaries like ILCompiler and crossgen2) to There are a few concerns with this approach - see @am11's comments in #84493 (comment), #84493 (comment), #84148 (comment) for full context. In summary:
@am11 I hope that's a fair summary - please add to this if I missed anything. So I'm opening this to discuss the choice of linker when building our product. Options are:
My preference is to continue using I'm opening this issue to continue the discussion and hopefully reach agreement on the approach. @am11 @janvorli @agocke @MichalStrehovsky @jkotas
|
I thought there was another consideration: we need a relatively recent version of |
Tagging subscribers to this area: @dotnet/runtime-infrastructure Issue Details#84148 changed the linker that we use in runtime builds (including when running NativeAOT on our binaries like ILCompiler and crossgen2) to There are a few concerns with this approach - see @am11's comments in #84493 (comment), #84493 (comment), #84148 (comment) for full context. In summary:
@am11 I hope that's a fair summary - please add to this if I missed anything. So I'm opening this to discuss the choice of linker when building our product. Options are:
My preference is to continue using I'm opening this issue to continue the discussion and hopefully reach agreement on the approach. @am11 @janvorli @agocke @MichalStrehovsky @jkotas
|
We recommend So lets apply the patch, turn default to lld and cleanup Alternatives are making less sense to me:
Why is this? binutils is used since .NET Core 1.0, there is no issue with licensing in using binutils to build any software; proprietary or otherwise.
This is not correct. The "toolchain" does this job. If configured properly, we don't need to manually specify prefixes for cross-compilation.
You will find it pretty hard to discover a distro which is not using
i.e. Line 432 in ed0f1c5
./build.sh -gcc )
|
I don't have a strong opinion on this. We're already in a situation where we can't test E2E the thing that will be produced by the toolchain because the version of ld is out of our control. The solution to that could be to just ship lld in the ILCompiler package. But that's a can of worms since constructing the command line to invoke the linker is per-distro bespoke magic and it's also the reason why we use clang as the "linker" instead of invoking ld directly. Ubuntu 18 comes with lld that is ancient. Ubuntu 22 has a good one. I don't have a good sense of the landscape. If we tell people to use lld but the version we need is hard to obtain, that would be a problem. I also don't like testing with a completely different linker codebase (bfd vs lld) than what we use on customer machines. We did run into linker issues in the past. At least using the same codebase (even though a different version) would keep things more sane. |
This has broken builds on Debian for me.
I do have llvm, clang, and lld in my /usr/bin, but they have a version number on the end. I tried helping the build process out by using ln -s to put a 'lld' in my PATH pointing at the right one, but that didn't fix it. What do I do? |
@kg, this is the situation when we have different versions of clang and lld installed. e.g. if I have clang-16, clang-14 and lld-14, installed, then the following things happen:
This is exactly how
community-driven scenarios are also affected.. Workaround is to |
Thanks, that indeed worked. I did |
cc @omajid |
I think mainly for the same reasoning as with lld
Thanks for the correction - fixed above. I got my wires crossed when I was thinking about the gcc support mentioned in #78559.
Filed #84934 to track this. Regarding runtime linker defaults: it sounds like we are all on board with using Regarding customer NativeAot linker defaults: I don't have a strong opinion on what the default should be, but if we consider both of them to be supported, we should have testing in place for both, at least to cover basic scenarios, even if most of our testing uses the default. |
I'm not quite sure what this means. I think |
I was thinking that the defaults used in ci should match those for the local dev scenario, but if there's a desire for the local dev scenario to use |
Yup, or more generally, the linker the CI legs are frequently using to test all NativeAOT tests is the linker we should recommend in the docs. In case it wasn't obvious, |
I think we could credibly test both linkers. It may not be in PR, but it probably is not a big deal to spin up an ld-specific run of the test suite with Ubuntu-latest-LTS. It seems like there's two separate considerations -- for our official build we want to keep the dependencies as tight as possible, and using LLVM for everything makes sense. But unlike with coreclr, the vast majority of linking is going to happen on user machines, so it's not particularly relevant what linker the official build machines use. In other words, if we think that |
Yes, no confusion here that this issue is about which linker is used to exercise the tests in CI; it is not about which linker is used to build official coreclr release. The linker we use in CI is the linker we should recommend for user. It is a "singular" linker, because we normally do not force non-default NativeAOT options in tests. There are number of options which we don't test and they are left as experimental / community-supported; e.g. static lib/exe, no-pie, static-pie etc. The red flag is our usage of
Makes sense. Alternatively, we can set
|
@jkotas @MichalStrehovsky @sbomer How do we feel about changing the default linker to Presumably we would still use |
nit: its name is |
Fine with me. |
Sounds good. Only one question:
Is the proposal that we would also check if lld is recent enough and consider it missing if it e.g. doesn't support the command line arguments we want to specify? I want to avoid situations when someone is e.g. on Ubuntu 18, installs lld, and gets worse off than if we used bfd (I might be wrong about this one - I don't know how old distros do we have to care about but do know that lld only became "good" "recently"). |
If |
What I meant is that lld is doing worse than bfd size-wise in general, but if we can't do linker script, it's significantly worse and users would be better off using |
The size difference with
I think we can keep it simple. The standing logic is that the newer toolchain brings about better optimizers and analyzers, and older libc is best to increase portability. This combination renders best results on any build machine. (for static executables, old libc is not necessary) |
Closing this since we decided that:
|
#84148 changed the linker that we use in runtime builds (including when running NativeAOT on our binaries like ILCompiler and crossgen2) to
lld
. This was motivated by a desire to move to cross-builds (mariner host OS, targeting old linux rootfs). Usinglld
simplifies the cross-compilation scenarios because it is a cross-linker, so doesn't require a separatebfd
linker with appropriate target prefix. We have also been wanting to move away frombinutils
as a dependency. Note that it doesn't change the default linker for customer NativeAOT scenarios, which still usebfd
.There are a few concerns with this approach - see @am11's comments in #84493 (comment), #84493 (comment), #84148 (comment) for full context. In summary:
lld
was only added recently and has not been well tested.bfd
by default in user scenarios, so we should be testing this in ci.lld
introduces size regression compared tobfd
. Numbers from Write linker script for lld to enable gc-sections #84493 (comment):@am11 I hope that's a fair summary - please add to this if I missed anything.
So I'm opening this to discuss the choice of linker when building our product. Options are:
lld
as we do with Build on CBL-mariner host with rootfs #84148.binutils
linker (need separate cross-linker for each supported architecture) to the mariner build images. We will need to pick the right prefixed linker to use based on the target platform.This is not currently supported in NativeAot.(edit: NativeAot will detect and used the right prefixed linker if available).My preference is to continue using
lld
, but add separate test legs that validate the customer scenarios usingbfd
. One challenge is that our NativeAOT tests usually run NativeAOT on the build machine, not on helix - so they are testing a cross-compilation scenario, not the customer scenario. This is simpler than getting all NativeAOT prerequisites onto the target machines to test native compilation. I think it would be worth adding separate tests for NativeAOT compilation that run in an environment that represents customer scenarios (for example, ubuntu withbfd
).I'm opening this issue to continue the discussion and hopefully reach agreement on the approach.
@am11 @janvorli @agocke @MichalStrehovsky @jkotas
The text was updated successfully, but these errors were encountered: