Cross-compiled Libstd for a new target, am having a weird error


I have been trying to port rust to a new custom target for a POC. I was successfully to cross-compile no_std files fairly easily, because there’s so much comprehensive support out there, but when it comes to porting std, since it’s so large, it was a bit harder. Either way, I was able to port libc, and std:sys, which enabled me to successfully cross-compile (using xargo to skip a step, but I will test this right after making this post).

So then, I wanted to compile a basic library with the help of xargo, that’d be a good benchmark. The code is as follows.

pub fn complete () {

This can and will successfully compile for my native target (nightly 1.28 for x86-64_unknown-linux-gnu) via cargo. After some careful hacking (mainly explicitly specifying the appropriate libstd as a dependency), I managed to cross-compile it for my new target.

The main way I tested to see if it works was to arbitrarily execute methods via an object file, which worked for a bit of a smaller function,


pub fn easy_() -> u32 {

#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }

The full object file is here, if you want to read it, but I can’t imagine it’s terribly interesting. The _ZN8addition5easy_17h7f35e0514a3234f2E symbol returned 3, so by that measure it was successful.

However, going back to my new code - the complete thing is similar, and makes sense to me in general, but when loaded into the target yields a pretty direct error.

 Warning: module 0x400be2010 holds reference to undefined symbol _ZN3std2io5stdio6_print17h4bc7153110a3f2f8E.

To be clear, invoking complete() results in a segmentation violation, which to me is a sign that it’s a failure.

Ok … so what is the symbol? It ostensibly is std::io:stdio::_print, which can be found on line 700 of src->libstd->io->stdio on github (I’d link it, but as a new user I’m constrained to two links in this post). This would invoke print_to, which doesn’t seem to be in the object code.

I really wish I could post more troubleshooting, I’m just lost about what to do. Where do I go about fixing this? My system bindings could be faulty, seeing as a significant amount of it was hacked together trying to get the POC working, but I’m not sure if that’d really fix the problem of the target not knowing about std::io::stdio::_print, which inherently relies upon rust, from what I’ve seen.

To be clear, maybe there’s an easier way of solving this first goal, all I want is to print to the system console via rust as my first step, but I might be gravely mistaken. What’s are my options? What should I try?


It sounds like there’s a problem that would on conventional targets result in a linker error, but that’s somehow not happening for you. Can you give some more details about your new target? Are you running an OS? How are you supposed to print to the system console?


I was thinking it’d be some kind linking problem, but I’m not sure (I’m using the default linker for x86_64_unknown-linux-gnu afaik) exactly how.

The target is mostly POSIX compliant. It is strictly speaking an OS, and it supports classic linux stdio (ie printf) to print to the system console.

Edit: I forgot to mention - here is the native code - for x86_64-unknown-linux-gnu, it exhibits the exact same error.

This is a linker error, I guess it’s being emitted too soon …


All objdump outputs you have linked are of object files. What is the output for the fully linked executable?


I don’t know if the final form would qualify as an executable, since it’s a library (though that just might be my lack of knowledge showing)

Custom target, fully compiled
Native target, fully compiled


rlibs are not fully linked. If you need to compile to a libray, use the staticlib or cdylib crate types.


They appear to only be supported for osx, linux and windows


A staticlib is just a libwhatever.a file, which I would imagine is something your custom target would support.