-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
#[used(compiler)]
and #[used(linker)]
should work on functions.
#94348
Comments
I think supporting |
I might be wrong but I'd imagine something like this should work as a workaround? #![feature(used_with_arg)]
#[used(compiler)]
pub static _FOO: unsafe extern "C" fn() -> () = foo;
#[no_mangle]
pub unsafe extern "C" fn foo() {} |
Agree that supporting |
`check_used` should only look at actual `used` attributes cc? rust-lang#94348 r? `@nikic`
`check_used` should only look at actual `used` attributes cc? rust-lang#94348 r? ``@nikic``
Unfortunately that doesn't work because we need the actual functions to be exported. We're polyfilling/implementing well known APIs like pthread. Unless of course that workaround also lets the function symbol stay around, but I assume it only keeps the static's symbol. |
I tested the static workaround and it doesn't seem to work (with |
@AzureMarker Ok I think I figured it out, and I was kinda XYed. Rust will just ignore your crate if you put it in the dependency list, but don't make another reference to it. Even with the |
Huh, I thought I already tested that. I'll check again just to make sure. |
As bjorn3 said, |
@carbotaniuman I tested this again with The issue I'm seeing is #47384 like you said, but this comment suggested to me that the problem would be fixed by |
Maybe #93791 will fix this? |
@AzureMarker What crate-type are you building your crate as? Do you have a single repo that I can just build to test it out? |
@carbotaniuman I see it with some crates for the Nintendo 3DS (in progress std port) which are compiling/linking to create an ELF file, but I'll try to make a minimal reproduction that runs on Linux. |
@carbotaniuman Here is a repository that reproduces the issue: The main issue spawns from a requirement in our rustc fork for the 3DS (to be upstreamed eventually). We don't want to link directly to the "libc" library on the 3DS because it's homebrew, and potentially causes legal issues (ex. using the low-level APIs of the 3DS kernel, see #88529 (comment)). Due to this, we have a few crates providing the libc implementation which are pulled in as regular dependencies, not std dependencies. They export well known libc functions which std uses. For example: https://github.com/Meziu/rust-linker-fix-3ds This reproduction repo has a "pretend-std" crate which represents std in this scenario. It relies on an extern "C" function which is defined in the main crate's lib.rs module (representing the homebrew libc). The main crate's lib.rs module holds the implementation of the extern function. And the main crate's main.rs module uses a "pretend-std" function. The issue is the link order, and how the linker drops unused symbols. Here is a snippet of
The lib.rs module is linked in first. This module included the implementation of the exported function, but since the exported function hasn't been required yet according to the linker, it's dropped. Second is the "pretend-std" crate, which requires the exported function. At this point the exported function is now required, but the implementation was already dropped. Third is just libc, which is an implementation detail (used in the exported function's signature). If In the 3DS case, we have multiple exported functions like this which are used by std, but thrown away by the linker before it starts linking in std (and realizes the functions are actually used). I see two possible fixes:
For more detail, here are the symbol tables of the lib.rs module and the pretend-std module (same with/without the
|
Related to #93798
cc @cynecx since you did the implementation.
cc @Meziu and @ian-h-chamberlain
The
#[used(compiler)]
and#[used(linker)]
should work on functions. They weren't explicitly one of the main motivating use cases brought up in #47384, but expanding them to support functions would be very beneficial. For example, in https://github.com/Meziu/pthread-3ds and https://github.com/Meziu/rust-linker-fix-3ds we have to have an empty "init" function just so the exported functions don't get thrown out.I was expecting these annotations to fix our problem, so I was excited to try them out when I heard they hit nightly. However, the following fails to compile:
playground link
Interestingly, changing to
#[used(linker)]
results in an extra message (Edit: fixed by #94377):Does
no_mangle
implyused(compiler)
?The text was updated successfully, but these errors were encountered: