Repository: rust
Issue: Linker error for no_std binary using musl
Labels: A-linkage,T-libs-api,T-compiler,O-musl

I tried to build a simple `no_std` "Hello World!" program using the `x86_64-unknown-linux-musl` target. The source code (in `src/main.rs`) is here:

```rust
#![no_std]
#![no_main]

use libc::{c_char, c_int, exit, puts};

#[no_mangle]
pub extern "C" fn main(_: c_int, _: *const *const c_char) -> c_int {
    unsafe {
        puts(b"Hello World!\0" as *const u8 as *const i8);
    }

    0
}

#[panic_handler]
fn panic_handler(_: &core::panic::PanicInfo) -> ! {
    unsafe {
        exit(1)
    }
}
```

When using my default `x86_64-unknown-linux-gnu` target, the program compiles and runs like it should, but with `x86_64-unknown-linux-musl`, I get this linking error:

```
error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-Wl,--eh-frame-hdr" "-m64" "-nostdlib" "/home/johannes/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib/crt1.o" "/home/johannes/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib/crti.o" "-L" "/home/johannes/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib" "/home/johannes/hello/target/x86_64-unknown-linux-musl/release/deps/hello-8e567d3b97d6bd11.hello.c72za6mx-cgu.0.rcgu.o" "-o" "/home/johannes/hello/target/x86_64-unknown-linux-musl/release/deps/hello-8e567d3b97d6bd11" "-Wl,--gc-sections" "-no-pie" "-Wl,-zrelro" "-Wl,-znow" "-Wl,-O1" "-nodefaultlibs" "-L" "/home/johannes/hello/target/x86_64-unknown-linux-musl/release/deps" "-L" "/home/johannes/hello/target/release/deps" "-L" "/home/johannes/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib" "-Wl,-Bstatic" "/home/johannes/hello/target/x86_64-unknown-linux-musl/release/deps/liblibc-8c2b3cf08263e000.rlib" "/home/johannes/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib/libcore-879310dc3b96af61.rlib" "/home/johannes/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib/libcompiler_builtins-d0572f7a936161bf.rlib" "-static" "-Wl,-Bdynamic" "/home/johannes/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib/crtn.o"
  = note: /usr/bin/ld: /home/johannes/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib/crt1.o: in function `_start_c':
          /build/musl-1.1.20/crt/crt1.c:17: undefined reference to `__libc_start_main'
          /usr/bin/ld: /home/johannes/hello/target/x86_64-unknown-linux-musl/release/deps/hello-8e567d3b97d6bd11.hello.c72za6mx-cgu.0.rcgu.o: in function `main':
          hello.c72za6mx-cgu.0:(.text.main+0xa): undefined reference to `puts'
          collect2: error: ld returned 1 exit status
```

I can build a normal (`std`-using) "Hello World!" program for musl without problems, only this `no_std` version doesn't work.

I am also able to work around this problem by instead moving the source code to `src/lib.rs` and compiling it as a library with `crate-type = ["staticlib"]`, then linking manually with `musl-gcc`. The error only occurs when trying to build a binary directly.

<details>
<summary>My Cargo.toml. Uncomment the two lines and move main.rs to lib.rs for the workaround.</summary>

```toml
[package]
name = "hello"
version = "0.1.0"
authors = ["me"]
edition = "2018"

#[lib]
#crate-type = ["staticlib"]

[dependencies]
libc = { version = "0.2", default-features = false }

[profile.dev]
panic = "abort"

[profile.release]
panic = "abort"
```
</details>