Skip to content

Commit

Permalink
Correctly infer ranlib/ar for cross-gcc toolchains
Browse files Browse the repository at this point in the history
A second try at alexcrichton#163.

The GCC convention is that if the toolchain is named `$target-gnu-gcc`,
then ranlib and ar will be available as `$target-gnu-gcc-ranlib` and
`$target-gnu-gcc-ar` respectively. The code as written would infer them
to be `$target-gnu-{ranlib,ar}`, which will only work if the tools from
`binutils` (which follow that convention) are on `$PATH`.

I've also updated the logic in line with the `cc` crate to check that
the inferred `AR`/`RANLIB` is actually executable before setting it as
an override.

See also rust-lang/cc-rs#736.
  • Loading branch information
Jon Gjengset committed Oct 26, 2022
1 parent cbbb491 commit c13be3c
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions src/lib.rs
Expand Up @@ -346,15 +346,25 @@ impl Build {
configure.env_remove("CROSS_COMPILE");

// Infer ar/ranlib tools from cross compilers if the it looks like
// we're doing something like `foo-gcc` route that to `foo-ranlib`
// as well.
// we're doing something like `foo-gcc` route that to `foo-gcc-ranlib`
// or `foo-ranlib` (for `binutils`) as well.
if path.ends_with("-gcc") && !target.contains("unknown-linux-musl") {
let path = &path[..path.len() - 4];
if env::var_os("RANLIB").is_none() {
configure.env("RANLIB", format!("{}-ranlib", path));
}
if env::var_os("AR").is_none() {
configure.env("AR", format!("{}-ar", path));
let suffix = &path[path.len() - 4..];
let path = &path[..path.len() - suffix.len()];
for &tool in &["RANLIB", "AR"] {
if env::var_os(tool).is_some() {
// Respect what came before.
break;
}

for &infix in &[suffix, ""] {
let candidate = format!("{}{}-{}", path, infix, tool.to_lowercase());
// Only choose a tool if it's actually executable
if Command::new(&candidate).output().is_ok() {
configure.env(tool, candidate);
break;
}
}
}
}

Expand Down

0 comments on commit c13be3c

Please sign in to comment.