Allow long link names in tar files

Without this, users trying to run `x.py dist` under a sufficiently long
path run into problems when we build the resulting tarballs due to
length limits in the original tar spec. The error looks like:

        Finished release [optimized + debuginfo] target(s) in 0.34s
    Copying stage0 std from stage0 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-musl)
    Building stage0 tool rust-installer (x86_64-unknown-linux-gnu)
        Finished release [optimized] target(s) in 0.35s
    Dist rust-std-1.67.1-x86_64-unknown-linux-musl
    Error: failed to generate installer

    Caused by:
        0: failed to tar file '/home/AAAAAAAAAAAAAA/BBBBBB/CCCC/DDD/EEEEE/FFFFFFFFFFFF/GGGGGGGGGGGGGGGG/HHHHHHHHHH/IIIIIIIIIIIIIII/JJJJJ/KKKKKKK/src/build/tmp/tarball/rust-std/x86_64-unknown-linux-musl/rust-std-1.67.1-x86_64-unknown-linux-musl/rust-std-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/libc.a'
        1: provided value is too long when setting link name for
    Build completed unsuccessfully in 0:00:03

The fix is to make use of the widely-supported GNU tar extensions which
lift this restriction. Switching to [`tar::Builder::append_link`] takes
care of that for us. See also alexcrichton/tar-rs#273.

[`tar::Builder::append_link`]: https://docs.rs/tar/0.4.38/tar/struct.Builder.html#method.append_link
This commit is contained in:
Jon Gjengset 2023-03-24 16:29:38 -07:00
parent 99c49d95cd
commit 4d5501037a
2 changed files with 3 additions and 4 deletions

View File

@ -13,7 +13,7 @@ path = "src/main.rs"
anyhow = "1.0.19"
flate2 = "1.0.1"
rayon = "1.0"
tar = "0.4.13"
tar = "0.4.38"
walkdir = "2"
xz2 = "0.1.4"
num_cpus = "1"

View File

@ -1,6 +1,6 @@
use anyhow::{bail, Context, Result};
use std::fs::{read_link, symlink_metadata};
use std::io::{empty, BufWriter, Write};
use std::io::{BufWriter, Write};
use std::path::Path;
use tar::{Builder, Header};
use walkdir::WalkDir;
@ -93,8 +93,7 @@ fn append_path<W: Write>(builder: &mut Builder<W>, src: &Path, path: &String) ->
header.set_metadata(&stat);
if stat.file_type().is_symlink() {
let link = read_link(src)?;
header.set_link_name(&link)?;
builder.append_data(&mut header, path, &mut empty())?;
builder.append_link(&mut header, path, &link)?;
} else {
if cfg!(windows) {
// Windows doesn't really have a mode, so `tar` never marks files executable.