Repository: rust
Issue: Linking static library that contains undefined references
Labels: A-linkage,A-FFI,T-compiler,C-bug,S-has-mcve

We have a library crate that links against a static C library that leaves some references undefined.
In our binary crate, we link against our library crate as well as against another static C library that defines these missing references.
However, ld won't find these symbols if the binary crate does not contain at least one reference to one of these symbols:

```
   Compiling example v0.1.0 (/home/b/example)
error: linking with `cc` failed: exit status: 1
  |
  = note: "cc" "-m64" "/tmp/rustc2VbYxW/symbols.o" "/home/b/example/target/debug/deps/example-967bcb4b3b618986.1t95jeuk88g9wzdt.rcgu.o" "/home/b/example/target/debug/deps/example-967bcb4b3b618986.34we4c3mmsq2x99n.rcgu.o" "/home/b/example/target/debug/deps/example-967bcb4b3b618986.4gm2pvgqqcya6v1r.rcgu.o" "/home/b/example/target/debug/deps/example-967bcb4b3b618986.4lgp39odypzzuknq.rcgu.o" "/home/b/example/target/debug/deps/example-967bcb4b3b618986.5apd8rbg2qnfnbpe.rcgu.o" "/home/b/example/target/debug/deps/example-967bcb4b3b618986.5bly17gm1j6vg264.rcgu.o" "/home/b/example/target/debug/deps/example-967bcb4b3b618986.og2d0ah2k01s005.rcgu.o" "/home/b/example/target/debug/deps/example-967bcb4b3b618986.2q6594hq230h2f7.rcgu.o" "-Wl,--as-needed" "-L" "/home/b/example/target/debug/deps" "-L" "../clibimpl" "-L" "../clib" "-L" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "-lclibimpl" "/home/b/example/target/debug/deps/libclib_sys-480304bbe153da98.rlib" "-Wl,--start-group" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-5670385a2fe8b60b.rlib" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-fd56ba6dbf7aaecc.rlib" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libobject-b8acf8e5c2e85baa.rlib" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libmemchr-1706edefffdca0a2.rlib" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libaddr2line-f483302e0b13708e.rlib" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgimli-725b0718fc18e1ed.rlib" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-de685fcf2157e6fb.rlib" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_detect-f613ac3eda05b9ff.rlib" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-3de98a7d049af6a1.rlib" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libminiz_oxide-c12183655bdce152.rlib" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libadler-0fc7beea925de7e3.rlib" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-8c34825485bf59dc.rlib" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-ba5f7e926e729d81.rlib" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-643de0950163a839.rlib" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-539ea2f72ef89687.rlib" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-871432094bb4c885.rlib" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-ef1a8ee61f2e39bf.rlib" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-f1646747442c1c7b.rlib" "-Wl,--end-group" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-ff283b4bf550fa1c.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-znoexecstack" "-L" "/home/b/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "/home/b/example/target/debug/deps/example-967bcb4b3b618986" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro,-znow" "-nodefaultlibs"
  = note: /usr/bin/ld: /home/b/example/target/debug/deps/libclib_sys-480304bbe153da98.rlib(clib.o): in function `foo':
          clib.c:(.text+0x9): undefined reference to `bar'
          collect2: error: ld returned 1 exit status
          
  = help: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
  = note: use the `-l` flag to specify native libraries to link
  = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)

error: could not compile `example` due to previous error
```

Is this intended and can somebody explain this behaviour?

`rustc --version --verbose`:
```
rustc 1.64.0 (a55dd71d5 2022-09-19)
binary: rustc
commit-hash: a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52
commit-date: 2022-09-19
host: x86_64-unknown-linux-gnu
release: 1.64.0
LLVM version: 14.0.6
```

<details><summary>Minimal reproducible example</summary>
<p>

`clib/clib.c`
```rust
extern void bar(void);

void foo() {
    bar();
}
```

`gcc -c -o clib.o clib.c && ar rcs libclib.a clib.o`

`clib-sys/build.rs`
```rust
fn main() {
    println!("cargo:rustc-link-search=../clib");
    println!("cargo:rustc-link-lib=static=clib");
}
```

`clib-sys/src/lib.rs`
```rust
extern "C" {
    pub fn foo();
    pub fn bar2();
}

pub fn safe_foo() {
    unsafe { foo() };
}
```

`clibimpl/clibimpl.c`
```rust
#include <stdio.h>

void bar() {
    printf("Hello World");
}

void bar2() {
}
```

`gcc -c -o clibimpl.o clibimpl.c && ar rcs libclibimpl.a clibimpl.o`

`example/Cargo.toml`
```rust
[dependencies]
clib-sys = { path = "../clib-sys" }
```

`example/build.rs`
```rust
fn main() {
    println!("cargo:rustc-link-search=../clibimpl");
    println!("cargo:rustc-link-lib=static=clibimpl");
}
```

`example/src/main.rs`
```rust
fn main() {
    clib_sys::safe_foo();
    // unsafe { clib_sys::bar2() }; // Uncomment this line to make the linking succeed
}
```

</p>
</details>