Add framework for compiler tests (#118)

This commit is contained in:
Ashley Hauck 2020-10-23 18:22:36 +02:00 committed by GitHub
parent 53b22b9fc3
commit 8681464af7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 117 additions and 9 deletions

View File

@ -32,6 +32,7 @@ jobs:
# Runs separately to add spir-v tools to Powershell's Path. # Runs separately to add spir-v tools to Powershell's Path.
run: echo "$HOME/spirv-tools/install/bin" >> $env:GITHUB_PATH run: echo "$HOME/spirv-tools/install/bin" >> $env:GITHUB_PATH
- run: rustup component add rust-src rustc-dev llvm-tools-preview - run: rustup component add rust-src rustc-dev llvm-tools-preview
- run: cargo build -p example-runner
# See: https://github.com/EmbarkStudios/rust-gpu/issues/84 # See: https://github.com/EmbarkStudios/rust-gpu/issues/84
- if: ${{ runner.os == 'macOS' }} - if: ${{ runner.os == 'macOS' }}
run: cargo test --workspace --exclude example-runner run: cargo test --workspace --exclude example-runner

1
Cargo.lock generated
View File

@ -1195,6 +1195,7 @@ dependencies = [
name = "spirv-builder" name = "spirv-builder"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"lazy_static",
"memchr", "memchr",
"raw-string", "raw-string",
"rustc_codegen_spirv", "rustc_codegen_spirv",

View File

@ -4,6 +4,12 @@ version = "0.1.0"
authors = ["Embark <opensource@embark-studios.com>"] authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018" edition = "2018"
# Note: Don't include this section in your own crates, these are just included here because our repo setup is weird.
[[bin]]
name = "example-runner"
doctest = false
test = false
[dependencies] [dependencies]
ash = "0.31" ash = "0.31"
ash-window = "0.5" ash-window = "0.5"

View File

@ -6,6 +6,9 @@ edition = "2018"
[lib] [lib]
crate-type = ["dylib"] crate-type = ["dylib"]
# Note: Don't include these two lines in your own crates, these are just included here because our repo setup is weird.
doctest = false
test = false
[dependencies] [dependencies]
spirv-std = { path = "../../spirv-std" } spirv-std = { path = "../../spirv-std" }

View File

@ -347,16 +347,23 @@ fn create_archive(files: &[&Path], metadata: &[u8], out_filename: &Path) {
} }
pub fn read_metadata(rlib: &Path) -> Result<MetadataRef, String> { pub fn read_metadata(rlib: &Path) -> Result<MetadataRef, String> {
for entry in Archive::new(File::open(rlib).unwrap()).entries().unwrap() { fn read_metadata_internal(rlib: &Path) -> Result<Option<MetadataRef>, std::io::Error> {
let mut entry = entry.unwrap(); for entry in Archive::new(File::open(rlib)?).entries()? {
if entry.path().unwrap() == Path::new(".metadata") { let mut entry = entry?;
let mut bytes = Vec::new(); if entry.path()? == Path::new(".metadata") {
entry.read_to_end(&mut bytes).unwrap(); let mut bytes = Vec::new();
let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(bytes); entry.read_to_end(&mut bytes)?;
return Ok(rustc_erase_owner!(buf.map_owner_box())); let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(bytes);
return Ok(Some(rustc_erase_owner!(buf.map_owner_box())));
}
} }
Ok(None)
}
match read_metadata_internal(rlib) {
Ok(Some(m)) => Ok(m),
Ok(None) => Err(format!("No .metadata file in rlib: {:?}", rlib)),
Err(io) => Err(format!("Failed to read rlib at {:?}: {}", rlib, io)),
} }
Err(format!("No .metadata file in rlib: {:?}", rlib))
} }
/// This is the actual guts of linking: the rest of the link-related functions are just digging through rustc's /// This is the actual guts of linking: the rest of the link-related functions are just digging through rustc's

View File

@ -13,3 +13,6 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
# See comment in lib.rs invoke_rustc for why this is here # See comment in lib.rs invoke_rustc for why this is here
rustc_codegen_spirv = { path = "../rustc_codegen_spirv" } rustc_codegen_spirv = { path = "../rustc_codegen_spirv" }
[dev-dependencies]
lazy_static = "1.4"

View File

@ -1,3 +1,6 @@
#[cfg(test)]
mod test;
mod depfile; mod depfile;
use raw_string::{RawStr, RawString}; use raw_string::{RawStr, RawString};
@ -37,7 +40,7 @@ impl SpirvBuilder {
} }
/// Whether to print build.rs cargo metadata (e.g. cargo:rustc-env=var=val). Defaults to true. /// Whether to print build.rs cargo metadata (e.g. cargo:rustc-env=var=val). Defaults to true.
pub fn print_metadata(&mut self, v: bool) -> &mut Self { pub fn print_metadata(mut self, v: bool) -> Self {
self.print_metadata = v; self.print_metadata = v;
self self
} }

View File

@ -0,0 +1,11 @@
use super::val;
#[test]
fn hello_world() {
val(r#"
#[allow(unused_attributes)]
#[spirv(entry = "fragment")]
pub fn main() {
}
"#);
}

View File

@ -0,0 +1,69 @@
mod basic;
use lazy_static::lazy_static;
use std::error::Error;
use std::path::{Path, PathBuf};
use std::sync::Mutex;
// Tests need to run serially, since they write project files to disk and whatnot. We don't want to
// create a new temp dir for every test, though, since then every test would need to build libcore.
// We could require the user to pass --thread-count 1 to cargo test, but that affects other tests.
// So make a global mutex wrapping every test.
lazy_static! {
static ref GLOBAL_MUTEX: Mutex<()> = Mutex::new(());
}
static CARGO_TOML: &str = r#"[package]
name = "test-project"
version = "0.1.0"
authors = ["Embark <opensource@embark-studios.com>"]
edition = "2018"
[lib]
crate-type = ["dylib"]
[dependencies]
spirv-std = { path = "../../spirv-std" }
[workspace]
"#;
static SRC_PREFIX: &str = r#"#![no_std]
#![feature(lang_items, register_attr)]
#![register_attr(spirv)]
use core::panic::PanicInfo;
use spirv_std::*;
#[panic_handler]
fn panic(_: &PanicInfo) -> ! {
loop {}
}
#[lang = "eh_personality"]
extern "C" fn rust_eh_personality() {}
"#;
fn setup(src: &str) -> Result<PathBuf, Box<dyn Error>> {
let project = Path::new("../target/test-spirv").to_owned();
let cargo_toml = project.join("Cargo.toml");
let lib_rs = project.join("src/lib.rs");
std::fs::create_dir_all(lib_rs.parent().unwrap())?;
// don't write cargo.toml if unchanged, so it doesn't get deps refreshed
if std::fs::read(&cargo_toml).map_or(true, |b| b != CARGO_TOML.as_bytes()) {
std::fs::write(cargo_toml, CARGO_TOML)?;
}
std::fs::write(lib_rs, format!("{}{}", SRC_PREFIX, src))?;
Ok(project)
}
fn build(src: &str) -> PathBuf {
let project = setup(src).expect("Failed to set up project");
crate::SpirvBuilder::new(&project)
.print_metadata(false)
.build()
.expect("Failed to build test")
}
fn val(src: &str) {
let _lock = GLOBAL_MUTEX.lock().unwrap();
// spirv-val is included in building
build(src);
}

View File

@ -6,4 +6,8 @@ edition = "2018"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
repository = "https://github.com/EmbarkStudios/rust-gpu" repository = "https://github.com/EmbarkStudios/rust-gpu"
[lib]
doctest = false
test = false
[dependencies] [dependencies]