-
Notifications
You must be signed in to change notification settings - Fork 133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cross compiling instructions #184
Comments
Yes I can help out, I am cross-compiling I have written a guide that I will post in the next comment (hope it's not too long), then you can see how involved the process is. |
Cross compiling the DBus crateThis guide assumes you are using Ubuntu for the host system and are cross compiling for a Raspberry Pi. All shell commands of this guide are available in both PowerShell and Bash. The following tasks have to be completed to set up cross compilation:
Setting up the Rust compilerIf Rust is not installed on your system, head over there to get it up and running. We are trying to cross compile for the ARMv7 architecture, so we need the GCC cross compiler toolchain for it. The following command installs commands prefixed with PowerShell (pwsh) & Bash sudo apt install gcc-arm-linux-gnueabihf Naturally, we need to inform the Rust compiler that this toolchain is available. Edit or create the file ~/.cargo/config [target.armv7-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc" Next we need to get Rust set up for the ARMv7 target. On a fresh install, only the standard library for your host system is installed (usually PowerShell (pwsh) & Bash rustup target add armv7-unknown-linux-gnueabihf Testing the Rust compiler configurationTo test what we just configured, create an empty directory somewhere and start a terminal in it. Then execute the following commands. PowerShell (pwsh) # Initialize a new Rust project in the current folder.
cargo init
# Compile the project for ARMv7.
cargo build --target=armv7-unknown-linux-gnueabihf
# Check the generated file. This should say ARM somewhere.
file "./target/armv7-unknown-linux-gnueabihf/debug/$((Get-Item $PWD).Name)"
# If the file could not be generated, check the configuration again.
# To test if the Rust compiler is working without Cargo, you can run
# the rustc compiler directly and test if the file generated this way is correct.
rustc --target=armv7-unknown-linux-gnueabihf -C linker=$((Get-Command arm-linux-gnueabihf-gcc).Source) ./src/main.rs
file ./main Bash # Initialize a new Rust project in the current folder.
cargo init
# Compile the project for ARMv7.
cargo build --target=armv7-unknown-linux-gnueabihf
# Check the generated file. This should say ARM somewhere.
file ./target/armv7-unknown-linux-gnueabihf/debug/${PWD##*/}
# If the file could not be generated, check the configuration again.
# To test if the Rust compiler is working without Cargo, you can run
# the rustc compiler directly and test if the file generated this way is correct.
rustc --target=armv7-unknown-linux-gnueabihf -C linker=$(which arm-linux-gnueabihf-gcc) ./src/main.rs
file ./main Now you have a working Rust cross-compilation toolchain set up. Next, we need to configure the DBus crate for cross compilation. Configuring the DBus crate for cross compilationThe DBus crate uses a build script that uses The crate's build script is specified in
There are two ways we can provide these keys to Cargo:
Usually a Cargo config file should be enough, just specify the names of the libraries and the paths to them and we should be good to go, right? Not so fast. Currently, there is an issue with how Cargo handles relative paths in Enough talk, to action! To see how to set up the DBus crate for cross compilation, we create a new project for it. Create an empty directory somewhere and start a terminal in it. Then execute the following commands. PowerShell (pwsh) & Bash # Initialize a new Rust project in the current folder.
cargo init Change the contents of main.rs fn main() -> Result<(), Box<dyn std::error::Error>> {
let _conn = dbus::Connection::get_private(dbus::BusType::Session)?;
Ok(())
} Next, add the DBus crate as an dependency by editing Cargo.toml [dependencies]
dbus = "0.6" Create a Cargo configuration file, which has to be in a .cargo/config [build]
# Specifies that the default target is ARMv7.
target = "armv7-unknown-linux-gnueabihf"
[target.armv7-unknown-linux-gnueabihf.dbus]
# Specifies the library search paths. Since they cannot be relative paths,
# we use a build script to provide them.
rustc-link-search = [
# Provided by the build script.
]
# Specifies the names of the native libraries that are required to build DBus.
rustc-link-lib = [
"dbus-1",
"gcrypt",
"gpg-error",
"lz4",
"lzma",
"pcre",
"selinux",
"systemd",
] Create the build script that will provide the library search paths. The build script will be named build.rs use std::env::var;
fn main() {
// The manifest dir points to the root of the project containing this file.
let manifest_dir = var("CARGO_MANIFEST_DIR").unwrap();
// We tell Cargo that our native ARMv7 libraries are inside a "libraries" folder.
println!("cargo:rustc-link-search={}/libraries/lib/arm-linux-gnueabihf", manifest_dir);
println!("cargo:rustc-link-search={}/libraries/usr/lib/arm-linux-gnueabihf", manifest_dir);
} If you tried building the project at this point, you should get a rather long error message with this at the top: How do you even find out which of the native packages are required? If you take a look at this line in the DBus build script, you see that it is looking for OK, now which version of libdbus-1 Information
If you do not have the target system at hand, there is still a way: If you are using the Raspbian release based on Debian buster, head to this link (this is a huge file!) and search for Now we know that we have to download In total, you have to download the following packages (the
Next, you have to extract each of these downloaded PowerShell (pwsh) & Bash dpkg-deb -x /path/to/package.deb /path/to/empty/folder Enter the folder you have extracted the package into and take a look at the files. The folder structure can be PowerShell (pwsh) New-Item -ItemType SymbolicLink -Target library.so.3 -Path library.so Bash ln -s library.so.3 library.so Then take all the contents of the folder you extracted the package into and move them into another folder called Repeat the extraction, symlinking and moving for all the other libraries. Finally, after all this is done, your
Finally, you are able to cross compile the project without error messages. PowerShell (pwsh) & Bash cargo build
# Should print something like: Finished dev [unoptimized + debuginfo] target(s) in 0.57s |
@nikonthethird Awesome, very well written! Would you like to submit a PR that completely replaces my non-working guide with yours?
Your way is doing all this manually; I think there should be some way that utilizes
This symlink is provided by the |
So that's what the dev packages do?!? Wow thanks, I will incorporate that into the guide. I also did not know about |
Also, do you think that Because when I tried that, I get link failures about |
There are also wrappers around debootstrap (sbuild, pbuilder, cowbuilder), some of these might be easier to work with. I haven't investigated.
I'm not sure, that's kind of where I got stuck? But if I want to compile this crate normally (i e not cross), then I mean, it's great that you found some way to make it work, but it does not make sense; why would you need more packages for cross compiling than what you need for non-cross? |
I tried using
Only when adding But I have good news: I have written a PowerShell script that completely configures a new Rust project with the DBus crate for cross compilation: DBusCrossCompile.zip You have to install PowerShell Core on your Ubuntu host, and then run in any shell: chmod +x ./DBusCrossCompile.ps1
./DBusCrossCompile.ps1 It creates a folder
Sorry it had to be PowerShell, but I'm a Windows dev by trade and Does this approach look better to you? There are no manual steps involved. If you have an idea how to |
Also, regarding the issue you had in your attempt at cross-compilation.
That's what the step
The paths are absolute! You have to change them to this:
Furthermore, some symlinks also point to absolute locations that have to be fixed, that's also another step in the script. If you get errors that some files could not be found again, it's probably that. |
Good catch! So with this finding of yours, I adjusted my own instructions slightly and got my version to compile as well! This is because I added Now I should probably verify that the final binary works on the target, but that will be a task for another day...have you done that with your version? |
Well, I have used
Indeed its main purpose is to create a rootfs. My guide just assumes you have one ready, e g, you start up your raspberry, run |
Absolutely, this is the output of the binary created by the script, running on a Raspberry Pi 3.
The reason I am using this manual approach is that the project I am working on has to be compiled by several people. Only two of them have the target ARM hardware. That's why we added the libraries to the git repository, that way anyone who has the toolchain installed can build the project. How do you want to proceed with the instructions? I think most people will be happy with plugging an SD card in to compile the project, so your original guide should be just fine? |
But I like yours as well 🙂 So I'm not sure. What do you think? Maybe have both guides and link to yours from mine? |
Ok, so I linked to the issue in the existing instructions, but I would be happy to merge the powershell script as well as your guide if you prefer. Thanks for the help anyhow! |
That sounds fine, thank you. I still have to update the guide a little, I'm on holiday until Sunday, but after that I will add the symlink and LD script changes. |
@nikonthethird |
I've started to write up some cross compiling instructions here: https://github.com/diwic/dbus-rs/blob/master/libdbus-sys/cross_compile.md
...but I can't get it to work. Anyone who wants to help out?
The text was updated successfully, but these errors were encountered: