Cross-compiling and jemalloc


#1

I’m trying to get rust compiled on Solaris/SPARC by cross-compiling from Solaris/x86. I’ve followed various hints around the place and got what seems to be a working target – the compilation works, as does linking of dylibs and rlibs, and executables still need a little help, but a simple no_std program succeeds by not dumping core, so I’m happy about all that. :slight_smile:

I have some cross-linking questions I’ll ask in another topic.

But I’m following the next step in @japaric’s great reddit answer, and I ran into the somewhat obvious issue that when building libstd with cargo, libjemalloc didn’t actually get cross-compiled. That clearly wasn’t going to work, so I turned off jemalloc support by passing --features "panic-unwind backtrace" to cargo, and that did in fact bypass building jemalloc and the alloc_jemalloc crate.

But now I end up with an error complaining that it can’t find the alloc_jemalloc crate. WTF? Turning on some debugging in rustc_metadata, I see

INFO:rustc_metadata::creader: resolving crate `extern crate alloc_jemalloc as alloc_jemalloc`
INFO:rustc_metadata::creader: lib.rs:1:1: 1:1
INFO:rustc_metadata::creader: falling back to a load
INFO:rustc_metadata::locator: lib candidate: /export/home/dduvall/sfw/rust/rust.git/x86_64-sun-solaris/stage2/lib/rustlib/x86_64-sun-solaris/lib/liballoc_jemalloc-0e45581d.rlib
INFO:rustc_metadata::locator: rlib reading metadata from: /export/home/dduvall/sfw/rust/rust.git/x86_64-sun-solaris/stage2/lib/rustlib/x86_64-sun-solaris/lib/liballoc_jemalloc-0e45581d.rlib
INFO:rustc_metadata::locator: reading "liballoc_jemalloc-0e45581d.rlib" => Duration { secs: 0, nanos: 125421 }
INFO:rustc_metadata::locator: metadata mismatch
error[E0463]: can't find crate for `alloc_jemalloc`

That second line came from an attempt to add another bit of debugging to tell me where the crate was being pulled in, since I couldn’t find it anywhere. I’m not sure I got that right, but I suspect that those line numbers are synthetic, and it just means that the compiler is adding it for me.

Is there any way to disable its usage with the rustc I have, or do I have to build a special version of rustc that’s been built with jemalloc disabled? Should rustc be smart enough to know (or to be told) that jemalloc isn’t wanted when cross-compiling? Something else I’m missing?


#2

You need to tell the backend to use the system allocator instead, with something like this applied to your target definition.


#3

I’m trying to get rust compiled on Solaris/SPARC by cross-compiling from Solaris/x86.

Wait, do we support Solaris/x86? TIL

I ran into the somewhat obvious issue that when building libstd with cargo, libjemalloc didn’t actually get cross-compiled

Do you mean that it didn’t get build at all or that it got natively compiled instead of cross compiled? In any case, you probably want to set these env variables:

export CC_sparc64_sun_solaris=sparc64-sun-solaris-gcc
export CARGO_TARGET_SPARC64_SUN_SOLARIS_LINKER=sparc64-sun-solaris-gcc

so I turned off jemalloc support by passing --features “panic-unwind backtrace”

I’m not sure that’s th right way to disable jemalloc support. I think you want to set exe_allocation_crate and the other similarly named field in the target specification to alloc_system. Even with that, I think that rustbuild will still compile the alloc_jemalloc crate but at least it won’t link it to your executables and libstd.dylib

If that still doesn’t work, then try applying this patch and building with the Cargo features you mentioned.

Another thing that may help is disabling the dylib build of std. Simply remove the crate-type = ["dylib", "lib"] line in std’s Cargo.toml.

Good luck!


#4

Well, “support” might be a bit strong. It’s on the tier 3 list, and technically the work that got it put into the tree was done on Illumos, but it was close enough for me to get it going based on posted stage0 compilers. I’m hoping to raise the support level eventually, but I’m not there yet.

I meant that it got natively compiled. I could use those environment variables, if our gcc did cross-compilation, but it doesn’t. I was hoping to avoid going down that route at all, but maybe that’s not possible? Is there any way to build rustc without a C/C++ compiler at all?

I’ll give that patch a try, but now I’m wondering if I’m going to be dead in the water anyway, without a C/C++ cross-compiler.

Thank you!


#5

cross compile rustc? No. It has to be linked to libc so you’ll need a cross toolchain, both the linker and at least a cross compiled libc.

If the goal is just to cross compile libstd without C/C++ then you’ll have remove the “backtrace” Cargo feature as well as apply the dylib patch. That should do it, at least on Linux, I don’t know if solaris has more C dependencies that get compiled as part of std.

BUT without a cross compiler you won’t be able to cross compile a program using the cross compiled std because you need a cross gcc (and libc and other stuff) to link the program …


#6

So I spent some time adding a new linker to rustc_trans::back which invokes the Solaris linker directly, and it is capable of cross-linking, as long as it’s pointed at the right libraries and CRT objects (this relates to the cross-linking question I referred to in my original post), which I currently have to do manually, since rustc itself doesn’t seem to have a way to point at a different directory to get those things. I wanted to do that anyway, so that we didn’t have to rely on gcc being present simply to build Rust programs, but if it meant that I didn’t have to worry about having a cross-compiler, all the better.