Raspberry Pi cross compilation failure

I am trying to cross compile a Rust source code project from my windows 7 OS machine to Raspberry Pi 3 platform.

I already installed on my machine a cross compilation tool-chain which I used in the past for Win / RPi cross compilation "arm-linux-gnueabihf" and configured it in the system path.

I updated the Cargo config file as follows:

[target.armv7-unknown-linux-gnueabihf]
linker = "C:/SysGCC/Raspberry/bin/arm-linux-gnueabihf-gcc.exe"

I also run the Cargo build with the following command: build --target=armv7-unknown-linux-gnueabihf

when running the cargo build, I got the following error in the terminal:

error: failed to run custom build command for hidapi v1.2.3

Caused by:
process didn't exit successfully: C:\Users\eybi.anaton\projects\DBMC2_project\customers\SoundChip\SC_EVK_platform\SW\source code\target\debug\build\hidapi-3a4e8897d15a6970\build-script-build (exit code: 101)
--- stderr
thread 'main' panicked at 'Unable to find libusb-1.0: "Cross compilation detected. Use PKG_CONFIG_ALLOW_CROSS=1 to override"'

can someone adivse me how to conifigure the pck-config flag PKG_CONFIG_CROSS to 1 in appropraite manner please?

Thank you

Eybi

That is to be set as an environment variable. On my Debian machine, I would...

PKG_CONFIG_ALLOW_CROSS=1 cargo build ...

One other env var I use

CC=arm-linux-gnueabihf-gcc

I would also avoid fiddling with files for settings, in this case config.toml, and would instead...

 CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc ...

Not sure these would work on windows though.

It's incorrect to set PKG_CONFIG_ALLOW_CROSS=1 without also configuring non-native pkg-config definitions!

That variable exists for a reason, because pkg-config's default behavior is incorrect and breaks builds.

1 Like

I see in the code which you provided that you check the existence of the path in Linux OS file system and if it does not exist, then you create it.
Could you kindly advise where this path should be configured in WINDOWS OS as well please?

Oh, I haven't noticed you're on Windows. In that case it just won't work, and I don't think it's even possible to make it work.

You're going to need WSL2 or a Linux VM.

the cargo builder uses HIDAPI crate which activates the PKG_CONFIG crate .
the following is the line which destroys the built:

pkg_config::find_library("libusb-1.0").expect("Unable to find libusb-1.0");

As I understand, PKG_CONFIG is invoked by the HIDAPI crate to verify the the LIBUSB library (which belong to Linux OS machine) exists on my Windows OS host machine that builds the code.
Obviously, as we deal with cross compilation here, the PKG_CONFIG *understands * that this case is cross compilation case and stops the build, as you said.

Can I add a line above, in which I configure the PKG_CONFIG package to use the PKG_CONFIG_ALLOW_CROSS flag with "1" instead?

something like: pkg_config::set_var("PKG_CONFIG_ALLOW_CROSS" , "1") ....?

I know that this is not the right RUST command format to put, but I just wrote it to give you the general idea...
Is this something that can be implemented? If so, could you kindly provide the correct syntax?

What I mean here is to invoke the PKG_CONFIG crate with the configuration flag before is searches the LIBUSB LInux native library...

The problem is if you just set this variable, you will get an error that libusb can't be found, and the build will fail too.

If you then painstakingly manage to install libusb on Windows in the way that pkg-config will find it, it will configure it for x86 Windows, so then you will get another error at linking that time that the libusb for linux ARM can't be found.

That PKG_CONFIG_ALLOW_CROSS is a reminder that pkg-config is useless for cross-compilation, unless you specifically install another operating system for another architecture and configure pkg-config to know where to find it. If you unblock pkg-config without doing all the necessary work to trick pkg-config into cross-compiling correctly, you will only get worse failures. And I say "trick", because pkg-config doesn't really understand the concept of cross-compilation, it's really a bad tool for this job, it's disabled for a very good reason.

That PKG_CONFIG_ALLOW_CROSS message is like a "ROAD CLOSED" sign. The problem is not the sign.

1 Like

Are there any alternative methods, if any, for cross-compiling RUST source code from Windows OS based host machine to RPi Linux OS based machine which do not involve PKG_CONFIG ?

Rust-native crates don't need pkg-config, only C-based crates. So rewrite everything in Rust :slight_smile:

But more seriously, install WSL and cross-compile from WSL to Pi.

Not sure if it's usable in your current setup, but cross solved all of my cross compilation issues (including for ARMv7).

As I understand Cross is alternative tool-chain manager than Cargo which is used for cross compiling Rust codes. How should I replace the CARGO.TOML file with CROSS.TOML file required by CROSS?

Hi Helioza,

Unfortunately, my RUST source code is based on Cargo tool-chain manager. I cannot modify it to work with Cross instead.

I don't use a cross.toml file, for me it just works. I didn't need to configure anything, I just installed it and ran it. If you've got more specific configuration going on it might be more difficult. I'm not sure it's accurate to call it an alternative to cargo since it uses cargo to build for most targets by default.

Hi Kornel,

I installed Ubuntu Linux virtual OS on my host laptop.
I modified the PKG_CONFIG lib.rs code as you described in the link which you shared.
I used the following command to cross-compile my source code:
cargo build --target=armv7-unknown-linux-gnueabihf

after doing so, I got the following error message from the compiler:

Compiling pkg-config v0.3.17
error[E0583]: file not found for module compress
** --> /home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/lib.rs:17:1**
** |**
17 | pub mod compress;
** | ^^^^^^^^^^^^^^^^^**
** |**
** = help: to create the module compress, create file "/home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/compress.rs"**

error[E0583]: file not found for module control
** --> /home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/lib.rs:18:1**
** |**
18 | pub mod control;
** | ^^^^^^^^^^^^^^^^**
** |**
** = help: to create the module control, create file "/home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/control.rs"**

error[E0583]: file not found for module data
** --> /home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/lib.rs:19:1**
** |**
19 | pub mod data;
** | ^^^^^^^^^^^^^**
** |**
** = help: to create the module data, create file "/home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/data.rs"**

error[E0583]: file not found for module manifest
** --> /home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/lib.rs:20:1**
** |**
20 | pub mod manifest;
** | ^^^^^^^^^^^^^^^^^**
** |**
** = help: to create the module manifest, create file "/home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/manifest.rs"**

error[E0583]: file not found for module dependencies
--> /home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/lib.rs:21:1
|
21 | mod dependencies;
| ^^^^^^^^^^^^^^^^^
|
= help: to create the module dependencies, create file "/home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/dependencies.rs"

error[E0583]: file not found for module ok_or
--> /home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/lib.rs:22:1
|
22 | mod ok_or;
| ^^^^^^^^^^
|
= help: to create the module ok_or, create file "/home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/ok_or.rs"

error[E0583]: file not found for module wordsplit
--> /home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/lib.rs:23:1
|
23 | mod wordsplit;
| ^^^^^^^^^^^^^^
|
= help: to create the module wordsplit, create file "/home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/wordsplit.rs"

error[E0583]: file not found for module error
--> /home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/lib.rs:24:1
|
24 | mod error;
| ^^^^^^^^^^
|
= help: to create the module error, create file "/home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/error.rs"

error[E0583]: file not found for module tararchive
--> /home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/lib.rs:25:1
|
25 | mod tararchive;
| ^^^^^^^^^^^^^^^
|
= help: to create the module tararchive, create file "/home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/tararchive.rs"

error[E0583]: file not found for module debarchive
--> /home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/lib.rs:26:1
|
26 | mod debarchive;
| ^^^^^^^^^^^^^^^
|
= help: to create the module debarchive, create file "/home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/debarchive.rs"

error[E0583]: file not found for module config
--> /home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/lib.rs:27:1
|
27 | mod config;
| ^^^^^^^^^^^
|
= help: to create the module config, create file "/home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/config.rs"

error[E0583]: file not found for module pathbytes
--> /home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/lib.rs:28:1
|
28 | mod pathbytes;
| ^^^^^^^^^^^^^^
|
= help: to create the module pathbytes, create file "/home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/pathbytes.rs"

error[E0583]: file not found for module listener
--> /home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/lib.rs:29:1
|
29 | pub mod listener;
| ^^^^^^^^^^^^^^^^^
|
= help: to create the module listener, create file "/home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/listener.rs"

error[E0463]: can't find crate for quick_error
--> /home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/src/lib.rs:16:14
|
16 | #[macro_use] extern crate quick_error;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate

error: aborting due to 14 previous errors

Some errors have detailed explanations: E0463, E0583.
For more information about an error, try rustc --explain E0463"

========================================================================

Any suggestion what to do next?

I would start by just cross compiling "hello world" (or similar) before I add projects that rely on cross compiling C libraries.

The reason I suggest this is that your problem might turn out to be that cargo can't cross compile the C-library hidapi to the target. If you look at the build script of hidapi:

fn main() {
    let target = env::var("TARGET").unwrap();

    if target.contains("linux") {
        compile_linux();
    } else if target.contains("windows") {
        compile_windows();
    } else if target.contains("darwin") {
        compile_macos();
    } else if target.contains("freebsd") {
        compile_freebsd();
    } else {
        panic!("Unsupported target os for hidapi-rs");
    }
}

It really doesn't look like Cargo can cross compile hidapi to armv7-unknown-linux-gnueabihf.

I found this tutorial pretty good to get started cross compiling for RPi from Linux. It works perfectly for me at least.

This is not exactly true. This is because when I cross build using cargo I define the target OS to be Linux, and when I debugged the compiling, I saw that it does enter to the first condition above and execute compile_linux() function.

Also if you look at the building error which I put above, you will see that the cross compiler failed in compiling PKG_CONFIG crate and not hidapi crate.

As far as I understand, the hidapi invokes PKG_CONFIG crate for verifying that the required libraries are installed in the host machine that cross compile the project. However, when it detects that they are not there (i.e. cross compiling case) it fails.

I tried to trick down the source code of PKG_CONFIG to put its CROSS COMPILATION flag to "1" in case it detects cross compilation, but got other failures shown above.

As I said, I already succeeded to cross compile native RUST code on my virtual OS machine,.

Any helps will be appreciated.

The errors you have about /home/eybi/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.17/ are bizarre. This should never happen, regardless whether it's cross-compiling or not.

What version of Rust do you have? The errors could be explained by having a very very outdated Rust version (< 1.31).

Alternatively, maybe the files really are missing for some reason. Try deleting /home/eybi/.cargo/registry/.

I checked and indeed the rustup version which I used was 1.22, so I removed it.
Could you point me out where can I download up-to-date version of rustup for my Linux virtual OS (version >1.31) ?

Thanks

rustup 1.22 is new. I was referring to rustc version.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.