title: Rust object file missing when linking with C using clang
body: <p>I trying to work though some simple FFI things to figure out how to get Rust to work with C or C++ code. My immediate question is:</p>
  
  <p>It seems when I compile Rust code to an object file, it is missing some of the bindings for the clang linker to finalize an executable. Here are two very simple files that I am using.</p>
  
  <p><strong>clink.c</strong></p>
  
  <pre class="lang-c prettyprint-override"><code>#include &lt;stdio.h&gt;
  #include &lt;stdbool.h&gt;
  
  int rust_int(int);
  bool rust_bool(int, int);
  
  /********************************/
  /* void rust_char_star(char *); */
  /********************************/
  
  int main(void) {
      printf("%d\n", rust_int(5));
      if (rust_bool(5, 6)) {
          printf("True\n");
      }
      else { printf("False\n"); }
  
      /******************************/
      /* rust_char_star("Testing"); */
      /******************************/
  
      return 0;
  }
  </code></pre>
  
  <p><strong>rustlink.rs</strong></p>
  
  <pre><code>use std::os::raw::{c_int, c_char};
  // use std::ffi::{CStr, CString};
  
  #[no_mangle]
  pub extern "C" fn rust_int(i: c_int) -&gt; c_int {
      i
  }
  
  #[no_mangle]
  pub extern "C" fn rust_bool(x: c_int, y: c_int) -&gt; bool {
      if x &gt; y {
          true
      }
      else {
          false
      }
  }
  
  ////////////////////////////////////////////////////////////////////////////
  // #[no_mangle]                                                           //
  // pub extern "C" fn rust_char_star(c: *const c_char) {                   //
  //     let str_printable = unsafe {CString::from_raw(c as *mut c_char) }; //
  //                                                                        //
  //     println!("{:?}", str_printable);                                   //
  // }                                                                      //
  ////////////////////////////////////////////////////////////////////////////
  </code></pre>
  
  <p>When I compile each of these without the <code>CString</code>, everything works as expected. Ignore the warning.</p>
  
  <pre class="lang-none prettyprint-override"><code>~/dev/rust/learn/clink$ rustc --emit obj --crate-type staticlib rustlink.rs
  warning: unused import: `c_char`
  use std::os::raw::{c_int, c_char};
                            ^^^^^^
  = note: #[warn(unused_imports)] on by default
  
  ~/dev/rust/learn/clink$ clang clink.c rustlink.o -o test
  ~/dev/rust/learn/clink$ ./test
  5
  False
  </code></pre>
  
  <p>When I uncomment all the code to use the type <code>CString</code> though, that's where I'm missing something. I'm not going to repost the above code with the comments removed. Here is what the output yields though.</p>
  
  <pre class="lang-none prettyprint-override"><code>~/dev/rust/learn/clink$ rustc --emit obj --crate-type staticlib rustlink.rs 
  warning: unused import: `CStr`
   --&gt; rustlink.rs:2:16
    |
  2 | use std::ffi::{CStr, CString};
    |                ^^^^
    |
    = note: #[warn(unused_imports)] on by default
  
  ~/dev/rust/learn/clink$ clang clink.c rustlink.o -o test
  rustlink.o: In function `alloc::alloc::dealloc':
  rustlink.3a1fbbbh-cgu.0:(.text._ZN5alloc5alloc7dealloc17hca8aab9ecdf50cafE+0x43): undefined reference to `__rust_dealloc'
  rustlink.o: In function `rust_char_star':
  rustlink.3a1fbbbh-cgu.0:(.text.rust_char_star+0xa): undefined reference to `std::ffi::c_str::CString::from_raw'
  rustlink.3a1fbbbh-cgu.0:(.text.rust_char_star+0x3a): undefined reference to `&lt;std::ffi::c_str::CString as core::fmt::Debug&gt;::fmt'
  rustlink.3a1fbbbh-cgu.0:(.text.rust_char_star+0xa9): undefined reference to `std::io::stdio::_print'
  rustlink.o:(.data.DW.ref.rust_eh_personality[DW.ref.rust_eh_personality]+0x0): undefined reference to `rust_eh_personality'
  clang: error: linker command failed with exit code 1 (use -v to see invocation)
  ~/dev/rust/learn/clink$ 
  </code></pre>
  
  <p>Going a little further. I attempted to compile the Rust code to a static library to be fed into clang. I'm uncertain why, but this is the result.</p>
  
  <pre class="lang-none prettyprint-override"><code>~/dev/rust/learn/clink$ rustc --crate-type staticlib rustlink.rs 
  warning: unused import: `CStr`
   --&gt; rustlink.rs:2:16
    |
  2 | use std::ffi::{CStr, CString};
    |                ^^^^
    |
    = note: #[warn(unused_imports)] on by default
  
  ~/dev/rust/learn/clink$ ls
  clink.c  librustlink.a  rustlink.o  rustlink.rs
  ~/dev/rust/learn/clink$ clang clink.c -o test -lrustlink
  /usr/bin/ld: cannot find -lrustlink
  clang: error: linker command failed with exit code 1 (use -v to see invocation)
  ~/dev/rust/learn/clink$ clang clink.c -o test -L -lrustlink
  /tmp/clink-357672.o: In function `main':
  clink.c:(.text+0x15): undefined reference to `rust_int'
  clink.c:(.text+0x3a): undefined reference to `rust_bool'
  clink.c:(.text+0x83): undefined reference to `rust_char_star'
  clang: error: linker command failed with exit code 1 (use -v to see invocation)
  ~/dev/rust/learn/clink$
  </code></pre>
  
  <p>This is where I am a little confused. I thought when you tell rustc that the crate-type is static that it includes all dependencies, but I guess that is not the case.</p>
  
  <p>Clearly I am missing a step. I would prefer that rustc include all bindings so I can just use a simple command to clang to produce an executable.</p>