Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run the full stage 2 run-make test suite in x86_64-gnu-debug #131917

Merged
merged 6 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ ENV RUST_CONFIGURE_ARGS \
# (without necessarily testing the result).
# - That the tests with `//@ needs-force-clang-based-tests` pass, since they
# don't run by default unless RUSTBUILD_FORCE_CLANG_BASED_TESTS is set.
# - FIXME(https://github.com/rust-lang/rust/pull/126155#issuecomment-2156314273):
# Currently we only run the subset of tests with "clang" in their name.

ENV SCRIPT \
python3 ../x.py --stage 2 build && \
python3 ../x.py --stage 2 test tests/run-make --test-args clang
python3 ../x.py --stage 2 test tests/run-make
4 changes: 3 additions & 1 deletion src/ci/github-actions/jobs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,9 @@ auto:
<<: *job-linux-4c

- image: x86_64-gnu-debug
<<: *job-linux-4c
# This seems to be needed because a full stage 2 build + run-make tests
# overwhelms the storage capacity of the standard 4c runner.
<<: *job-linux-4c-largedisk

- image: x86_64-gnu-distcheck
<<: *job-linux-8c
Expand Down
18 changes: 18 additions & 0 deletions src/tools/run-make-support/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,12 @@ pub struct CompletedProcess {
}

impl CompletedProcess {
#[must_use]
#[track_caller]
pub fn stdout(&self) -> Vec<u8> {
self.output.stdout.clone()
}

#[must_use]
#[track_caller]
pub fn stdout_utf8(&self) -> String {
Expand All @@ -234,12 +240,24 @@ impl CompletedProcess {
String::from_utf8_lossy(&self.output.stdout.clone()).to_string()
}

#[must_use]
#[track_caller]
pub fn stderr(&self) -> Vec<u8> {
self.output.stderr.clone()
}

#[must_use]
#[track_caller]
pub fn stderr_utf8(&self) -> String {
String::from_utf8(self.output.stderr.clone()).expect("stderr is not valid UTF-8")
}

#[must_use]
#[track_caller]
pub fn invalid_stderr_utf8(&self) -> String {
String::from_utf8_lossy(&self.output.stderr.clone()).to_string()
}

#[must_use]
pub fn status(&self) -> ExitStatus {
self.output.status
Expand Down
66 changes: 66 additions & 0 deletions src/tools/run-make-support/src/external_deps/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ pub fn llvm_pdbutil() -> LlvmPdbutil {
LlvmPdbutil::new()
}

/// Construct a new `llvm-dis` invocation. This assumes that `llvm-dis` is available
/// at `$LLVM_BIN_DIR/llvm-dis`.
pub fn llvm_dis() -> LlvmDis {
LlvmDis::new()
}

/// Construct a new `llvm-objcopy` invocation. This assumes that `llvm-objcopy` is available
/// at `$LLVM_BIN_DIR/llvm-objcopy`.
pub fn llvm_objcopy() -> LlvmObjcopy {
LlvmObjcopy::new()
}

/// A `llvm-readobj` invocation builder.
#[derive(Debug)]
#[must_use]
Expand Down Expand Up @@ -123,6 +135,20 @@ pub struct LlvmPdbutil {
cmd: Command,
}

/// A `llvm-dis` invocation builder.
#[derive(Debug)]
#[must_use]
pub struct LlvmDis {
cmd: Command,
}

/// A `llvm-objcopy` invocation builder.
#[derive(Debug)]
#[must_use]
pub struct LlvmObjcopy {
cmd: Command,
}

crate::macros::impl_common_helpers!(LlvmReadobj);
crate::macros::impl_common_helpers!(LlvmProfdata);
crate::macros::impl_common_helpers!(LlvmFilecheck);
Expand All @@ -132,6 +158,8 @@ crate::macros::impl_common_helpers!(LlvmNm);
crate::macros::impl_common_helpers!(LlvmBcanalyzer);
crate::macros::impl_common_helpers!(LlvmDwarfdump);
crate::macros::impl_common_helpers!(LlvmPdbutil);
crate::macros::impl_common_helpers!(LlvmDis);
crate::macros::impl_common_helpers!(LlvmObjcopy);

/// Generate the path to the bin directory of LLVM.
#[must_use]
Expand Down Expand Up @@ -390,3 +418,41 @@ impl LlvmPdbutil {
self
}
}

impl LlvmObjcopy {
/// Construct a new `llvm-objcopy` invocation. This assumes that `llvm-objcopy` is available
/// at `$LLVM_BIN_DIR/llvm-objcopy`.
pub fn new() -> Self {
let llvm_objcopy = llvm_bin_dir().join("llvm-objcopy");
let cmd = Command::new(llvm_objcopy);
Self { cmd }
}

/// Dump the contents of `section` into the file at `path`.
#[track_caller]
pub fn dump_section<S: AsRef<str>, P: AsRef<Path>>(
&mut self,
section_name: S,
path: P,
) -> &mut Self {
self.cmd.arg("--dump-section");
self.cmd.arg(format!("{}={}", section_name.as_ref(), path.as_ref().to_str().unwrap()));
self
}
}

impl LlvmDis {
/// Construct a new `llvm-dis` invocation. This assumes that `llvm-dis` is available
/// at `$LLVM_BIN_DIR/llvm-dis`.
pub fn new() -> Self {
let llvm_dis = llvm_bin_dir().join("llvm-dis");
let cmd = Command::new(llvm_dis);
Self { cmd }
}

/// Provide an input file.
pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self.cmd.arg(path.as_ref());
self
}
}
11 changes: 7 additions & 4 deletions src/tools/run-make-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,17 @@ pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rust

// These rely on external dependencies.
pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc};
pub use c_build::{build_native_dynamic_lib, build_native_static_lib, build_native_static_lib_optimized, build_native_static_lib_cxx};
pub use c_build::{
build_native_dynamic_lib, build_native_static_lib, build_native_static_lib_cxx,
build_native_static_lib_optimized,
};
pub use cargo::cargo;
pub use clang::{clang, Clang};
pub use htmldocck::htmldocck;
pub use llvm::{
llvm_ar, llvm_bcanalyzer, llvm_dwarfdump, llvm_filecheck, llvm_nm, llvm_objdump, llvm_profdata,
llvm_readobj, LlvmAr, LlvmBcanalyzer, LlvmDwarfdump, LlvmFilecheck, LlvmNm, LlvmObjdump,
LlvmProfdata, LlvmReadobj,
llvm_ar, llvm_bcanalyzer, llvm_dis, llvm_dwarfdump, llvm_filecheck, llvm_nm, llvm_objcopy,
llvm_objdump, llvm_profdata, llvm_readobj, LlvmAr, LlvmBcanalyzer, LlvmDis, LlvmDwarfdump,
LlvmFilecheck, LlvmNm, LlvmObjcopy, LlvmObjdump, LlvmProfdata, LlvmReadobj,
};
pub use python::python_command;
pub use rustc::{aux_build, bare_rustc, rustc, rustc_path, Rustc};
Expand Down
1 change: 0 additions & 1 deletion src/tools/tidy/src/allowed_run_make_makefiles.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ run-make/branch-protection-check-IBT/Makefile
run-make/cat-and-grep-sanity-check/Makefile
run-make/extern-fn-reachable/Makefile
run-make/incr-add-rust-src-component/Makefile
run-make/issue-84395-lto-embed-bitcode/Makefile
run-make/jobserver-error/Makefile
run-make/libs-through-symlinks/Makefile
run-make/split-debuginfo/Makefile
Expand Down
84 changes: 61 additions & 23 deletions tests/run-make/cross-lang-lto-riscv-abi/rmake.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
//! Make sure that cross-language LTO works on riscv targets,
//! which requires extra `target-abi` metadata to be emitted.
//! Make sure that cross-language LTO works on riscv targets, which requires extra `target-abi`
//! metadata to be emitted.
//@ needs-force-clang-based-tests
//@ needs-llvm-components riscv
//@ needs-llvm-components: riscv

//@ needs-force-clang-based-tests
// FIXME(#126180): This test can only run on `x86_64-gnu-debug`, because that CI job sets
// RUSTBUILD_FORCE_CLANG_BASED_TESTS and only runs tests which contain "clang" in their
// name.
// However, this test does not run at all as its name does not contain "clang".

use std::path::PathBuf;
use std::process::{Command, Output};
use std::{env, str};
// ignore-tidy-linelength

use run_make_support::{bin_name, clang, llvm_readobj, rustc};
use object::elf;
use object::read::elf as readelf;
use run_make_support::{bin_name, clang, object, rfs, rustc};

fn check_target(target: &str, clang_target: &str, carch: &str, is_double_float: bool) {
fn check_target<H: readelf::FileHeader<Endian = object::Endianness>>(
target: &str,
clang_target: &str,
carch: &str,
is_double_float: bool,
) {
eprintln!("Checking target {target}");
// Rust part
rustc()
Expand All @@ -39,16 +38,55 @@ fn check_target(target: &str, clang_target: &str, carch: &str, is_double_float:

// Check that the built binary has correct float abi
let executable = bin_name("riscv-xlto");
let output = llvm_readobj().input(&executable).file_header().run();
let stdout = String::from_utf8_lossy(&output.stdout);
eprintln!("obj:\n{}", stdout);

assert!(!(is_double_float ^ stdout.contains("EF_RISCV_FLOAT_ABI_DOUBLE")));
let data = rfs::read(&executable);
let header = <H>::parse(&*data).unwrap();
let endian = match header.e_ident().data {
elf::ELFDATA2LSB => object::Endianness::Little,
elf::ELFDATA2MSB => object::Endianness::Big,
x => unreachable!("invalid e_ident data: {:#010b}", x),
};
// Check `(e_flags & EF_RISCV_FLOAT_ABI) == EF_RISCV_FLOAT_ABI_DOUBLE`.
//
// See
// <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#elf-object-files>.
if is_double_float {
assert_eq!(
header.e_flags(endian) & elf::EF_RISCV_FLOAT_ABI,
elf::EF_RISCV_FLOAT_ABI_DOUBLE,
"expected {target} to use double ABI, but it did not"
);
} else {
assert_ne!(
header.e_flags(endian) & elf::EF_RISCV_FLOAT_ABI,
elf::EF_RISCV_FLOAT_ABI_DOUBLE,
"did not expected {target} to use double ABI"
);
}
}

fn main() {
check_target("riscv64gc-unknown-linux-gnu", "riscv64-linux-gnu", "rv64gc", true);
check_target("riscv64imac-unknown-none-elf", "riscv64-unknown-elf", "rv64imac", false);
check_target("riscv32imac-unknown-none-elf", "riscv32-unknown-elf", "rv32imac", false);
check_target("riscv32gc-unknown-linux-gnu", "riscv32-linux-gnu", "rv32gc", true);
check_target::<elf::FileHeader64<object::Endianness>>(
"riscv64gc-unknown-linux-gnu",
"riscv64-linux-gnu",
"rv64gc",
true,
);
check_target::<elf::FileHeader64<object::Endianness>>(
"riscv64imac-unknown-none-elf",
"riscv64-unknown-elf",
"rv64imac",
false,
);
check_target::<elf::FileHeader32<object::Endianness>>(
"riscv32imac-unknown-none-elf",
"riscv32-unknown-elf",
"rv32imac",
false,
);
check_target::<elf::FileHeader32<object::Endianness>>(
"riscv32gc-unknown-linux-gnu",
"riscv32-linux-gnu",
"rv32gc",
true,
);
}
14 changes: 0 additions & 14 deletions tests/run-make/issue-84395-lto-embed-bitcode/Makefile

This file was deleted.

27 changes: 27 additions & 0 deletions tests/run-make/issue-84395-lto-embed-bitcode/rmake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//! Smoke test to make sure the embed bitcode in elf created with
//! `--plugin-opt=-lto-embed-bitcode=optimized` is valid llvm BC module.
//!
//! See <https://github.com/rust-lang/rust/issues/84395> where passing
//! `-lto-embed-bitcode=optimized` to lld when linking rust code via `linker-plugin-lto` doesn't
//! produce the expected result.
//!
//! See PR <https://github.com/rust-lang/rust/pull/98162> which initially introduced this test.

//@ needs-force-clang-based-tests

use run_make_support::{env_var, llvm_dis, llvm_objcopy, rustc};

fn main() {
rustc()
.input("test.rs")
.arg("-Clink-arg=-fuse-ld=lld")
.arg("-Clinker-plugin-lto")
.arg(format!("-Clinker={}", env_var("CLANG")))
.arg("-Clink-arg=-Wl,--plugin-opt=-lto-embed-bitcode=optimized")
.arg("-Zemit-thin-lto=no")
.run();

llvm_objcopy().dump_section(".llvmbc", "test.bc").arg("test").run();

llvm_dis().arg("test.bc").run();
}
Loading