Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Rust export its whole standard library when building a DLL?

I'm currently trying to write a dynamic library with Rust which will be loaded from a existing program. I need to export a few functions with specific names and calling conventions. Everything works, but as soon as I use anything from the standard library:

  • The DLL size balloons to over 3MiB (Not exactly pretty, but I could live with that)
  • The whole standard library gets exported from the DLL. Here is a lists with all exports: http://pastebin.com/LsG1u96C (5100 functions)

Am I missing some compiler switch? I compile the following code with rustc without any options:

#![crate_type = "dylib"]
#![feature(std_misc)]

use std::ffi::CString;

#[link(name = "user32")]
#[allow(non_snake_case)]
extern "stdcall" {
    fn MessageBoxA(hWnd: u32, lpText: *const i8, lpCaption: *const i8, uType: u32) -> u32;
}

#[no_mangle]
#[allow(non_snake_case)]
pub unsafe extern "stdcall" fn _AddLuaState(lua_state_ptr: u32)
{
    let info_str = format!("Lua State Created: {}!", lua_state_ptr);
    let info_cstring = CString::new(info_str).unwrap();
    let caption = CString::new("Hello from my Rust Library!").unwrap();
    MessageBoxA(0, info_cstring.as_ptr(), caption.as_ptr(), 0);
}

_AddLuaState@4 is the only function that should be exported.

This is on a Windows 8.1 machine with rustc 1.0.0-nightly (522d09dfe 2015-02-19) (x86)

Update: It looks like when compiling a dynamically linked file with rustc -C prefer-dynamic, the DLL size shrinks to 60kiB and there are only 3 extra exports (http://pastebin.com/G0AYZrpF) which all look quite reasonable. But I'd still prefer a statically linked library.

like image 636
dbeinder Avatar asked Feb 21 '15 22:02

dbeinder


1 Answers

Recently the new crate type "cdylib" has been added that likely better fits your use-case. Replace the first line of your source file with:

#![crate_type = "cdylib"]

When using the Cargo package manager instead of directly calling rustc update Cargo.toml to contain the following lines:

[lib]
crate-type = ["cdylib"]

For more details have a look at Rust pull request #33553.

In my test it decreased the size of the following simple "Hello World" DLL from 650k (dylib) down to 8k (cdylib). Also the number of exported symbols is decreased massively.

#[no_mangle]
pub extern fn hello_rust() -> *const u8 {
    "Hello, world!\0".as_ptr()
}
like image 71
blerontin Avatar answered Oct 24 '22 17:10

blerontin