-
Notifications
You must be signed in to change notification settings - Fork 13k
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
-C linker
flag is misleading
#32721
Comments
Right we currently expect |
Since |
So for lld To input macho binaries you use the I think this is what @alexcrichton was suggesting wrt a flavor flag, that we'd need a new flag to allow fine grained control of the linker? Note the flags lld implements are the system linker flags ( Similarly for osx. I think this is the part I'm confused about, on the windows side it looks like the system linker, eg link.exe is used for this flag, but on the UNIX side, the compiler driver is used... This is why as @retep998 suggested, using It's just seems a little inconsistent, and hence my suggestion the flag is misleading. I'm not sure what the best approach is though without breaking stuff, but I suspect as cross compilation gets more and more momentum people still want finer and finer control of their linker selection on rust (and not just a compiler driver like GCC/clang/cc)... :/ |
@m4b yeah to clarify I was thinking of something like We call
We currently don't probe for that information, but we'd have to do so to start calling |
So on the one hand, for a potentially quick win, I like the idea of a On the other I'm a little worried it might be confusing? However, I think what we're really getting at here is advanced linking in rust, so I'm thinking it might be useful to outline or survey some use cases that will/are coming up w.r.t. rust linking, or what we all have in mind. So, I actually submitted a bug report on So for me, in particular, one of the things I'd like to use the After much derping about, I've actually managed to use #!/bin/bash
# new rustup.rs nightly darwin toolchain
DIR=/home/m4b/.multirust/toolchains/nightly/lib/rustlib/x86_64-apple-darwin/lib
# assumes you've got the darwin system binaries from `/usr/lib/` hanging out here (change this to wherever they might be)
DARWIN_PATH=/home/m4b/binaries/darwin/usr/lib
SYS=$DARWIN_PATH/system
# i built lld from source, and this is the path to it
LLD=/home/m4b/Downloads/llvm-3.8.0.src/build/bin/lld
MAIN=$1
NAME=${MAIN%.*}
rustc --target=x86_64-apple-darwin $MAIN
$LLD -flavor darwin -arch x86_64 -t "$SYS/libsystem_m.dylib" "$SYS/libsystem_kernel.dylib" "$SYS/libsystem_info.dylib" "$SYS/libsystem_malloc.dylib" "$SYS/libsystem_platform.dylib" "$SYS/libsystem_c.dylib" "$SYS/libsystem_pthread.dylib" "$SYS/libunwind.dylib" "$SYS/libdyld.dylib" "$DIR/liblibc-18402db3.rlib" "$DIR/libstd-18402db3.rlib" "$DIR/libcollections-18402db3.rlib" "$DIR/librustc_unicode-18402db3.rlib" "$DIR/librand-18402db3.rlib" "$DIR/liballoc-18402db3.rlib" "$DIR/liballoc_jemalloc-18402db3.rlib" "$DIR/libcore-18402db3.rlib" "$DIR/libcompiler-rt.a" ${NAME}.0.o -o ${NAME}_darwin (note: while the final produced binary is "syntactically" correct, it segfaults if I attempt to run it on OSX in the getenv call, which is just a whole other can of worms :P) So ideally, one use case would be if I could transfer the So the final rustc invocation is perhaps something like:
and it:
It's also occurred to me, depending on how mature
(where The same command would work on OSX (or GNU/Linux) too, just that the path to the needed system binaries is variable, i.e., the local cross compiling paths to stuff like Or again, we build our own cross-platform linker in Rust 💯 😆 Ok, that was really a mouthful, sorry, I'll let someone else talk :) |
I know I'd personally love to "just use lld", but I think as you're discovering it unfortunately seems like it's not quite ready for prime time just yet. My recommendation for advanced linking in Rust would be to just not use the compiler altogether. You're essentially just fighting a long uphill battle trying to pack so much into the compiler, it'll be easier if you just produce a staticlib and then link that yourself (passing all the fancy flags you'd like). There are downsides to doing that, unfortunately, but the "long tail of fixing bugs" seems like it may be smaller in that case! |
Now I'm a little confused, as these two statements seem to be slightly at odds. Are you in favor of a flavor flag for calling different linkers or not? Also since rustc/cargo aren't just compilers, but also compiler drivers (otherwise why link args, and linker flags?), why wouldn't we want to add a more robust linker selection functionality? (And yes, lld is definitely not ready, but it was simply an exampl/use case of how someone might cross link, which is an issue I see repeatedly asked, and which I mistakenly thought the solution to was the -C linker flag) Lastly, so we don't lose sight, the original impetus for this issue is that the linker flag is misleading, which I still maintain. And especially in light of whether the official answer to advanced linking with rust is "don't use rustc"- why provide these flags at all? |
I would be fine adding flags to control the flavor of the linker, but those will take some time to stabilize and work out the kinks. In general if you're doing crazy shenanigans with the linker it's just better to do them directly because you probably want control over what's going on rather than trying to work with rustc randomly injecting arguments. The flag is exposed because in many situations you just need to specify a different executable than the default (for example in cross-compiling situations). |
Linker flavor seems to have been implemented in #40018 I still think -linker is misleading :P but it's too late to change I think. Closing this issue, tho I suspect as more people experiment with cross linking more people will be confused by the name choices ;) Anyway the cross compilation story in rust is getting really exciting, awesome work everyone ! |
from
rustc -C help
we're told that:I mistakenly thought that this accepted a path to a system linker (e.g.,
/usr/bin/ld
on GNU/Linux or OSX); instead it really seems to want a compiler driver likecc
orclang
.For example, one would expect the following two invocations to be the same (on a typical GNU/Linux system) if it expected an actual linker:
but the second errors out because
ld
does not understand the emulation mode "64":(but
cc
does)Besides being misleading, the current invocation seems to require the hard-coded command line arguments to be understood by whatever "linker" (compiler driver) is passed.
Perhaps if you're only targetting
cc
derivatives this might suffice. But if the flag is for switching out the linker (e.g., using gold instead of ld, or even lld), the current implementation simply will not work.For example, suppose we're on GNU/Linux and we have our
main.rs
, and we compile it with the new shiny--target
switches from nightly like so:we'll error out in the linking phase, since
cc
is trying to link a mach-o binary using the system linker,/usr/bin/ld
, which only understands ELF binaries.I naively thought this was what the
-C linker
flag was for, for the above reasons, and so tried:But this of course won't work because:
-flavor darwin
, etc. flags passed and the current linker= does not facilitate calling it appropriatelycc
-esque driver.So if the purpose of the
-C linker
flag is really a compiler driver, then probably-C driver
would be a better name (and at the very least change the -C help output for the flag), but if not, then there's some work cut out... I'm thinking in the latter case it might almost be best if when the user specifies a-C linker
then all linking flags are cleared, and it's up to the user to pass the appropriate flags via-C linker-flags
.The text was updated successfully, but these errors were encountered: