2022-04-25 07:19:42 -05:00
|
|
|
//! The common code for `tests/lang_tests_*.rs`
|
2020-05-10 09:54:30 -05:00
|
|
|
use std::{
|
|
|
|
env::{self, current_dir},
|
2023-10-19 06:48:42 -05:00
|
|
|
path::{Path, PathBuf},
|
|
|
|
process::Command,
|
2020-05-10 09:54:30 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
use lang_tester::LangTester;
|
|
|
|
use tempfile::TempDir;
|
|
|
|
|
2022-04-25 07:19:42 -05:00
|
|
|
/// Controls the compile options (e.g., optimization level) used to compile
|
|
|
|
/// test code.
|
|
|
|
#[allow(dead_code)] // Each test crate picks one variant
|
|
|
|
pub enum Profile {
|
|
|
|
Debug,
|
|
|
|
Release,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn main_inner(profile: Profile) {
|
2020-05-10 09:54:30 -05:00
|
|
|
let tempdir = TempDir::new().expect("temp dir");
|
|
|
|
let current_dir = current_dir().expect("current dir");
|
|
|
|
let current_dir = current_dir.to_str().expect("current dir").to_string();
|
|
|
|
let gcc_path = include_str!("../gcc_path");
|
|
|
|
let gcc_path = gcc_path.trim();
|
|
|
|
env::set_var("LD_LIBRARY_PATH", gcc_path);
|
2023-10-19 06:48:42 -05:00
|
|
|
|
|
|
|
fn rust_filter(filename: &Path) -> bool {
|
|
|
|
filename.extension().expect("extension").to_str().expect("to_str") == "rs"
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature="master")]
|
|
|
|
fn filter(filename: &Path) -> bool {
|
|
|
|
rust_filter(filename)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(feature="master"))]
|
|
|
|
fn filter(filename: &Path) -> bool {
|
|
|
|
if let Some(filename) = filename.to_str() {
|
|
|
|
if filename.ends_with("gep.rs") {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rust_filter(filename)
|
|
|
|
}
|
|
|
|
|
2020-05-10 09:54:30 -05:00
|
|
|
LangTester::new()
|
|
|
|
.test_dir("tests/run")
|
2023-10-19 06:48:42 -05:00
|
|
|
.test_file_filter(filter)
|
2020-05-10 09:54:30 -05:00
|
|
|
.test_extract(|source| {
|
|
|
|
let lines =
|
|
|
|
source.lines()
|
|
|
|
.skip_while(|l| !l.starts_with("//"))
|
|
|
|
.take_while(|l| l.starts_with("//"))
|
|
|
|
.map(|l| &l[2..])
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
.join("\n");
|
|
|
|
Some(lines)
|
|
|
|
})
|
|
|
|
.test_cmds(move |path| {
|
|
|
|
// Test command 1: Compile `x.rs` into `tempdir/x`.
|
|
|
|
let mut exe = PathBuf::new();
|
|
|
|
exe.push(&tempdir);
|
|
|
|
exe.push(path.file_stem().expect("file_stem"));
|
|
|
|
let mut compiler = Command::new("rustc");
|
|
|
|
compiler.args(&[
|
|
|
|
&format!("-Zcodegen-backend={}/target/debug/librustc_codegen_gcc.so", current_dir),
|
|
|
|
"--sysroot", &format!("{}/build_sysroot/sysroot/", current_dir),
|
|
|
|
"-Zno-parallel-llvm",
|
|
|
|
"-C", "link-arg=-lc",
|
|
|
|
"-o", exe.to_str().expect("to_str"),
|
|
|
|
path.to_str().expect("to_str"),
|
|
|
|
]);
|
2023-09-06 18:01:04 -05:00
|
|
|
|
|
|
|
// TODO(antoyo): find a way to send this via a cli argument.
|
|
|
|
let test_target = std::env::var("CG_GCC_TEST_TARGET");
|
|
|
|
if let Ok(ref target) = test_target {
|
|
|
|
compiler.args(&["--target", &target]);
|
|
|
|
let linker = format!("{}-gcc", target);
|
|
|
|
compiler.args(&[format!("-Clinker={}", linker)]);
|
|
|
|
let mut env_path = std::env::var("PATH").unwrap_or_default();
|
|
|
|
// TODO(antoyo): find a better way to add the PATH necessary locally.
|
|
|
|
env_path = format!("/opt/m68k-unknown-linux-gnu/bin:{}", env_path);
|
|
|
|
compiler.env("PATH", env_path);
|
|
|
|
}
|
|
|
|
|
2023-01-09 16:42:35 -06:00
|
|
|
if let Some(flags) = option_env!("TEST_FLAGS") {
|
|
|
|
for flag in flags.split_whitespace() {
|
|
|
|
compiler.arg(&flag);
|
|
|
|
}
|
|
|
|
}
|
2022-04-25 07:19:42 -05:00
|
|
|
match profile {
|
|
|
|
Profile::Debug => {}
|
|
|
|
Profile::Release => {
|
|
|
|
compiler.args(&[
|
|
|
|
"-C", "opt-level=3",
|
|
|
|
"-C", "lto=no",
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
}
|
2020-05-10 09:54:30 -05:00
|
|
|
// Test command 2: run `tempdir/x`.
|
2023-09-06 18:01:04 -05:00
|
|
|
if test_target.is_ok() {
|
|
|
|
let vm_parent_dir = std::env::var("CG_GCC_VM_DIR")
|
|
|
|
.map(|dir| PathBuf::from(dir))
|
|
|
|
.unwrap_or_else(|_| std::env::current_dir().unwrap());
|
|
|
|
let vm_dir = "vm";
|
|
|
|
let exe_filename = exe.file_name().unwrap();
|
|
|
|
let vm_home_dir = vm_parent_dir.join(vm_dir).join("home");
|
|
|
|
let vm_exe_path = vm_home_dir.join(exe_filename);
|
|
|
|
// FIXME(antoyo): panicking here makes the test pass.
|
|
|
|
let inside_vm_exe_path = PathBuf::from("/home").join(&exe_filename);
|
|
|
|
let mut copy = Command::new("sudo");
|
|
|
|
copy.arg("cp");
|
|
|
|
copy.args(&[&exe, &vm_exe_path]);
|
|
|
|
|
|
|
|
let mut runtime = Command::new("sudo");
|
|
|
|
runtime.args(&["chroot", vm_dir, "qemu-m68k-static"]);
|
|
|
|
runtime.arg(inside_vm_exe_path);
|
|
|
|
runtime.current_dir(vm_parent_dir);
|
|
|
|
vec![
|
|
|
|
("Compiler", compiler),
|
|
|
|
("Copy", copy),
|
|
|
|
("Run-time", runtime),
|
|
|
|
]
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
let runtime = Command::new(exe);
|
|
|
|
vec![
|
|
|
|
("Compiler", compiler),
|
|
|
|
("Run-time", runtime),
|
|
|
|
]
|
|
|
|
}
|
2020-05-10 09:54:30 -05:00
|
|
|
})
|
|
|
|
.run();
|
|
|
|
}
|