Stream: t-compiler/major changes

Topic: Update the existing musl targets to be dy… compiler-team#422


triagebot (Apr 01 2021 at 13:55, on Zulip):

A new proposal has been announced: Update the existing musl targets to be dynamically linked. #422. It will be announced at the next meeting to try and draw attention to it, but usually MCPs are not discussed during triage meetings. If you think this would benefit from discussion amongst the team, consider proposing a design meeting.

triagebot (Apr 01 2021 at 19:55, on Zulip):

@T-compiler: Proposal #422 has been seconded, and will be approved in 10 days if no objections are raised.

André Hänsel (Apr 09 2021 at 11:40, on Zulip):

Is this the right place for comments about https://github.com/rust-lang/compiler-team/issues/422?
I might be misunderstanding the benefits of that proposal, but for me it seems like a step back. I use the x86_64-unknown-linux-musl target when I cross-compile from Windows to Linux. When I build on Linux for Linux I use x86_64-unknown-linux-gnu, but I think that target can't do cross-compilation. Now, the binaries I produce should of course run on normal (glibc-based) Linux, and preferably on Alpine Linux (the only musl-based Linux I know) as well. If I understand correctly, if the musl target were to be dynamically linked, they would stop working on normal Linux, right?
Cross-compilation is already crippled by the fact that rustup doesn't install enough stuff to cross-compile C code, so for example simply having the ring crate as a (recursive) dependency already breaks it, and this proposal seems to break even more use cases.

Joshua Nelson (Apr 09 2021 at 12:04, on Zulip):

If I understand correctly, if the musl target were to be dynamically linked, they would stop working on normal Linux, right?

They will be dynamically linked by default, you could still specify static linking with RUSTFLAGS=-Ctarget-feature=+crt-static

André Hänsel (Apr 09 2021 at 12:44, on Zulip):

Would that be possible from Cargo.toml/Cargo-config?

Joshua Nelson (Apr 09 2021 at 12:47, on Zulip):

I don't see why not, cargo.config should work

Joshua Nelson (Apr 09 2021 at 12:48, on Zulip):

When I build on Linux for Linux I use x86_64-unknown-linux-gnu, but I think that target can't do cross-compilation

I haven't tested but I would expect these to work with +crt-static too

André Hänsel (Apr 09 2021 at 12:49, on Zulip):

Well ok, then I don't care. :) Cross-compilation already needs linker = "rust-lld", so one more config line doesn't matter. Best would be if it worked out of the box of course.

Joshua Nelson (Apr 09 2021 at 12:50, on Zulip):

yeah I definitely think we should have a blog post or something explaining exactly how to get the old behavior

André Hänsel (Apr 09 2021 at 12:57, on Zulip):

I haven't tested but I would expect these to work with +crt-static too

Hm, I have set that RUSTFLAGS variable that you wrote and tried a cargo build --target=x86_64-unknown-linux-gnu.

André Hänsel (Apr 09 2021 at 12:58, on Zulip):

Doesn't work.
image.png

Joshua Nelson (Apr 09 2021 at 12:58, on Zulip):

hmm maybe not if you're building with an MSVC toolchain

André Hänsel (Apr 09 2021 at 12:59, on Zulip):

Isn't it a GNU toolchain?

Joshua Nelson (Apr 09 2021 at 12:59, on Zulip):

so it is

Joshua Nelson (Apr 09 2021 at 12:59, on Zulip):

not sure then

André Hänsel (Apr 09 2021 at 13:02, on Zulip):

I learned about that linker = "rust-lld" setting in a GitHub issue that I somehow cannot find right now, but if I remember correctly they explicitly said that cross-compilation on Windows for Linux only works with x86_64-unknown-linux-musl.

André Hänsel (Apr 09 2021 at 13:04, on Zulip):

Ah, found it.
https://github.com/japaric/rust-cross/issues/33#issuecomment-348802985
https://github.com/japaric/rust-cross/issues/33#issuecomment-500111581

hyd-dev (Apr 09 2021 at 13:05, on Zulip):

I think just setting +crt-static won't work. You need to build libc yourself. I think musl works now because libstd (or the libc crate, I'm not sure) distributed by rustup bundles a prebuilt musl, but I assume that's no longer the case if libc becomes dynamically-linked by default.

André Hänsel (Apr 09 2021 at 13:05, on Zulip):

The first comment says you need musl.

Joshua Nelson (Apr 09 2021 at 13:07, on Zulip):

I think musl works now because libstd distributed by rustup bundled a prebuilt musl, but I assume that's no longer the case if the target becomes dynamically-linked by default.

I mean, that doesn't necessarily have to change. I don't think removing it gets us anything other than maybe a little internal cleanup

Wesley Wiser (Apr 09 2021 at 13:39, on Zulip):

Joshua Nelson said:

yeah I definitely think we should have a blog post or something explaining exactly how to get the old behavior

This is very much the plan! The MCP just got posted to /r/rust before we had gotten that far.

simulacrum (Apr 09 2021 at 13:42, on Zulip):

I think you need something like -Cself-contained=yes or something, I forget the name

Wesley Wiser (Apr 09 2021 at 13:45, on Zulip):

@Vadim Petrochenkov mentioned on the MCP:

The correct combination of flags to preserve the old behavior is
-C target-feature=+crt-static -C link-self-contained=yes
because the old musl targets not only link libc statically by default, they also link libc and crt objects shipped with rustc by default, which is also undesirable and should be avoided in the new target config.

Greg (Apr 09 2021 at 15:30, on Zulip):

Is there a reason to not tie this change to the 2021 edition? That would greatly reduce the backwards incompatibility issues...

Joshua Nelson (Apr 09 2021 at 15:33, on Zulip):

editions are per crate, this is a property of the final binary

Joshua Nelson (Apr 09 2021 at 15:33, on Zulip):

also, this is a bugfix, and I don't think bugfixes should be tied to an edition

Greg (Apr 09 2021 at 15:35, on Zulip):

The final binary (or other artifact)... is a crate though? Just take the behavior from the edition of the final binary/artifact (which is the typical place things like target settings are read from...).

This changes the behavior of programs that work perfectly well, so that they don't work anymore. That's not just a bugfix.

nagisa (Apr 09 2021 at 15:51, on Zulip):

Static vs dynamic linking produces different codegen across the crate graph.

Greg (Apr 09 2021 at 15:54, on Zulip):

Yes, I'm not questioning that, so does setting [profile.dev] opt-level=2. Inheriting codegen flags of all kinds from the final crate seems to be normal, I'm not grasping why this is a problem for codegen settings that derive from editions?

nagisa (Apr 09 2021 at 15:59, on Zulip):

Worth it to remove cargo from the equation entirely as it doesn't really interact with editions. Once that's done, how does rustc invocation to compile a dependency know that the final artifact will use edition2021 definition of the musl target? What if the current use produces two final artifacts with different editions?

nagisa (Apr 09 2021 at 16:01, on Zulip):

There could be some sort of a solution here but thatd require a fair amount of design effort I feel

nagisa (Apr 09 2021 at 16:02, on Zulip):

To extend the edition mechanism in rustc that is

Greg (Apr 09 2021 at 16:07, on Zulip):

rustc --help indicates that I can only specify one edition per invocation of rustc - so I assume you're referring to a sitution where I have another build system, I build a dependency with some fixed code gen settings, and then I try to link to it from two binaries, one with edition 2018 and one with edition 2021?

Or to put it another way, to link to 2018 musl crates from 2021 musl crates you'd have to pass in to one of them the flags to say "and use the other editions defaults for how to link to musl". Cargo could do that automatically, but rustc can't because it doesn't know the dependency graph at the time of compiling.

Ok - makes sense that that would at least be mildly problematic...

Simon Sapin (Apr 09 2021 at 16:41, on Zulip):

Has it been considered to make new targets instead of a breaking change to the existing ones?

Joshua Nelson (Apr 09 2021 at 16:42, on Zulip):

yes, that was the original proposal

Joshua Nelson (Apr 09 2021 at 16:42, on Zulip):

https://github.com/rust-lang/rust/pull/82556

Ariadne Conill (Apr 09 2021 at 20:06, on Zulip):

I agree that it would be nice to have a --static shorthand for people who want a static build like before. Would there be any interest in adding that to cargo? I can work on it.

Ariadne Conill (Apr 09 2021 at 20:07, on Zulip):

by all means, we do not want to negatively impact rust users who depend on the specific use case that was enabled by the -musl targets. we just want to not have to fight those targets anymore :)

Ariadne Conill (Apr 09 2021 at 20:10, on Zulip):

Joshua Nelson said:

I think musl works now because libstd distributed by rustup bundled a prebuilt musl, but I assume that's no longer the case if the target becomes dynamically-linked by default.

I mean, that doesn't necessarily have to change. I don't think removing it gets us anything other than maybe a little internal cleanup

it seems to me, the only thing that would change is that rust ships a libc.a alongside the libc crate. that does not seem like it is that difficult to do.

Ariadne Conill (Apr 09 2021 at 20:12, on Zulip):

anyway, i ask for everyone to be patient. we are trying to solve a situation that came about due to lack of early communication. there is no desire to break anybody's particular use case and i think everyone is dedicated to that

Ariadne Conill (Apr 09 2021 at 20:25, on Zulip):

i do however promise you that we're not coming for your static musl binaries. we want people to keep doing that if they want to. making sure that still works is definitely part of the goal here.

Érico Nogueira Rolim (Apr 09 2021 at 20:26, on Zulip):

Ariadne Conill said:

I agree that it would be nice to have a --static shorthand for people who want a static build like before. Would there be any interest in adding that to cargo? I can work on it.

If this can be added for the same release as the target behavior changes, I think it would be ideal. Write a nice blog post about it and include it in the release notes, and everyone updating their rust toolchains in CI/CD can just add the flag :)

Ariadne Conill (Apr 09 2021 at 20:26, on Zulip):

yep

leo60228 (Apr 09 2021 at 21:41, on Zulip):

I'm not personally concerned about the breaking change (though I'm not convinced this would qualify as a bugfix). However, I think that any change should try to avoid additional friction when creating static binaries. --target x86_64-unknown-linux-musl -C target-feature=+crt-static -C link-self-contained=yes is obviously pretty bad in comparison. An x86_64-unknown-linux-musl_static target is one option. Another option could be the --static flag proposed above, though I think some more deliberation is necessary on how that should work. One idea I had was to make --static equivalent to today's --target x86_64-unknown-linux-musl on all x64 Linux hosts, but to make --target x86_64-unknown-linux-gnu --static statically link glibc (which wouldn't necessarily be supported, it could just be an error).

leo60228 (Apr 09 2021 at 21:49, on Zulip):

This seems unrelated, though. Overall I think that changing x86_64-unknown-linux-musl is good, but should definitely be combined with work towards making static linking easier. Another idea is to have --static tie into Cargo to let crates do things like replace openssl with rustls and vendor C dependencies?

Ariadne Conill (Apr 09 2021 at 21:59, on Zulip):

well rust previous behavior with the -musl target could be considered bad too depending on how you look at it

Ariadne Conill (Apr 09 2021 at 21:59, on Zulip):

i call it a bug :)

Ariadne Conill (Apr 09 2021 at 22:00, on Zulip):

i also think --static should not imply a musl target by default

Ariadne Conill (Apr 09 2021 at 22:00, on Zulip):

that would be inappropriate and we may consider that problematic in the musl community :)

Joshua Nelson (Apr 09 2021 at 22:01, on Zulip):

leo60228 said:

This seems unrelated, though. Overall I think that changing x86_64-unknown-linux-musl is good, but should definitely be combined with work towards making static linking easier. Another idea is to have --static tie into Cargo to let crates do things like replace openssl with rustls and vendor C dependencies?

I like the idea that crates can see if they're being compiled with --static

Érico Nogueira Rolim (Apr 09 2021 at 22:01, on Zulip):

leo60228 said:

This seems unrelated, though. Overall I think that changing x86_64-unknown-linux-musl is good, but should definitely be combined with work towards making static linking easier. Another idea is to have --static tie into Cargo to let crates do things like replace openssl with rustls and vendor C dependencies?

I think this is a very different decision, and should probably still depend on feature flags. rustls doesn't even work on powerpc, for example.

Ariadne Conill (Apr 09 2021 at 22:03, on Zulip):

to be clear to the musl community, the use of the -musl targets in rust presently is inappropriate, in the same way that distributing a modified firefox would be seen as mozilla as inappropriate

Ariadne Conill (Apr 09 2021 at 22:03, on Zulip):

(we have discussed this at length already and the devs understand our position, i just mention it again for end users who are new.)

Ariadne Conill (Apr 09 2021 at 22:05, on Zulip):

specifically, the promotion of the concept that musl is explicitly for static linking by the rust community has done harm to musl. rich already elaborated on that in the original PR though :)

leo60228 (Apr 09 2021 at 22:16, on Zulip):

I understand the issues with musl implying static, though I'm not sure I see the issue with static defaulting to musl. In my experience, musl conventional for statically linked binaries on Linux, not just for Rust code.

Ariadne Conill (Apr 09 2021 at 22:20, on Zulip):

which means that you are a victim of the misrepresentation of musl as a project

Ariadne Conill (Apr 09 2021 at 22:20, on Zulip):

the largest consumer of musl is alpine, the second largest is openwrt, the third largest is void

Ariadne Conill (Apr 09 2021 at 22:20, on Zulip):

all of which are dynamically linked distributions

Ariadne Conill (Apr 09 2021 at 22:23, on Zulip):

yes, musl is much better at static linking than glibc, and that’s something the musl community is quite happy to evangelize, but in general musl should be regarded in the same way as glibc. the default and preferred linking mode is dynamic.

Ariadne Conill (Apr 09 2021 at 22:24, on Zulip):

if you download a prebuilt musl cross compilation toolchain from musl.cc, it does not generate static binaries by default, even when cross compiling. this is why we view the difference in rustc behavior to be inappropriate.

Ariadne Conill (Apr 09 2021 at 22:26, on Zulip):

and of course had the rust team discussed with us prior to implementing the musl port in the first place, this entire situation could have been avoided. instead, the musl community has to basically retcon in an entirely different set of targets to replace the ones rust ships. that’s not good for the musl community or rust, and it doesn’t make the musl community want to evangelize rust, even though many other interests are aligned

Ariadne Conill (Apr 09 2021 at 22:28, on Zulip):

this is an admittedly disruptive change but a change i hope will be fruitful, by making it easier for the musl community to support rust users, there will be more evangelism of rust in the musl community. more adoption is good for everyone.

Érico Nogueira Rolim (Apr 09 2021 at 22:30, on Zulip):

And for the record, people can want to statically link glibc, for whatever reason. ld spits out warnings if you use features which don't work well with static linking (so DNS, dealing with users/groups, and iconv), but if you don't make use of them, things will mostly work

leo60228 (Apr 09 2021 at 23:11, on Zulip):

For some reason I was under the impression that glibc was licensed under the GPL with an exception for static linking. I'm not sure where I got that idea from. --static on x86_64-unknown-linux-gnu without a --target flag defaulting to statically-linked glibc makes sense then, I think.

leo60228 (Apr 09 2021 at 23:12, on Zulip):

--static defaulting to musl was more that I'd like to be able to produce a working static binary with a single flag (today --target=x86_64-unknown-linux-musl, possibly --static in the future). I'm fine with other solutions that provide that too.

Ariadne Conill (Apr 09 2021 at 23:13, on Zulip):

--target=x86_64-unknown-linux-musl does not semantically mean "give me a static binary" though. that meaning is the result of harmful misrepresentation of the musl project by evangelists with good intentions. the road to hell is paved with good intentions, as they say.

leo60228 (Apr 09 2021 at 23:24, on Zulip):

I'm not disagreeing with that. My point is solely from a usability perspective. Today, the single flag --target=x86_64-unknown-linux-musl will produce a useful static binary. After any musl-related changes, I'd like there to still be a single flag that does so, though I'm less concerned about what that flag is or the implementation of it.

leo60228 (Apr 09 2021 at 23:29, on Zulip):

My understanding is that the proposal here is to improve the experience for people using musl-based systems, which I support. I was considering ways to avoid worsening the experience for building static Linux binaries.
I think the analogy between --static and --target=x86_64-unknown-linux-musl was misleading on my part. I was just trying to clarify that I think it's important that with a theoretical --static flag then cargo build --static would "just work," without any need for something like cargo build --target=x86_64-unknown-linux-musl --static.

Ariadne Conill (Apr 10 2021 at 01:21, on Zulip):

well, no, --static should give you a static binary, even if your static binary uses parts of glibc that is broken with static linking. if you want musl, you should ask for musl with --target. tools should not try to outsmart their operators, that turns them into a useful foot gun.

Ariadne Conill (Apr 10 2021 at 01:22, on Zulip):

it is a feature that your tool does exactly what you specify, nothing more or less.

Ariadne Conill (Apr 10 2021 at 01:23, on Zulip):

there is also the problem of C dependencies, if you compile dependencies with your glibc toolchain, and then staticly link them into a musl binary, bad things are likely to happen.

Ariadne Conill (Apr 10 2021 at 01:23, on Zulip):

which is a problem already

Érico Nogueira Rolim (Apr 10 2021 at 04:22, on Zulip):

Ariadne Conill said:

which is a problem already

https://github.com/rust-lang/rust/issues/82912 for reference

Lokathor (Apr 10 2021 at 05:08, on Zulip):

if you ask for --static and the target can't provide it, cargo should just say that and suggest an alternateive.

Ariadne Conill (Apr 10 2021 at 05:14, on Zulip):

sure, that would be reasonable

Josh Triplett (Apr 12 2021 at 06:30, on Zulip):

With my cargo team hat on, I would love to see a --static option, as well as a corresponding .cargo/config.toml option (in a target's section).

Josh Triplett (Apr 12 2021 at 06:30, on Zulip):

Short-term it should just affect the options used to build.

Josh Triplett (Apr 12 2021 at 06:31, on Zulip):

Long-term (not in the initial version) I would love to expose that to crates so they know to link external libraries statically vs dynamically.

Ariadne Conill (Apr 12 2021 at 06:43, on Zulip):

yep that is what i had in mind @Josh Triplett :)

Alex Crichton (Apr 12 2021 at 18:36, on Zulip):

I've read over some of the discussion here and on the issue (although not super closely), but I figured it might be worth adding my thoughts here. My main reaction is that this change is going to likely cause a lot of breakage that's very hard to detect up-front throughout the ecosystem. Since added I (and I think many others?) have equated the Rust target with a statically linked binary to run on Linux. I saw that the migration plan involves lints but almost all of the musl build processes I've created are in CI and I don't really watch them daily so at least for me personally once this change is made I'll probably have a long tail of projects where whenever they receive a PR with failing CI I'll need to go fix them. I don't personally have an opinion on whether this change is worth the breakage or not.

I do, however, think that this is indicative of a larger problem that may be worth solving (not blocking this change per se, just a problem to have on the radar). Currently AFAIK there's a lot of reported pain trying to compile projects dynamically linked against musl, whereas compiling statically is much easier. I am also under the impression that the pain is "you need to pass RUSTFLAGS to Cargo". In that sense by switching the defaults it seems like it's just penalizing a different group of users. All the pain previously felt by those wishing to link dynamically will now be felt by those linking statically. I won't really pretend to think I have an answer to this, but I figured it'd be worth pointing out.

The last thing that I'd add is that I haven't seen anywhere the expected scale of what the breakage is going to look like. Or rather what the expected scale of "folks who need to update their build processes to pass new flags". That I realize would be very hard to measure, but would also be a very valuable data point in considering a change like this. For example making a change like this probably looks quite different if it affects 90% of Rust users vs 1%.

Jason Mobarak (Apr 12 2021 at 19:38, on Zulip):

I definitely support the idea of a --static flag that's analogous to the current musl target (regardless of whether this also requires a target specification to achieve the current behavior)-- we don't use any musl dynamic targets, but we do build fully static binaries using the current musl target. I also advocate the relative ease of creating fully static binaries as one of the benefits of Rust.

Vadim Petrochenkov (Apr 12 2021 at 20:04, on Zulip):

Sigh, static linking is not the (whole) point of the current musl behavior.
The point is "self-containedness" - you only install Rust, no extra toolchains, and you are immediately able to produce static executables (which are also self-contained).
This approach requires shipping libc binaries together with Rust toolchain, so if this is something you are going to do it with the proposed "--static flag", then 1) the flag will be a misnomer (statically linking with non-bundled toolchain makes very much sense too, but doesn't satisfy the self-containedness property), 2) the flag will pretty much work for musl only because you cannot bundle, for example, glibc for licensing reasons, IIRC, 3) libc bundling received many complaints in the past about libc not being properly updated (which led to #72274).

Andrew Chin (eminence) (Apr 12 2021 at 20:56, on Zulip):

If I read the github issue correctly, it looks like under this proposed change, the behavior of compiling with --target x86_64-unknown-linux-musl will be essentially:

env RUSTFLAGS="-C target-feature=-crt-static" cargo build --target x86_64-unknown-linux-musl

Is that right?

Andrew Chin (eminence) (Apr 12 2021 at 21:04, on Zulip):

If so, then for at least some cases (like for me), the breakage will be immediate, as compiling with -C target-feature=-crt-static results in an immediate build error. If this will be true for most people, then it seems like this change might cause wide-spread annoyance, but it's not likely to cause any hard to detect "hidden effects" (for example, a build that is successful, but fails at runtime in some non-obvious way)

Ariadne Conill (Apr 13 2021 at 00:24, on Zulip):

Alex Crichton said:

I've read over some of the discussion here and on the issue (although not super closely), but I figured it might be worth adding my thoughts here. My main reaction is that this change is going to likely cause a lot of breakage that's very hard to detect up-front throughout the ecosystem. Since added I (and I think many others?) have equated the Rust target with a statically linked binary to run on Linux. I saw that the migration plan involves lints but almost all of the musl build processes I've created are in CI and I don't really watch them daily so at least for me personally once this change is made I'll probably have a long tail of projects where whenever they receive a PR with failing CI I'll need to go fix them. I don't personally have an opinion on whether this change is worth the breakage or not.

I do, however, think that this is indicative of a larger problem that may be worth solving (not blocking this change per se, just a problem to have on the radar). Currently AFAIK there's a lot of reported pain trying to compile projects dynamically linked against musl, whereas compiling statically is much easier. I am also under the impression that the pain is "you need to pass RUSTFLAGS to Cargo". In that sense by switching the defaults it seems like it's just penalizing a different group of users. All the pain previously felt by those wishing to link dynamically will now be felt by those linking statically. I won't really pretend to think I have an answer to this, but I figured it'd be worth pointing out.

The last thing that I'd add is that I haven't seen anywhere the expected scale of what the breakage is going to look like. Or rather what the expected scale of "folks who need to update their build processes to pass new flags". That I realize would be very hard to measure, but would also be a very valuable data point in considering a change like this. For example making a change like this probably looks quite different if it affects 90% of Rust users vs 1%.

Mostly agree, but at the same time, what rust is implying with the -musl targets is harmful to the musl community. I think having a self-contained executable feature is awesome, and have nothing against that, but the association that musl == self-contained executables is fundamentally harmful to musl, to the point that we are now formulating a policy document to ensure this never happens again. It makes sense that musl be used as a basis for this feature, but this feature should not be called "musl" if that makes sense.

Ariadne Conill (Apr 13 2021 at 00:34, on Zulip):

i would like to arrive at a scenario where the -musl targets do not violate musl policies, and the ability to easily make self-contained executables is retained.

Ariadne Conill (Apr 13 2021 at 00:36, on Zulip):

perhaps introducing a new set of targets explicitly for the self-contained executables feature, calling them something like -sce, which does all of the things needed to have musl as a self-contained executable could work for that and allow us to have -musl targets creating conformant binaries for musl-platform hosts

Érico Nogueira Rolim (Apr 13 2021 at 01:06, on Zulip):

Vadim Petrochenkov said:

Sigh, static linking is not the (whole) point of the current musl behavior.
The point is "self-containedness" - you only install Rust, no extra toolchains, and you are immediately able to produce static executables (which are also self-contained).
This approach requires shipping libc binaries together with Rust toolchain, so if this is something you are going to do it with the proposed "--static flag", then 1) the flag will be a misnomer (statically linking with non-bundled toolchain makes very much sense too, but doesn't satisfy the self-containedness property), 2) the flag will pretty much work for musl only because you cannot bundle, for example, glibc for licensing reasons, IIRC, 3) libc bundling received many complaints in the past about libc not being properly updated (which led to #72274).

So maybe cargo --target x86_64-unknown-linux-musl --self-contained? Where --self-contained could imply --static (which IMO still makes sense as a separate flag - there are cases where static linking works just fine). Then using just --static will use libc.a from the linker's library search path instead of the bundled one.

Alex Crichton (Apr 13 2021 at 01:24, on Zulip):

@Ariadne Conill to clarify, I'm specifically not passing personal judgement on whether I agree with this change or not. My point is that irrespective of its correctness Rust has stability guarantees and I think that they're important to consider. Rust has had breaking changes in the past fixing bugs, but even small bugs which have the possibility of breaking many users are carefully scrutinized to figure out the best roll-out plan. The "have our cake" part here seems to be to switch the targets to align with other targets and the musl community, but the "eat it too" part will come from rolling this out in a way that doesn't abruptly cause the Rust community to lose faith in the compiler's stability guarantees or the compiler's musl target.

I realize, though, that I'm literally the one to blame for this quandry. I added the musl targets originally to Rust and advocated for their inclusion. There's not much I can do about that now, though, so I wanted to at least offer my thoughts on the stability/breakage aspect.

nagisa (Apr 13 2021 at 09:38, on Zulip):

Worth noting that targets/compiler APIs never really had a stability coverage as thorough as libs or language interfaces. This has a potential to be a change affecting most users so far compared to other breaking target changes we've done in the past, though.

Lokathor (Apr 13 2021 at 13:32, on Zulip):

i like the -sce plan because it's a plan that could also be rolled out for windows and mac builds too.

nagisa (Apr 13 2021 at 14:21, on Zulip):

I don't see why we couldn't do whatever musl would do (most likely a separate component of some sort?), but distributing proprietary binaries is unlikely to be something we'd be able to do in general, I don't think.

Lokathor (Apr 13 2021 at 14:29, on Zulip):

I am not aware of any proprietary code that would need to be distributed for a windows SCE.

pnkfelix (Apr 13 2021 at 18:59, on Zulip):

@Alex Crichton my attitude is that whatever lint is issued here, it needs to be given the same treatment as “future incompatibility lints”, which are meant to get somewhat more visiblility in the build output (in terms of being summarized at the end of even a successful build).

pnkfelix (Apr 13 2021 at 18:59, on Zulip):

its true that maybe people won’t even notice that. But at some point then the line is going to be “do you break the build, or do you not break the build."

pnkfelix (Apr 13 2021 at 19:00, on Zulip):

I want us to at least consider being willing to break the build. The project is still relatively young, we should be brave enough to fix mistakes like this.

Alex Crichton (Apr 13 2021 at 20:32, on Zulip):

@pnkfelix makes sense about the lints yeah. Also though I'm neither advocating for or against this change, and I agree that breakage is fine to happen in the general sense (Rust/Cargo have historically had many instances of breakage in the past). I also agree that it's ok for Rust to change these targets.

My points are about assessing the expected scale of breakage (this seems unlikely to be feasible and/or possible) and also about how if many folks complained about passing the -Ctarget-feature=-crt-static flag then there's likely also going to be many folks complaining about passing the -Ctarget-feature=+crt-static flag (plus the -Clink-self-contained=yes flag)

pnkfelix (Apr 13 2021 at 21:05, on Zulip):

It does seem hard to assess the scale of breakage if the diagnostic gets overlooked by our users, for whatever reason.

pnkfelix (Apr 13 2021 at 21:07, on Zulip):

Also, it is sounding like people are pushing for a new -Clink-self-contained=yes flag. I don’t mind adding that, but it does change the trade-offs here slightly, in that, under my former understanding, we were going to be able to silence the lint here by using a flag that the compiler already supports.

pnkfelix (Apr 13 2021 at 21:07, on Zulip):

But if this -Clink-self-contained=yes flag is going to be the official way to achieve the desired goal here, then that’s a new flag...

Andrew Chin (eminence) (Apr 13 2021 at 21:09, on Zulip):

this is a very weak measure, but here is a search of github that I think shows how many github CI workflows build with the x86_64-unknown-linux-musl. These results don't show how many are already using RUSTFLAGS to set the necessary target-feature. But if we assume that most of these don't, then there's probably going to be about 1000 different projects that will probably have broken CI builds if they did nothing

(here's a similar search for travis CI)

simulacrum (Apr 13 2021 at 23:17, on Zulip):

That flag... already exists I think?

Joshua Nelson (Apr 13 2021 at 23:18, on Zulip):

well it certainly does something

Joshua Nelson (Apr 13 2021 at 23:18, on Zulip):
$ rustc -Clink-self-contained=yes main.rs
$ ./main
Segmentation fault (core dumped)
Joshua Nelson (Apr 13 2021 at 23:19, on Zulip):

(this is a x86_64-unknown-linux-gnu host)

Ariadne Conill (Apr 13 2021 at 23:25, on Zulip):

that's likely because the wrong crtN.o blob is used :P

Joshua Nelson (Apr 13 2021 at 23:27, on Zulip):

what does that mean?

nagisa (Apr 13 2021 at 23:28, on Zulip):

It is (also) dynamically linked, still.

Joshua Nelson (Apr 13 2021 at 23:29, on Zulip):

nagisa said:

It is (also) dynamically linked, still.

rustc -Ctarget-feature=+crt-static -Clink-self-contained=yes main.rs also segfaults

Joshua Nelson (Apr 13 2021 at 23:31, on Zulip):

anyway it's not really important for gnu targets

Jonas Schievink [he/him] (Apr 13 2021 at 23:35, on Zulip):

our crt object logic is documented here https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/spec/crt_objects/index.html

Ariadne Conill (Apr 14 2021 at 03:16, on Zulip):

basically if you wind up with two instances of libc in a single binary, it will violently explode.

Érico Nogueira Rolim (Apr 14 2021 at 12:43, on Zulip):

pnkfelix said:

But if this -Clink-self-contained=yes flag is going to be the official way to achieve the desired goal here, then that’s a new flag...

I'm not sure if a relevant cargo flag is implied here, but I think making the behavior depend on long verbose RUSTFLAGS setting is not really ideal; having a fully supported cargo --sce or similar (which removes the need, for now, for a --static, if we want to discuss that into the future) makes for a much better user experience, and avoids using the same flags for the build tools (proc_macros and whatever other friends)/.

pnkfelix (Apr 14 2021 at 14:09, on Zulip):

I was only speaking from the perspective of the interface into rustc up above, not the whole end-to-end experience of someone using cargo. I agree that we can provide a better user-experience there.

pnkfelix (Apr 14 2021 at 14:10, on Zulip):

simulacrum said:

That flag... already exists I think?

hmm, okay, my mistake. (Though I guess it sounds like we might have to change its current behavior, if I understand the rest of the conversation correctly.)

Vadim Petrochenkov (Apr 17 2021 at 10:37, on Zulip):

I have a suggestion that may be silly or may be not - report all the warnings discussed above in cargo instead of rustc.

Cargo detects situations similar to a "typical CI setup" linked above (https://github.com/search?q=x86_64-unknown-linux-musl+extension%3Ayml+extension%3Ayaml+path%3A%2F.github%2F&type=Code&ref=advsearch&l=&l=), and adds -Ctarget-feature=+crt-static -Clink-self-contained=yes to the compiler flags automatically with a warning and suggestion to add the flags manually.

Vadim Petrochenkov (Apr 17 2021 at 10:39, on Zulip):

In this case the tool providing the suggestion will be the same tool that is to blame if the suggestion doesn't work (due to cargo's target vs host flags issues).

Ariadne Conill (Apr 27 2021 at 18:40, on Zulip):

hi, i am just checking in to see what the next steps are with this

Josh Triplett (Apr 27 2021 at 18:50, on Zulip):

I recently made a related change: the next version of libz-sys will stop assuming that musl means static linking, and will allow dynamically linking zlib on a musl target if available.

Josh Triplett (Apr 27 2021 at 18:50, on Zulip):

So if you're using musl and libz-sys, and want to statically link, you'll have to specify the static feature flag to libz-sys.

Josh Triplett (Apr 27 2021 at 18:51, on Zulip):

(Long-term, I think cargo needs a general "I want to statically link" indication that can be passed down to library crates.)

pnkfelix (Apr 28 2021 at 01:57, on Zulip):

Ariadne Conill said:

hi, i am just checking in to see what the next steps are with this

So the MCP itself has been seconded. I don’t think any concerns have been raised that would lead to us to abandon the proposal. I do think the proper next steps are to update the proposal itself with some additional info to help address the concerns that have been raised.

Vadim Petrochenkov (Apr 28 2021 at 11:17, on Zulip):

The change will also obviously not happen without an implementation - 1) switching defaults in target specs, trivial + 2) compatibility layer / warnings preferably in cargo, shouldn't be hard either.

I'd expect one of the musl people pushing for the change to step in and implement this, otherwise it's unlikely to be done any time soon.

pnkfelix (Apr 28 2021 at 15:33, on Zulip):

I think I should be able to mentor the development effort, though

pnkfelix (Apr 28 2021 at 15:34, on Zulip):

that is, I agree with @Vadim Petrochenkov that the bulk of the work should probably come from a stakeholder, but that stakeholder shouldn’t have to fear that they’d be working in a vacuum.

Josh Triplett (Apr 28 2021 at 16:23, on Zulip):

A thought just crossed my mind that we could reasonably have a transition period here. Specifically, when building for a musl target, if we're not given an option one way or the other regarding static linking, we could attempt to detect if we have a system version of musl available to link to, and if we don't find one, we could statically link but emit a warning explaining that in the future we will default to dynamic.

Josh Triplett (Apr 28 2021 at 16:24, on Zulip):

If you have a system version of musl that we can find, or if rustc itself is built for musl, we can skip that transition period and always assume you want to link dynamically unless you specifically request static linking.

Josh Triplett (Apr 28 2021 at 16:26, on Zulip):

I think that behavior would help people who are currently relying on the default of static linking to transition to needing to specify that.

pnkfelix (Apr 28 2021 at 16:38, on Zulip):

Interesting. That's a step further than the diagnostic I was proposing

Josh Triplett (Apr 28 2021 at 17:57, on Zulip):

@Ariadne Conill For distributions that ship dynamically linked musl binaries, is the Rust toolchain built with musl as well?

Josh Triplett (Apr 28 2021 at 17:58, on Zulip):

(I'd assume so, unless you're cross-compiling from another system.)

Ariadne Conill (Apr 28 2021 at 20:41, on Zulip):

yes

Ariadne Conill (Apr 28 2021 at 20:42, on Zulip):

i can do the work next week, probably.

Ariadne Conill (Apr 28 2021 at 20:42, on Zulip):

i just formally became chair of the new alpine security team, so i am trying to hit the ground running with that in the immediate moment, but should be able to circle back to this next week :)

Wesley Wiser (Apr 28 2021 at 21:23, on Zulip):

Congrats! :smile:

Josh Triplett (Apr 28 2021 at 23:06, on Zulip):

Ariadne Conill said:

yes

Given that, I think we'd get a lot of benefit out of a transition period that makes musl-based toolchains default to dynamic linking for musl targets right away, and makes non-musl-based toolchains make a best effort to look for a dynamic libmusl to link to (use it if found, static link and warn for a release or two otherwise).

Josh Triplett (Apr 28 2021 at 23:07, on Zulip):

That should allow for a fairly fast transition, and give plenty of warning to anyone who is currently assuming musl means static, without forcing any long-term issues after the transition.

Ariadne Conill (Apr 29 2021 at 00:35, on Zulip):

yeah i thought we were all on the same page regarding that :)

Josh Triplett (Apr 29 2021 at 05:08, on Zulip):

We'd talked about a transition period, but I hadn't seen any mentions of how we could make that transition smoother other than designating a cutover point and announcing it.

simulacrum (Apr 29 2021 at 11:35, on Zulip):

We could potentially make it opt-in via some workspace Cargo.toml flag and make it dependent on the edition of the root. Bit awkward, but not necessarily that bad, and realistically pretty soon.

simulacrum (Apr 29 2021 at 11:36, on Zulip):

(we could also phase it in across all editions over time like NLL after that)

apiraino (May 06 2021 at 17:30, on Zulip):

Hello all, according to the MCP procedure, this proposal should be accepted and issue #422 closed.
Since the discussion went to some length, I'm asking if I can close it (as the implementation will run on another track)

Last update: May 07 2021 at 08:00UTC