Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add root_path_env property to shaders macro #2180

Merged
merged 4 commits into from
Apr 11, 2023
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 48 additions & 5 deletions vulkano-shaders/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,15 @@
//! in conjunction with the `src` or `path` field. This allows using shaders compiled through a
//! separate build system.
//!
//! ## `root_path_env: "..."`
//!
//! Instead of searching relative to your `Cargo.toml`, search relative to some other folder
//! specified by this env variable. The intended use case is using `OUT_DIR` to be able to load
//! shaders generated by your build script. Defaults to `CARGO_MANIFEST_DIR` corresponding to the
//! folder of your `Cargo.toml`.
//!
//! See [`cargo-env-vars`] for a full set of env variables set by cargo.
//!
//! ## `shaders: { first: { src: "...", ty: "..." }, ... }`
//!
//! With these options the user can compile several shaders in a single macro invocation. Each
Expand Down Expand Up @@ -200,6 +209,7 @@
//! | `shaderc-build-from-source` | Build the `shaderc` library from source when compiling. |
//! | `shaderc-debug` | Compile shaders with debug information included. |
//!
//! [cargo-env-vars]: https://doc.rust-lang.org/cargo/reference/environment-variables.html
//! [cargo-expand]: /~https://github.com/dtolnay/cargo-expand
//! [`ShaderModule::from_words_with_data`]: vulkano::shader::ShaderModule::from_words_with_data
//! [`SpecializationConstants`]: vulkano::shader::SpecializationConstants
Expand Down Expand Up @@ -247,12 +257,34 @@ pub fn shader(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
}

fn shader_inner(mut input: MacroInput) -> Result<TokenStream> {
let root = env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".into());
let (root, relative_path_error_msg) = match input.root_path_env.as_ref() {
None => (
env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".into()),
"to your Cargo.toml".to_owned(),
),
Some(root_path_env) => {
let root = match env::var(root_path_env.value()) {
Ok(e) => e,
Err(e) => {
bail!(
root_path_env,
"env variable `{root_path_env:?}` provided by `root_path_env` parameter of \
the shader was {e:?}! Typical parameters are `OUT_DIR` to gather results \
from your build script, or left default to search relative to your Cargo.toml."
)
}
};
let env = root_path_env.value();
let error = format!("to the path `{root}` specified by the env variable `{env:?}`");
(root, error)
}
};

let root_path = Path::new(&root);
let shaders = mem::take(&mut input.shaders); // yoink

let mut shaders_code = Vec::with_capacity(input.shaders.len());
let mut types_code = Vec::with_capacity(input.shaders.len());
let mut shaders_code = Vec::with_capacity(shaders.len());
let mut types_code = Vec::with_capacity(shaders.len());
let mut type_registry = TypeRegistry::default();

for (name, (shader_kind, source_kind)) in shaders {
Expand All @@ -273,7 +305,7 @@ fn shader_inner(mut input: MacroInput) -> Result<TokenStream> {
bail!(
path,
"file `{full_path:?}` was not found, note that the path must be relative \
to your Cargo.toml",
{relative_path_error_msg}",
);
}

Expand Down Expand Up @@ -302,7 +334,7 @@ fn shader_inner(mut input: MacroInput) -> Result<TokenStream> {
bail!(
path,
"file `{full_path:?}` was not found, note that the path must be relative \
to your Cargo.toml",
{relative_path_error_msg}",
);
}

Expand Down Expand Up @@ -350,6 +382,7 @@ enum SourceKind {
}

struct MacroInput {
root_path_env: Option<LitStr>,
include_directories: Vec<PathBuf>,
macro_defines: Vec<(String, String)>,
shared_constants: bool,
Expand All @@ -365,6 +398,7 @@ impl MacroInput {
#[cfg(test)]
fn empty() -> Self {
MacroInput {
root_path_env: None,
include_directories: Vec::new(),
macro_defines: Vec::new(),
shared_constants: false,
Expand All @@ -382,6 +416,7 @@ impl Parse for MacroInput {
fn parse(input: ParseStream<'_>) -> Result<Self> {
let root = env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".into());

let mut root_path_env = None;
let mut include_directories = Vec::new();
let mut macro_defines = Vec::new();
let mut shared_constants = None;
Expand Down Expand Up @@ -583,6 +618,13 @@ impl Parse for MacroInput {
}
}
}
"root_path_env" => {
let lit = input.parse::<LitStr>()?;
if root_path_env.is_some() {
bail!(lit, "field `root_path_env` is already defined");
}
root_path_env = Some(lit);
}
"include" => {
let in_brackets;
bracketed!(in_brackets in input);
Expand Down Expand Up @@ -709,6 +751,7 @@ impl Parse for MacroInput {
}

Ok(MacroInput {
root_path_env,
include_directories,
macro_defines,
shared_constants: shared_constants.unwrap_or(false),
Expand Down