libcnb_package/
cross_compile.rs1use indoc::{formatdoc, indoc};
2use std::env::consts;
3use std::ffi::OsString;
4use which::which;
5
6pub fn cross_compile_assistance(target_triple: impl AsRef<str>) -> CrossCompileAssistance {
12 let target_triple = target_triple.as_ref();
13 let (gcc_binary_name, help_text) = match (target_triple, consts::OS, consts::ARCH) {
14 (AARCH64_UNKNOWN_LINUX_MUSL, OS_LINUX, ARCH_X86_64) => (
15 "aarch64-linux-gnu-gcc",
16 indoc! {"
17 To install an aarch64 cross-compiler on Ubuntu:
18 sudo apt-get install g++-aarch64-linux-gnu libc6-dev-arm64-cross musl-tools
19 "},
20 ),
21 (AARCH64_UNKNOWN_LINUX_MUSL, OS_MACOS, ARCH_X86_64 | ARCH_AARCH64) => (
22 "aarch64-unknown-linux-musl-gcc",
23 indoc! {"
24 To install an aarch64 cross-compiler on macOS:
25 brew install messense/macos-cross-toolchains/aarch64-unknown-linux-musl
26 "},
27 ),
28 (AARCH64_UNKNOWN_LINUX_MUSL, OS_LINUX, ARCH_AARCH64)
29 | (X86_64_UNKNOWN_LINUX_MUSL, OS_LINUX, ARCH_X86_64) => (
30 "musl-gcc",
31 indoc! {"
32 To install musl-tools on Ubuntu:
33 sudo apt-get install musl-tools
34 "},
35 ),
36 (X86_64_UNKNOWN_LINUX_MUSL, OS_LINUX, ARCH_AARCH64) => (
37 "x86_64-linux-gnu-gcc",
38 indoc! {"
39 To install an x86_64 cross-compiler on Ubuntu:
40 sudo apt-get install g++-x86-64-linux-gnu libc6-dev-amd64-cross musl-tools
41 "},
42 ),
43 (X86_64_UNKNOWN_LINUX_MUSL, OS_MACOS, ARCH_X86_64 | ARCH_AARCH64) => (
44 "x86_64-unknown-linux-musl-gcc",
45 indoc! {"
46 To install an x86_64 cross-compiler on macOS:
47 brew install messense/macos-cross-toolchains/x86_64-unknown-linux-musl
48 "},
49 ),
50 _ => return CrossCompileAssistance::NoAssistance,
51 };
52
53 match which(gcc_binary_name) {
54 Ok(_) => {
55 if gcc_binary_name == "musl-gcc" {
58 CrossCompileAssistance::Configuration {
59 cargo_env: Vec::new(),
60 }
61 } else {
62 CrossCompileAssistance::Configuration {
63 cargo_env: vec![
64 (
65 OsString::from(format!(
69 "CARGO_TARGET_{}_LINKER",
70 target_triple.to_uppercase().replace('-', "_")
71 )),
72 OsString::from(gcc_binary_name),
73 ),
74 (
75 OsString::from(format!("CC_{}", target_triple.replace('-', "_"))),
78 OsString::from(gcc_binary_name),
79 ),
80 ],
81 }
82 }
83 }
84 Err(_) => CrossCompileAssistance::HelpText(formatdoc! {"
85 For cross-compilation from {0} {1} to {target_triple},
86 a C compiler and linker for the target platform must be installed:
87
88 {help_text}
89 You will also need to install the Rust target:
90 rustup target add {target_triple}
91 ",
92 consts::ARCH,
93 consts::OS
94 }),
95 }
96}
97
98pub enum CrossCompileAssistance {
99 NoAssistance,
101 HelpText(String),
104 Configuration {
106 cargo_env: Vec<(OsString, OsString)>,
107 },
108}
109
110pub const AARCH64_UNKNOWN_LINUX_MUSL: &str = "aarch64-unknown-linux-musl";
112pub const X86_64_UNKNOWN_LINUX_MUSL: &str = "x86_64-unknown-linux-musl";
113
114const OS_LINUX: &str = "linux";
116const OS_MACOS: &str = "macos";
117const ARCH_X86_64: &str = "x86_64";
118const ARCH_AARCH64: &str = "aarch64";