Returns path to the metadata json.
(builder: &SpirvBuilder)
| 539 | |
| 540 | // Returns path to the metadata json. |
| 541 | fn invoke_rustc(builder: &SpirvBuilder) -> Result<PathBuf, SpirvBuilderError> { |
| 542 | // Okay, this is a little bonkers: in a normal world, we'd have the user clone |
| 543 | // rustc_codegen_spirv and pass in the path to it, and then we'd invoke cargo to build it, grab |
| 544 | // the resulting .so, and pass it into -Z codegen-backend. But that's really gross: the user |
| 545 | // needs to clone rustc_codegen_spirv and tell us its path! So instead, we *directly reference |
| 546 | // rustc_codegen_spirv in spirv-builder's Cargo.toml*, which means that it will get built |
| 547 | // alongside build.rs, and cargo will helpfully add it to LD_LIBRARY_PATH for us! However, |
| 548 | // rustc expects a full path, instead of a filename looked up via LD_LIBRARY_PATH, so we need |
| 549 | // to copy cargo's understanding of library lookup and find the library and its full path. |
| 550 | let rustc_codegen_spirv = find_rustc_codegen_spirv(); |
| 551 | |
| 552 | let mut rustflags = vec![ |
| 553 | format!("-Zcodegen-backend={}", rustc_codegen_spirv.display()), |
| 554 | // Ensure the codegen backend is emitted in `.d` files to force Cargo |
| 555 | // to rebuild crates compiled with it when it changes (this used to be |
| 556 | // the default until https://github.com/rust-lang/rust/pull/93969). |
| 557 | "-Zbinary-dep-depinfo".to_string(), |
| 558 | "-Csymbol-mangling-version=v0".to_string(), |
| 559 | "-Zcrate-attr=feature(register_tool)".to_string(), |
| 560 | "-Zcrate-attr=register_tool(rust_gpu)".to_string(), |
| 561 | // HACK(eddyb) this is the same configuration that we test with, and |
| 562 | // ensures no unwanted surprises from e.g. `core` debug assertions. |
| 563 | "-Coverflow-checks=off".to_string(), |
| 564 | "-Cdebug-assertions=off".to_string(), |
| 565 | // HACK(eddyb) we need this for `core::fmt::rt::Argument::new_*` calls |
| 566 | // to *never* be inlined, so we can pattern-match the calls themselves. |
| 567 | "-Zinline-mir=off".to_string(), |
| 568 | ]; |
| 569 | |
| 570 | // Wrapper for `env::var` that appropriately informs Cargo of the dependency. |
| 571 | let tracked_env_var_get = |name| { |
| 572 | if let MetadataPrintout::Full | MetadataPrintout::DependencyOnly = builder.print_metadata { |
| 573 | println!("cargo:rerun-if-env-changed={name}"); |
| 574 | } |
| 575 | env::var(name) |
| 576 | }; |
| 577 | |
| 578 | let mut llvm_args = vec![]; |
| 579 | if builder.multimodule { |
| 580 | llvm_args.push("--module-output=multiple".to_string()); |
| 581 | } |
| 582 | match builder.spirv_metadata { |
| 583 | SpirvMetadata::None => (), |
| 584 | SpirvMetadata::NameVariables => { |
| 585 | llvm_args.push("--spirv-metadata=name-variables".to_string()); |
| 586 | } |
| 587 | SpirvMetadata::Full => llvm_args.push("--spirv-metadata=full".to_string()), |
| 588 | } |
| 589 | if builder.relax_struct_store { |
| 590 | llvm_args.push("--relax-struct-store".to_string()); |
| 591 | } |
| 592 | if builder.relax_logical_pointer { |
| 593 | llvm_args.push("--relax-logical-pointer".to_string()); |
| 594 | } |
| 595 | if builder.relax_block_layout { |
| 596 | llvm_args.push("--relax-block-layout".to_string()); |
| 597 | } |
| 598 | if builder.uniform_buffer_standard_layout { |
no test coverage detected