cc-rs icon indicating copy to clipboard operation
cc-rs copied to clipboard

Fails to compile with nvcc when passing RUSTFLAGS='-C target-feature=+crt-static'

Open solkitten opened this issue 2 years ago • 10 comments

When I'm trying to make a static build of my rust application with some cuda code doing: RUSTFLAGS='-C target-feature=+crt-static' cargo build --release I'm getting the following error under linux:

 cargo:warning=nvcc fatal   : Unknown option '-static'
  exit status: 1

Tested with CUDA 12

solkitten avatar Jan 20 '23 12:01 solkitten

While I know how to fix it, one can wonder what's up the -static flag to start with. Indeed, cc-rs produces .a files for rustc to link with, while from C compiler's view the-static flag is a link flag. In other words at no point -static is actually meaningful in the context, because cc-rs never links anything. In yet another words, I'd say that cc-rs shouldn't issue the flag in question. As opposed to ~fixing it on the nvcc side~ making it work with nvcc.

dot-asm avatar Jan 20 '23 15:01 dot-asm

On a tangential note. As for "cc-rs never links anything." One can also argue that cc-rs shouldn't issue -shared flag either. For the same reason, it's a link flag to C compiler. Well, documentation suggests that cc-rs can produce .so, but it never worked (see for example #594). And even if it's implemented, it's not really an excuse to pass the flag at the -c stage. I mean shared support would be about adding an explicit link-shared-library step. Or replacing the ar step with it? Either way, that's where the -shared flag would be used, not with cc -c...

dot-asm avatar Jan 20 '23 15:01 dot-asm

Just in case. Tracing the introduction of corresponding methods back suggests that it was triggered by a linking error suggesting to recompile with -fPIC. So one would expect -static/-shared to affect the compiler's command line, but I don't see that it does. In sense that cc -shared -c ... doesn't add -fPIC to compiler command line... Or vice versa... The original dispute was about musl target, but the same can be said about musl-gcc... As well as about cc on an all-musl system... Was it the case at some point in time? Well, not even gcc-2.95.3 adds -fPIC if I pass -shared... In all cases -static/-shared appeared as pure link flags, i.e. how to link things.

dot-asm avatar Jan 20 '23 16:01 dot-asm

An additional note. gcc-3-ish did require -fPIC [passed at -c stage] for shared link, while contemporary gcc-s seem to always generate PIC. It actually takes an explicit -fno-PIC to prevent it from referring to _GLOBAL_OFFSET_TABLE_. For reference, clang on the other hand still requires -fPIC the way gcc-3-ish did... Well, at least clang-10...

As for defaulting to -fPIC. Normally -fPIC doesn't affect your chances for static link, at least not on x86_64 Linux. Which is why it's not a problem to default to PIC.

dot-asm avatar Jan 20 '23 17:01 dot-asm

To summarize. The suggestion for resolution is to either no-op static_flag() and shared_flag() methods, or have them pass a suitable value to pic() method.

dot-asm avatar Jan 20 '23 17:01 dot-asm

The remark is arguably a bit misleading in the context of the original query. Because it's about static_flag() and shared_flag() methods, while passing -C target-feature=+crt-static does not result in invoking the static_flag() method. Instead the -static flag is passed explicitly. But the spirit is all the same. Namely, cc-rs doesn't do any linking and hence formally has no business passing link flags such as -static and -shared to the compiler. If we can agree on this, I can prepare a PR...

dot-asm avatar Feb 01 '23 15:02 dot-asm

Namely, cc-rs doesn't do any linking and hence formally has no business passing link flags such as -static and -shared to the compiler. If we can agree on this, I can prepare a PR...

This is a bug, pretty much. A concern I have is how many people in the wild are relying on it, though...

thomcc avatar Jul 26 '23 07:07 thomcc

I agree for -static, though.

thomcc avatar Jul 26 '23 07:07 thomcc

A concern I have is how many people in the wild are relying on it, though...

cc-rs always calls the compiler with the -c flag on all the people-in-the-wild's behalf. Can we agree on that? Because here is the thing, -static and -shared flags are ignored with -c. Because, again, these are meaningful only at the link stage, something cc-rs is not engaged in, it's rustc's domain. In other words people in the wild are not relying on it, just oblivious of the fact that it's ignored.

Just in case, -static and -shared are not actually antonyms. -shared means "produce a shared library," while -static means "don't link with shared libraries." Is this the difference you refer to with "I agree for -static, though."? Even if this is the case, consider the following. It's a well-known fact that cc-rs doesn't produce shared libraries. This is despite the fact that documentation wording suggests that it does. This yields two options, a) implement shared libraries generation in cc-rs (in which case -shared flag would have to be used, but not with -c!); b) simply acknowledge the reality and say that shared library linking is not cc-rs business. In either case there is no place for the -shared flag in the current implementation.

In case you wonder, I for one would advocate for b) with the following rationale. It's consistent with the cc-rs' nature, producing some object files for rustc to link with. (Recall that rustc can produce shared libraries, so what's up with linking shared libraries with cc-rs anyway?) If a user has a legitimate need to produce a shared library for rustc to link with, then they should be advised to use other means like cmake-rs. They would probably be better off anyway, as linking a shared library can get pretty nuanced.

dot-asm avatar Jul 26 '23 09:07 dot-asm

Yeah, I'm not sure. I agree with your assessment, but think that a is better, given that people will expect that it works (we claim it does, and it's reasonable to believe it does as well). Plenty of people use cc-rs in cases outside of Rust build scripts anyway, in which case it's totally reasonable to want to produce a shared library.

cmake-rs also doesn't handle cross-compilation as well as cc-rs, not to mention needing to use cmake.

thomcc avatar Jul 26 '23 14:07 thomcc