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

specify linker/compiler _with flags_ for cross compilation #8071

Closed
saurik opened this issue Apr 5, 2020 · 8 comments
Closed

specify linker/compiler _with flags_ for cross compilation #8071

saurik opened this issue Apr 5, 2020 · 8 comments
Labels
C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`

Comments

@saurik
Copy link

saurik commented Apr 5, 2020

So, I do a lot of cross compilation. I always set up my builds to do cross compilation to all targets from at least my computer if not from most common operating systems. I cross compile to lots of different systems and work with a lot of toolchains. I even "cross compile", routinely, even from an operating system to itself, such as from Linux to Linux due to wanting to run the binaries on an older version of a different distribution.

One of the things that has always been a pretty fundamental for effective and universal cross compilation is that the tools you are using aren't just "binaries": they are "commands". You can't just say "here's the compiler, treat it as gcc" or "here's the linker, treat it as ld"... you have to pass linker scripts, sysroot paths, runtime library configurations (for threading/exception mechanisms or to select a C++ standard library), binary paths (gcc and clang -B), weird flags to map paths in specialized embedded debugging information... lots of stuff.

This isn't just how I have ended up generalizing this problem: in the Firefox build system, they do the same thing... and they ran into the same problem I'm seeing, which is that cargo doesn't seem to think of cross compiling in this way. Their solution seems to have been to have a shell script "wrapper" that they pretend is a compiler/linker that passes extra arguments smuggled in via environment variables... which is 1) crazy indirect and 2) is difficult to make work correctly on Windows due to it being difficult to just "run a shell script" (which then became a documented limitation of the Firefox build system).

https://bugzilla.mozilla.org/show_bug.cgi?id=1329737

Instead of doing all of this, can there be some mechanism for just providing extra compiler/linker arguments? I would argue that a compiler/linker is always a command--like, maybe you want to use something like distcc, which is classically done by just setting the compiler to "/path/to/distcc /path/to/gcc", which already is fundamentally not going to work if the compiler is required to be a binary, and to point it out: this isn't even a "flag"... the path to the compiler at this point is the "flag" :(--but it at least needs to have a way to provide extra arguments.

The meson build environment also insists on modeling the compiler/linker as a binary, but it at least provides a way to throw in extra arguments in other variables (c_link_flags, for example), so maybe Cargo can do that? Then projects such as all of mine--and Firefox! ;P--will be able to do the flexible cross-compilation that we are used to, with custom toolchains and limited sysroots and new standard libraries... compiling should be fun ;P.

@saurik saurik added the C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` label Apr 5, 2020
@ehuss
Copy link
Contributor

ehuss commented Apr 5, 2020

Instead of doing all of this, can there be some mechanism for just providing extra compiler/linker arguments?

Does setting rustflags not work for you? They can be set per target in the config, and rustc has -C link-arg to pass additional args to the linker. I'm not really sure what you're asking for.

@saurik
Copy link
Author

saurik commented Apr 18, 2020

@ehuss So, for my current use case (which is relatively simple; in the past I've ended up with much more complex scenarios, including having to run a linker using wine/darling/docker), that worked; thanks!!! I simply didn't know about link-arg and it wasn't coming up when I was searching for how to do cross compilation (but what did come up was that referenced Mozilla issue of people coming up with workarounds ;P).

FWIW, I will say that your response makes it sound like I should know about link-arg, but the documentation I poured over didn't list it (it only shows linker) and even knowing its name and doing direct searches for "link-arg" I'm only coming up with things like the commit that added it, the issue it closed, a stack overflow question, and a few blog posts. Is there somewhere with more magic documentation I should know of? ;P

For whatever reference if anyone ever sees this, here is what I'm now passing.

CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS: -C link-arg=--sysroot -C link-arg=/Users/saurik/orchid/tst-network/out-lnx/sysroot -C link-arg=--gcc-toolchain=/Users/saurik/orchid/tst-network/out-lnx/sysroot/usr -C link-arg=-B/Users/saurik/Library/Android/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/darwin-x86_64/x86_64-linux-android/bin -C link-arg=-target -C link-arg=x86_64-pc-linux-gnu

(Closing this issue as apparently there's a way to do this.)

@saurik saurik closed this as completed Apr 18, 2020
@ehuss
Copy link
Contributor

ehuss commented Apr 18, 2020

but the documentation I poured over didn't list it

Oh, sorry, I didn't mean to imply that you should know about it, my wording was poor.

Here is the documentation for rustc flags: https://doc.rust-lang.org/rustc/codegen-options/index.html#link-arg Although it is very sparse.

I'll make it a point to add links to the rustc argument documentation from the cargo docs, so there is at least some cross-reference. Probably won't help for those using search engines, but that's a tricky thing to control.

Someday I'd love to see an entire book on "linking with rust" that covered both simple and advanced linking topics.

@petrochenkov
Copy link
Contributor

CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS: -C link-arg=--sysroot -C link-arg=/Users/saurik/orchid/tst-network/out-lnx/sysroot -C link-arg=--gcc-toolchain=/Users/saurik/orchid/tst-network/out-lnx/sysroot/usr -C link-arg=-B/Users/saurik/Library/Android/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/darwin-x86_64/x86_64-linux-android/bin -C link-arg=-target -C link-arg=x86_64-pc-linux-gnu

Simplified:

CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS: -C link-args="--sysroot /Users/saurik/orchid/tst-network/out-lnx/sysroot --gcc-toolchain=/Users/saurik/orchid/tst-network/out-lnx/sysroot/usr -B/Users/saurik/Library/Android/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/darwin-x86_64/x86_64-linux-android/bin -target x86_64-pc-linux-gnu

@saurik
Copy link
Author

saurik commented Apr 18, 2020

@petrochenkov I am under the impression from rust-lang/rust#36574 that usage of link-args is to be discouraged.

@saurik
Copy link
Author

saurik commented Apr 18, 2020

(And, FWIW, it is actually much easier for me to generate that nested -C link-arg= string, due to the particulars of what end up being potentially triple-nested quoting in my build generation system that I don't want to deal with ;P.)

@saurik
Copy link
Author

saurik commented Apr 18, 2020

(Re-reading that thread more carefully in fact it would seem like link-args wouldn't even work correctly as an environment variable like that as I guess the quoting isn't even implemented on Rust's end? Like, have you actually used link-args like that and it works?)

@petrochenkov
Copy link
Contributor

Like, have you actually used link-args like that and it works?

Ah, I see.
I used it, but not with Cargo and RUSTFLAGS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`
Projects
None yet
Development

No branches or pull requests

3 participants