Cross-compiling 1.65.0 to a new mips target

I'm in the process of making the mipsel-unknown-netbsd target build. This should in theory be quite easy, since the CPU architecture and the ABI should be well-known already. I've come quite a way, and all of LLVM is built, as well as rustdoc and rustc, ref.:

$ ls -l build/mipsel-unknown-netbsd/stage2/bin
total 23384
-rwxr-xr-x  4 he  125      9288 Nov 23 19:37 rustc
-rwxr-xr-x  4 he  125  11916016 Nov 23 19:39 rustdoc
$ 

and those are MIPS executables.

This is a 32-bit target, so "of course" it needs to use -latomic to support 64-bit atomics. And by the looks of it, it's now trying to link the cargo executable for the target, and failing because -latomic is not present on the rustc compiler invocation. I have already modified compiler/rustc_llvm/build.rs along the lines of Fix build on powerpc-unknown-freebsd by pkubaj · Pull Request #104572 · rust-lang/rust · GitHub, but this apparently does not influence the linking of cargo. The cross compiler invocation contains

"-o" "/usr/pkgsrc/wip/rust-1.65/work/rustc-1.65.0-src/build/x86_64-unknown-netbsd/stage1-tools/mipsel-unknown-netbsd/release/deps/cargo-a1651116a97b672b"

So ... the question then becomes: what part of the rather twisted build system determines whether to add -latomic to the linking of cargo? I have tried looking around for other places/systems which also need this library added, but have so far come up empty. "Help!"

What exactly needs 64-bit atomics? In Rust code atomic types should only be available if the target has native support. Did you set max_atomic_width: Some(32) in the target specification?

What exactly needs 64-bit atomics? In Rust code atomic types
should only be available if the target has native support.

The core of the error message is

  = note: /u/mipsel/tools/bin/../lib/gcc/mipsel--netbsd/7.5.0/../../../../mipsel--netbsd/bin/ld: /usr/pkgsrc/wip/rust-1.65/work/rustc-1.65.0-src/build/x86_64-unknown-netbsd/stage1-tools/mipsel-unknown-netbsd/release/deps/libopenssl_sys-4f1d9a5d1439daf0.rlib(threads_pthread.o): in function `CRYPTO_atomic_add':
          threads_pthread.c:(.text.CRYPTO_atomic_add+0x10): undefined reference to `__atomic_is_lock_free'
          /u/mipsel/tools/bin/../lib/gcc/mipsel--netbsd/7.5.0/../../../../mipsel--netbsd/bin/ld: threads_pthread.c:(.text.CRYPTO_atomic_add+0x40): undefined reference to `__atomic_is_lock_free'

Did you set max_atomic_width: Some(32) in the target
specification?

Yep:

use crate::abi::Endian;
use crate::spec::{Target, TargetOptions};

pub fn target() -> Target {
    let mut base = super::netbsd_base::opts();
    base.max_atomic_width = Some(32);

    Target {
        llvm_target: "mipsel-unknown-netbsd".into(),
        pointer_width: 32,
        data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(),
        arch: "mips".into(),
        options: TargetOptions {
            mcount: "__mcount".into(),
            endian: Endian::Little,
            ..base
        },
    }
}

Looks like openssl depends on it. You can probably fixing it using some code like

You can also try setting the OPENSSL_NO_VENDOR env var to make it dynamically link to the system openssl installation.

2 Likes

Thanks, that and the pointer to the openssl fix set me on the right path, and I now have a cross-built bootstrap kit for rust 1.65.0 for mipsel-unknown-netbsd. Now to see if it works...