Rust Howto (Request)

FWIW, my fork was a hack to get around cross compiling Qt5.6. You might be interested in checking out this PR, which adds Qt5.6 detection to qmetaobject-rs https://github.com/woboq/qmetaobject-rs/pull/123

I’m trying to build it myself in sfdk now, to see whether it works, but I get

error: linker `arm-linux-gnueabihf-gcc` not found
  |
  = note: No such file or directory (os error 2)

… in the sb2 environment (sb2 -t SailfishOS-3.4.0.24-armv7hl cargo test --target-dir=sfdk-armv7hl/).

Here is how I compiled hello_world or @thigg Qt demo application:using @coderus Docker-based build image:

# run Docker container 
docker run --name sdk --rm -d coderus/sailfishos-platform-sdk:latest tail -f /dev/null

# launch a container shell
docker exec -it sdk bash

# install cargo and rust packages
USER=`whoami` su -p -c "sb2 -m sdk-install -t SailfishOS-3.4.0.22-armv7hl zypper -n in rust cargo"

# let's build @thigg demo application
git clone https://gitlab.com/thigg/rust-qt-sailfish-example
cd rust-qt-sailfish-example/
USER=`whoami` su -p -c "sb2 -t SailfishOS-3.4.0.22-armv7hl cargo build"

Now take a nap as building takes some time.

The final binary can be copied from running SDK container to Docker host by executing the following command on the Docker host:

docker cp sdk:/home/nemo/rust-qt-sailfish-example/target/debug/hello_world ./

From there you can copy it to your device or emulator alas it will crash with the illegal instruction error.

FYI, @coderus has just split their Docker image in three, cfr. https://hub.docker.com/r/coderus/, https://github.com/CODeRUS/docker-sailfishos-platform-sdk/issues/2

These new images contain 3.4.0.24, you might want to retry against that (former all-in image was 3.4.0.22 iirc).


Based on these images, I have built three others https://gitlab.com/rubdos/sailo-rs/, these contain the dependencies I need for Whisperfish (which is very few, on top of Rust, Cargo and Qt5-devel). These may interest you, although the build process is very different (cross compiling and -rpath-hacking, instead of emulated compiling). At least the source might interest you.

1 Like

AIO image is still and will be available as before.

1 Like

Ah, those three are additional images then. Sorry, I’ve misread your reply on Github! Thanks for providing the images! I can confirm Whisperfish compiles for aarch64 :slight_smile:

Hi @rubdos,

Thanks for pointing out Whispherfish_rs to me and also providing some Dockerfile for building your compile environment.

I tried to compile @thigg’s project but failed for missing libs (some build.rs hacking is needed I guess).

What are your experiences switching over from Go to Rust?

I am Go dev for more that five years but started learning Rust 2018 recently. I think Go + Rust where you need speed and no GC delays is a good combination.

Cheers,
Nek

Yes, as said, my Rust-Sailfish images need a lot of build.rs hacking, and it’s not clean, at all. If at all possible, I’d rather spend effort in getting qmetaobject-rs and alike to build on SFDK.


About Go and Rust, let me get you some :salt: to go with this: I have never written a line of Go, I am the new “organizer” (haven’t organised anything yet, because COVID strikes) of the Belgium Rust User Group. I’d consider myself part of the Rust Evangelism Strike Force.

That said, Whisperfish 0.5 was written in Go. What I completely disliked (but that could have been the Go-Textsecure library) was the callback hell. Textsecure required from Whisperfish to implement certain methods that called back into the QML to get passwords, phonenumbers, etc. I found it became quite a spaghetti. The GoMethod() vs goMethod() way of distinguishing public and private was very confusing to me (it still is).

What did go well, was mapping go routines onto my async worker. I did have to write a Qt-Sailfish specific async runtime (fancy Rustspeak for an event loop) to get it to work, but hey, that was fun!

In the end, I’m unsure what hole Go would fill for me. I use Rust for almost anything, and when I do want something dynamic, I’d revert to Python or Scheme or something like that. But that’s probably because I didn’t join the Go-train when it was there, and at this point I’d be very late joining it!

By the way, feel free to join #whisperfish (on Freenode IRC) or #whisperfish:rubdos.be (on Matrix) if you want to talk about Rust (on Sailfish). That’s an invite for everyone here. We tend to go off-topic now and then anyway, talking about electric cars and such.

Anyone has an update for this? (bump)

As an example I created a GitHub project: https://github.com/R1tschY/harbour-rust-example

5 Likes

Been able to run the example. Looks really good.
2 things:

  1. Wasn’t able to use the SailfishIDE to build it. (Will investigate into this sometime)
  2. Cant start the app from the app grid, but launching it from /usr/bin/… works.

Thanks @R1tschY

The example has been updated. Both things should now work.

That is so awesome!

I do have one question though: Why do you build with “-j 1”? On my machine the build time dropped from “forever” (i.e. ~23 minutes) to only “really long” (12 minutes) after dropping it.

Why do you build with “-j 1”?

I thought QEMU is using a global lock for ARM and than “-j1” is faster, but I did no measurements so maybe I’m just wrong. When it is faster there is no reason to leave it.

Thanks, it is indeed faster without -j 1. I updated it.

Hi @R1tschY, thanks for the project example!
I get this when building for SFOS 3.4 ARM:

+ CARGO_INCREMENTAL=0
+ cargo build --release --target-dir=target --locked --manifest-path /home/vlad/Projects/harbour-rust-example/rpm/../Cargo.toml
   Compiling proc-macro2 v1.0.24
   Compiling memchr v2.3.3
   Compiling unicode-xid v0.2.1
   Compiling syn v1.0.45
   Compiling lazy_static v1.4.0
   Compiling regex-syntax v0.6.20
   Compiling cc v1.0.61
   Compiling byteorder v1.3.4
   Compiling if_rust_version v1.0.0
   Compiling pkg-config v0.3.19
   Compiling thread_local v1.0.1
error[E0463]: can't find crate for `unicode_xid`
  --> /home/mersdk/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-1.0.24/src/fallback.rs:16:5
   |
16 | use unicode_xid::UnicodeXID;
   |     ^^^^^^^^^^^ can't find crate

error: aborting due to previous error

Any advice? I did added the rust package in Tools->Options->Sailfish OS->Build Engine->Manage build targets->Manage packages…

I have no idea how this can happen. Did you try to cleanup and compile again? Maybe it is a concurrency problem.

“Build Engine->Manage build targets->Manage packages…” is not needed, because the build dependencies rustc and cargo are installed automatically. But should do no harm.

@R1tschY maybe it would make sense to add a few more components to the example.
A two-paged application with a few components and layouts would be nice!
Edit: sorry just noticed this is basically there (thats happening when you reply very long after looking into something…) I’ll look into it again and check what I encounter when I’m trying to build something more complex

Hello,
First, sorry for the necromancy (raising thread out of the dead)
Thanks all for this thread that was very informative about how to develop with the recent Rust addition.

I have faced nearly all issues in this thread :wink: and have some answers to give too !

  1. It seems that the VirtualBox based SDK is unable to build rust correctly. I have seen the “crate not found error” appearing. This doesn’t appear with Coderus’s docker images
  2. To build i486 Rust packages, you need to actually install Rust in the build engine. So you should run something like
sudo zypper in rust cargo
# Then install it in sb2, see below
  1. Due to the cross compilation features of scratchbox, it’s dangerous to install gcc inside the target. You might want to use some hacks like
sb2 -R zypper in --download-only -y rust cargo && \
    sb2 -R rm $(sb2 find  /var/cache/zypp/packages/jolla/oss/armv7hl/ -name cpp-*.rpm) && \
    sb2 -R rm $(sb2 find  /var/cache/zypp/packages/jolla/oss/armv7hl/ -name gcc-*.rpm) && \
    sb2 -R rpm -i --nodeps $(sb2 find  /var/cache/zypp/packages/jolla/oss/armv7hl/ -name *.rpm)

ie: download the packages, remove cpp and gcc RPM and install the rest.
(Also note the absence of wildcards and the use of find, wildcards cannot be propagated through sb2)

2 Likes

It seems to me the Rust in the current SDK is way to old since many applications does not compile. Including my new planned Sailserver. I also tried wisperfish with the default installed Rust and it failed.

Then I tried to install GitHub - sailfishos/rust after I succesfully built packages with mb2 command.

But now I am stuck how I install those packages in the toolchain using sb2 -t SailfishOS-latest-aarch64 zypper -p . install rust cargo # (-p standing in RPMS catalog btw) failed cause it expects root. But if run sb2 as root sb2 fails to find the target for some unknown reason. Can someone give a hint how to install local rpm packages in a sysroot in the builder? I also tried rpm install but then got another error about rpm.lock file etc…

Are you using the Platform SDK (sfossdk) or the Application SDK (sfdk)? I’m going to assume you’re using sfdk, but if that’s not the case then you’ll need to adjust the following. Also, are you using snapshots? This is important because installing into a target doesn’t necessarily make a package available in a snapshot. To check run sfdk config and see whether snapshot is set.

If you have a local rpm package that you want to install to a target, one way to do it is like this:

sfdk engine exec sb2 -t <target> -R -m sdk-install rpm -U <file.rpm> 

The -R -m sdk-install part is what gives you the root access you need.

If you’re using snapshots you should avoid installing anything into the target like this, since it will mean an important benefit of using snapshots – knowing whether you’ve captured all of the dependencies – is lost. So if you have snapshots enabled you should install into the snapshot instead. The easiest way to find the name of the snapshot in use is to do a build. The snapshot name is output right at the start, like this:

Taking snapshot 'SailfishOS-4.1.0.24-armv7hl.mb2.2LJ' of 'SailfishOS-4.1.0.24-armv7hl' target...

In this case you’d change the install command to the following:

sfdk engine exec sb2 -t SailfishOS-4.1.0.24-armv7hl.mb2.2LJ -R -m sdk-install rpm -U <file.rpm> 

(i.e. use the snapshot name instead of the target name).

One other thing you could consider is using a shared output directory (see sfdk --help-all and search for SHARED), since in this case sfdk will automatically search the output directory for any build dependencies.

Please do share your experiences with Sailserver and rust, it’d be interesting to hear how things progress.

1 Like