From d72abde8e92ec3cd51c6ecb71e386fced8563924 Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Mon, 16 Jan 2023 10:57:53 +1100 Subject: [PATCH] Fixed #704: Fix `get_target_from_rustc` for alpine (#705) On Alpine, rustc returns host triple `x86_64-alpine-linux-musl`, so we have to adopt code from [`convert_custom_linux_target`](https://github.com/crossbeam-rs/crossbeam/blob/5519aeb5c2156c5aff9a88d41dcfbcd838e9a1ea/build-common.rs#L1-L13) to fix this. * Optimize `get_target_from_rustc`: Avoid frequent String allocation caused by `Cursor::new(stdout).lines()` which calls `BufRead::lines` and returns `Lines` iterator, which returns `Item = io::Result`. Signed-off-by: Jiahao XU Signed-off-by: Jiahao XU --- crates/detect-targets/src/detect.rs | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/crates/detect-targets/src/detect.rs b/crates/detect-targets/src/detect.rs index 0216d4ad..62af9f20 100644 --- a/crates/detect-targets/src/detect.rs +++ b/crates/detect-targets/src/detect.rs @@ -2,7 +2,6 @@ use std::{ borrow::Cow, env, ffi::OsStr, - io::{BufRead, Cursor}, process::{Output, Stdio}, }; @@ -99,10 +98,26 @@ async fn get_target_from_rustc() -> Option { return None; } - Cursor::new(stdout) + let stdout = String::from_utf8_lossy(&stdout); + let target = stdout .lines() - .filter_map(|line| line.ok()) - .find_map(|line| line.strip_prefix("host: ").map(|host| host.to_owned())) - // All valid target triple must be in the form of $arch-$os-$abi. - .filter(|target| target.split('-').count() >= 3) + .find_map(|line| line.strip_prefix("host: "))?; + + // The target triplets have the form of 'arch-vendor-system'. + // + // When building for Linux (e.g. the 'system' part is + // 'linux-something'), replace the vendor with 'unknown' + // so that mapping to rust standard targets happens correctly. + // + // For example, alpine set `rustc` host triple to + // `x86_64-alpine-linux-musl`. + // + // Here we use splitn with n=4 since we just need to check + // the third part to see if it equals to "linux" and verify + // that we have at least three parts. + let mut parts: Vec<&str> = target.splitn(4, '-').collect(); + if *parts.get(2)? == "linux" { + parts[1] = "unknown"; + } + Some(parts.join("-")) }