我该如何查找当前 Rust 编译器的默认 LLVM 目标三元组?

19

我想覆盖构建脚本,这意味着添加一个配置部分,看起来像这样:

[target.x86_64-unknown-linux-gnu.foo]
rustc-link-search = ["/path/to/foo"]
rustc-link-lib = ["foo"]
root = "/path/to/foo"
key = "value"

但是我使用的是Mac,所以x86_64-unknown-linux-gnu不是正确的目标三元组。

如何发现rustc或cargo当前正在使用哪个目标三元组?

rustc --print cfg打印一系列值,这些值似乎与三元组不对应(特别是其中没有unknown)。

rustc --print target-list显示所有可用的目标;我只想要默认值。


2
你的 Mac 的目标三元组可能是 x86_64-apple-darwin。中间部分是供应商,在 Linux 中为 unknown,但在 Mac 上为 apple。然而,看起来你想独立于目标配置构建脚本,所以你根本不需要目标三元组。 - Sven Marnach
是的,我通过查看列表找到了正确的答案——发现了两个“darwin”目标,并知道我在“x86_64”上,但这仍然需要我思考。您能否详细说明“根本不需要目标三元组”的含义? - Roger Lipscombe
7个回答

11

根据 @konstin 的答案

$ rustc -vV | sed -n 's|host: ||p'

这会给你类似于:

x86_64-unknown-linux-gnu

8

cargo使用rustc -vV命令检测默认目标三元组(源代码)。我们也可以采用同样的方法:

use std::process::Command;

use anyhow::{format_err, Context, Result};
use std::str;

fn get_target() -> Result<String> {
    let output = Command::new("rustc")
        .arg("-vV")
        .output()
        .context("Failed to run rustc to get the host target")?;
    let output = str::from_utf8(&output.stdout).context("`rustc -vV` didn't return utf8 output")?;

    let field = "host: ";
    let host = output
        .lines()
        .find(|l| l.starts_with(field))
        .map(|l| &l[field.len()..])
        .ok_or_else(|| {
            format_err!(
                "`rustc -vV` didn't have a line for `{}`, got:\n{}",
                field.trim(),
                output
            )
        })?
        .to_string();
    Ok(host)
}

fn main() -> Result<()> {
    let host = get_target()?;
    println!("target triple: {}", host);
    Ok(())
}

1
将编译器输出通过 awk 进行三重处理:$ rustc -vV | awk '/host/ { print $2 }' x86_64-unknown-linux-gnu - Frank P

3
您可以使用 current_platform crate:
use current_platform::CURRENT_PLATFORM;

fn main() {
    println!("Running on {}", CURRENT_PLATFORM);
}

在桌面Linux上,这将打印Running on x86_64-unknown-linux-gnu

与所有其他答案不同的是,这是零成本:平台在编译时确定,因此没有运行时开销。相比之下,调用rustc是昂贵的:如果通过rustup.rs安装Rust,则任何rustc命令都需要大约100毫秒。


3

我经常编写跨平台的shell脚本或Python程序,需要检查我的当前Rust默认目标三元组。虽然我不喜欢手动搜索字符串值。

为了更轻松地获取默认的目标三元组,我将 konstin的回答 打包成一个命令行工具。

你可以使用以下命令进行安装:

cargo install default-target

然后你只需运行该程序即可使用:

default-target

这个命令会返回你当前的目标三元组(target triple),类似于x86_64-apple-darwinx86_64-unknown-linux-gnu

你可以在crates.iodocs.rsGitHub上找到有关这个crate更多的细节。


你可能想要将其从调用 rustc -vV 切换为使用 https://crates.io/crates/current_platform - 这样更快,而且不需要你定位 rustc 二进制文件。 - Shnatsel
@Shnatsel,这是一个有趣的想法。但如果我在编译时将目标三元组嵌入到default-target中,是否可能rustc的目标三元组会变化?例如,同一台机器是否可以同时具有x86_64-unknown-linux-muslx86_64-unknown-linux-gnu这两个不同的二进制文件? - James Mishra
是的,如果您使用rustup,您可以切换默认目标。rust-lang.github.io/rustup/overrides.html 我不确定这是否也出现在rustc -vV中。 - Shnatsel

2

如果您使用的是足够新的rustc编译器:

$ rustc -Z unstable-options --print target-spec-json | grep llvm-target

1
哦。错误:选项 \Z` 仅在夜间编译器上被接受`(rustc 1.42.0)。 - Jens
你可以随时添加 +nightly,即 rustc +nightly -Z unstable-options --print target-spec-json | grep llvm-target - undefined

2

也许不是特别优雅,但我发现这个方法很有效:

rustup show | grep default | grep -Po "^[^-]+-\K\S+"

虽然过滤命令并不十分优雅,但使用rustup show似乎比接受的答案更好。特别是因为rustup是Rust的安装程序。 - undefined

2

以下是对我有用的方法(受Rodrigo答案启发):

RUSTC_BOOTSTRAP=1 rustc -Z unstable-options --print target-spec-json | python3 -c 'import json,sys;obj=json.load(sys.stdin);print(obj["llvm-target"])'

RUSTC_BOOTSTRAP=1可以绕过正常的检查,允许在非夜间版本中使用某些功能。我还使用了一个正确的JSON解析器而不是grep。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接