Skip to content
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

Tracking issue for link_args stabilization #29596

Closed
aturon opened this issue Nov 5, 2015 · 30 comments · Fixed by #83820
Closed

Tracking issue for link_args stabilization #29596

aturon opened this issue Nov 5, 2015 · 30 comments · Fixed by #83820
Assignees
Labels
A-linkage Area: linking into static, shared libraries and binaries B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-dev-tools Relevant to the dev-tools subteam, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@aturon
Copy link
Member

aturon commented Nov 5, 2015

This issue tracks stabilization for the #[link_args] attribute.

@aturon aturon added T-lang Relevant to the language team, which will review and decide on the PR/issue. B-unstable Blocker: Implemented in the nightly compiler and unstable. labels Nov 5, 2015
@aturon
Copy link
Member Author

aturon commented Nov 5, 2015

@alexcrichton (or anyone else), any ideas what the blockers are here?

@aturon
Copy link
Member Author

aturon commented Nov 5, 2015

From the reference:

The compiler's usage of the system linker is not guaranteed to continue in the future, and if the system linker is not used then specifying custom flags doesn't have much meaning.

@alexcrichton
Copy link
Member

Some thoughts of mine:

  • Right now we split arguments on spaces, so there's no way to specify an argument with a space in it
  • This is super non-cross-platform. Even within one platform there's no guarantee that we'll always call the same linker.
  • It's unclear what the "propagation semantics" of link args should be. For example if you build an rlib, should the arguments be passed to when that rlib is included in a linker invocation? Should it be passed upstream continuously after that is then later used in linker invocations?

@WiSaGaN
Copy link
Contributor

WiSaGaN commented Jan 18, 2016

Since we do not have a good solution for now, but as a system language, it is sometimes necessary to specify args like this (even only for specific platforms), put it behind a feature gate and only letting nightly branch to use it seems to be a compromise to make.

@iwinux
Copy link

iwinux commented Feb 18, 2016

Got hit by this issue when trying out https://gist.github.com/jansegre/043f5ab7f53e23890eed.

As LuaJIT requires, I need to link the binary with flags -pagezero_size 10000 -image_base 100000000, which seems only achievable via #[link_args = "..."].

Could this be done without using Rust nightly? Obviously link_args is not available as of Rust 1.6.0:

src/main.rs:1:1: 1:23 error: #[feature] may not be used on the stable release channel
src/main.rs:1 #![feature(link_args)]

@retep998
Copy link
Member

You can use the command line flag -Clink-args="-pagezero_size 10000 -image_base 100000000" which does work fine (or cargo rustc -- -Clink-args="blah")

@comex
Copy link
Contributor

comex commented Jun 6, 2016

It seems strange to allow -C link-args on the command line without -Z unstable-options, yet keep the source code equivalent unstable.

@retep998
Copy link
Member

retep998 commented Jun 6, 2016

I'd rather we fix the issue with being unable to have spaces in the linker arguments before stabilizing either of them. Unfortunately -Clink-args being stable makes that difficult.

@retep998
Copy link
Member

retep998 commented Jun 22, 2017

So uh, is it intentional that this became accidentally stable?

#![link_args = "-l bunny"]
fn main() {}
rustc 1.18.0 (03fc9d622 2017-06-06)
warning: unused attribute
 --> <anon>:2:1
  |
2 | #![link_args = "-l bunny"]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: #[warn(unused_attributes)] on by default

error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib" "./out.0.o" "-o" "./out" "-Wl,--gc-sections" "-pie" "-nodefaultlibs" "-L" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-f4594d3e53dcb114.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/librand-1efbcfd8938372b6.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcollections-532a3dbf317eff86.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_unicode-cfbd6648f7db2ee5.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-a0157c0ca919c364.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-488b4ab4bd53a138.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-ca07b617414dd0fa.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc_jemalloc-492d8ea7fa3384ff.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-88c194c15fdb6521.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-687e6a964d22cbb4.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-987729be881d4d32.rlib" "-Wl,-Bdynamic" "-l" "dl" "-l" "rt" "-l" "pthread" "-l" "gcc_s" "-l" "pthread" "-l" "c" "-l" "m" "-l" "rt" "-l" "pthread" "-l" "util" "-l" "bunny"
  = note: /usr/bin/ld: cannot find -lbunny
          collect2: error: ld returned 1 exit status
          

error: aborting due to previous error

Also it warns that the attribute is unused despite having a very obvious effect. Also we still don't have a superior #![link_arg] yet which is capable of handling arguments with spaces in them.

@est31
Copy link
Member

est31 commented Jun 22, 2017

@retep998 I guess its a mistake, yes. There is a working feature gate, together with a gate test, but it seems to be only active on the foreign module declaration, so extern { .. } or extern C { .. }.

@retep998
Copy link
Member

But there's no reason to even tie a link_args to an extern block. At least with link you can use the kind to infer whether to apply dllimport to those extern symbols, but for arbitrary linker arguments there's nothing you can do.

@est31
Copy link
Member

est31 commented Jun 22, 2017

@retep998 I guess its simply a mistake. The bug in the feature gate is probably that way since the initial implementation e338a41 (no idea what ast::item_foreign_mod meant back then but it means probably exactly what extern { .. } means now).

IMO we should do one of these two things:

  • Emit warnings and fix the feature gate after a few cycles, or
  • Stabilize the feature right away, or with some previous thinking.

@aturon
Copy link
Member Author

aturon commented Jul 3, 2017

cc @rust-lang/compiler, it appears that there was an unintended stabilization here; decision needed.

@aturon aturon added I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 3, 2017
@joshtriplett
Copy link
Member

Unless there's a sign of usage in the wild, I think the right answer here is to fix the broken feature gate and keep this unstable.

@nikomatsakis
Copy link
Contributor

triage: P-high

We decided to try and fix this. @pnkfelix will either prep a PR or write-up some mentoring instructions.

@rust-highfive rust-highfive added P-high High priority and removed I-nominated labels Jul 6, 2017
@pnkfelix pnkfelix removed their assignment Nov 12, 2018
@jonas-schievink jonas-schievink added the A-linkage Area: linking into static, shared libraries and binaries label Jan 7, 2020
@jonas-schievink
Copy link
Contributor

This would be very useful for embedded applications, which currently all have to create a custom .cargo/config that passes the linker script to the linker.

What happens with #[link_args] in an rlib? Will those args be passed to the final linker invocation in the binary? (if not, that's fine, we can work around that, but it should probably be a conscious choice)

@petrochenkov
Copy link
Contributor

petrochenkov commented Jun 27, 2020

ping <wg-embedded> (how to ping it?) @jamesmunns @japaric @therealprof

I'd like to remove this attribute (preferably?) or bring it to some reasonable state.

Given the already listed issues

  • whitespace treatment
  • non-portability (even between e.g. gcc and the underlying ld)
  • non-propagation of link_args from dependencies

and other issues

  • the relative order between #[link] and #[link_args] attributes is not respected, all the link_args are passed together after all the libraries

what are the current use cases for this feature?

Is it possible to comfortably replace it with command line options from cargo configs or build scripts?

@petrochenkov petrochenkov self-assigned this Jun 27, 2020
@jonas-schievink
Copy link
Contributor

Passing arbitrary linker flags from build.rs would also work, I believe. Not for all the nice feature I had in mind, but at least it would allow removing .cargo/config from embedded projects.

@petrochenkov
Copy link
Contributor

I have submitted an RFC about some more fine-grained control over linking - rust-lang/rfcs#2951.

The "Future possibilities" section contains a paragraph about a potential order-preserving, propagating and single-argument alternative to #[link_args].

@therealprof
Copy link
Contributor

Ping works. ;)

I don't recall ever having seen #[link_args] in the wild. It certainly would be nice to have more control about the linking process and linker configuration from the application without requiring a build.rs and sans custom config in .cargo/config but we have been able to do without for a long time...

@retep998
Copy link
Member

If I could specify linker arguments from build scripts then I wouldn't care for this attribute at all, but I currently have neither so...

@petrochenkov
Copy link
Contributor

petrochenkov commented Jun 28, 2020

If I could specify linker arguments from build scripts

cargo:rustc-flags=-Clink-arg=-my-link-arg

?

(There's also cargo:rustc-cdylib-link-arg=FLAG which seems a pretty random recent addition and a part of some potential larger feature.)

@retep998
Copy link
Member

retep998 commented Jun 28, 2020

@petrochenkov cargo:rustc-flags specifically parses for -l and -L flags only and was deprecated in favor of the dedicated cargo:rustc-link-lib and cargo:rustc-link-search flags. cargo:rustc-cdylib-link-arg is great but only applies to cdylibs and there is no equivalent for regular binaries yet. Once cargo:rustc-link-arg and/or cargo:rustc-bin-link-arg exist however, then I would be in favor of getting rid of #[link_args] and never seeing it again.

xu-cheng added a commit to xu-cheng/incubator-teaclave-sgx-sdk that referenced this issue Aug 1, 2020
In order to use the switchless feature of the SGX, the app binary needs
to be linked with the following flags.

```
-Wl,--whole-archive -lsgx_uswitchless -Wl,--no-whole-archive
````

Noted that there is currently no proper way to pass custom link flags to
all the binaries in a cargo project. As such, the `link_args` macro need
to be set for each of Rust files with `main` methods.

References:

* Build flags used in Intel SGX sample code: https://github.com/intel/linux-sgx/blob/ce4a18d9a0963b14f717cc7462241cfadd233f55/SampleCode/Switchless/Makefile#L104
* Rust tracking issue on `link_args`: rust-lang/rust#29596
* PR for `cargo:rustc-link-arg-bins` in cargo build script: rust-lang/cargo#8441
@Mic92
Copy link
Contributor

Mic92 commented Dec 19, 2020

.cargo/config breaks build.rs for the flags I want to use. Having a cargo:rustc-link-arg sounds like the way to go. I am surprised it was not implemented this way in the first place.

@petrochenkov
Copy link
Contributor

Cargo now supports passing -C link-arg options to rustc in reasonable way via cargo:rustc-link-arg* directives in build scripts, so the attribute can be removed now.

I've submitted a PR doing that - #83820.

Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Apr 4, 2021
Remove attribute `#[link_args]`

Closes rust-lang#29596

The attribute could always be replaced with `-C link-arg`, but cargo didn't provide a reasonable way to pass such flags to rustc.
Now cargo supports `cargo:rustc-link-arg*` directives in build scripts (https://doc.rust-lang.org/cargo/reference/unstable.html#extra-link-arg), so this attribute can be removed.
@bors bors closed this as completed in 3c2e4ff Apr 5, 2021
flip1995 pushed a commit to flip1995/rust-clippy that referenced this issue Apr 8, 2021
Remove attribute `#[link_args]`

Closes rust-lang/rust#29596

The attribute could always be replaced with `-C link-arg`, but cargo didn't provide a reasonable way to pass such flags to rustc.
Now cargo supports `cargo:rustc-link-arg*` directives in build scripts (https://doc.rust-lang.org/cargo/reference/unstable.html#extra-link-arg), so this attribute can be removed.
@ilyvion
Copy link

ilyvion commented Oct 4, 2022

The removal of this makes it hard to do certain things in the playground. I realize that's probably not a priority or reason to keep it, I'm just pointing it out. There's no -C link-arg, build.rs or .cargo/config there.

@gmorenz
Copy link

gmorenz commented May 7, 2024

I really wanted this as an attribute because build.rs didn't make it possible to only pass linker arguments to certain executables. For instance, the binary I'm building but not the integration tests cargo test runs.

It turns out that #![feature(link_arg_attribute)] has made this possible again, just with slightly strange syntax for a global argument:

#[link(kind = "link-arg", name="-nostartfiles", modifiers="+verbatim")]
extern "C" {}

Leaving this comment mostly for anyone else who comes across this issue trying to figure out how to do it. I did a few weeks ago and at the time just gave up on using cargo test as the entrance point for my tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-dev-tools Relevant to the dev-tools subteam, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.