Using rustc with a custom libc

Hello, I'm working on a project that's generating some C binaries, but those binaries must link in a Rust static library I'm writing. The binaries need to be statically linked (so I'm using musl libc) and cross compiled for several architectures (currently x86_64, mips, and arm). I installed the necessary cross-compiled targets with rustup (x86_64-unknown-linux-musl, mips-unknown-linux-musl, and arm-unknown-linux-musleabi), built my crate as a static lib for those targets, then linked the Rust static libs into my C binaries.

I started running into some strange crashes when running the binaries (all of them happening while invoking libc calls), when I realized something potentially problematic: the toolchains used to generate these Rust cross-compiled targets are almost certainly not the same as the toolchains I'm using to compile/link my C code. In particular, the static libs that I generate from my Rust crate contain all the libc symbols from liblibc-<HASH>.rlib from the Rust toolchain. I don't exactly know how the linking process is going to deal with those symbols being defined both by libc.a and this Rust static lib, but it doesn't give me a good feeling...

To try and resolve my issues, I thought that I might need to compile rustc using the same toolchains (same gcc + musl libc versions) that I plan on using for my C code. Does this seem like the right course of action? I figured that poking around the various scripts in src/ci/docker from the Rust language repo might lead me in the right direction, and hopefully I can adapt them for the versions of musl/gcc that I'm using. Is that the right place to start looking? Are those scripts the same ones that generate the stable Rust releases?

I forgot to mention it, but I'm trying to stick with stable Rust versions, and the host architecture that I'm working on is x86_64-unknown-linux-gnu.

Thanks so much for any help!

Rust's libc crate is an equivalent of C's .h files. It doesn't contain any code itself, so that .rlib file is just Rust metadata without any symbols going into the executable.

The only thing that has to match is the prototypes of functions and structs with their actual implementation, and this is supposed to be standardized.

libc definitely works with musl, because that's one of officially supported targets.

I can't say for sure it can't be the libc crate, but it's more likely that the crate and linking are fine, and the crashes come from your code, or misuse of libc functions (after all, they're all unsafe, and will crash if you use them incorrectly).

Thanks so much for the reply @kornel!

I'm definitely not discounting the possibility of my own C code containing issues (I'll try and put together a minimal reproduction of this issue soon), but I wanted to clear something up that you brought up: I'm not talking about Rust's libc crate, I'm talking about the liblibc-<HASH>.rlib that comes with the Rust toolchain distribution (my apologies, my original post didn't make that clear). If I look at the liblibc-<HASH>.rlib file for the x86_64 musl target, I see this:

$ du -h ~/.rustup/toolchains/1.35.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib/liblibc-a19d328d73c1ea73.rlib
4.1M    ~/.rustup/toolchains/1.35.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib/liblibc-a19d328d73c1ea73.rlib

4.1 MB is too big for just headers. Then, if I run nm on that file, I see tons of object files (1293 of them) with text sections. Here's just a little segment of that:

$ nm ~/.rustup/toolchains/1.35.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib/liblibc-a19d328d73c1ea73.rlib | tail -n 10
                 U __syscall_cp
                 U __syscall_ret
0000000000000000 T write

                 U __syscall_cp
                 U __syscall_ret
0000000000000000 T writev

These correspond with object files built from musl libc. This rlib is where Rust binaries get all of their libc function definitions (at least for musl targets), and I'm concerned about the disconnect between this rlib and the libc.a from my own musl libc.