How can I properly link when doing FFI without std or a dynamic linker?

Currently I'm building the crate as a simple lib, then linking all the objects in the archive together and then with my C code (this is probably kludge-y, but I can't figure out how to better do it), so:

cargo build
mkdir temp
mv target/target/debug/libfoobar.rlib temp
cd temp
ar x libfoobar.rlib
rm libfoobar.rlib
ld -o foobar.o -r *.o
mv foobar.o ..
cd ..
rm -r temp
# ... Compile baz.o from C code ... then
gcc -static -T linker.ld -o final_product.img -ffreestanding -nostdlib foobar.o baz.o -lgcc

but sadly this gives me linking errors when I try to do basically anything interesting in my Rust code (specifically, implementing fmt::Write for a UART port structure):

/usr/bin/ld: foobar.o: in function `core::ptr::mut_ptr::<impl *mut T>::add::precondition_check':
/home/caelus/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ub_checks.rs:68:(.text._ZN63_$LT$foobar..serial..UARTPort$u20$as$u20$core..fmt..Write$GT$9write_str17hdf840a6f1a942deeE+0x8a): undefined reference to `core::panicking::panic_nounwind'
/home/caelus/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ub_checks.rs:68:(.text._ZN63_$LT$foobar..serial..UARTPort$u20$as$u20$core..fmt..Write$GT$9write_str17hdf840a6f1a942deeE+0x8a): relocation truncated to fit: R_X86_64_PLT32 against undefined symbol `core::panicking::panic_nounwind'
/usr/bin/ld: foobar.o: in function `foobar::serial::UARTPort::test_transmit_empty':
/home/caelus/foobar/src/rust/serial.rs:81:(.text._ZN63_$LT$foobar..serial..UARTPort$u20$as$u20$core..fmt..Write$GT$9write_str17hdf840a6f1a942deeE+0x96): undefined reference to `core::panicking::panic_const::panic_const_add_overflow'
/home/caelus/foobar/src/rust/serial.rs:81:(.text._ZN63_$LT$foobar..serial..UARTPort$u20$as$u20$core..fmt..Write$GT$9write_str17hdf840a6f1a942deeE+0x96): relocation truncated to fit: R_X86_64_PLT32 against undefined symbol `core::panicking::panic_const::panic_const_add_overflow'
collect2: error: ld returned 1 exit status

I'm presuming this is an issue with the symbols from core getting mangled. How should I achieve what I'm trying to do? The Nomicon's FFI guide sets LD_LIBRARY_PATH, presumably to include symbols from std, but of course that's not available here.

.rlib files are not usable except as inputs to rustc, because they haven't yet instantiated all needed generic or inlinable functions. To compile something you can link together with non-Rust code, you must compile a library with crate-type = ["staticlib"] using cargo first. The resulting library will contain all needed Rust functions and static items.

Ah, I see, thanks! I didn't know the difference between lib and staticlib. It links and runs fine now. (Just a note: is it possible to safely remove the .eh_frame section? I have panic=abort anyways, so I don't think it's necessary, and it wasn't present in the .rlibs, but I'm not familiar with the intricacies of Rust stack unwinding.)