Skip to content

Commit b004794

Browse files
committed
iox-#73 Support cross compile for aarch64
1 parent fdd6495 commit b004794

File tree

4 files changed

+221
-44
lines changed

4 files changed

+221
-44
lines changed

iceoryx-sys/build.rs

Lines changed: 217 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,193 @@ use std::io::{Error, ErrorKind};
88
use std::process::Command;
99

1010
const ICEORYX_VERSION: &str = "v2.0.3";
11+
const ATTR_VERSION: &str = "2.5.1";
12+
const ACL_VERSION: &str = "2.3.1";
1113

12-
fn make_and_install(source_dir: &str, build_dir: &str, install_dir: &str) -> std::io::Result<()> {
14+
fn extract(archive: &str, source_dir: &str) -> std::io::Result<()> {
15+
if !Command::new("mkdir")
16+
.args(["-p", source_dir])
17+
.status()?
18+
.success()
19+
{
20+
return Err(Error::new(
21+
ErrorKind::Other,
22+
format!("Could not create source dir for '{}'!", source_dir),
23+
));
24+
}
25+
26+
if !Command::new("tar")
27+
.args([
28+
"-xf",
29+
archive,
30+
"-C",
31+
source_dir,
32+
"--strip-components=1",
33+
])
34+
.status()?
35+
.success()
36+
{
37+
return Err(Error::new(
38+
ErrorKind::Other,
39+
format!(
40+
"Could not extract archive '{}' to '{}'!",
41+
archive, source_dir
42+
),
43+
));
44+
}
45+
46+
Ok(())
47+
}
48+
49+
fn autogen(source_dir: &str) -> std::io::Result<()> {
50+
if !Command::new("./autogen.sh")
51+
.current_dir(source_dir)
52+
.status()?
53+
.success()
54+
{
55+
return Err(Error::new(
56+
ErrorKind::Other,
57+
format!("Failed to run autogen.sh in {}", source_dir)
58+
));
59+
}
60+
61+
Ok(())
62+
}
63+
64+
fn configure(source_dir: &str, build_dir: &str, install_dir: &str, toolchain_prefix: Option<&str>) -> std::io::Result<()> {
65+
if !Command::new("mkdir")
66+
.args(["-p", build_dir])
67+
.status()?
68+
.success()
69+
{
70+
return Err(Error::new(
71+
ErrorKind::Other,
72+
format!("Could not create build dir for '{}'!", build_dir),
73+
));
74+
}
75+
76+
let mut args = Vec::new();
77+
78+
if let Some(toolchain_prefix) = toolchain_prefix {
79+
args.push(format!("--host={}", toolchain_prefix));
80+
}
81+
82+
args.push(format!("--prefix={}", install_dir));
83+
args.push(format!("--enable-shared=no"));
84+
85+
if !Command::new(format!("{}/configure", source_dir))
86+
.current_dir(build_dir)
87+
.args(args)
88+
.env("CFLAGS", format!("-I{}/include", install_dir))
89+
.env("LDFLAGS", format!("-L{}/lib", install_dir))
90+
.status()?
91+
.success()
92+
{
93+
return Err(Error::new(
94+
ErrorKind::Other,
95+
format!("Failed to run configure in {}", source_dir)
96+
));
97+
}
98+
99+
Ok(())
100+
}
101+
102+
fn make(build_dir: &str) -> std::io::Result<()> {
103+
if !Command::new("make")
104+
.current_dir(build_dir)
105+
.status()?
106+
.success()
107+
{
108+
return Err(Error::new(
109+
ErrorKind::Other,
110+
format!("Failed to run make in {}", build_dir)
111+
));
112+
}
113+
114+
Ok(())
115+
}
116+
117+
fn make_install(build_dir: &str) -> std::io::Result<()> {
118+
if !Command::new("make")
119+
.current_dir(build_dir)
120+
.args(["install"])
121+
.status()?
122+
.success()
123+
{
124+
return Err(Error::new(
125+
ErrorKind::Other,
126+
format!("Failed to run make install in {}", build_dir)
127+
));
128+
}
129+
130+
Ok(())
131+
}
132+
133+
fn extract_toolchain_prefix(toolchain_cmake_file: &str) -> std::io::Result<Option<String>> {
134+
let toolchain_cmake = std::fs::read_to_string(toolchain_cmake_file);
135+
136+
if toolchain_cmake.is_err() {
137+
return Err(Error::new(
138+
ErrorKind::Other,
139+
format!("failed to read cmake file {}", toolchain_cmake_file)
140+
));
141+
}
142+
143+
let toolchain_cmake = toolchain_cmake.unwrap();
144+
145+
let segs = toolchain_cmake
146+
.lines()
147+
.map(|l| l.trim())
148+
.find(|line| line.starts_with("set(CMAKE_C_COMPILER"))
149+
.map(|line| line.split_whitespace().last().unwrap().trim_matches('"'))
150+
.map(|line| line.trim_matches(')'))
151+
.map(|line| line.split('-').collect::<Vec<_>>());
152+
153+
if segs.is_none() || segs.as_ref().unwrap().is_empty() {
154+
return Err(Error::new(
155+
ErrorKind::Other,
156+
format!("extracted empty triple from cmake file {}", toolchain_cmake_file)
157+
));
158+
}
159+
160+
let segs = segs.unwrap();
161+
Ok(Some(segs[0..segs.len() - 1].join("-")))
162+
}
163+
164+
fn make_and_install(archive_dir: &str, source_dir: &str, build_dir: &str, install_dir: &str) -> std::io::Result<()> {
13165
let cmake_install_prefix = format!("-DCMAKE_INSTALL_PREFIX={}", install_dir);
14166
let cmake_prefix_path = format!("-DCMAKE_PREFIX_PATH={}", install_dir);
15167

168+
let target = env::var("TARGET").expect("Target");
169+
let host = env::var("HOST").expect("Host");
170+
171+
let (extra_cmake_args, toolchain_prefix) = if target == host {
172+
(vec![], None)
173+
} else {
174+
let toolchain_cmake_file = format!("{}/toolchain.{}.cmake", archive_dir, target);
175+
(vec![format!("-DCMAKE_TOOLCHAIN_FILE={}", toolchain_cmake_file)], extract_toolchain_prefix(&toolchain_cmake_file)?)
176+
};
177+
178+
if let Some(toolchain_prefix) = toolchain_prefix {
179+
// cross compiling, compile libattr and libacl on our own
180+
// compile attr
181+
let attr_source_dir = format!("{}/{}", source_dir, "attr");
182+
let attr_build_dir = format!("{}/{}", build_dir, "attr");
183+
extract(&format!("{}/attr-{}.tar.gz", archive_dir, ATTR_VERSION), &attr_source_dir)?;
184+
autogen(&attr_source_dir)?;
185+
configure(&attr_source_dir, &attr_build_dir, &install_dir, Some(&toolchain_prefix))?;
186+
make(&attr_build_dir)?;
187+
make_install(&attr_build_dir)?;
188+
189+
// compile acl
190+
let acl_source_dir = format!("{}/{}", source_dir, "acl");
191+
let acl_build_dir = format!("{}/{}", build_dir, "acl");
192+
extract(&format!("{}/acl-{}.tar.gz", archive_dir, ACL_VERSION), &acl_source_dir)?;
193+
configure(&acl_source_dir, &acl_build_dir, &install_dir, Some(&toolchain_prefix))?;
194+
make(&acl_build_dir)?;
195+
make_install(&acl_build_dir)?;
196+
}
197+
16198
for iceoryx_component in ["iceoryx_hoofs", "iceoryx_posh"] {
17199
let component_source_dir = format!("{}/{}", source_dir, iceoryx_component);
18200
let component_build_dir = format!("{}/{}", build_dir, iceoryx_component);
@@ -28,34 +210,55 @@ fn make_and_install(source_dir: &str, build_dir: &str, install_dir: &str) -> std
28210
));
29211
}
30212

213+
let mut cmake_args = extra_cmake_args.clone();
214+
cmake_args.push(format!("-DCMAKE_BUILD_TYPE=Release"));
215+
cmake_args.push(format!("-DBUILD_SHARED_LIBS=OFF"));
216+
cmake_args.push(format!("-DROUDI_ENVIRONMENT=ON"));
217+
cmake_args.push(cmake_prefix_path.clone());
218+
cmake_args.push(cmake_install_prefix.clone());
219+
cmake_args.push(component_source_dir.clone());
220+
31221
if !Command::new("cmake")
32222
.current_dir(&component_build_dir)
33-
.args([
34-
"-DCMAKE_BUILD_TYPE=Release",
35-
"-DBUILD_SHARED_LIBS=OFF",
36-
"-DROUDI_ENVIRONMENT=ON",
37-
&cmake_prefix_path,
38-
&cmake_install_prefix,
39-
&component_source_dir,
40-
])
223+
.env("CFLAGS", format!("-I{}/include", install_dir))
224+
.env("LDFLAGS", format!("-L{}/lib", install_dir))
225+
.args(&cmake_args)
41226
.status()?
42227
.success()
43228
{
44229
return Err(Error::new(
45230
ErrorKind::Other,
46-
format!("Could not run cmake for '{}'!", iceoryx_component),
231+
format!(
232+
"Could not run cmake for '{}'!\nWork Dir: {}\nCommand: cmake {}",
233+
iceoryx_component,
234+
component_build_dir,
235+
cmake_args.join(" ")
236+
),
47237
));
48238
}
49239

240+
let mut cmake_args = Vec::new();
241+
cmake_args.push(format!("--build"));
242+
cmake_args.push(format!("."));
243+
cmake_args.push(format!("--target"));
244+
cmake_args.push(format!("install"));
245+
50246
if !Command::new("cmake")
51247
.current_dir(&component_build_dir)
52-
.args(["--build", ".", "--target", "install"])
248+
.env("CFLAGS", format!("-I{}/include", install_dir))
249+
.env("LDFLAGS", format!("-L{}/lib", install_dir))
250+
.args(&cmake_args)
53251
.status()?
54252
.success()
55253
{
56254
return Err(Error::new(
57255
ErrorKind::Other,
58-
format!("Could not build '{}'!", iceoryx_component),
256+
format!(
257+
"Could not build '{}'!\nWork Dir: {}\nCommand: cmake {}",
258+
iceoryx_component,
259+
component_build_dir,
260+
cmake_args.join(" ")
261+
),
59262
));
60263
}
61264
}
@@ -64,38 +267,7 @@ fn make_and_install(source_dir: &str, build_dir: &str, install_dir: &str) -> std
64267
}
65268

66269
fn extract_archive(archive_dir: &str, source_dir: &str, version: &str) -> std::io::Result<()> {
67-
if !Command::new("mkdir")
68-
.args(["-p", source_dir])
69-
.status()?
70-
.success()
71-
{
72-
return Err(Error::new(
73-
ErrorKind::Other,
74-
format!("Could not create source dir for '{}'!", source_dir),
75-
));
76-
}
77-
78-
if !Command::new("tar")
79-
.args([
80-
"-xf",
81-
&format!("{}/{}.tar.gz", archive_dir, version),
82-
"-C",
83-
source_dir,
84-
"--strip-components=1",
85-
])
86-
.status()?
87-
.success()
88-
{
89-
return Err(Error::new(
90-
ErrorKind::Other,
91-
format!(
92-
"Could not extract archive '{}' to '{}'!",
93-
version, source_dir
94-
),
95-
));
96-
}
97-
98-
Ok(())
270+
extract(&format!("{}/{}.tar.gz", archive_dir, version), source_dir)
99271
}
100272

101273
fn main() -> std::io::Result<()> {
@@ -110,6 +282,7 @@ fn main() -> std::io::Result<()> {
110282
extract_archive(&iceoryx_archive_dir, &iceoryx_source_dir, ICEORYX_VERSION)?;
111283

112284
make_and_install(
285+
&iceoryx_archive_dir,
113286
&iceoryx_source_dir,
114287
&iceoryx_build_dir,
115288
&iceoryx_install_dir,
506 KB
Binary file not shown.
66 KB
Binary file not shown.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
set(CMAKE_SYSTEM_NAME Linux)
2+
3+
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
4+
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)

0 commit comments

Comments
 (0)