Skip to content
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

iox-#73 Support cross compile for aarch64 #74

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[env]
RUST_TEST_THREADS = "1" # prevent running multiple RouDiEnvironments in parallel with `cargo test`
NEXTEST_TEST_THREADS = "1" # prevent running multiple RouDiEnvironments in parallel with `cargo nextest run`

[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ Safe Rust bindings for [Eclipse iceoryx](https://github.com/eclipse-iceoryx/iceo
- [How to start RouDi](#how-to-start-roudi)
- [Run the simple publisher and subscriber example](#run-the-simple-publisher-and-subscriber-example)
3. [How to write a simple application](#how-to-write-a-simple-application)
4. [Limitations](#limitations)
4. [Cross-compiling](#cross-compiling)
5. [Limitations](#limitations)

## About

Expand Down Expand Up @@ -262,6 +263,23 @@ Please have a look at the [examples](https://github.com/eclipse-iceoryx/iceoryx-
in the repository. It contains additional examples to show how uninitialized samples can be loaned and
how the `wait_for_samples` method of the `SampleReceiver` can be used to get notified on new samples.

## Cross-Compiling

`iceoryx-sys` uses `cmake` to build `iceoryx`, which has a dependency to `libacl` on Linux. As a result,
to link to a cross-compiled version of the native `iceoryx`, it's necessary to set several environment variables
to link against the prebuilt libacl.

To tell the linker lookup libraries from your sysroot, please set the following environment variables, and invoke the build script:

```bash
# let's take the target aarch64-unknown-linux-gnu for instance
SYSROOT=/path/to/your/cross/compile/sysroot
export LDFLAGS="--sysroot $SYSROOT"
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C link-arg=--sysroot=$SYSROOT"

cargo build --target aarch64-unknown-linux-gnu --all-targets
```

## Limitations

Currently, only a subset of Eclipse iceoryx v2.0 is supported and some features are missing.
Expand Down
51 changes: 37 additions & 14 deletions iceoryx-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,25 @@ use std::process::Command;

const ICEORYX_VERSION: &str = "v2.0.3";

fn make_and_install(source_dir: &str, build_dir: &str, install_dir: &str) -> std::io::Result<()> {
fn make_and_install(
cpp_dir: &str,
source_dir: &str,
build_dir: &str,
install_dir: &str,
) -> std::io::Result<()> {
let cmake_install_prefix = format!("-DCMAKE_INSTALL_PREFIX={}", install_dir);
let cmake_prefix_path = format!("-DCMAKE_PREFIX_PATH={}", install_dir);

let target = env::var("TARGET").expect("Target");
let host = env::var("HOST").expect("Host");

let extra_cmake_args = if target == host {
vec![]
} else {
let toolchain_cmake_file = format!("{}/toolchain.{}.cmake", cpp_dir, target);
vec![format!("-DCMAKE_TOOLCHAIN_FILE={}", toolchain_cmake_file)]
};

for iceoryx_component in ["iceoryx_hoofs", "iceoryx_posh"] {
let component_source_dir = format!("{}/{}", source_dir, iceoryx_component);
let component_build_dir = format!("{}/{}", build_dir, iceoryx_component);
Expand All @@ -28,16 +43,17 @@ fn make_and_install(source_dir: &str, build_dir: &str, install_dir: &str) -> std
));
}

let mut cmake_args = extra_cmake_args.clone();
cmake_args.push("-DCMAKE_BUILD_TYPE=Release".into());
cmake_args.push("-DBUILD_SHARED_LIBS=OFF".into());
cmake_args.push("-DROUDI_ENVIRONMENT=ON".into());
cmake_args.push(cmake_prefix_path.clone());
cmake_args.push(cmake_install_prefix.clone());
cmake_args.push(component_source_dir.clone());

if !Command::new("cmake")
.current_dir(&component_build_dir)
.args([
"-DCMAKE_BUILD_TYPE=Release",
"-DBUILD_SHARED_LIBS=OFF",
"-DROUDI_ENVIRONMENT=ON",
&cmake_prefix_path,
&cmake_install_prefix,
&component_source_dir,
])
.args(&cmake_args)
.status()?
.success()
{
Expand All @@ -47,9 +63,15 @@ fn make_and_install(source_dir: &str, build_dir: &str, install_dir: &str) -> std
));
}

let mut cmake_args = Vec::new();
cmake_args.push("--build");
cmake_args.push(".");
cmake_args.push("--target");
cmake_args.push("install");

if !Command::new("cmake")
.current_dir(&component_build_dir)
.args(["--build", ".", "--target", "install"])
.args(&cmake_args)
.status()?
.success()
{
Expand All @@ -63,7 +85,7 @@ fn make_and_install(source_dir: &str, build_dir: &str, install_dir: &str) -> std
Ok(())
}

fn extract_archive(archive_dir: &str, source_dir: &str, version: &str) -> std::io::Result<()> {
fn extract_archive(cpp_dir: &str, source_dir: &str, version: &str) -> std::io::Result<()> {
if !Command::new("mkdir")
.args(["-p", source_dir])
.status()?
Expand All @@ -78,7 +100,7 @@ fn extract_archive(archive_dir: &str, source_dir: &str, version: &str) -> std::i
if !Command::new("tar")
.args([
"-xf",
&format!("{}/{}.tar.gz", archive_dir, version),
&format!("{}/{}.tar.gz", cpp_dir, version),
"-C",
source_dir,
"--strip-components=1",
Expand All @@ -102,14 +124,15 @@ fn main() -> std::io::Result<()> {
let out_dir = env::var("OUT_DIR").expect("Target output directory");
let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("Cargo manifest directory");

let iceoryx_archive_dir = format!("{}/{}", manifest_dir, "iceoryx-cpp");
let iceoryx_cpp_dir = format!("{}/{}", manifest_dir, "iceoryx-cpp");
let iceoryx_source_dir = format!("{}/{}/", out_dir, "iceoryx-cpp");
let iceoryx_build_dir = format!("{}/{}", out_dir, "iceoryx-build");
let iceoryx_install_dir = format!("{}/{}", out_dir, "iceoryx-install");

extract_archive(&iceoryx_archive_dir, &iceoryx_source_dir, ICEORYX_VERSION)?;
extract_archive(&iceoryx_cpp_dir, &iceoryx_source_dir, ICEORYX_VERSION)?;

make_and_install(
&iceoryx_cpp_dir,
&iceoryx_source_dir,
&iceoryx_build_dir,
&iceoryx_install_dir,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
set(CMAKE_SYSTEM_NAME Linux)

set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)