-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Add rustc-bin-link-arg and rustc-link-arg custom build options #7811
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @ehuss (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
@ehuss @alexcrichton FYI, the Enarx project needs this for our microkernels. |
@joshtriplett Tagging you due to your comment here: #6298 (comment) |
I like this very much, and it mostly looks reasonable to me. I don't think it's worth pulling in a new dependency just for this, though. Would you consider making a version that doesn't pull in bitflags, and just uses an enum? I would happily propose such a version for merge. (This introduces new interfaces, so I would want to get team consensus. |
66d69b6
to
2a66af5
Compare
@joshtriplett I pushed a version that does not add a |
Looks good to me. Confirming consensus for the new interface: @rfcbot merge |
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
I think before merging this it would be good to add some tests. Additionally, to confirm, this does not transitively apply throughout the crate graph, right? Only for one particular package? Also, we initially hesitated in adding this degree of custom link arguments for disambiguation reasons. For example there's no way to pass custom link args to just one binary in a multi-binary project. Similarly can you clarify the use cases of I personally think that we'll want to add the ability to pass custom link arguments for just one binary at a time, and then having an escape hatch for "pass this everywhere" also seems fine. |
A test for this (and probably other stuff) would probably be wise. I'm not super familiar with the cargo code base. Could you give me a recommendation of where to start?
This strikes me as an orthogonal concern. Having a "global args" option doesn't preclude having a "local args" option.
We are producing a kernel. The most important use is a linker script to control layout. We also don't want rustc to strip what it thinks are unused symbols. We are also producing a specialized ELF loader which needs to ensure its own contents are loaded out of the way. We use a linker script for this. Someone might theoretically propose an alternative interface for just linker scripts. The problem is that they aren't portable at all. So you're already way into the weeds when you have need for one. The bottom line is that if Rust is a systems language (it is), you need to have control over the linker (is this the right place to complain about
A linker script to strip unwanted sections is something that would be fairly commonly used across all linked artifacts.
Although there may be need for this, I'm not aware of any.
As I mentioned above, nothing in this patch prevents this. I simply consider it out of scope of this patch. It is also perfectly possible to split crates to have one binary per crate to work around this problem. |
We discussed this in the Cargo team meeting, and came to the following conclusions:
Does that sound reasonable, as a path forward? |
Regarding crates with multiple binaries: I personally think it's reasonable to have an option for all binaries; that doesn't preclude us adding another option for a specific binary in the future. |
Done: https://internals.rust-lang.org/t/rustc-bin-link-arg-and-rustc-link-arg/11695
If this requires unstable Rust, we don't gain any value from this option since our project does not allow the use of nightly. I also personally dislike this option because it will likely break out of the box |
On January 23, 2020 7:40:57 PM PST, Nathaniel McCallum ***@***.***> wrote:
> We discussed this in the Cargo team meeting, and came to the
following conclusions:
>
> * This needs a bit of further discussion on internals; could you
please start a thread on it? (We're not asking for it to be bikeshedded
extensively, just asking for it to be looked at by a broader audience
to find out if it fits the needs of others.)
Done:
https://internals.rust-lang.org/t/rustc-bin-link-arg-and-rustc-link-arg/11695
> * If you'd like to experiment with this _before_ that discussion
concludes, or provide a way for people to experiment with it, then you
could make it unstable for a bit, requiring a `-Z build-link-arg` or
similar to enable it. (We could detect that output from the build
script, and if the flag is not present, provide a warning if not using
the `-Z build-link-arg` option.) When the discussion concludes, we
could drop that flag and process this build script output by default.
If this requires unstable Rust, we don't gain any value from this
option since our project does not allow the use of nightly. I also
personally dislike this option because it will likely break out of the
box `rls` setups (which will be unable to build projects using this
option).
We're not suggesting that this remain unstable for a prolonged period of time. In particular, since this seems like a straightforward extension of the existing linker args mechanism to additional crate types, I don't expect a substantial degree of complexity here. What we're suggesting is that while the discussion proceeds on internals, you could implement a version of this that's enabled with a -Z option, and for my part I would have no problem merging such a version immediately. The participants in the internals discussions can try it out immediately (and I'd like to do so myself), you can simply submit a PR to delete the -Z option.
|
Both are similar to rustc-cdylib-link-arg. The rustc-bin-link-arg option adds -C link-arg=... on binary targets. The rustc-link-arg option adds -C link-arg=... on all supported targets (currently only binaries and cdylib libraries).
This hides the new rustc-bin-link-arg and rustc-link-arg build script configuration items behind an unstable flag.
@joshtriplett I added |
Looks great, thank you! I would be in favor of merging this, for experimentation purposes, and opening a tracking issue for future stabilization. @alexcrichton @ehuss @nrc Does this seem reasonable, with the unstable option added to gate it? |
No problem.
I actually tried to do this when I added
It seems to me that such a warning would need to have a view of both the parsed options and all artifacts in the current crate. Could you recommend such a place?
I think it is reasonable to ask for tests. However, I'm not sure how to actually implement a test that can be applied everywhere. A build script, for example, will only work on some linkers. Adding
Does anyone have a suggestion?
I honestly don't know. Many linker arguments contain
A binary that loads plugins (cdylib) would do this. And it may share a linker script to strip out unneeded ELF sections. |
You'll need to pass a bool into the parsing code that indicates whether or not the unstable flag is enabled. Code like Code like
I think similar to above, inside
I think it would be reasonable to create a very basic test that just makes sure the flags are passed to rustc, but they don't actually have to work. So, for example, have a build script that emits // This is just verifying the flag is passed. Since it is a bogus flag, it should cause a failure.
p.cargo("build -v")
.with_status(101)
.with_stderr_contains("[RUNNING] `rustc --crate-name foo [..]-C link-arg=--this_is_a_bogus_flag[..]")
.run(); At least, I think that should fail on all platforms. |
☔ The latest upstream changes (presumably #7857) made this pull request unmergeable. Please resolve the merge conflicts. |
@npmccallum do you still plan on pushing on this? For some context this would also end up being pretty useful to the tch-rs create as we need to pass the |
Is this the right place to complain about the fact that cargo still only allows a single cdylib crate in a package? I disagree with this argument because if we ever do finally support multiple cdylibs in a single package, then the disambiguation problem will already exist with the current This feature would be extremely useful for Windows users, allowing us more control over linking to manifests, which is a necessary fact of life for any serious production software on Windows. |
@npmccallum I'm still interested in this, if you have the bandwidth for it. |
@joshtriplett I still think this approach is valid for other reasons. However, we ended up taking a different approach. Specifically, we are working to have static-pie working by default on |
@npmccallum I still have a need for this myself, if you have any plans to implement it in the future. (Also, note that musl has some performance issues.) |
Windows users have a general need for this and would love to have this. |
in |
@joshtriplett, I took a stab at finishing implementing this in #8441. |
Cargo currently cannot handle our needs. It cannot build static binaries with the standard entry point on glibc. Nor can it build cdylib or static binaries with a custom entry point on musl. Nor can it build different crates for different targets in the same workspace. While we work to resolve these issues in upstream cargo, we need to ditch the top-level workspace for now. We can revisit this at a later time. For more background, see: rust-lang/cargo#7811 rust-lang/cargo#7804 https://github.com/rust-lang/rfcs/pull/2735/files
Finish implementation of `-Zextra-link-arg`. This is a continuation of #7811, which adds tests and a warning if the `-Zextra-link-arg` flag is not specified. Also moved the documentation into `unstable.md`.
Closing, as I believe this is now implemented via #8441. Thanks @npmccallum for getting it started! |
Stabilize the rustc-link-arg option This change removes the unstable option (tracked by #9426) and unconditionally accepts additional linker arguments (as implemented in #7811 and #8441). Documentation is moved from unstable to what appeared to be the correct location. I am not aware of any significant concerns with the option and it appears consistent with some other existing stable linker options. Please let me know if this is not the appropriate process or if there is anything that I am missing from the PR.
Per the comment for `RUSTC_FLAGS_FOR_BIN`: > Ultimately, this should move to the Cargo.toml, for example when > rust-lang/cargo#7811 is merged into Cargo. this moves setting the linker script search path to build.rs, which is enabled by the addition of the `cargo:rustc-link-arg=FLAG` instruction for build scripts. This removes the need to special case the -L flag so that it is only used when creating a binary and not when compiling dependencies, since that is exactly what the new build script instruction handles.
Both are similar to
rustc-cdylib-link-arg
. Therustc-bin-link-arg
option adds-C link-arg=...
on binary targets. Therustc-link-arg
option adds-C link-arg=...
on all supported targets (currently only binaries and cdylib libraries).