MCPcopy Create free account
hub / github.com/Rust-GPU/rust-gpu / do_link

Function do_link

crates/rustc_codegen_spirv/src/link.rs:518–588  ·  view source on GitHub ↗

This is the actual guts of linking: the rest of the link-related functions are just digging through rustc's shenanigans to collect all the object files we need to link.

(
    sess: &Session,
    cg_args: &CodegenArgs,
    objects: &[PathBuf],
    rlibs: &[PathBuf],
    outputs: &OutputFilenames,
    disambiguated_crate_name_for_dumps: &OsStr,
)

Source from the content-addressed store, hash-verified

516/// This is the actual guts of linking: the rest of the link-related functions are just digging through rustc's
517/// shenanigans to collect all the object files we need to link.
518fn do_link(
519 sess: &Session,
520 cg_args: &CodegenArgs,
521 objects: &[PathBuf],
522 rlibs: &[PathBuf],
523 outputs: &OutputFilenames,
524 disambiguated_crate_name_for_dumps: &OsStr,
525) -> linker::LinkResult {
526 let load_modules_timer = sess.timer("link_load_modules");
527
528 let mut modules = Vec::new();
529 let mut add_module = |file_name: &OsStr, bytes: &[u8]| {
530 let module = {
531 let mut loader = rspirv::dr::Loader::new();
532 rspirv::binary::parse_bytes(bytes, &mut loader).unwrap();
533 loader.module()
534 };
535 if let Some(dir) = &cg_args.dump_pre_link {
536 // FIXME(eddyb) is it a good idea to re-`assemble` the `rspirv::dr`
537 // module, or should this just save the original bytes?
538 std::fs::write(
539 dir.join(file_name).with_extension("spv"),
540 spirv_tools::binary::from_binary(&module.assemble()),
541 )
542 .unwrap();
543 }
544 modules.push(module);
545 };
546
547 // `objects` are the plain obj files we need to link - usually produced by the final crate.
548 for obj in objects {
549 add_module(obj.file_name().unwrap(), &std::fs::read(obj).unwrap());
550 }
551
552 // `rlibs` are archive files we've created in `create_archive`, usually produced by crates that are being
553 // referenced. We need to unpack them and add the modules inside.
554 for rlib in rlibs {
555 let mut archive = Archive::new(File::open(rlib).unwrap());
556 while let Some(entry) = archive.next_entry() {
557 let mut entry = entry.unwrap();
558 if entry.header().identifier() != METADATA_FILENAME.as_bytes() {
559 // std::fs::read adds 1 to the size, so do the same here - see comment:
560 // https://github.com/rust-lang/rust/blob/72868e017bdade60603a25889e253f556305f996/library/std/src/fs.rs#L200-L202
561 let mut bytes = Vec::with_capacity(entry.header().size() as usize + 1);
562 entry.read_to_end(&mut bytes).unwrap();
563
564 let file_name = std::str::from_utf8(entry.header().identifier()).unwrap();
565 add_module(OsStr::new(file_name), &bytes);
566 }
567 }
568 }
569
570 drop(load_modules_timer);
571
572 // Do the link...
573 let link_result = linker::link(
574 sess,
575 modules,

Callers 1

link_exeFunction · 0.85

Calls 1

linkFunction · 0.70

Tested by

no test coverage detected