fn new_with_check()

in src/compiler/rust.rs [2379:2440]


    fn new_with_check(executable: PathBuf, env_vars: &[(OsString, OsString)]) -> Result<Self> {
        let temp_dir = tempfile::Builder::new()
            .prefix("sccache-rlibreader")
            .tempdir()
            .context("Could not create temporary directory for rlib output")?;
        let temp_rlib = temp_dir.path().join("x.rlib");

        let mut cmd = process::Command::new(&executable);
        cmd.arg("--crate-type=rlib")
            .arg("-o")
            .arg(&temp_rlib)
            .arg("-")
            .env_clear()
            .envs(env_vars.to_vec());

        let process::Output {
            status,
            stdout,
            stderr,
        } = cmd.output()?;

        if !stdout.is_empty() {
            bail!(
                "rustc stdout non-empty when compiling a minimal rlib: {:?}",
                String::from_utf8_lossy(&stdout)
            )
        }
        if !stderr.is_empty() {
            bail!(
                "rustc stderr non-empty when compiling a minimal rlib: {:?}",
                String::from_utf8_lossy(&stderr)
            )
        }
        if !status.success() {
            bail!(
                "Failed to compile a minimal rlib with {}",
                executable.display()
            )
        }

        // The goal of this cache is to avoid repeated lookups when building a single project. Let's budget 3MB.
        // Allowing for a 100 byte path, 50 dependencies per rlib and 20 characters per crate name, this roughly
        // approximates to `path_size + path + vec_size + num_deps * (systemtime_size + string_size + crate_name_len)`
        //                 `   3*8    +  100 +   3*8    +    50    * (      8         +     3*8     +       20      )`
        //                 `2748` bytes per crate
        // Allowing for possible overhead of up to double (for unused space in allocated memory), this means we
        // can cache information from about 570 rlibs - easily enough for a single project.
        const CACHE_SIZE: u64 = 3 * 1024 * 1024;
        let cache = LruCache::with_meter(CACHE_SIZE, DepsSize);
        let rustc_version = Self::get_rustc_version(&executable, env_vars)?;

        let rlib_dep_reader = RlibDepReader {
            cache: Mutex::new(cache),
            executable,
            ls_arg: Self::get_correct_ls_arg(rustc_version),
        };
        if let Err(e) = rlib_dep_reader.discover_rlib_deps(env_vars, &temp_rlib) {
            bail!("Failed to read deps from minimal rlib: {}", e)
        }

        Ok(rlib_dep_reader)
    }