Skip to content

staticlib creates huge files #18569

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
mahkoh opened this issue Nov 3, 2014 · 9 comments
Closed

staticlib creates huge files #18569

mahkoh opened this issue Nov 3, 2014 · 9 comments
Labels
A-codegen Area: Code generation

Comments

@mahkoh
Copy link
Contributor

mahkoh commented Nov 3, 2014

#![no_std]
#![feature(lang_items)]
#![crate_type = "staticlib"]

extern crate core;

#[lang = "stack_exhausted"] extern fn stack_exhausted() { }
#[lang = "eh_personality"] extern fn eh_personality() { }
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop { } }

This creates a 1.3MB file unsuitable for distribution. The real size should be closer to 0 bytes because there are 0 public symbols.

@mprobinson
Copy link
Contributor

This looks very similar to #18541 , although worse because the linker version script workaround does not work in this case.

@alexchandel
Copy link

I don't think this is the same issue as #18541.

In this case, compiling this on OS X x86_64 with rustc --emit obj small.rs produces a 4KB Mach-O object file, the smallest possible. There are only 5 symbols: _rust_stack_exhausted, __ZN15stack_exhausted10__rust_abiE, _rust_eh_personality, __ZN14eh_personality10__rust_abiE, _rust_begin_unwind.

But compiling with rustc small.rs and emitting a static library causes libcompiler-rt, libmorestack, and libcore to be included in the archive. libcompiler-rt and libcore each add about 600K.

It's worth noting that in the equivalent bare-bones executable, none of that is included, and the final binary is 8K (on OS X).

@steveklabnik steveklabnik added the A-codegen Area: Code generation label Jan 27, 2015
@alexchandel
Copy link

On the other hand, compiling a small stdlib program like

fn main() {std::io::stdio::stdout_raw().write_all(b"Hi\n");}

even with -O -C lto -C no-stack-check -Z no-landing-pads emits a massive 292K executable on OS X, as of alpha. The equivalent C program is 4K (the smallest normal executable size on OS X) and most of that is 0's. So Rust does have a bloat problem.

By instruction count, at least two thirds of that rust executable is jemalloc.

@alexchandel
Copy link

It seems like the allocations performed in the lang_start drag jemalloc in. There should be a way to do this without allocation right? It would shave off 200K+ from the minimal executable size.

@alexchandel
Copy link

In fact, I think it's just one allocation:

let thread: Thread = NewThread::new(Some("<main>".to_string()));

NewThread should be rewritten to take &'static str alternatively!

@rprichard
Copy link
Contributor

I just opened issue #22525. It might be related.

@alexchandel
Copy link

@rprichard My minimal stdlib program, compiled above with rustc -C opt-level=2 -C lto -C no-stack-check -Z no-landing-pads test.rs or rustc -C opt-level=3 -C lto -C no-stack-check -Z no-landing-pads test.rs, is 276kB. An improvement, but still bloated.

I also checked the instruction usage, and literally 70.6% of the executable is jemalloc.

@vadimcn
Copy link
Contributor

vadimcn commented Feb 23, 2015

On Windows, at least half of the executable size appears to be due to jemalloc's debug into.
rustc -Clto -Copt-level=3 hello.rs gives me a 822K executable. Adding -Clink-args=-Wl,-strip-all brings that down to 437K..

@alexchandel
Copy link

FYI, Rust's branch of LLVM just learned about je_mallocx, so this may see some improvement. I doubt it though, since the NewThread is so low-level.

@mahkoh mahkoh closed this as completed Apr 11, 2015
@rust-lang rust-lang locked and limited conversation to collaborators Apr 11, 2015
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
A-codegen Area: Code generation
Projects
None yet
Development

No branches or pull requests

6 participants