-
Notifications
You must be signed in to change notification settings - Fork 247
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
spirv-builder: build rustc_codegen_spirv
with the right toolchain via build script.
#1103
base: main
Are you sure you want to change the base?
Conversation
fb5b92f
to
b69a12f
Compare
// Set up a workspace in `$OUT_DIR` to bootstrap building this very crate | ||
// (`spirv-builder`) with `rust-toolchain.toml` and `Cargo.lock` taken from | ||
// our `rustc_codegen_spirv` dependency. | ||
let ws = out_dir.join("nested-self-builder"); | ||
fs::create_dir_all(ws.join("src")).unwrap(); | ||
fs::write( | ||
ws.join("Cargo.toml"), | ||
format!( | ||
r#" | ||
[workspace] | ||
|
||
[package] | ||
name = "nested-self-builder" | ||
edition = "2021" | ||
version = "0.0.0" | ||
|
||
[dependencies.spirv-builder] | ||
path = {spirv_builder_path:?} | ||
default-features = false | ||
features = [{spirv_builder_features}] | ||
|
||
# Enable incremental by default in release mode, as well. | ||
[profile.release] | ||
incremental = true | ||
"#, | ||
spirv_builder_path = env!("CARGO_MANIFEST_DIR"), | ||
spirv_builder_features = propagate_features | ||
.iter() | ||
.copied() | ||
.chain(["internal-unstable-trigger-self-build-for-backend"]) | ||
.map(|feat| format!("{feat:?}")) | ||
.collect::<Vec<_>>() | ||
.join(", "), | ||
), | ||
) | ||
.unwrap(); | ||
const NESTED_SELF_BUILDER_MAIN_RS: &str = r#" | ||
fn main() { | ||
let dylib_path = spirv_builder::codegen_backend::codegen_backend_dylib_path(); | ||
println!("cargo:rerun-if-changed={}", dylib_path.display()); | ||
println!("cargo:rustc-env=SPIRV_BUILDER_CODEGEN_BACKEND_DYLIB_PATH={}", dylib_path.display()); | ||
println!("cargo:rustc-env=SPIRV_BUILDER_RUSTUP_TOOLCHAIN={}", env!("RUSTUP_TOOLCHAIN")); | ||
} | ||
"#; | ||
let ws_src_main_rs = ws.join("src/main.rs"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New idea (from #911 (comment)) to consider trying:
The diff I'm commenting on generates a pair of Cargo.toml
and src/main.rs
- it could be a -Z script
combined .rs
file, forcing Cargo to help out with caching.
That is, we could manage ~/.cache/rust-gpu
(something respecting $XDG_CACHE_HOME
in reality), under which we generate a -Z script
.rs
file per choice of contents (as in, we can content-address it, i.e. the files just take a name given by their own hash).
That directory of .rs
files would be relatively miniscule, but Cargo should be able to e.g. automatically GC the target dirs it created itself (under ~/.cargo
) to build -Z script
packages.
This has been a long-time coming, I've mostly been putting it off because of how annoying it'd be to implement.
(turns out I was a bit wrong and there's so many more things that don't work, than the few that do)
For some background, also see previous discussion in:
Rough summary of the new approach:
spirv-builder
with no special featuresspirv-builder
's build script kicks in and creates a private temporary helper workspace, which:spirv-builder
being built (via path dependency, to wherever it is)internal-unstable-trigger-self-build-for-backend
special feature, which in turn is what enables therustc_codegen_spirv
optional dependencyrust-toolchain.toml
(andCargo.lock
) thatrustc_codegen_spirv
needs are still unknown!spirv-builder
's build script usescargo_metadata
to find its ownrustc_codegen_spirv
dependency, from the perspective of the helper workspace that enables it via the special featurespirv-builder
is useless for this)rust-toolchain.toml
andCargo.lock
are copied from therustc_codegen_spirv
found withcargo_metadata
spirv-builder
, including therustc_codegen_spirv
dylib, whose path can be embedded in the outer build--release
, incremental, etc.spirv-builder
will use information from its build script, to run the correctrustup
toolchain, with the correctrustc_codegen_spirv
dylib path, regardless of the outer toolchain/env vars/etc.Benefits:
rust-toolchain.toml
or nested workspaces/helper binaries againCargo.toml
is no longer needed to ensure the codegen backend gets optimizedspirv-builder
SpirvBuilder
generate some APIs to conveniently rebuild all the same shaders (making the SPIR-V blobs almost like "self-updating values")Downsides:
rustc_codegen_spirv
, which now has its own nested workspacerustc_codegen_spirv
to be built than they'd wantrust-toolchain.toml
around to runcargo check
on the host with the same toolchaincargo +nightly-... check
suggestions to errors etc.If you want to give this a go, remove
rust-toolchain.toml
(and anything you added to e.g.Cargo.toml
for overriding profiles for build dependency, any weird workspace indirection executables etc.) and add:(assuming you're already depending on
spirv-builder = "0.9"
)