| 467 | } |
| 468 | |
| 469 | fn create_archive(files: &[&Path], metadata: &[u8], out_filename: &Path) { |
| 470 | let files_with_names = files.iter().map(|file| { |
| 471 | ( |
| 472 | file, |
| 473 | file.file_name() |
| 474 | .unwrap() |
| 475 | .to_str() |
| 476 | .expect("archive file names should be valid ASCII/UTF-8"), |
| 477 | ) |
| 478 | }); |
| 479 | let out_file = File::create(out_filename).unwrap(); |
| 480 | let mut builder = GnuBuilder::new( |
| 481 | out_file, |
| 482 | iter::once(METADATA_FILENAME) |
| 483 | .chain(files_with_names.clone().map(|(_, name)| name)) |
| 484 | .map(|name| name.as_bytes().to_vec()) |
| 485 | .collect(), |
| 486 | ); |
| 487 | builder |
| 488 | .append( |
| 489 | &Header::new(METADATA_FILENAME.as_bytes().to_vec(), metadata.len() as u64), |
| 490 | metadata, |
| 491 | ) |
| 492 | .unwrap(); |
| 493 | |
| 494 | let mut filenames = FxHashSet::default(); |
| 495 | filenames.insert(METADATA_FILENAME); |
| 496 | for (file, name) in files_with_names { |
| 497 | assert!( |
| 498 | filenames.insert(name), |
| 499 | "Duplicate filename in archive: {:?}", |
| 500 | file.file_name().unwrap() |
| 501 | ); |
| 502 | |
| 503 | // NOTE(eddyb) we can't use `append_path` or `append_file`, as they |
| 504 | // record too much metadata by default (mtime/UID/GID, at least), |
| 505 | // which is determintal to reproducible build artifacts, but also |
| 506 | // can misbehave in environments with high UIDs/GIDs (see #889). |
| 507 | let file = File::open(file).unwrap(); |
| 508 | let header = Header::new(name.as_bytes().to_vec(), file.metadata().unwrap().len()); |
| 509 | // NOTE(eddyb) either `fs::File`, or the result of `fs::read`, could fit |
| 510 | // here, but `fs::File` has specialized file->file copying on some OSes. |
| 511 | builder.append(&header, file).unwrap(); |
| 512 | } |
| 513 | builder.into_inner().unwrap(); |
| 514 | } |
| 515 | |
| 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. |