Skip to content

Rust is inconsistently re-exporting rlib symbols from a binary #84934

@erickt

Description

@erickt

I noticed some strange behavior while trying to optimize file size. Consider this cargo setup:

Cargo.toml:

[package]
name = "foo"
version = "0.1.0"
authors = ["Erick Tryzelaar <etryzelaar@google.com>"]
edition = "2018"

src/lib.rs:

#[no_mangle]
pub fn big1() {}

#[no_mangle]
pub fn big2() {}

#[no_mangle]
pub fn big3() {}

examples/big1.rs:

fn main() {
    foo::big1();
}

examples/big2.rs:

fn main() {
    foo::big2();
}

examples/big3.rs:

fn main() {
    foo::big3();
}

On my mac using both rustc 1.51.0 (2fd73fabe 2021-03-23) and rustc 1.53.0-nightly (42816d61e 2021-04-24), I found that the rust binary for the two examples will be different:

% rustup run stable cargo build --release --all-targets && ls -l target/release/examples/{big1,big2,big3}
-rwxr-xr-x  1 etryzelaar  primarygroup  432536 May  4 17:02 target/release/examples/big1
-rwxr-xr-x  1 etryzelaar  primarygroup  432576 May  4 17:02 target/release/examples/big2
-rwxr-xr-x  1 etryzelaar  primarygroup  432608 May  4 17:02 target/release/examples/big3

Those handful of bytes of difference appears to be because for some reason, big2 binary is re-exporting the _big2 function, but the big1 binary does not re-export _big1:

% diff <(nm -g target/release/examples/big1) <(nm -g target/release/examples/big2)
192a193
> 00000001000037e0 T _big2
200c201
< 0000000100003740 T _main
---
> 0000000100003720 T _main

% diff <(nm -g target/release/examples/big1) <(nm -g target/release/examples/big3)
192a193,194
> 00000001000037e0 T _big2
> 00000001000037e0 T _big3
200c202
< 0000000100003740 T _main
---
> 0000000100003770 T _main

Ideally we'd optimize away all these symbols to shave off some bytes, but if that's difficult, we probably should at least make things consistent.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-codegenArea: Code generationA-linkageArea: linking into static, shared libraries and binariesC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions