-
Notifications
You must be signed in to change notification settings - Fork 9
Description
If cargo libcnb package (or libcnb-test, once #704 is fixed) detects that the required cross-compilation toolchain is not installed, it prints the help messages here:
libcnb.rs/libcnb-package/src/cross_compile.rs
Lines 9 to 91 in a9759ee
| pub fn cross_compile_assistance(target_triple: impl AsRef<str>) -> CrossCompileAssistance { | |
| // Background: https://omarkhawaja.com/cross-compiling-rust-from-macos-to-linux/ | |
| if target_triple.as_ref() == X86_64_UNKNOWN_LINUX_MUSL && cfg!(target_os = "macos") { | |
| // There is more than just one binary name here since we also support the binary name for | |
| // an older version cross_compile_assistance which suggested installing a different | |
| // toolchain. | |
| let possible_gcc_binary_names = ["x86_64-unknown-linux-musl-gcc", "x86_64-linux-musl-gcc"]; | |
| possible_gcc_binary_names | |
| .iter() | |
| .find_map(|binary_name| which(binary_name).ok()) | |
| .map_or_else(|| CrossCompileAssistance::HelpText(String::from( | |
| r"For cross-compilation from macOS to x86_64-unknown-linux-musl, a C compiler and | |
| linker for the target platform must be installed on your computer. | |
| The easiest way to install the required cross-compilation toolchain is to run: | |
| brew install messense/macos-cross-toolchains/x86_64-unknown-linux-musl | |
| For more information, see: | |
| https://github.com/messense/homebrew-macos-cross-toolchains", | |
| )), |gcc_binary_path| { | |
| CrossCompileAssistance::Configuration { | |
| cargo_env: vec![ | |
| ( | |
| // Required until Cargo can auto-detect the musl-cross gcc/linker itself, | |
| // since otherwise it checks for a binary named 'musl-gcc': | |
| // https://github.com/FiloSottile/homebrew-musl-cross/issues/16 | |
| // https://github.com/rust-lang/cargo/issues/4133 | |
| OsString::from("CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER"), | |
| OsString::from(&gcc_binary_path), | |
| ), | |
| ( | |
| // Required so that any crates that call out to gcc are also cross-compiled: | |
| // https://github.com/alexcrichton/cc-rs/issues/82 | |
| OsString::from("CC_x86_64_unknown_linux_musl"), | |
| OsString::from(&gcc_binary_path), | |
| ), | |
| ], | |
| } | |
| }) | |
| } else if target_triple.as_ref() == X86_64_UNKNOWN_LINUX_MUSL && cfg!(target_os = "linux") { | |
| match which("musl-gcc") { | |
| Ok(_) => CrossCompileAssistance::Configuration { | |
| cargo_env: Vec::new(), | |
| }, | |
| Err(_) => CrossCompileAssistance::HelpText(String::from( | |
| r"For cross-compilation from Linux to x86_64-unknown-linux-musl, a C compiler and | |
| linker for the target platform must be installed on your computer. | |
| The easiest way to install 'musl-gcc' is to install the 'musl-tools' package: | |
| - https://packages.ubuntu.com/focal/musl-tools | |
| - https://packages.debian.org/bullseye/musl-tools", | |
| )), | |
| } | |
| } else if target_triple.as_ref() == AARCH64_UNKNOWN_LINUX_MUSL && cfg!(target_os = "linux") { | |
| let gcc_binary_path = "aarch64-linux-gnu-gcc"; | |
| match which(gcc_binary_path) { | |
| Ok(_) => CrossCompileAssistance::Configuration { | |
| cargo_env: vec![ | |
| ( | |
| OsString::from("CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER"), | |
| OsString::from(gcc_binary_path), | |
| ), | |
| ( | |
| OsString::from("CC_aarch64_unknown_linux_musl"), | |
| OsString::from(gcc_binary_path), | |
| ), | |
| ], | |
| }, | |
| Err(_) => CrossCompileAssistance::HelpText(String::from( | |
| r"For cross-compilation from Linux to aarch64-unknown-linux-musl, a C compiler and | |
| linker for the target platform must installed on your computer. | |
| The easiest way to install the 'g++-aarch64-linux-gnu', 'libc6-dev-arm64-cross', and 'musl-tools' packages: | |
| - https://packages.ubuntu.com/focal/g++-aarch64-linux-gnu | |
| - https://packages.ubuntu.com/focal/musl-tools | |
| - https://packages.ubuntu.com/focal/libc6-dev-arm64-cross", | |
| )), | |
| } | |
| } else { | |
| CrossCompileAssistance::NoAssistance | |
| } | |
| } |
That help message explains how to install the musl-tools package (or Homebrew equivalent), after which the packaging steps will get further, but will then fail again with errors of form:
test expected_pack_failure ... ok
Compiling component-a v0.0.0 (/Users/emorley/src/libcnb.rs/libcnb-test/tests/fixtures/buildpacks/component-a)
test build_workspace_component_buildpack ... FAILEDomponent-a(bin)
error[E0463]: can't find crate for `std`
|
= note: the `x86_64-unknown-linux-musl` target may not be installed
= help: consider downloading the target with `rustup target add x86_64-unknown-linux-musl`
error: cannot find macro `println` in this scope
--> src/main.rs:2:5
|
2 | println!("Buildpack A");
| ^^^^^^^
error: requires `sized` lang_item
For more information about this error, try `rustc --explain E0463`.
Whilst this next set of errors is better than nothing (it at least suggests the next command that needs running, rustup target add x86_64-unknown-linux-musl):
- the command the user needs to run is somewhat buried inside the rest of the error message
- it has meant twice in a row the user tried to run a command and it has failed - giving the impression of a never-ending set of undocumented setup steps
For a more pleasant UX, we should suggest running the rustup target add x86_64-unknown-linux-musl command in the original compile assistance message. Worst case the user reinstalls an already added target (which will just be a no-op), or misses the second install suggestion, and proceeds to see the error above anyway.