|
| 1 | +//! Make sure that cross-language LTO works on riscv targets, |
| 2 | +//! which requires extra abi metadata to be emitted. |
| 3 | +//@ needs-matching-clang |
| 4 | +//@ needs-llvm-components riscv |
| 5 | +extern crate run_make_support; |
| 6 | + |
| 7 | +use run_make_support::{bin_name, rustc, tmp_dir}; |
| 8 | +use std::{ |
| 9 | + env, |
| 10 | + path::PathBuf, |
| 11 | + process::{Command, Output}, |
| 12 | + str, |
| 13 | +}; |
| 14 | + |
| 15 | +fn handle_failed_output(output: Output) { |
| 16 | + eprintln!("output status: `{}`", output.status); |
| 17 | + eprintln!("=== STDOUT ===\n{}\n\n", String::from_utf8(output.stdout).unwrap()); |
| 18 | + eprintln!("=== STDERR ===\n{}\n\n", String::from_utf8(output.stderr).unwrap()); |
| 19 | + std::process::exit(1) |
| 20 | +} |
| 21 | + |
| 22 | +fn check_target(target: &str, clang_target: &str, carch: &str, abi: &str, is_double_float: bool) { |
| 23 | + eprintln!("Checking target {target} with abi {abi}"); |
| 24 | + // Rust part |
| 25 | + rustc() |
| 26 | + .input("riscv-xlto.rs") |
| 27 | + .crate_type("rlib") |
| 28 | + .target(target) |
| 29 | + .panic("abort") |
| 30 | + .linker_plugin_lto("on") |
| 31 | + .run(); |
| 32 | + // C part |
| 33 | + let clang = env::var("CLANG").unwrap(); |
| 34 | + let mut cmd = Command::new(clang); |
| 35 | + let executable = tmp_dir().join("riscv-xlto"); |
| 36 | + cmd.arg("-target") |
| 37 | + .arg(clang_target) |
| 38 | + .arg(format!("-march={carch}")) |
| 39 | + .arg(format!("-mabi={abi}")) |
| 40 | + .arg(format!("-flto=thin")) |
| 41 | + .arg(format!("-fuse-ld=lld")) |
| 42 | + .arg("-nostdlib") |
| 43 | + .arg("-o") |
| 44 | + .arg(&executable) |
| 45 | + .arg("cstart.c") |
| 46 | + .arg(tmp_dir().join("libriscv_xlto.rlib")); |
| 47 | + eprintln!("{cmd:?}"); |
| 48 | + let output = cmd.output().unwrap(); |
| 49 | + if !output.status.success() { |
| 50 | + handle_failed_output(output); |
| 51 | + } |
| 52 | + // Check that the built binary has correct float abi |
| 53 | + let llvm_readobj = |
| 54 | + PathBuf::from(env::var("LLVM_BIN_DIR").unwrap()).join(bin_name("llvm-readobj")); |
| 55 | + let mut cmd = Command::new(llvm_readobj); |
| 56 | + cmd.arg("--file-header").arg(executable); |
| 57 | + eprintln!("{cmd:?}"); |
| 58 | + let output = cmd.output().unwrap(); |
| 59 | + if output.status.success() { |
| 60 | + assert!( |
| 61 | + !(is_double_float |
| 62 | + ^ dbg!(str::from_utf8(&output.stdout).unwrap()) |
| 63 | + .contains("EF_RISCV_FLOAT_ABI_DOUBLE")) |
| 64 | + ) |
| 65 | + } else { |
| 66 | + handle_failed_output(output); |
| 67 | + } |
| 68 | +} |
| 69 | + |
| 70 | +fn main() { |
| 71 | + check_target("riscv64gc-unknown-linux-gnu", "riscv64-linux-gnu", "rv64gc", "lp64d", true); |
| 72 | + check_target("riscv64imac-unknown-none-elf", "riscv64-unknown-elf", "rv64imac", "lp64", false); |
| 73 | + check_target("riscv32imac-unknown-none-elf", "riscv32-unknown-elf", "rv32imac", "ilp32", false); |
| 74 | + check_target("riscv32gc-unknown-linux-gnu", "riscv32-linux-gnu", "rv32gc", "ilp32d", true); |
| 75 | +} |
0 commit comments