Skip to content

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

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

Open
solkitten opened this issue Jan 20, 2023 · 10 comments

Comments

@solkitten
Copy link

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

@dot-asm
Copy link
Contributor

dot-asm commented Jan 20, 2023

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
Copy link
Contributor

dot-asm commented Jan 20, 2023

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
Copy link
Contributor

dot-asm commented Jan 20, 2023

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
Copy link
Contributor

dot-asm commented Jan 20, 2023

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
Copy link
Contributor

dot-asm commented Jan 20, 2023

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
Copy link
Contributor

dot-asm commented Feb 1, 2023

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...

@thomcc
Copy link
Member

thomcc commented Jul 26, 2023

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
Copy link
Member

thomcc commented Jul 26, 2023

I agree for -static, though.

@dot-asm
Copy link
Contributor

dot-asm commented Jul 26, 2023

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.

@thomcc
Copy link
Member

thomcc commented Jul 26, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants