-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
macOS: Crate symbols get discarded when crate appears unused #133491
Comments
hey @madsmtm What do you think we have wrought upon ourselves today? |
Fair chance this is because of linkers only pulling in object files from archives when a symbol in them is referenced unless |
I'd be surprised if |
It appears that |
Does |
|
I think the issue is that the If I use |
And I'll see if I can figure out a way to make the |
I've run out of time for now, but might continue work on this in perhaps a few days, perhaps weeks. Noting down my findings in the meantime: This can be reproduced with just a library crate Running // dep.rs
#![crate_type = "rlib"]
#![no_std]
extern "C" {
fn printf(format: *const core::ffi::c_char, ...) -> i32;
}
#[used]
#[link_section = "__DATA,__mod_init_func,mod_init_funcs"]
#[no_mangle]
pub static INIT: extern "C" fn() = init;
pub extern "C" fn init() {
unsafe { printf(b"inside initializer\n\0".as_ptr().cast()) };
}
#[no_mangle]
pub fn foo() {} // main.rs
#![no_std]
#![feature(start)]
extern crate dep;
#[link(name = "System")]
extern "C" {}
extern "Rust" {
fn foo();
}
#[panic_handler]
fn handle(_: &core::panic::PanicInfo<'_>) -> ! {
loop {}
}
extern "C" {
fn printf(format: *const core::ffi::c_char, ...) -> i32;
}
#[start]
fn main(a: isize, l: *const *const u8) -> isize {
// dep::foo();
// foo();
unsafe { printf(b"in main\n\0".as_ptr().cast()) };
return 0;
} Adding I've managed to produce a // helper.rs
#![crate_type = "lib"]
#![no_std]
extern "Rust" {
fn foo();
}
pub fn use_foo() {
unsafe { foo() };
} The difference between that and Hypotheses:
|
I tried this code:
Within the base crate, the
#[divan::bench]
macro is used for benchmarking crate internals. Its generated code translates to something similar to:This crate has a benchmark executable with only:
I expected to see this happen: run the
add
benchmark and output the results. This runs correctly on Linux and Windows, but not macOS.Instead, this happened:
divan::main()
cannot find the benchmark because the pre-main
constructor function never ran.In order to make the benchmarks visible to the executable, the base crate needs to have one of its items appear to be used, such as
black_box
-ing any item from the crate.Note that this also happens with code like:
This issue occurs even when doing
extern crate my_crate
oruse my_crate as _
, which is a known workaround for similar issues.Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: