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

⚓ rust    📅 2025-05-14    👤 surdeus    👁️ 2      

surdeus

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.

3 posts - 2 participants

Read full topic

🏷️ rust_feed