Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Mention the rustup target add step in the initial cross-compile assistance message #716

@edmorley

Description

@edmorley

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:

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.

GUS-W-14438920.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions