Skip to content

Commit 731a5e8

Browse files
committed
link: switch from tar to ar for .rlibs.
1 parent 5a431e6 commit 731a5e8

File tree

4 files changed

+52
-31
lines changed

4 files changed

+52
-31
lines changed

Cargo.lock

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/rustc_codegen_spirv/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ num-traits = { version = "0.2", features = ["libm"] }
3535
syn = { version = "1", features = ["visit", "visit-mut"] }
3636

3737
# Normal dependencies.
38+
ar = "0.8.0"
3839
bimap = "0.6"
3940
indexmap = "1.6.0"
4041
rspirv = { git = "https://github.com/gfx-rs/rspirv.git", rev = "c2a11ba7961fa7c675800f50c1903f0e96c633f8" }
@@ -44,7 +45,6 @@ serde = { version = "1.0", features = ["derive"] }
4445
serde_json = "1.0"
4546
smallvec = "1.6.1"
4647
spirv-tools = { version = "0.6.1", default-features = false }
47-
tar = "0.4.30"
4848
topological-sort = "0.1"
4949

5050
[dev-dependencies]

crates/rustc_codegen_spirv/src/link.rs

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::codegen_cx::{CodegenArgs, ModuleOutputType};
22
use crate::{
33
linker, CompileResult, ModuleResult, SpirvCodegenBackend, SpirvModuleBuffer, SpirvThinBuffer,
44
};
5+
use ar::{Archive, GnuBuilder, Header};
56
use rspirv::binary::Assemble;
67
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared};
78
use rustc_codegen_ssa::back::write::CodegenContext;
@@ -19,12 +20,12 @@ use rustc_session::output::{check_file_is_writeable, invalid_output_for_target,
1920
use rustc_session::utils::NativeLibKind;
2021
use rustc_session::Session;
2122
use std::env;
22-
use std::ffi::{CString, OsStr};
23+
use std::ffi::CString;
2324
use std::fs::File;
2425
use std::io::{BufWriter, Read};
26+
use std::iter;
2527
use std::path::{Path, PathBuf};
2628
use std::sync::Arc;
27-
use tar::{Archive, Builder, Header};
2829

2930
pub fn link<'a>(
3031
sess: &'a Session,
@@ -439,35 +440,53 @@ fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
439440
}
440441

441442
fn create_archive(files: &[&Path], metadata: &[u8], out_filename: &Path) {
442-
let file = File::create(out_filename).unwrap();
443-
let mut builder = Builder::new(file);
444-
{
445-
let mut header = Header::new_gnu();
446-
header.set_path(METADATA_FILENAME).unwrap();
447-
header.set_size(metadata.len() as u64);
448-
header.set_cksum();
449-
builder.append(&header, metadata).unwrap();
450-
}
443+
let files_with_names = files.iter().map(|file| {
444+
(
445+
file,
446+
file.file_name()
447+
.unwrap()
448+
.to_str()
449+
.expect("archive file names should be valid ASCII/UTF-8"),
450+
)
451+
});
452+
let out_file = File::create(out_filename).unwrap();
453+
let mut builder = GnuBuilder::new(
454+
out_file,
455+
iter::once(METADATA_FILENAME)
456+
.chain(files_with_names.clone().map(|(_, name)| name))
457+
.map(|name| name.as_bytes().to_vec())
458+
.collect(),
459+
);
460+
builder
461+
.append(
462+
&Header::new(METADATA_FILENAME.as_bytes().to_vec(), metadata.len() as u64),
463+
metadata,
464+
)
465+
.unwrap();
466+
451467
let mut filenames = FxHashSet::default();
452-
filenames.insert(OsStr::new(METADATA_FILENAME));
453-
for file in files {
468+
filenames.insert(METADATA_FILENAME);
469+
for (file, name) in files_with_names {
454470
assert!(
455-
filenames.insert(file.file_name().unwrap()),
471+
filenames.insert(name),
456472
"Duplicate filename in archive: {:?}",
457473
file.file_name().unwrap()
458474
);
475+
// NOTE(eddyb) this could just be `builder.append_path(file)`, but we
476+
// have to work around https://github.com/mdsteele/rust-ar/issues/19.
459477
builder
460-
.append_path_with_name(file, file.file_name().unwrap())
478+
.append_file(name.as_bytes(), &mut File::open(file).unwrap())
461479
.unwrap();
462480
}
463481
builder.into_inner().unwrap();
464482
}
465483

466484
pub fn read_metadata(rlib: &Path) -> Result<MetadataRef, String> {
467485
fn read_metadata_internal(rlib: &Path) -> Result<Option<MetadataRef>, std::io::Error> {
468-
for entry in Archive::new(File::open(rlib)?).entries()? {
486+
let mut archive = Archive::new(File::open(rlib).unwrap());
487+
while let Some(entry) = archive.next_entry() {
469488
let mut entry = entry?;
470-
if entry.path()? == Path::new(METADATA_FILENAME) {
489+
if entry.header().identifier() == METADATA_FILENAME.as_bytes() {
471490
let mut bytes = Vec::new();
472491
entry.read_to_end(&mut bytes)?;
473492
let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(bytes);
@@ -507,12 +526,13 @@ fn do_link(
507526
// `rlibs` are archive files we've created in `create_archive`, usually produced by crates that are being
508527
// referenced. We need to unpack them and add the modules inside.
509528
for rlib in rlibs {
510-
for entry in Archive::new(File::open(rlib).unwrap()).entries().unwrap() {
529+
let mut archive = Archive::new(File::open(rlib).unwrap());
530+
while let Some(entry) = archive.next_entry() {
511531
let mut entry = entry.unwrap();
512-
if entry.path().unwrap() != Path::new(METADATA_FILENAME) {
532+
if entry.header().identifier() != METADATA_FILENAME.as_bytes() {
513533
// std::fs::read adds 1 to the size, so do the same here - see comment:
514534
// https://github.com/rust-lang/rust/blob/72868e017bdade60603a25889e253f556305f996/library/std/src/fs.rs#L200-L202
515-
let mut bytes = Vec::with_capacity(entry.size() as usize + 1);
535+
let mut bytes = Vec::with_capacity(entry.header().size() as usize + 1);
516536
entry.read_to_end(&mut bytes).unwrap();
517537
modules.push(load(&bytes));
518538
}

deny.toml

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,7 @@ vulnerability = "deny"
66
unmaintained = "warn"
77
yanked = "warn"
88
notice = "warn"
9-
ignore = [
10-
# The tar crate allows creating directories outside dst when unpacking.
11-
# Safe to ignore: we both create/control all input tar files, and we do not unpack them.
12-
# https://github.com/alexcrichton/tar-rs/issues/238
13-
"RUSTSEC-2021-0080",
14-
]
9+
ignore = []
1510

1611
# This section is considered when running `cargo deny check bans`.
1712
# More documentation about the 'bans' section can be found here:
@@ -32,8 +27,8 @@ deny = [
3227
skip = [
3328
#{ name = "ansi_term", version = "=0.11.0" },
3429
]
35-
# Similarly to `skip` allows you to skip certain crates during duplicate
36-
# detection. Unlike skip, it also includes the entire tree of transitive
30+
# Similarly to `skip` allows you to skip certain crates during duplicate
31+
# detection. Unlike skip, it also includes the entire tree of transitive
3732
# dependencies starting at the specified crate, up to a certain depth, which is
3833
# by default infinite
3934
skip-tree = [
@@ -60,7 +55,7 @@ allow = [
6055
"BSD-2-Clause",
6156
"BSD-3-Clause",
6257
"ISC",
63-
58+
6459
"Zlib",
6560
]
6661
# Allow 1 or more licenses on a per-crate basis, so that particular licenses

0 commit comments

Comments
 (0)