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.
|
# 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
1
Cargo.lock
generated
@ -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",
|
||||||
|
@ -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"
|
||||||
|
@ -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" }
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
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"
|
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]
|
||||||
|
Loading…
Reference in New Issue
Block a user