-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Enabling +crt-static
in a blanket way breaks dynamic libraries including proc macros
#71651
Comments
I think a new option The only thing we need to assess is compatibility for windows-msvc and wasm32-wasi targets which currently supports linking In case of WASM we can enable In case of Windows-MSVC I need @retep998's expertise here. |
The big issue you have to care about on Windows with regards to the CRT is that you never share CRT objects across a dll boundary unless both sides are using the same dynamic CRT. Because using CRT types is very rare in the Rust ecosystem, and the proc macro interface does not have any CRT types in it, I see no reason why |
@alexcrichton Is it a common case to bundle libc (I'm not even sure what it does on the target) into wasm 1) executables and 2) libraries? Is it desirable to support the case of bundling libc, but linking dynamically to some other libraries? |
For wasm32-wasi the meaning of The purpose here is somewhat similar to MinGW where, by default, if you don't compile any C code in your application It's currently most common to not pass anything, meaning |
Part of the confusion here is that As far as I'm aware,
I think this is the correct answer. Can you please expand on what makes it fragile? And what you're referring to that "musl actually supports"? Linking a dylib/cdylib against musl's Ignoring I would also expect it to be common for projects to provide both a dylib crate and executables (CLI, tests, etc.). I only see two ways to compile both from the same |
@smaeul
Sometimes having a separate copy of libc with all the global data in a
With musl I tried it with "hello world"-like examples and it worked too :) UPD: Clarification - I did all of this with C++ and gcc, not with Rust (it doesn't matter much in this case though). |
Some history in links: #71586 (comment) |
If anyone's interested, here's the workaround I use for the simple case where the top crate has a program and you just want that crate to build static programs:
#!/bin/bash
crate_name=0
for i in "$@" ; do
if [[ $i == "--crate-name" ]] ; then
crate_name=1
continue
elif [[ "$crate_name" == "1" ]] ; then
if [[ "$i" == "crate-name-of-your-program" ]] ; then
set -- "$@" -C target-feature=+crt-static
break
fi
fi
crate_name=0
done
exec rustc "$@" |
Copypasting from #90020 (comment): I went through major targets supporting dynamic linking and they all seem to expose relatively similar behavior with regards to linking CRT (libc or analogues) dynamically or statically. An executable and all its dynamic dependencies must share a common CRT for things like cross-binary exceptions and cross-binary allocations/deallocations on platform like Windows (which don't do most of OS interactions through CRT), and maybe for other shared resource management as well on platforms like Linux (which do most of OS interactions through CRT).
Whether a dynamic library may require managing shared resources is ultimately a user's choice. Side note: for targets doing dynamic linking in userspace via ELF interpreter field (Linux), we can remove the interpreter field and speedup their launch if there's no dynamic dependencies at all (CRT or others). So the question is what "with(out) an explicit request" above means. Considering the above, I think my suggested solution is:
|
This issue is still not resolved after a year. It blocks me from static linking (using glibc) projects has any proc-macro crates in the dependency closure. I think it's not something like "how to deal with crt-static on libs". It's the crt-static should applied to any build-time dependencies in the first place. Maybe we should make |
This is pretty much rust-lang/cargo#7563 generalized, which was fixed in #69519, which I don't consider a correct or satisfactory solution.
#71586 may be a good preliminary reading.
If you are building something with Cargo and set
-C target-feature=+crt-static
throughRUSTFLAGS
, orcrt-static
is enabled by default through a target specification, it will be set for all crates during the build, including proc macros and cdylibs (and build scripts?).In most cases this is not an intention when we are enabling
crt-static
.In most cases the intention is to enable it for executables only.
So if enabling
crt-static
for executables (via env var or a target spec) also enables it for libraries, it usually results only in "collateral damage".If the target doesn't support
+crt-static
for libaries, we just get an error like rust-lang/cargo#7563 reported.If the target supports
+crt-static
for libraries, we get a very weird library which is unlikely to work when dynamically loaded as a proc macro crate (I didn't verify that though).As a result, we need a way to enable
crt-static
for executables without collaterally damaging libaries.Moreover, this way should be the default.
#71586 (comment) lists some possible alternatives of doing this.
-Ctarget-feature=-crt-static
for proc macro crates or all libraries in Cargo (cc @ehuss), modifying RUSTFLAGS. Question: how to opt-out?-Ctarget-feature=+crt-static-dylib
controlling static linking of libraries instead of-Ctarget-feature=-crt-static
. It would almost never be used on Unix-like targets (not sure about windows-msvc and wasm).crt-static
, but introduce a new option-C disable-crt-static-for-dylibs
or something. Cargo would then use it for proc macro crates or all libraries. Question: how to opt-out?+crt-static
for libraries if the target doesn't support it. This is fragile, musl actually supports it despite the current value of the flag of the musl target spec. If the flag is enabled, proc macros will break.+crt-static
for libraries always. It is almost never used on Unix-like targets (not sure about windows-msvc and wasm).+crt-static-dylib
looks strictly better.crt-static
defaults in target specs - one for executables and one for libraries. Solves one half of the problem, but explicit+crt-static
inRUSTFLAGS
will still cause collateral damage.The text was updated successfully, but these errors were encountered: