How portable is Rust?


#1

Hello,
Exactly how portable is Rust code and the Rust compiler? How easily could the Rust compiler (or cross compiler) be ported to a new platform? Does rust code need a nontrivial amount of modification to be ported to a different platform?


#2

Portability of Rust compiler is mainly restricted by portability of LLVM. If you can get LLVM working for a platform, then the Rust compiler should be able to target it. At least, if the platform is not too weird; e.g. byte must have 8 bits, numbers must be 2’s-complement, etc. That generally matches what C programs expect in practice, but not what C historically/theoretically supported.

Rust programs are pretty portable. With C I never had patience to support Windows, but with Rust it’s easy enough, that I even managed to make Debian package generator run on Windows :slight_smile:

There’s a category of no_std” libraries that as the name implies, don’t require Rust’s standard library, so they can work in many constrained environments, e.g. micro-controllers that don’t have an OS.


#3

k


#4

I’m interested to learn more about this can you guide me where to go!


#5

That would be the Rust embedded book for a general introduction to using Rust on microcontrollers as well as the Discovery book for a tutorial that you can follow along on actual hardware.


#6

To add to that, there might be certain embedded devices that only have a vendor-provided, likely proprietary, possibly outdated C compiler as the only means of writing software for them, and since rust does not compile to C, you can’t write Rust software for those devices.

For a list of embedded hardware that someone else has already developed crates for, see https://github.com/rust-embedded/awesome-embedded-rust/blob/master/README.md


#7

Thanks! Just as a quick (kind of unrelated) question, approximately how many times more complicated is Rust compared to C? For C++ it would be quite a lot (some people have said up to 10 times). What about Rust?


#8

This is of course difficult to answer. It depends on what you view as complex and simple. Syntactically, Rust is not that complex in my view. Most of the expressive power and complexity comes in my view from the type system and in particular lifetimes and ownership.

Since your avatar is the >>= of monadic bind, I’ll assume that you are familiar with Haskell. I’d say that Rust is quite close to Haskell in complexity and also in terms of features (except that Rust can reach more closely to the hardware and thus needs to deal with memory representation much more frequently than you need to in Haskell).


#9

Rust is generally believed to have a rather steep learning curve in the beginning, and C++ tends to become a huge mess once the project becomes more complex (which is why mozilla developed rust for servo).

To quote The Zen of Python:

Simple is better than complex.
Complex is better than complicated.

:wink:


#10

It’s 1.5 C :wink:

But it’s sort-of a loaded question. Brainfuck as a language is a waaay simpler than C. It’s about the simplest language that can be Turing complete, and yet, even trying to write “Hello World” in it explains its name.

In terms of features Rust is somewhere between C and C++, but to me using Rust is easier. It’s easier to use than C, because I don’t have to complicate program’s flow to perform manual cleanups all the time. It’s easier to understand what the code does, because it doesn’t spend half of code lines on error handling (but still handles all the errors). And I can use non-trivial data structures like BTreeMap cleanly and efficiently with a couple of lines of code instead of rolling my own or integrating some macro-mashup. And I can concatenate strings without double-checking that I’m not overflowing any buffers.


#11

About, but note quite fully. Brainfuck has 8 characters! That’s 5 characters too many. Say hello to Iota and Jot. :stuck_out_tongue:


#12

[Let’s drop the Brainfuck derail.]


#13

So just out of curiosity, concretely what is required to add support to Rust for a new target if llvm already supports that target?


#14

May you like to see my post Compile to mutliple targets at once


#15

Are you saying that “all” that is required to add support to is providing a linker for that platform?

(Not that I’m implying that writing a linker is a trivial amount of work)


#16

You need to add the targets, like:"

`~$cargo build --target=arm-linux-androideabi`

Install the required toolchain, based on your system, and the required targets

Add the linkers, like:

[target.arm-linux-androideabi]
linker = "/home/rust/android-18-toolchain/bin/arm-linux-androideabi-clang"

Build the executables, either individually, as:

cargo build --target=armv7-unknown-linux-gnueabihf;

or through a .sh script, like

~$ ./build.sh

Script file sample:

# !/bin/sh
#!/usr/bin/env/bash
echo "Running script commands at"
echo "os: " $OSTYPE
echo "host" $HOSTTYPE
if [ $OSTYPE == 'msys' ]
then
  echo "Building Windows library"
  cargo build --target=x86_64-pc-windows-msvc
elif [ $OSTYPE == 'linux-gnu' ]
then
  echo "Building Linux/WASM/Raspberry/Android libraries"
  cargo build --target=x86_64-unknown-linux-gnu
  cargo build --target=wasm32-unknown-unknown
  cargo build --target=armv7-unknown-linux-gnueabihf
  cargo build --target=arm-linux-androideabi;
fi

echo "Building process completed, press any key to exit"
read

#17

I think their question might have been “how do you add support for a new target that’s not already being distributed by rustup”.


#18

this describes how rust was adapted to the RISC-V ISA, including a patch, might be useful to get an idea what it entails to add a new architecture (besides LLVM support)


#19

Thanks, this gives a good idea of what’s required.
I gotta say, it’s less code than I though it would be, and that’s a really good thing.