mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-25 08:14:12 +00:00
Add framework for compiler tests (#118)
This commit is contained in:
parent
53b22b9fc3
commit
8681464af7
1
.github/workflows/ci.yaml
vendored
1
.github/workflows/ci.yaml
vendored
@ -32,6 +32,7 @@ jobs:
|
||||
# Runs separately to add spir-v tools to Powershell's Path.
|
||||
run: echo "$HOME/spirv-tools/install/bin" >> $env:GITHUB_PATH
|
||||
- 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
|
||||
- if: ${{ runner.os == 'macOS' }}
|
||||
run: cargo test --workspace --exclude example-runner
|
||||
|
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1195,6 +1195,7 @@ dependencies = [
|
||||
name = "spirv-builder"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
"raw-string",
|
||||
"rustc_codegen_spirv",
|
||||
|
@ -4,6 +4,12 @@ version = "0.1.0"
|
||||
authors = ["Embark <opensource@embark-studios.com>"]
|
||||
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]
|
||||
ash = "0.31"
|
||||
ash-window = "0.5"
|
||||
|
@ -6,6 +6,9 @@ edition = "2018"
|
||||
|
||||
[lib]
|
||||
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]
|
||||
spirv-std = { path = "../../spirv-std" }
|
||||
|
@ -347,16 +347,23 @@ fn create_archive(files: &[&Path], metadata: &[u8], out_filename: &Path) {
|
||||
}
|
||||
|
||||
pub fn read_metadata(rlib: &Path) -> Result<MetadataRef, String> {
|
||||
for entry in Archive::new(File::open(rlib).unwrap()).entries().unwrap() {
|
||||
let mut entry = entry.unwrap();
|
||||
if entry.path().unwrap() == Path::new(".metadata") {
|
||||
let mut bytes = Vec::new();
|
||||
entry.read_to_end(&mut bytes).unwrap();
|
||||
let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(bytes);
|
||||
return Ok(rustc_erase_owner!(buf.map_owner_box()));
|
||||
fn read_metadata_internal(rlib: &Path) -> Result<Option<MetadataRef>, std::io::Error> {
|
||||
for entry in Archive::new(File::open(rlib)?).entries()? {
|
||||
let mut entry = entry?;
|
||||
if entry.path()? == Path::new(".metadata") {
|
||||
let mut bytes = Vec::new();
|
||||
entry.read_to_end(&mut bytes)?;
|
||||
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
|
||||
|
@ -13,3 +13,6 @@ serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
# See comment in lib.rs invoke_rustc for why this is here
|
||||
rustc_codegen_spirv = { path = "../rustc_codegen_spirv" }
|
||||
|
||||
[dev-dependencies]
|
||||
lazy_static = "1.4"
|
||||
|
@ -1,3 +1,6 @@
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
mod depfile;
|
||||
|
||||
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.
|
||||
pub fn print_metadata(&mut self, v: bool) -> &mut Self {
|
||||
pub fn print_metadata(mut self, v: bool) -> Self {
|
||||
self.print_metadata = v;
|
||||
self
|
||||
}
|
||||
|
11
spirv-builder/src/test/basic.rs
Normal file
11
spirv-builder/src/test/basic.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use super::val;
|
||||
|
||||
#[test]
|
||||
fn hello_world() {
|
||||
val(r#"
|
||||
#[allow(unused_attributes)]
|
||||
#[spirv(entry = "fragment")]
|
||||
pub fn main() {
|
||||
}
|
||||
"#);
|
||||
}
|
69
spirv-builder/src/test/mod.rs
Normal file
69
spirv-builder/src/test/mod.rs
Normal 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);
|
||||
}
|
@ -6,4 +6,8 @@ edition = "2018"
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/EmbarkStudios/rust-gpu"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
test = false
|
||||
|
||||
[dependencies]
|
||||
|
Loading…
Reference in New Issue
Block a user