title: Why is the Rust libstd linked dynamically without using -C prefer-dynamic flag after compiling a dynamic library?
body: <p>I am having an issue understanding how Cargo links binaries when building a dynamic library. To understand it better, I took the <a href="https://github.com/uutils/coreutils" rel="nofollow noreferrer">coreutils project</a> and tried to build 'ls' changing Cargo.toml and other stuff to make the executable as small as possible. I rapidly found out that linking libraries dynamically could reduce the size of the executables drastically. </p>
  
  <p>Digging through the internet for optimizations, I found that when you generate libraries as "dylibs" in Cargo, they still include "libstd" statically unless you explicitly tell the compiler to include it dynamically using the flag "-C prefer-dynamic". </p>
  
  <p>I don't use the flag, but still end up having libstd linked dynamically, which is very strange. </p>
  
  <h1>Cargo.toml for ls</h1>
  
  <p>I modified this a bit.</p>
  
  <pre><code>[package]
  name = "ls"
  version = "0.0.1"
  authors = ["Jeremiah Peschka &lt;jeremiah.peschka@gmail.com&gt;"]
  
  
  
  [lib]
  crate-type=["dylib"]
  name = "uu_ls"
  path = "ls.rs"
  
  [dependencies]
  getopts = "0.2.14"
  pretty-bytes = "0.2.1"
  term_grid = "0.1.5"
  termsize = "0.1.4"
  time = "0.1.38"
  lazy_static = "0.2.8"
  unicode-width = "0.1.4"
  
  [dependencies.uucore]
  path = "../uucore"
  default-features = false
  features = ["entries"]
  
  [[bin]]
  name = "ls"
  path = "main.rs"
  </code></pre>
  
  <h1>Cargo.toml of uucore</h1>
  
  <p>This is the only dependency of ls that I need to compile:</p>
  
  <pre><code>[package]
  name = "uucore"
  version = "0.0.1"
  authors = []
  
  
  [dependencies]
  getopts = "0.2.14"
  time = { version = "0.1.38", optional = true }
  data-encoding = { version = "^1.1", optional = true }
  
  [dependencies.libc]
  git = "https://github.com/rust-lang/libc.git"
  optional = true
  
  [features]
  fs = ["libc"]
  utf8 = []
  encoding = ["data-encoding"]
  parse_time = []
  utmpx = ["time", "libc"]
  process = ["libc"]
  signals = []
  entries = ["libc"]
  wide = []
  utsname = ["libc"]
  default = ["fs", "libc", "utf8", "utsname", "encoding", "parse_time", "utmpx", "process", "entries", "signals", "wide"]
  
  [lib]
  crate-type=["dylib"]
  path = "lib.rs"
  name = "uucore"
  </code></pre>
  
  <p>After building the library, I determine whether if it is linked dynamically: </p>
  
  <pre class="lang-none prettyprint-override"><code>ldd ~/target/release/libuu_ls.so 
      linux-vdso.so.1 =&gt;  (0x00007ffd96b98000)
      libuucore.so =&gt; not found
      libstd-8eeda694d27cc3ba.so =&gt; /home/cibo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/libstd-8eeda694d27cc3ba.so (0x00007f86a29d0000)
      librt.so.1 =&gt; /lib/x86_64-linux-gnu/librt.so.1 (0x00007f86a27c8000)
      libpthread.so.0 =&gt; /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f86a25ab000)
      libgcc_s.so.1 =&gt; /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f86a2394000)
      libc.so.6 =&gt; /lib/x86_64-linux-gnu/libc.so.6 (0x00007f86a1fca000)
      libm.so.6 =&gt; /lib/x86_64-linux-gnu/libm.so.6 (0x00007f86a1cc1000)
      libdl.so.2 =&gt; /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f86a1abc000)
      /lib64/ld-linux-x86-64.so.2 (0x0000558ebb132000)
  </code></pre>
  
  <p>As you can see, libstd is dynamically linked here. </p>