cc-rs
cc-rs copied to clipboard
Fails to compile with nvcc when passing RUSTFLAGS='-C target-feature=+crt-static'
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
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.
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
...
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.
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.
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.
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...
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...
I agree for -static
, though.
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.
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.