OpenWRT MIPS cross-compile error

Hi folks,

I've been trying to follow rust-cross as well as rust-on-openwrt and try to get a basic hello world running on OpenWRT with MIPS.

I followed the instructions, downloaded the SDK (OpenWRT SDK for Linux 15.05.1), set it up, added the target mips-unknown-linux-gnu to rustup.rs and then used

rustc --target mips-unknown-linux-gnu -C --linker=mips-openwrt-linux-gcc hello.rs

where hello.rs is just a plain "Hello world" fn.

Here is the error I get, which makes me think something is wrong my toolchain - maybe someone has an idea how to fix it? maybe @japaric?

error: linking with `mips-openwrt-linux-gcc` failed: exit code: 1
note: "mips-openwrt-linux-gcc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-L" "/root/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-gnu/lib" "hello.0.o" "-o" "hello" "-Wl,--gc-sections" "-pie" "-nodefaultlibs" "-L" "/root/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-gnu/lib" "-Wl,-Bstatic" "-Wl,-Bdynamic" "/root/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-gnu/lib/libstd-39b92f95.rlib" "/root/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-gnu/lib/libpanic_unwind-39b92f95.rlib" "/root/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-gnu/lib/libunwind-39b92f95.rlib" "/root/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-gnu/lib/librand-39b92f95.rlib" "/root/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-gnu/lib/libcollections-39b92f95.rlib" "/root/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-gnu/lib/librustc_unicode-39b92f95.rlib" "/root/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-gnu/lib/liballoc-39b92f95.rlib" "/root/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-gnu/lib/liballoc_jemalloc-39b92f95.rlib" "/root/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-gnu/lib/liblibc-39b92f95.rlib" "/root/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-gnu/lib/libcore-39b92f95.rlib" "-l" "dl" "-l" "pthread" "-l" "gcc_s" "-l" "pthread" "-l" "c" "-l" "m" "-l" "rt" "-l" "util" "-l" "compiler-rt"
note: mips-openwrt-linux-gcc: warning: environment variable 'STAGING_DIR' not defined
mips-openwrt-linux-gcc: warning: environment variable 'STAGING_DIR' not defined
/root/code/sdk/openwrt-15.05/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/../lib/gcc/mips-openwrt-linux-uclibc/4.8.3/../../../../mips-openwrt-linux-uclibc/bin/ld: Warning: hello uses -msoft-float (set by /root/code/sdk/openwrt-15.05/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/../lib/gcc/mips-openwrt-linux-uclibc/4.8.3/crtbeginS.o), /root/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-gnu/lib/libstd-39b92f95.rlib(fileline.o) uses unknown floating point ABI 5
/root/code/sdk/openwrt-15.05/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/../lib/gcc/mips-openwrt-linux-uclibc/4.8.3/../../../../mips-openwrt-linux-uclibc/bin/ld: Warning: hello uses -msoft-float (set by /root/code/sdk/openwrt-15.05/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/../lib/gcc/mips-openwrt-linux-uclibc/4.8.3/crtbeginS.o), /root/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-gnu/lib/libstd-39b92f95.rlib(posix.o) uses unknown floating point ABI 5
/root/code/sdk/openwrt-15.05/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/../lib/gcc/mips-openwrt-linux-uclibc/4.8.3/../../../../mips-openwrt-linux-uclibc/bin/ld: Warning: hello uses -msoft-float (set by /root/code/sdk/openwrt-15.05/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/../lib/gcc/mips-openwrt-linux-uclibc/4.8.3/crtbeginS.o), /root/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-gnu/lib/libstd-39b92f95.rlib(state.o) uses unknown floating point ABI 5
/root/code/sdk/openwrt-15.05/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/../lib/gcc/mips-openwrt-linux-uclibc/4.8.3/../../../../mips-openwrt-linux-uclibc/bin/ld: Warning: hello uses -msoft-float (set by /root/code/sdk/openwrt-15.05/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/../lib/gcc/mips-openwrt-linux-uclibc/4.8.3/crtbeginS.o), /root/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-gnu/lib/libstd-39b92f95.rlib(elf.o) uses unknown floating point ABI 5

Full output here: Build Error · GitHub

Rust version used is 1.11.0 on Linux 64bit

Thanks much,
Michael

OpenWRT 15.05.1 is uclibc based so you have to use the mips-unknown-linux-uclibc target not the mips-unknown-linux-gnu one, which is glibc based. The uclibc target is new-ish so it may not be available in the latest stable release of Rust; I haven't check.

Sadly, we don't yet have binary releases of standard crates for this target so you can't rustup target add mips-unknown-linux-uclibc right now. You'll have to build the standard crates yourself and that means using the nightly channel. I can post instructions on how to do that if you want to try.

Alternatively, if you can switch your device to OpenWRT trunk then you can use the mips-unknown-linux-musl target instead. rustup target add does work for that target.

@japaric thanks very much for the clarification. I can't switch the device to trunk, I need to use 15.05.1 for now.

If it isn't too much effort for you to write it up I'd love to give it a try, but feel free to point me at the right pieces online as well. Is this the right place to start: GitHub - japaric/rust-cross: Everything you need to know about cross compiling Rust programs! ?

Thanks again,
Michael

Yeah, those instructions should work.

Some modifications you could do:

  • Instead of grabbing the whole git repository you could use the source that rustup provides.

Do rustup component add rust-src and the source will be available at $(rustc --print sysroot)/lib/rustlib/src/rust. This source is guaranteed to match your compiler.

  • Instead of creating shims you could use rustbuild and point to the toolchain using env variables.

Additionally, pass the --enable-rustbuild flag to configure. Then set these env variables:

export AR_mips_unknown_linux_musl=/path/to/mips-openwrt-linux-ar
export CC_mips_unknown_linux_musl=/path/to/mips-openwrt-linux-gcc
export CXX_mips_unknown_linux_musl=/path/to/mips-openwrt-linux-g++

I finally got it to work and wrote it down here: Rust on the WiFi Pineapple (and OpenWrt) – daschl writes. sometimes.