Skip to content

Commit

Permalink
Merge pull request #25 from tombh/refactor-files-lints
Browse files Browse the repository at this point in the history
Put commands in their own files and some stricter lints
  • Loading branch information
schell authored Dec 15, 2024
2 parents 4462c42 + f0fc1ea commit e4b1ad8
Show file tree
Hide file tree
Showing 11 changed files with 831 additions and 713 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/push.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name: push

on:
on:
push:
branches:
branches:
- main
pull_request:

Expand All @@ -13,18 +13,18 @@ env:
jobs:
install-and-build-shaders:
strategy:
matrix:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
defaults:
run:
run:
shell: bash
env:
env:
RUST_LOG: debug
steps:
- uses: actions/checkout@v2
- uses: moonrepo/setup-rust@v1
- run: rustup default stable
- run: rustup default stable
- run: rustup update
- run: cargo test
- run: cargo install --path crates/cargo-gpu
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ test_output
cmy_triangle_renderer.svg
.aider*
flamegraph.svg

# Compiled shader assets from running tests
crates/shader-crate-template/shaders
31 changes: 30 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[workspace]
members = [
"crates/cargo-gpu",
"crates/cargo-gpu",
"crates/shader-crate-template"
]

Expand All @@ -21,3 +21,32 @@ relative-path = "1.9.3"
serde = { version = "1.0.214", features = ["derive"] }
serde_json = "1.0.132"
toml = "0.8.19"

[workspace.lints.rust]
missing_docs = "warn"

[workspace.lints.clippy]
all = { level = "warn", priority = 0 }
pedantic = { level = "warn", priority = 0 }
nursery = { level = "warn", priority = 0 }
cargo = { level = "warn", priority = 0 }
restriction = { level = "warn", priority = 0 }
blanket_clippy_restriction_lints = { level = "allow", priority = 1 }

arithmetic_side_effects = { level = "allow", priority = 1 }
absolute_paths = { level = "allow", priority = 1 }
cargo_common_metadata = { level = "allow", priority = 1 }
implicit_return = { level = "allow", priority = 1 }
single_call_fn = { level = "allow", priority = 1 }
question_mark_used = { level = "allow", priority = 1 }
multiple_crate_versions = { level = "allow", priority = 1 }
pub_with_shorthand = { level = "allow", priority = 1 }
partial_pub_fields = { level = "allow", priority = 1 }
pattern_type_mismatch = { level = "allow", priority = 1 }
print_stdout = { level = "allow", priority = 1 }
std_instead_of_alloc = { level = "allow", priority = 1 }

# TODO: Try to not depend on these lints
unwrap_used = { level = "allow", priority = 1 }
panic = { level = "allow", priority = 1 }

6 changes: 5 additions & 1 deletion crates/cargo-gpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ name = "cargo-gpu"
version = "0.1.0"
edition = "2021"
description = "Generates shader .spv files from rust-gpu shader crates"
repository = "https://github.com/Rust-GPU/cargo-gpu"
readme = "../../README.md"

keywords = ["gpu", "compiler"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
Expand Down Expand Up @@ -33,3 +34,6 @@ codegen-units = 256
opt-level = 3
incremental = true
codegen-units = 256

[lints]
workspace = true
142 changes: 142 additions & 0 deletions crates/cargo-gpu/src/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
//! `cargo gpu build`, analogous to `cargo build`
use std::io::Write as _;

use clap::Parser;
use spirv_builder_cli::{Linkage, ShaderModule};

use crate::{install::Install, target_spec_dir};

/// `cargo build` subcommands
#[derive(Parser, Debug)]
pub struct Build {
/// Install the `rust-gpu` compiler and components
#[clap(flatten)]
install: Install,

/// Directory containing the shader crate to compile.
#[clap(long, default_value = "./")]
pub shader_crate: std::path::PathBuf,

/// Shader target.
#[clap(long, default_value = "spirv-unknown-vulkan1.2")]
shader_target: String,

/// Set cargo default-features.
#[clap(long)]
no_default_features: bool,

/// Set cargo features.
#[clap(long)]
features: Vec<String>,

/// Path to the output directory for the compiled shaders.
#[clap(long, short, default_value = "./")]
pub output_dir: std::path::PathBuf,
}

impl Build {
/// Entrypoint
pub fn run(&mut self) {
let (dylib_path, spirv_builder_cli_path) = self.install.run();

// Ensure the shader output dir exists
log::debug!("ensuring output-dir '{}' exists", self.output_dir.display());
std::fs::create_dir_all(&self.output_dir).unwrap();
self.output_dir = self.output_dir.canonicalize().unwrap();

// Ensure the shader crate exists
self.shader_crate = self.shader_crate.canonicalize().unwrap();
assert!(
self.shader_crate.exists(),
"shader crate '{}' does not exist. (Current dir is '{}')",
self.shader_crate.display(),
std::env::current_dir().unwrap().display()
);

let spirv_builder_args = spirv_builder_cli::Args {
dylib_path,
shader_crate: self.shader_crate.clone(),
shader_target: self.shader_target.clone(),
path_to_target_spec: target_spec_dir().join(format!("{}.json", self.shader_target)),
no_default_features: self.no_default_features,
features: self.features.clone(),
output_dir: self.output_dir.clone(),
};

// UNWRAP: safe because we know this always serializes
let arg = serde_json::to_string_pretty(&spirv_builder_args).unwrap();
log::info!("using spirv-builder-cli arg: {arg}");

// Call spirv-builder-cli to compile the shaders.
let output = std::process::Command::new(spirv_builder_cli_path)
.arg(arg)
.stdout(std::process::Stdio::inherit())
.stderr(std::process::Stdio::inherit())
.output()
.unwrap();
assert!(output.status.success(), "build failed");

let spirv_manifest = self.output_dir.join("spirv-manifest.json");
if spirv_manifest.is_file() {
log::debug!(
"successfully built shaders, raw manifest is at '{}'",
spirv_manifest.display()
);
} else {
log::error!("missing raw manifest '{}'", spirv_manifest.display());
panic!("missing raw manifest");
}

let shaders: Vec<ShaderModule> =
serde_json::from_reader(std::fs::File::open(&spirv_manifest).unwrap()).unwrap();

let mut linkage: Vec<_> = shaders
.into_iter()
.map(
|ShaderModule {
entry,
path: filepath,
}| {
use relative_path::PathExt as _;
let path = self.output_dir.join(filepath.file_name().unwrap());
std::fs::copy(&filepath, &path).unwrap();
let path_relative_to_shader_crate =
path.relative_to(&self.shader_crate).unwrap().to_path("");
Linkage::new(entry, path_relative_to_shader_crate)
},
)
.collect();

// Write the shader manifest json file
let manifest_path = self.output_dir.join("manifest.json");
// Sort the contents so the output is deterministic
linkage.sort();
// UNWRAP: safe because we know this always serializes
let json = serde_json::to_string_pretty(&linkage).unwrap();
let mut file = std::fs::File::create(&manifest_path).unwrap_or_else(|error| {
log::error!(
"could not create shader manifest file '{}': {error}",
manifest_path.display(),
);
panic!("{error}")
});
file.write_all(json.as_bytes()).unwrap_or_else(|error| {
log::error!(
"could not write shader manifest file '{}': {error}",
manifest_path.display(),
);
panic!("{error}")
});

log::info!("wrote manifest to '{}'", manifest_path.display());

if spirv_manifest.is_file() {
log::debug!(
"removing spirv-manifest.json file '{}'",
spirv_manifest.display()
);
std::fs::remove_file(spirv_manifest).unwrap();
}
}
}
Loading

0 comments on commit e4b1ad8

Please sign in to comment.