Manually invoke rustc to link .o files to binary

I am exploring the rustc, and would like to understand how to manually link the .o files into a executable.

  1. create new project by cargo new hello

  2. emit .o files by cargo +nightly rustc -vv -- --emit=obj

  3. how to invovke rustc to link the generated .o files in target/debug/deps to a executable?

I tried ld.lld, but have below errors, seems missing to specify the compiler runtime

ld.lld-14  /home/gftea/repo/hello/target/debug/deps/hello-18bf37c42f8fa4a6.o
ld.lld-14: error: undefined symbol: std::rt::lang_start_internal::hc680b25eab888da9
>>> referenced by rt.rs:165 (/rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/rt.rs:165)
>>>               /home/gftea/repo/hello/target/debug/deps/hello-18bf37c42f8fa4a6.o:(std::rt::lang_start::h8ebc40c383e97ff8)

ld.lld-14: error: undefined symbol: core::panicking::panic_fmt::h4235fa9b4675b332
>>> referenced by mod.rs:396 (/rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/fmt/mod.rs:396)
>>>               /home/gftea/repo/hello/target/debug/deps/hello-18bf37c42f8fa4a6.o:(core::fmt::Arguments::new_v1::h13780d65d7abde6e)

ld.lld-14: error: undefined symbol: _Unwind_Resume
>>> referenced by function.rs:251 (/rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/ops/function.rs:251)
>>>               /home/gftea/repo/hello/target/debug/deps/hello-18bf37c42f8fa4a6.o:(core::ops::function::FnOnce::call_once::h8b351b06410f3f30)

ld.lld-14: error: undefined symbol: std::io::stdio::_print::hd86e5e43b045ff1c
>>> referenced by main.rs:2 (src/main.rs:2)
>>>               /home/gftea/repo/hello/target/debug/deps/hello-18bf37c42f8fa4a6.o:(hello::main::h6f6c1503373bf8d0)

ld.lld-14: error: undefined symbol: rust_eh_personality
>>> referenced by 1ilynpcbq5qyesrs
>>>               /home/gftea/repo/hello/target/debug/deps/hello-18bf37c42f8fa4a6.o:(DW.ref.rust_eh_personality)

This is not possible without hacks. A raw .o file misses a lot of information rustc needs to correctly generate shims (like the allocator shim for switching between #[global_allocator] and the default allocator in libstd) and invoke the linker (linker arguments are store in the crate metadata, not object files). What exactly are you trying to do? If you want to embed the rust code in a C project you should build a .a archive using --crate-type staticlib and then link this .a archive. If you pass --print native-static-libs while running rustc, it will print a list of linker arguments you need to link, although for simple examples that don't depend on anything other than libc gcc and clang generally already include all necessary linker arguments for you. Note that trying to link two rust staticlibs into the same executable or dynamic library will result in symbol conflicts.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.