Skip to content

Commit e4b1ad8

Browse files
authored
Merge pull request #25 from tombh/refactor-files-lints
Put commands in their own files and some stricter lints
2 parents 4462c42 + f0fc1ea commit e4b1ad8

File tree

11 files changed

+831
-713
lines changed

11 files changed

+831
-713
lines changed

.github/workflows/push.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
name: push
22

3-
on:
3+
on:
44
push:
5-
branches:
5+
branches:
66
- main
77
pull_request:
88

@@ -13,18 +13,18 @@ env:
1313
jobs:
1414
install-and-build-shaders:
1515
strategy:
16-
matrix:
16+
matrix:
1717
os: [ubuntu-latest, macos-latest, windows-latest]
1818
runs-on: ${{ matrix.os }}
1919
defaults:
20-
run:
20+
run:
2121
shell: bash
22-
env:
22+
env:
2323
RUST_LOG: debug
2424
steps:
2525
- uses: actions/checkout@v2
2626
- uses: moonrepo/setup-rust@v1
27-
- run: rustup default stable
27+
- run: rustup default stable
2828
- run: rustup update
2929
- run: cargo test
3030
- run: cargo install --path crates/cargo-gpu

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@ test_output
1717
cmy_triangle_renderer.svg
1818
.aider*
1919
flamegraph.svg
20+
21+
# Compiled shader assets from running tests
22+
crates/shader-crate-template/shaders

Cargo.toml

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[workspace]
22
members = [
3-
"crates/cargo-gpu",
3+
"crates/cargo-gpu",
44
"crates/shader-crate-template"
55
]
66

@@ -21,3 +21,32 @@ relative-path = "1.9.3"
2121
serde = { version = "1.0.214", features = ["derive"] }
2222
serde_json = "1.0.132"
2323
toml = "0.8.19"
24+
25+
[workspace.lints.rust]
26+
missing_docs = "warn"
27+
28+
[workspace.lints.clippy]
29+
all = { level = "warn", priority = 0 }
30+
pedantic = { level = "warn", priority = 0 }
31+
nursery = { level = "warn", priority = 0 }
32+
cargo = { level = "warn", priority = 0 }
33+
restriction = { level = "warn", priority = 0 }
34+
blanket_clippy_restriction_lints = { level = "allow", priority = 1 }
35+
36+
arithmetic_side_effects = { level = "allow", priority = 1 }
37+
absolute_paths = { level = "allow", priority = 1 }
38+
cargo_common_metadata = { level = "allow", priority = 1 }
39+
implicit_return = { level = "allow", priority = 1 }
40+
single_call_fn = { level = "allow", priority = 1 }
41+
question_mark_used = { level = "allow", priority = 1 }
42+
multiple_crate_versions = { level = "allow", priority = 1 }
43+
pub_with_shorthand = { level = "allow", priority = 1 }
44+
partial_pub_fields = { level = "allow", priority = 1 }
45+
pattern_type_mismatch = { level = "allow", priority = 1 }
46+
print_stdout = { level = "allow", priority = 1 }
47+
std_instead_of_alloc = { level = "allow", priority = 1 }
48+
49+
# TODO: Try to not depend on these lints
50+
unwrap_used = { level = "allow", priority = 1 }
51+
panic = { level = "allow", priority = 1 }
52+

crates/cargo-gpu/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ name = "cargo-gpu"
33
version = "0.1.0"
44
edition = "2021"
55
description = "Generates shader .spv files from rust-gpu shader crates"
6+
repository = "https://github.com/Rust-GPU/cargo-gpu"
67
readme = "../../README.md"
7-
8+
keywords = ["gpu", "compiler"]
89
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
910

1011
[dependencies]
@@ -33,3 +34,6 @@ codegen-units = 256
3334
opt-level = 3
3435
incremental = true
3536
codegen-units = 256
37+
38+
[lints]
39+
workspace = true

crates/cargo-gpu/src/build.rs

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
//! `cargo gpu build`, analogous to `cargo build`
2+
3+
use std::io::Write as _;
4+
5+
use clap::Parser;
6+
use spirv_builder_cli::{Linkage, ShaderModule};
7+
8+
use crate::{install::Install, target_spec_dir};
9+
10+
/// `cargo build` subcommands
11+
#[derive(Parser, Debug)]
12+
pub struct Build {
13+
/// Install the `rust-gpu` compiler and components
14+
#[clap(flatten)]
15+
install: Install,
16+
17+
/// Directory containing the shader crate to compile.
18+
#[clap(long, default_value = "./")]
19+
pub shader_crate: std::path::PathBuf,
20+
21+
/// Shader target.
22+
#[clap(long, default_value = "spirv-unknown-vulkan1.2")]
23+
shader_target: String,
24+
25+
/// Set cargo default-features.
26+
#[clap(long)]
27+
no_default_features: bool,
28+
29+
/// Set cargo features.
30+
#[clap(long)]
31+
features: Vec<String>,
32+
33+
/// Path to the output directory for the compiled shaders.
34+
#[clap(long, short, default_value = "./")]
35+
pub output_dir: std::path::PathBuf,
36+
}
37+
38+
impl Build {
39+
/// Entrypoint
40+
pub fn run(&mut self) {
41+
let (dylib_path, spirv_builder_cli_path) = self.install.run();
42+
43+
// Ensure the shader output dir exists
44+
log::debug!("ensuring output-dir '{}' exists", self.output_dir.display());
45+
std::fs::create_dir_all(&self.output_dir).unwrap();
46+
self.output_dir = self.output_dir.canonicalize().unwrap();
47+
48+
// Ensure the shader crate exists
49+
self.shader_crate = self.shader_crate.canonicalize().unwrap();
50+
assert!(
51+
self.shader_crate.exists(),
52+
"shader crate '{}' does not exist. (Current dir is '{}')",
53+
self.shader_crate.display(),
54+
std::env::current_dir().unwrap().display()
55+
);
56+
57+
let spirv_builder_args = spirv_builder_cli::Args {
58+
dylib_path,
59+
shader_crate: self.shader_crate.clone(),
60+
shader_target: self.shader_target.clone(),
61+
path_to_target_spec: target_spec_dir().join(format!("{}.json", self.shader_target)),
62+
no_default_features: self.no_default_features,
63+
features: self.features.clone(),
64+
output_dir: self.output_dir.clone(),
65+
};
66+
67+
// UNWRAP: safe because we know this always serializes
68+
let arg = serde_json::to_string_pretty(&spirv_builder_args).unwrap();
69+
log::info!("using spirv-builder-cli arg: {arg}");
70+
71+
// Call spirv-builder-cli to compile the shaders.
72+
let output = std::process::Command::new(spirv_builder_cli_path)
73+
.arg(arg)
74+
.stdout(std::process::Stdio::inherit())
75+
.stderr(std::process::Stdio::inherit())
76+
.output()
77+
.unwrap();
78+
assert!(output.status.success(), "build failed");
79+
80+
let spirv_manifest = self.output_dir.join("spirv-manifest.json");
81+
if spirv_manifest.is_file() {
82+
log::debug!(
83+
"successfully built shaders, raw manifest is at '{}'",
84+
spirv_manifest.display()
85+
);
86+
} else {
87+
log::error!("missing raw manifest '{}'", spirv_manifest.display());
88+
panic!("missing raw manifest");
89+
}
90+
91+
let shaders: Vec<ShaderModule> =
92+
serde_json::from_reader(std::fs::File::open(&spirv_manifest).unwrap()).unwrap();
93+
94+
let mut linkage: Vec<_> = shaders
95+
.into_iter()
96+
.map(
97+
|ShaderModule {
98+
entry,
99+
path: filepath,
100+
}| {
101+
use relative_path::PathExt as _;
102+
let path = self.output_dir.join(filepath.file_name().unwrap());
103+
std::fs::copy(&filepath, &path).unwrap();
104+
let path_relative_to_shader_crate =
105+
path.relative_to(&self.shader_crate).unwrap().to_path("");
106+
Linkage::new(entry, path_relative_to_shader_crate)
107+
},
108+
)
109+
.collect();
110+
111+
// Write the shader manifest json file
112+
let manifest_path = self.output_dir.join("manifest.json");
113+
// Sort the contents so the output is deterministic
114+
linkage.sort();
115+
// UNWRAP: safe because we know this always serializes
116+
let json = serde_json::to_string_pretty(&linkage).unwrap();
117+
let mut file = std::fs::File::create(&manifest_path).unwrap_or_else(|error| {
118+
log::error!(
119+
"could not create shader manifest file '{}': {error}",
120+
manifest_path.display(),
121+
);
122+
panic!("{error}")
123+
});
124+
file.write_all(json.as_bytes()).unwrap_or_else(|error| {
125+
log::error!(
126+
"could not write shader manifest file '{}': {error}",
127+
manifest_path.display(),
128+
);
129+
panic!("{error}")
130+
});
131+
132+
log::info!("wrote manifest to '{}'", manifest_path.display());
133+
134+
if spirv_manifest.is_file() {
135+
log::debug!(
136+
"removing spirv-manifest.json file '{}'",
137+
spirv_manifest.display()
138+
);
139+
std::fs::remove_file(spirv_manifest).unwrap();
140+
}
141+
}
142+
}

0 commit comments

Comments
 (0)