Linker = gcc-sysroot

I am running into a problem that has me stumped. Rust programs, compiled under yocto, will compile without error and will compile properly for the target.

But when I have move the build outside of yocto, I am running into a hornet's nest of problems.

The 'linker' (for yocto) specified in the rust .cargo/config is:

linker = "gcc-sysroot"

But outside yocto it will produce an error saying it can not find 'gcc-sysroot' (and there is no export for it). However there are exports for ${CC} and --sysroot.

One other problem is if I set my 'default' for cargo as 'arm7-unknown-linux-gnueabihf' (which I have specified in .cargo.config as [target.armv7-unknown-linux-gnueabihf]) it complains can not find the rustc version.

$ rustup default stable-armv7-unknown-linux-gnueabihf
info: using existing install for 'stable-armv7-unknown-linux-gnueabihf'
info: default toolchain set to 'stable-armv7-unknown-linux-gnueabihf'

stable-armv7-unknown-linux-gnueabihf unchanged - (error reading rustc version)

and

$ rustup show
Default host: x86_64-unknown-linux-gnu

installed toolchains
--------------------

stable-armv7-unknown-linux-gnueabihf (default)
stable-x86_64-unknown-linux-gnu

active toolchain
----------------

stable-armv7-unknown-linux-gnueabihf (default)
(error reading rustc version)

And then If I attempt

$ cargo build --target=armv7-unknown-linux-gnueabihf --release

/home//.rustup/toolchains/stable-armv7-unknown-linux-gnueabihf/bin/cargo: 1: /home//.rustup/toolchains/stable-armv7-unknown-linux-gnueabihf/bin/cargo: Syntax error: word unexpected (expecting ")")

but if I rustup default stable-x86_64-unknown-linux-gnu. It will compile binaries for x86 and not my target which I would expect.

I am fairly new to rust. So if this seems like a noob question (it is !!!)

I feel it has something to do with defining 'gcc-sysroot' somewhere else.

Hi!

I have a working workflow with and without yokto on armv7. I am building a shared library, and link it to specific versions of libc to get it working with multiple different environments.

First:
cargo does not look at ${CC} at all. Of course, if your build.rs calls other build tools, these might use the ${CC} environment variable to build code.

Also:
You probably don not want to set rustup default stable-armv7-unknown-linux-gnueabihf as default.
You have to know. that the llvm based rust compiler in comparison to e.g. gcc is a cross compiler by default.
rustup default stable-armv7-unknown-linux-gnueabihf will set the default toolchain. This toolchain however won`t be able to run on your host.
If you want to compile for arm you have to:

1.) Set back to default toolchain, which is able to run on your system

rustup default set stable-for-your-host-architecture

2.) Install rust standard libraries for architecture (note that the compiler itself already supports armv7 out of the box)

rustup target add armv7-unknown-linux-gnueabihf

3.) now edit .cargo/config:

[build]
# Set default build target to armv7hf
target = "armv7-unknown-linux-gnueabihf"

# Configure linker for your target
[target.armv7-unknown-linux-gnueabihf]
linker = "your-gcc-verion-for-armv7-with-sysroot"
 

Thank you Roland.

OK. set it back to my host (an x86_64 box)

** $ rustup default stable-x86_64-unknown-linux-gnu **

$ rustup show
** Default host: x86_64-unknown-linux-gnu **

installed toolchains
--------------------

stable-armv7-unknown-linux-gnueabihf
stable-x86_64-unknown-linux-gnu (default)

installed targets for active toolchain
--------------------------------------

armv7-unknown-linux-gnueabihf
x86_64-unknown-linux-gnu

active toolchain
----------------

stable-x86_64-unknown-linux-gnu (default)
rustc 1.34.1 (fc50f328b 2019-04-24)

However now it seems the cross compiler has a problem complaining that 'ld' can not find some libraries during the build.

The error I see is:

= note: /opt/dey/2.2-r1/sysroots/x86_64-deysdk-linux/usr/libexec/arm-dey-linux-gnueabi/gcc/arm-dey-linux-gnueabi/6.2.0/real-ld: cannot find crti.o: No such file or directory
/opt/dey/2.2-r1/sysroots/x86_64-deysdk-linux/usr/libexec/arm-dey-linux-gnueabi/gcc/arm-dey-linux-gnueabi/6.2.0/real-ld: cannot find crtbeginS.o: No such file or directory
collect2: error: ld returned 1 exit status

error: aborting due to previous error

Sigh..

One moment please, I have to remote login into my working PC. I can dig up an example there.

Note, that I am using the arm-unknown-linux-gnueabihf rust target. There should not
be any issues with the armv7 one.

Okay, here is my .cargo/config:

[build]
target = "arm-unknown-linux-gnueabihf"

[target.arm-unknown-linux-gnueabihf]
linker = "arm-poky-linux-gnueabi-gcc"
ar = "arm-poky-linux-gnueabi-ar"

Cargo.toml:

[package]
...

[profile.release]
lto = true
codegen-units = 1

[lib]
crate-type = ["cdylib"]

...

External build tool (which calls cargo for me):
I converted it to a bash file for you, I can not really show you parts of the real build system.

#!/bin/bash
toolchain_sysroot= "/opt/poky/2.6.1/sysroots/armv7vet2hf-neon-poky-linux-gnueabi"
VERSION="x.x.x"
NAME="XXX"

# Import some enviroment setup from yokto
# This sets up PKG_CONFIG_PATH etc...

source /opt/poky/2.6.1/environment-setup-armv7vet2hf-neon-poky-linux-gnueabi

# Let cargo pass options to the C linker / compiler
# Sets --sysroot for arm-poky-linux-gnueabi-gcc invocation
# Also tweaks the SONAME in the elf file (for yokto style library versioning)
export RUSTFLAGS='-Clink-arg=-Wl,-soname=lib${NAME}.${VERSION} -Clink-arg=--sysroot=${toolchain_sysroot}'

# My crate uses the *cc* crate as a build dependency, which uses pkg-config to hunt down
# some native dependencies
export PKG_CONFIG_ALLOW_CROSS=1
cargo build --release --target=arm-unknown-linux-gnueabihf

# Some post processing / packaging stuff, not really interesting for you.,,

1 Like

Again. Thank you Roland.

Now I am getting clean compiles. Turns out to be a little more simpler than that. But your answer provides most of the 'meat', and for my target there are some very slight differences.

My .cargo/config file had
linker ="gcc-sysroot'

After I invoked the 'source .....' for my target build environment to get to the sdk's sysroot.

Then I needed to create a 'gcc-sysroot' file in the /sysroot of the target's sdk (this satisfied the cargo build error).

with the contents of

#!/bin/bash
SYSROOT=/opt/dey/2.2-r1/sysroots/cortexa9hf-neon-dey-linux-gnueabi
/opt/dey/2.2-r1/sysroots/x86_64-deysdk-linux/usr/bin/arm-dey-linux-gnueabi/arm-dey-linux-gnueabi-gcc --sysroot=$SYSROOT $(echo "$@" | sed 's/-L /usr/lib //g')

This works, and what was missing. So now all the .cargo/config files can access the same SDK for the target, and the RUST compiles are completing and all I need is 'linker='gcc-sysroot" in the .cargo/config file.

Now the only mystery to solve is on the target and the rustlib dependencies for the executable(s).

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.