Rust-lang (rustc/cargo) for OpenWrt - testing needed

Hi,

I stumbled on this thread while looking to see if Rust is already a good candidate for OpenWRT package development. Currently we develop everything in C but the added value of Rust's thread safety and compile time memory access validation would be huge. Especially because valgrind or any other runtime memory debuggers aren't created for the MIPS targets we use.

@Grommish thank you very much for your dedication and hard work. I have downloaded your latest version of the lang/rust package (from 6 days ago) in my OpenWRT 19.07 toolchain. As I'm willing to compile a simple Hello World rust program for my MIPS target. The build was failing the first time but I found out this was because I didn't have ccache installed on my host. Now the build succeeds :slight_smile:

I'm however not succeeding in getting a minimal Hello World example working. I've now created a simple package and a Makefile like this:

daanpape/rust-hello-world: Attempt to make a simple Rust Hello World example in OpenWRT (github.com)

And I'm getting a linker error:

error: linking with `cc` failed: exit code: 1
  |
  = note: /usr/bin/ld: main.main.7rcbfp3g-cgu.0.rcgu.o: relocations in generic ELF (EM: 8)
          /usr/bin/ld: main.main.7rcbfp3g-cgu.0.rcgu.o: relocations in generic ELF (EM: 8)
          /usr/bin/ld: main.main.7rcbfp3g-cgu.0.rcgu.o: error adding symbols: file in wrong format
          collect2: error: ld returned 1 exit status

Could you give me any pointers?

Update: I got it working by looking at the suricata example. I updated the github. I'm going to try and add some floating point operations, also the binary is quite large. I think this might be optimized in the future.

The build system is using your existing Host's Rust Toolchain, which probably isn't equipped to Cross-compile.

Add this to your test package and see what it does. You may or may not need the RUSTFLAGS, but I left them in for documentation sake. In my Suricata package, I only need it as you see it.

CONFIGURE_VARS += \
	CARGO_HOME=$(CARGO_HOME) \
	ac_cv_path_CARGO="$(CARGO_HOME)/bin/cargo" \
	ac_cv_path_RUSTC="$(CARGO_HOME)/bin/rustc"
#	RUSTFLAGS="-C linker=$(TARGET_CC_NOCACHE) -C ar=$(TARGET_AR)"

Errors on the Package/install but that's alright. Notice it built it.

grommish@DESKTOP-N35LRJ4:~/openwrt$ make -j1 V=sc package/feeds/packages/rust-hello-world/compile
make[2]: Entering directory '/home/grommish/openwrt/scripts/config'
make[2]: 'conf' is up to date.
make[2]: Leaving directory '/home/grommish/openwrt/scripts/config'
time: target/linux/prereq#0.12#0.01#0.12
make[1]: Entering directory '/home/grommish/openwrt'
make[2]: Entering directory '/home/grommish/openwrt/package/libs/toolchain'
echo "libc" >> /home/grommish/openwrt/staging_dir/target-mips64_octeonplus_64_musl/pkginfo/toolchain.default.install
echo "libgcc" >> /home/grommish/openwrt/staging_dir/target-mips64_octeonplus_64_musl/pkginfo/toolchain.default.install
echo "libatomic" >> /home/grommish/openwrt/staging_dir/target-mips64_octeonplus_64_musl/pkginfo/toolchain.default.install
echo "libpthread" >> /home/grommish/openwrt/staging_dir/target-mips64_octeonplus_64_musl/pkginfo/toolchain.default.install
echo "librt" >> /home/grommish/openwrt/staging_dir/target-mips64_octeonplus_64_musl/pkginfo/toolchain.default.install
make[2]: Leaving directory '/home/grommish/openwrt/package/libs/toolchain'
time: package/libs/toolchain/compile#0.18#0.01#0.16
make[2]: Entering directory '/home/grommish/openwrt/feeds/packages/utils/rust-hello-world'
rm -f /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/.configured_*
rm -f /home/grommish/openwrt/staging_dir/target-mips64_octeonplus_64_musl/stamp/.rust-hello-world_installed
(cd /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/./; if [ -x ./configure ]; then find /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/ -name config.guess | xargs -r chmod u+w; find /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/ -name config.guess | xargs -r -n1 cp --remove-destination /home/grommish/openwrt/scripts/config.guess; find /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/ -name config.sub | xargs -r chmod u+w; find /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/ -name config.sub | xargs -r -n1 cp --remove-destination /home/grommish/openwrt/scripts/config.sub; AR="mips64-openwrt-linux-musl-gcc-ar" AS="mips64-openwrt-linux-musl-gcc -c -Os -pipe -mno-branch-likely -march=octeon+ -mtune=octeon3 -mabi=64 -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -msoft-float -fmacro-prefix-map=/home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1=rust-hello-world-0.0.1 -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro" LD=mips64-openwrt-linux-musl-ld NM="mips64-openwrt-linux-musl-gcc-nm" CC="mips64-openwrt-linux-musl-gcc" GCC="mips64-openwrt-linux-musl-gcc" CXX="mips64-openwrt-linux-musl-g++" RANLIB="mips64-openwrt-linux-musl-gcc-ranlib" STRIP=mips64-openwrt-linux-musl-strip OBJCOPY=mips64-openwrt-linux-musl-objcopy OBJDUMP=mips64-openwrt-linux-musl-objdump SIZE=mips64-openwrt-linux-musl-size CFLAGS="-Os -pipe -mno-branch-likely -march=octeon+ -mtune=octeon3 -mabi=64 -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -msoft-float -fmacro-prefix-map=/home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1=rust-hello-world-0.0.1 -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro " CXXFLAGS="-Os -pipe -mno-branch-likely -march=octeon+ -mtune=octeon3 -mabi=64 -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -msoft-float -fmacro-prefix-map=/home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1=rust-hello-world-0.0.1 -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro " CPPFLAGS="-I/home/grommish/openwrt/staging_dir/toolchain-mips64_octeonplus_64_gcc-10.2.0_musl/usr/include -I/home/grommish/openwrt/staging_dir/toolchain-mips64_octeonplus_64_gcc-10.2.0_musl/include/fortify -I/home/grommish/openwrt/staging_dir/toolchain-mips64_octeonplus_64_gcc-10.2.0_musl/include " LDFLAGS="-L/home/grommish/openwrt/staging_dir/toolchain-mips64_octeonplus_64_gcc-10.2.0_musl/usr/lib -L/home/grommish/openwrt/staging_dir/toolchain-mips64_octeonplus_64_gcc-10.2.0_musl/lib -znow -zrelro "  CARGO_HOME=/home/grommish/openwrt/staging_dir/hostpkg ac_cv_path_CARGO="/home/grommish/openwrt/staging_dir/hostpkg/bin/cargo" ac_cv_path_RUSTC="/home/grommish/openwrt/staging_dir/hostpkg/bin/rustc"  ./configure --target=mips64-openwrt-linux --host=mips64-openwrt-linux --build=x86_64-pc-linux-gnu --program-prefix="" --program-suffix="" --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/lib --sysconfdir=/etc --datadir=/usr/share --localstatedir=/var --mandir=/usr/man --infodir=/usr/info --disable-nls  ; fi; )
touch /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/.configured_68b329da9893e34099c7d8ad5cb9c940
rm -f /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/.built
touch /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/.built_check
cd /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1 && cargo rustc --target=mips64-openwrt-linux-musl --release -- -C linker=mips64-openwrt-linux-musl-gcc -C ar=mips64-openwrt-linux-musl-gcc-ar
   Compiling rust-hello-world v0.0.1 (/home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1)
    Finished release [optimized] target(s) in 0.95s
touch /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/.built
rm -rf /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/.pkgdir/rust-hello-world.installed /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/.pkgdir/rust-hello-world
mkdir -p /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/.pkgdir/rust-hello-world
install -d -m0755 /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/.pkgdir/rust-hello-world/usr/sbin
install -m0755 /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/target/mips-openwrt-linux-musl/release/main /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/.pkgdir/rust-hello-world/usr/sbin/rust-hello-world
install: cannot stat '/home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/target/mips-openwrt-linux-musl/release/main': No such file or directory
make[2]: *** [Makefile:53: /home/grommish/openwrt/build_dir/target-mips64_octeonplus_64_musl/rust-hello-world-0.0.1/.pkgdir/rust-hello-world.installed] Error 1
make[2]: Leaving directory '/home/grommish/openwrt/feeds/packages/utils/rust-hello-world'
time: package/feeds/packages/rust-hello-world/compile#1.33#0.11#1.12
    ERROR: package/feeds/packages/rust-hello-world failed to build.
make[1]: *** [package/Makefile:114: package/feeds/packages/rust-hello-world/compile] Error 1
make[1]: Leaving directory '/home/grommish/openwrt'
make: *** [/home/grommish/openwrt/include/toplevel.mk:230: package/feeds/packages/rust-hello-world/compile] Error 2

Hi, strange that it is giving the errors on your side. I got it working without errors on my side even without the configure arguments. I don't have rust installed on the host, only in the toolchain through your lang/rust package. I'm now working to build the std crate package and disable static linking.

My update on github is now working perfect, even pulling in external crates and building them. I only need to have the Cargo.toml and source files in the src directory. In my setup the IPK is build ok and I can install using opkg which is good.

I didn't use the ac_cv_path_ variables nor CONFIGURE_VARS as I'm not using autoconf, cmake or not even GNU Make but pure Rust Cargo. The key was to use cargo rustc instead of cargo build and pass in the correct compiler and linker with the $(CARGO_HOME) variable.

I think the Makefile is now quite universal and we could send in a patch in the OpenWRT build system to have a rust.mk for rust packages which define these build functions. What do you think?

I now read that Rust is not ABI stable which is off course bad for OpenWRT where binary size is of the utmost importance. However as OpenWRT is compiled from source this should not be a huge issue as upgrading rust just means to recompile all rust binaries in the toolchain and doing a sysupgrade.

My first attempts as creating the libstd-**.so are not successful, makefile here: daanpape/rust-libstd: OpenWRT package which provides the libstd-*.so shared library (github.com)

UPDATE
I now realized that the libstd-**.so is already compiled by the rust package itself and it's living in the staging_dir of the toolchain. I have updated the makefile of the rust-libstd package to create an IPK file of it. I also updated the rust-hello-world example to make use of this. It runs perfectly on my MIPS softfloat target (Atheros Qualcomm AR9331). I think this is a good setup for OpenWRT devices as you can now write multiple rust applications without having having a ton of RAM and flash usage. The only downside to this is that for every crate that you import a separate package should be made which also compiles this external crate with dynamic linking, for some crates this could become tedious. It would be handy if you could select which crates to link in dynamically (libstd) and which statically, I don't know if this is possible?

Current sizes:

rust-hello-world 4204B (4.11kB)
libstd-61e1ef472d25ade8.so 2029380B (1981.82kB)

The libstd thus is very very large, as a comparison libc (musl) is 626692B (612KB)

AFAIK, MUSL is dynamically linked, and I set that in the linux_musl.rs file.

I am not a Programmer, nor do I understand Rust, but I wanted a package (Suricata6) that required it, so I made it work :slight_smile:

Ny test-bed is a MIPS64 device, so I can't test for other platforms. I also was looking into creating rustc/cargo artifacts for the target systems, but LLVM doesn't seem to like MIPS64, so I'm at a dead-end for that. I will revisit in the future. For now, this package is strictly used as a HOST toolchain.

I'm seeing the error and you aren't because you are hard-coding your links

define Package/rust-hello-world/install
        $(INSTALL_DIR) $(1)/usr/sbin
        $(INSTALL_BIN) $(PKG_BUILD_DIR)/target/mips-openwrt-linux-musl/release/main $(1)/usr/sbin/rust-hello-world
endef

$(PKG_BUILD_DIR)/target/mips-openwrt-linux-musl/release/main doesn't exist for me, and is giving the error because of it. but, that is to be expected.

Also, any suggestions from those who actually use Rust would be a tremendous help. I'm currently at the point of trying to shrink the dist file footprint to set as a "default" for compiler options, and then let people break it/balloon it as they see fit.

Hi @Grommish,

For not being a programmer you are doing a heck of a job for which I'm very grateful. The error is indeed a bad mistake from my side and I have now fixed it. The examples I've made should now work.

I'm now focussing on optimizing size as I think this is more important than speed optimizations on our OpenWRT platforms. I have just tested and rust is doing what I want out of the box:

  • The libstd is now always linked in dynamically
  • All libraries that rust can't find in the toolchain will be linked in statically.

This is very nice behavior as this let's you choose which library you make available as an OpenWRT package and which not. This is exacly what you want on an embedded device, so far so good.

I' now convinced that we should work on the lang/rust package that you made and optimize the prebuilt libstd with the following:

  • Abort on Panic instead of doing the backtrace
  • Remove all debug symbols (this is done already in my example)
  • Compile with optimization level z
  • Strip all unnecessary symbols, just doing a string command on the precompiled lib shows that there is a lot to win.

I'm going to try and find some time to do this. Maybe you already know where the optimization options can be set?

In the Config.in file, it holds the switches exposed by ./configure, with the exception of --set, which can change anything in the config.yaml - for good or ill, I've had some feedback in the PR about actually being able to turn certain switches off, for example.

I'm still working on reducing the dist installation file size for the host (currently ~350Mb for my x86_64-mips64 toolchain, down from 550Mb). I just want to find a default that's as minimal as possible.

Keep in mind that I've yet to compile (for example) a rustc/cargo stage2 for MIPS64 itself (Cross-compile is fine) because of the LLVM issue, but in theory, if the OpenWrt build system will build on the host, you should be able to make rust

updated PR - added mipsel support

Is there an example of an OpenWrt Makefile for a package written in Rust?

This started so I could play with Suricata6, which uses Rust. See the PR below

1 Like

I have updated the PRs for Rust, Suricata 6, and LibHTP

Rust now splits out the Host and Target Rust toolchains, and dealing with multiple target toolchains are now handled better

Suricata saw updates to the Build Logic and DEPENDS, moved LibHTP external to Suricata package

LibHTP introduced external to Suricata.

Any questions/issues/etc, let me know.

2 Likes

Hello,
I was able to install Rust using the standard rustup script.

root@OpenWrt:~# curl https://sh.rustup.rs -sSf | sh
info: downloading installer
Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure

Welcome to Rust!
...
Current installation options:


   default host triple: x86_64-unknown-linux-musl
     default toolchain: stable
               profile: minimal
  modify PATH variable: yes

info: default toolchain set to 'stable-x86_64-unknown-linux-musl'

  stable-x86_64-unknown-linux-musl installed - rustc 1.53.0 (53cb7b09b 2021-06-17)


Rust is installed now. Great!

To get started you may need to restart your current shell.
This would reload your PATH environment variable to include
Cargo's bin directory ($HOME/.cargo/bin).

To configure your current shell, run:
source $HOME/.cargo/env
root@OpenWrt:~# source $HOME/.cargo/env
root@OpenWrt:~# rustc --version
rustc 1.53.0 (53cb7b09b 2021-06-17)
root@OpenWrt:~# cargo --version
cargo 1.53.0 (4369396ce 2021-04-27)

However, I get a linker error when I try to compile a simple "hello world" app

root@OpenWrt:~# cargo new testapp
     Created binary (application) `testapp` package
root@OpenWrt:~# cd testapp/
root@OpenWrt:~/testapp# cargo run
   Compiling testapp v0.1.0 (/root/testapp)
error: linker `cc` not found
  |
  = note: No such file or directory (os error 2)

error: aborting due to previous error

error: could not compile `testapp`

To learn more, run the command again with --verbose.
root@OpenWrt:~/testapp#

Please how do I fix this? Thanks.

Anyway, I am able to cross-compile using cargo build --target=x86_64-unknown-linux-musl on Linux (Ubuntu) and then run the application in OpenWRT.

This is for creating the rust toolchain to be included as part of the OpenWrt, not for installing rustc/cargo on the device itself. While it potentially be done, it's something for much rather down the line.

This is because there is limited gcc support for OpenWrt. It isn't designed to be able to be a build environment.

You are able to run the rustup because you are using an x86_64 device. The grand majority of devices, unfortunately, aren't. If you are building on x86_64 for x86_64 using the host's x86_64 rustc/cargo installation, then yes, it should work fine. But that's beyond the rust-lang package because it relies on the host machine having a given package. You could always have cross-compiled rust applications for OpenWrt if you were willing to accept making rust a build-environment requirement.

You should also be aware that Openwrt reports it's own triple in rust as x86_64-openwrt-linux-musl

I can't help you with compiling rust applications or using rustc/cargo on the OpenWrt device. At the very least, the missing build tools will be a hinderence, and musl is dynamically linked (and rustup is statically linked)

If you ever want a real shot of OpenWrt having rust-lang support, I'd check out the PR. Although I've shifted my efforts to other things, I'm still kicking around on rust-lang and suricata

I agree with you. Installing the standard rustc/cargo binaries on a OpenWRT device is not worth the stress right now because cross-compilation on a Linux machine works perfectly.
At least, I was able to easily cross-compile a warp web server application on a Linux machine (it uses tokio, serde, hyper and a ton of other Rust crates) and then run the application smoothly on OpenWRT.

For now, I will stick with the cross-compilation option. Please what's the current status of the Rust toolchain for OpenWRT? I will be great to have Rust by default under the language packages.

1 Like

It is in Draft PR status because it needs more wide-range testing. It works for the devices I have to actually test it, and overall should probably be redone to slim it down and see what other ways I can do it. It's still a WIP but you're welcome to test it.

I've been able to start back on rust-lang, and have been pushing updates.

I think I've finalized aarch64, arm, armv7, mips, mipsel, mips64, and x86_64. The arm/armv7 should now correctly determine if the target needs hard-float or not.

powerpc has been dropped from the package for now, as it seems to have LLVM issues. For anyone who wants to test rust-lang for powerpc, I've left provisions in the Makefile to pass the correct defines (--D__ppc__) to LLVM for powerpc targets if it's called directly (make package/feeds/packages/rust/host/{clean,compile}), but it isn't enabled in the rust-lang package DEPENDS

This is simply at the stage rust-lang toolchain compiles, and I've not tested that they successfully cross-compile, or that the cross-compiled package actually works correctly, for any ARCH other than mips64 and mipsel. I have no reason to suspect it won't work, but early on I ran into issues with mips64 where it compiled both the toolchain and suricata6 but would immediately SIGILL because of the static vs dynamic linking (musl issue). I had no indication of an issue until it just died on the device.

If anyone would like to test and see if rust-lang builds for your target, I'd appreciate the feedback. If anyone has a target ARCH not listed, let me know (I don't play outside of the very confined world of the Octeon MIPS64 branch often) as I'm not up on the other ARCHs.

  21M dl/rust-1.56.1-aarch64-unknown-linux-musl-install.tar.xz
  20M dl/rust-1.56.1-arm-unknown-linux-musleabihf-install.tar.xz
  20M dl/rust-1.56.1-armv7-unknown-linux-musleabihf-install.tar.xz
  22M dl/rust-1.56.1-mips64-unknown-linux-muslabi64-install.tar.xz
  20M dl/rust-1.56.1-mipsel-unknown-linux-musl-install.tar.xz
 364M dl/rust-1.56.1-x86_64-unknown-linux-gnu-install.tar.xz
  22M dl/rust-1.56.1-x86_64-unknown-linux-musl-install.tar.xz
 109M dl/rust-1.56.1.tar.xz

I'm also verifying arm-unknown-linux-musleabi and expect it should compile correctly.

Appreciate any help or feedback!

1 Like

Hi @Grommish thanks a ton for your work on this! I'm working on building Rust code for a couple of devices running OpenWRT, and what you've done here is hugely valuable.

That said, when running what I believe is your latest, I came across a small issue. I think I've maybe addressed it, but am still waiting for the build to complete, so figured I'd post here in the meantime

What I did was to apply your patch to the version of openwrt/packages (@ this fairly recent commit) that's used by the Teltonika SDK, which is relevant for the routers I'm building for. Although this is probably not 100% the envisaged approach, it feels like it ought to work. And it mostly does. I can request to build a sample Rust program, which triggers building of the toolchain, and that mostly builds, but then I get to an error such as

Building stage1 std artifacts (x86_64-unknown-linux-gnu -> mips-openwrt-linux-musl)
error: failed to run `rustc` to learn about target-specific information

Caused by:
  process didn't exit successfully: `/home/ubuntu/rutos-ath79-rut9-gpl/build_dir/hostpkg/rust-1.57.0/build/bootstrap/debug/rustc - --crate-name ___ --print=file-names -Zsymbol-mangling-version=legacy -Zmacro-backtrace '-Clink-args=-Wl,-rpath,$ORIGIN/../lib' -Ctarget-feature=-crt-static -Zsave-analysis -Cprefer-dynamic -L native=/home/ubuntu/rutos-ath79-rut9-gpl/staging_dir/toolchain-mips_24kc_gcc-8.4.0_musl/lib -Cembed-bitcode=yes '-Zcrate-attr=doc(html_root_url="https://doc.rust-lang.org/nightly/")' --target mips-openwrt-linux-musl --crate-type bin --crate-type rlib --crate-type dylib --crate-type cdylib --crate-type staticlib --crate-type proc-macro --print=sysroot --print=cfg` (exit status: 1)
  --- stderr
  error: Error loading target specification: Could not find specification for target "mips-openwrt-linux-musl". Run `rustc --print target-list` for a list of built-in targets

Now, mips-openwrt-linux-musl is indeed not a valid target that's recognized by rustc. That should be mips-unknown-linux-musl, right? I've not really been able to track down where that discrepancy arises, but it feels to me like $RUSTC_TARGET_ARCH gets incorrectly set to the "raw" target triple, rather than the Rust-specific one. From what I can tell the solution is to switch the commenting towards the end of rust_targets.mk, so that

RUSTC_TARGET_ARCH:=$(ARCH)-unknown-linux-$(patsubst "%",%,$(RUST_TARGET_SUFFIX))

I'm now trying to build with that. Initially got a weird ld error about mismatch in "VFP register arguments" (potentially related to the hard vs soft float issue you mentioned), but have now cleaned the build tree and am building from scratch just to be sure it wasn't a conflict with a previous build.

Finally, do you still have a method for using rustup to install the Rust toolchain? I used that to build binaries for the architectures that I'm interested in (armv7 and mips) outside of the OpenWRT tree, and it worked fine - so I'm wondering if there's a way to integrate this into the OpenWRT build process (for supported architectures), to avoid building rustc from source.

1 Like

Hi!

Couple of things:

  1. rustup won't work because rustup is statically linked, and OpenWrt MUSL requires dynamically linked libraries. I wish we could use rustup..

  2. OpenWrt uses xxxx-openwrt-linux-musl for the tuples. I'm working on the best way to integrate this into Openwrt and Rust-lang. I have access to a MIPS64 device, so that's what I'm currently testing. Previously I had MIPS/MIPS64/Aarch64/x86_64 working (ARM, ARMv5/v6/v7 is proving a pain).

I've gone from cross-linking tuples from xxxx-openwrt-linux-musl to the built-in rust-lang tuples (xxxx-unknown-linux-muslxxx) to just upstream'ing the tuples as Tier 3 targets (https://github.com/rust-lang/rust/pull/92300)

I've been trying to figure out the best way to integrate long-term into the build system and potentially be able to introduce rustc and cargo natively on-device for the higher-end devices that might need it (although that will depend on LLVM adding support for the target Arch)

Compiling rust-lang takes about 4 hours on my device from a clean slate, so it just takes time to build, test, fail, repeat :smiley:

ARM Targets are going to be tricky because OpenWrt uses multiple ways to define ARM functionality (like VFP/NEON) across the trees, so that'll have to come later.

grommish@DESKTOP-AW:~/openwrt/staging_dir/host/bin$ file rustc
rustc: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=76008b88647eb342385535fc311bfaf0d769c225, for GNU/Linux 3.2.0, not stripped

This is my cross-compiled rustc for the build system (used to cross).

I'll probably push an update here soon, as I've been trying to organize the Makefiles to better be readable and organized.

I can push a MIPS enabled commit, if you'd like to test

I should add: I'm not a programmer and I don't know rust. So, if you actually know rust, it would be very helpful if you'd be willing to help test that what actually builds, builds correctly.