//! A library for [Cargo build scripts](https://doc.rust-lang.org/cargo/reference/build-scripts.html)
//! to compile a set of C/C++/assembly/CUDA files into a static archive for Cargo
//! to link into the crate being built. This crate does not compile code itself;
//! it calls out to the default compiler for the platform. This crate will
//! automatically detect situations such as cross compilation and
//! [various environment variables](#external-configuration-via-environment-variables) and will build code appropriately.
//!
//! # Example
//!
//! First, you'll want to both add a build script for your crate (`build.rs`) and
//! also add this crate to your `Cargo.toml` via:
//!
//! ```toml
//! [build-dependencies]
//! cc = "1.0"
//! ```
//!
//! Next up, you'll want to write a build script like so:
//!
//! ```rust,no_run
//! // build.rs
//! cc::Build::new()
//!     .file("foo.c")
//!     .file("bar.c")
//!     .compile("foo");
//! ```
//!
//! And that's it! Running `cargo build` should take care of the rest and your Rust
//! application will now have the C files `foo.c` and `bar.c` compiled into a file
//! named `libfoo.a`. If the C files contain
//!
//! ```c
//! void foo_function(void) { ... }
//! ```
//!
//! and
//!
//! ```c
//! int32_t bar_function(int32_t x) { ... }
//! ```
//!
//! you can call them from Rust by declaring them in
//! your Rust code like so:
//!
//! ```rust,no_run
//! extern "C" {
//!     fn foo_function();
//!     fn bar_function(x: i32) -> i32;
//! }
//!
//! pub fn call() {
//!     unsafe {
//!         foo_function();
//!         bar_function(42);
//!     }
//! }
//!
//! fn main() {
//!     call();
//! }
//! ```
//!
//! See [the Rustonomicon](https://doc.rust-lang.org/nomicon/ffi.html) for more details.
//!
//! # External configuration via environment variables
//!
//! To control the programs and flags used for building, the builder can set a
//! number of different environment variables.
//!
//! * `CFLAGS` - a series of space separated flags passed to compilers. Note that
//!   individual flags cannot currently contain spaces, so doing
//!   something like: `-L=foo\ bar` is not possible.
//! * `CC` - the actual C compiler used. Note that this is used as an exact
//!   executable name, so (for example) no extra flags can be passed inside
//!   this variable, and the builder must ensure that there aren't any
//!   trailing spaces. This compiler must understand the `-c` flag. For
//!   certain `TARGET`s, it also is assumed to know about other flags (most
//!   common is `-fPIC`).
//! * `AR` - the `ar` (archiver) executable to use to build the static library.
//! * `CRATE_CC_NO_DEFAULTS` - the default compiler flags may cause conflicts in
//!   some cross compiling scenarios. Setting this variable
//!   will disable the generation of default compiler
//!   flags.
//! * `CC_ENABLE_DEBUG_OUTPUT` - if set, compiler command invocations and exit codes will
//!   be logged to stdout. This is useful for debugging build script issues, but can be
//!   overly verbose for normal use.
//! * `CC_SHELL_ESCAPED_FLAGS` - if set, `*FLAGS` will be parsed as if they were shell
//!   arguments (similar to `make` and `cmake`) rather than splitting them on each space.
//!   For example, with `CFLAGS='a "b c"'`, the compiler will be invoked with 2 arguments -
//!   `a` and `b c` - rather than 3: `a`, `"b` and `c"`.
//! * `CXX...` - see [C++ Support](#c-support).
//!
//! Furthermore, projects using this crate may specify custom environment variables
//! to be inspected, for example via the `Build::try_flags_from_environment`
//! function. Consult the project’s own documentation or its use of the `cc` crate
//! for any additional variables it may use.
//!
//! Each of these variables can also be supplied with certain prefixes and suffixes,
//! in the following prioritized order:
//!
//!   1. `<var>_<target>` - for example, `CC_x86_64-unknown-linux-gnu`
//!   2. `<var>_<target_with_underscores>` - for example, `CC_x86_64_unknown_linux_gnu`
//!   3. `<build-kind>_<var>` - for example, `HOST_CC` or `TARGET_CFLAGS`
//!   4. `<var>` - a plain `CC`, `AR` as above.
//!
//! If none of these variables exist, cc-rs uses built-in defaults.
//!
//! In addition to the above optional environment variables, `cc-rs` has some
//! functions with hard requirements on some variables supplied by [cargo's
//! build-script driver][cargo] that it has the `TARGET`, `OUT_DIR`, `OPT_LEVEL`,
//! and `HOST` variables.
//!
//! [cargo]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#inputs-to-the-build-script
//!
//! # Optional features
//!
//! ## Parallel
//!
//! Currently cc-rs supports parallel compilation (think `make -jN`) but this
//! feature is turned off by default. To enable cc-rs to compile C/C++ in parallel,
//! you can change your dependency to:
//!
//! ```toml
//! [build-dependencies]
//! cc = { version = "1.0", features = ["parallel"] }
//! ```
//!
//! By default cc-rs will limit parallelism to `$NUM_JOBS`, or if not present it
//! will limit it to the number of cpus on the machine. If you are using cargo,
//! use `-jN` option of `build`, `test` and `run` commands as `$NUM_JOBS`
//! is supplied by cargo.
//!
//! # Compile-time Requirements
//!
//! To work properly this crate needs access to a C compiler when the build script
//! is being run. This crate does not ship a C compiler with it. The compiler
//! required varies per platform, but there are three broad categories:
//!
//! * Unix platforms require `cc` to be the C compiler. This can be found by
//!   installing cc/clang on Linux distributions and Xcode on macOS, for example.
//! * Windows platforms targeting MSVC (e.g. your target triple ends in `-msvc`)
//!   require Visual Studio to be installed. `cc-rs` attempts to locate it, and
//!   if it fails, `cl.exe` is expected to be available in `PATH`. This can be
//!   set up by running the appropriate developer tools shell.
//! * Windows platforms targeting MinGW (e.g. your target triple ends in `-gnu`)
//!   require `cc` to be available in `PATH`. We recommend the
//!   [MinGW-w64](https://www.mingw-w64.org/) distribution.
//!   You may also acquire it via
//!   [MSYS2](https://www.msys2.org/), as explained [here][msys2-help].  Make sure
//!   to install the appropriate architecture corresponding to your installation of
//!   rustc. GCC from older [MinGW](http://www.mingw.org/) project is compatible
//!   only with 32-bit rust compiler.
//!
//! [msys2-help]: https://github.com/rust-lang/rust/blob/master/INSTALL.md#building-on-windows
//!
//! # C++ support
//!
//! `cc-rs` supports C++ libraries compilation by using the `cpp` method on
//! `Build`:
//!
//! ```rust,no_run
//! cc::Build::new()
//!     .cpp(true) // Switch to C++ library compilation.
//!     .file("foo.cpp")
//!     .compile("foo");
//! ```
//!
//! For C++ libraries, the `CXX` and `CXXFLAGS` environment variables are used instead of `CC` and `CFLAGS`.
//!
//! The C++ standard library may be linked to the crate target. By default it's `libc++` for macOS, FreeBSD, and OpenBSD, `libc++_shared` for Android, nothing for MSVC, and `libstdc++` for anything else. It can be changed in one of two ways:
//!
//! 1. by using the `cpp_link_stdlib` method on `Build`:
//! ```rust,no_run
//! cc::Build::new()
//!     .cpp(true)
//!     .file("foo.cpp")
//!     .cpp_link_stdlib("stdc++") // use libstdc++
//!     .compile("foo");
//! ```
//! 2. by setting the `CXXSTDLIB` environment variable.
//!
//! In particular, for Android you may want to [use `c++_static` if you have at most one shared library](https://developer.android.com/ndk/guides/cpp-support).
//!
//! Remember that C++ does name mangling so `extern "C"` might be required to enable Rust linker to find your functions.
//!
//! # CUDA C++ support
//!
//! `cc-rs` also supports compiling CUDA C++ libraries by using the `cuda` method
//! on `Build`:
//!
//! ```rust,no_run
//! cc::Build::new()
//!     // Switch to CUDA C++ library compilation using NVCC.
//!     .cuda(true)
//!     .cudart("static")
//!     // Generate code for Maxwell (GTX 970, 980, 980 Ti, Titan X).
//!     .flag("-gencode").flag("arch=compute_52,code=sm_52")
//!     // Generate code for Maxwell (Jetson TX1).
//!     .flag("-gencode").flag("arch=compute_53,code=sm_53")
//!     // Generate code for Pascal (GTX 1070, 1080, 1080 Ti, Titan Xp).
//!     .flag("-gencode").flag("arch=compute_61,code=sm_61")
//!     // Generate code for Pascal (Tesla P100).
//!     .flag("-gencode").flag("arch=compute_60,code=sm_60")
//!     // Generate code for Pascal (Jetson TX2).
//!     .flag("-gencode").flag("arch=compute_62,code=sm_62")
//!     // Generate code in parallel
//!     .flag("-t0")
//!     .file("bar.cu")
//!     .compile("bar");
//! ```

#![doc(html_root_url = "https://docs.rs/cc/1.0")]
#![deny(warnings)]
#![deny(missing_docs)]
#![deny(clippy::disallowed_methods)]
#![warn(clippy::doc_markdown)]

use std::borrow::Cow;
use std::collections::HashMap;
use std::env;
use std::ffi::{OsStr, OsString};
use std::fmt::{self, Display, Formatter};
use std::fs;
use std::io::{self, Write};
use std::path::{Component, Path, PathBuf};
#[cfg(feature = "parallel")]
use std::process::Child;
use std::process::Command;
use std::sync::{Arc, RwLock};

use shlex::Shlex;

#[cfg(feature = "parallel")]
mod parallel;
mod windows;
// Regardless of whether this should be in this crate's public API,
// it has been since 2015, so don't break it.
pub use windows::find_tools as windows_registry;

mod command_helpers;
use command_helpers::*;

mod tool;
pub use tool::Tool;
use tool::ToolFamily;

mod target_info;
mod tempfile;

mod utilities;
use utilities::*;

#[derive(Debug, Eq, PartialEq, Hash)]
struct CompilerFlag {
    compiler: Box<Path>,
    flag: Box<OsStr>,
}

type Env = Option<Arc<OsStr>>;

/// A builder for compilation of a native library.
///
/// A `Build` is the main type of the `cc` crate and is used to control all the
/// various configuration options and such of a compile. You'll find more
/// documentation on each method itself.
#[derive(Clone, Debug)]
pub struct Build {
    include_directories: Vec<Arc<Path>>,
    definitions: Vec<(Arc<str>, Option<Arc<str>>)>,
    objects: Vec<Arc<Path>>,
    flags: Vec<Arc<OsStr>>,
    flags_supported: Vec<Arc<OsStr>>,
    known_flag_support_status_cache: Arc<RwLock<HashMap<CompilerFlag, bool>>>,
    ar_flags: Vec<Arc<OsStr>>,
    asm_flags: Vec<Arc<OsStr>>,
    no_default_flags: bool,
    files: Vec<Arc<Path>>,
    cpp: bool,
    cpp_link_stdlib: Option<Option<Arc<str>>>,
    cpp_set_stdlib: Option<Arc<str>>,
    cuda: bool,
    cudart: Option<Arc<str>>,
    ccbin: bool,
    std: Option<Arc<str>>,
    target: Option<Arc<str>>,
    host: Option<Arc<str>>,
    out_dir: Option<Arc<Path>>,
    opt_level: Option<Arc<str>>,
    debug: Option<bool>,
    force_frame_pointer: Option<bool>,
    env: Vec<(Arc<OsStr>, Arc<OsStr>)>,
    compiler: Option<Arc<Path>>,
    archiver: Option<Arc<Path>>,
    ranlib: Option<Arc<Path>>,
    cargo_output: CargoOutput,
    link_lib_modifiers: Vec<Arc<OsStr>>,
    pic: Option<bool>,
    use_plt: Option<bool>,
    static_crt: Option<bool>,
    shared_flag: Option<bool>,
    static_flag: Option<bool>,
    warnings_into_errors: bool,
    warnings: Option<bool>,
    extra_warnings: Option<bool>,
    env_cache: Arc<RwLock<HashMap<Box<str>, Env>>>,
    apple_sdk_root_cache: Arc<RwLock<HashMap<Box<str>, Arc<OsStr>>>>,
    apple_versions_cache: Arc<RwLock<HashMap<Box<str>, Arc<str>>>>,
    emit_rerun_if_env_changed: bool,
    cached_compiler_family: Arc<RwLock<HashMap<Box<Path>, ToolFamily>>>,
    shell_escaped_flags: Option<bool>,
}

/// Represents the types of errors that may occur while using cc-rs.
#[derive(Clone, Debug)]
enum ErrorKind {
    /// Error occurred while performing I/O.
    IOError,
    /// Invalid architecture supplied.
    ArchitectureInvalid,
    /// Environment variable not found, with the var in question as extra info.
    EnvVarNotFound,
    /// Error occurred while using external tools (ie: invocation of compiler).
    ToolExecError,
    /// Error occurred due to missing external tools.
    ToolNotFound,
    /// One of the function arguments failed validation.
    InvalidArgument,
    /// No known macro is defined for the compiler when discovering tool family
    ToolFamilyMacroNotFound,
    /// Invalid target
    InvalidTarget,
    #[cfg(feature = "parallel")]
    /// jobserver helpthread failure
    JobserverHelpThreadError,
}

/// Represents an internal error that occurred, with an explanation.
#[derive(Clone, Debug)]
pub struct Error {
    /// Describes the kind of error that occurred.
    kind: ErrorKind,
    /// More explanation of error that occurred.
    message: Cow<'static, str>,
}

impl Error {
    fn new(kind: ErrorKind, message: impl Into<Cow<'static, str>>) -> Error {
        Error {
            kind,
            message: message.into(),
        }
    }
}

impl From<io::Error> for Error {
    fn from(e: io::Error) -> Error {
        Error::new(ErrorKind::IOError, format!("{}", e))
    }
}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:?}: {}", self.kind, self.message)
    }
}

impl std::error::Error for Error {}

/// Represents an object.
///
/// This is a source file -> object file pair.
#[derive(Clone, Debug)]
struct Object {
    src: PathBuf,
    dst: PathBuf,
}

impl Object {
    /// Create a new source file -> object file pair.
    fn new(src: PathBuf, dst: PathBuf) -> Object {
        Object { src, dst }
    }
}

impl Build {
    /// Construct a new instance of a blank set of configuration.
    ///
    /// This builder is finished with the [`compile`] function.
    ///
    /// [`compile`]: struct.Build.html#method.compile
    pub fn new() -> Build {
        Build {
            include_directories: Vec::new(),
            definitions: Vec::new(),
            objects: Vec::new(),
            flags: Vec::new(),
            flags_supported: Vec::new(),
            known_flag_support_status_cache: Arc::new(RwLock::new(HashMap::new())),
            ar_flags: Vec::new(),
            asm_flags: Vec::new(),
            no_default_flags: false,
            files: Vec::new(),
            shared_flag: None,
            static_flag: None,
            cpp: false,
            cpp_link_stdlib: None,
            cpp_set_stdlib: None,
            cuda: false,
            cudart: None,
            ccbin: true,
            std: None,
            target: None,
            host: None,
            out_dir: None,
            opt_level: None,
            debug: None,
            force_frame_pointer: None,
            env: Vec::new(),
            compiler: None,
            archiver: None,
            ranlib: None,
            cargo_output: CargoOutput::new(),
            link_lib_modifiers: Vec::new(),
            pic: None,
            use_plt: None,
            static_crt: None,
            warnings: None,
            extra_warnings: None,
            warnings_into_errors: false,
            env_cache: Arc::new(RwLock::new(HashMap::new())),
            apple_sdk_root_cache: Arc::new(RwLock::new(HashMap::new())),
            apple_versions_cache: Arc::new(RwLock::new(HashMap::new())),
            emit_rerun_if_env_changed: true,
            cached_compiler_family: Arc::default(),
            shell_escaped_flags: None,
        }
    }

    /// Add a directory to the `-I` or include path for headers
    ///
    /// # Example
    ///
    /// ```no_run
    /// use std::path::Path;
    ///
    /// let library_path = Path::new("/path/to/library");
    ///
    /// cc::Build::new()
    ///     .file("src/foo.c")
    ///     .include(library_path)
    ///     .include("src")
    ///     .compile("foo");
    /// ```
    pub fn include<P: AsRef<Path>>(&mut self, dir: P) -> &mut Build {
        self.include_directories.push(dir.as_ref().into());
        self
    }

    /// Add multiple directories to the `-I` include path.
    ///
    /// # Example
    ///
    /// ```no_run
    /// # use std::path::Path;
    /// # let condition = true;
    /// #
    /// let mut extra_dir = None;
    /// if condition {
    ///     extra_dir = Some(Path::new("/path/to"));
    /// }
    ///
    /// cc::Build::new()
    ///     .file("src/foo.c")
    ///     .includes(extra_dir)
    ///     .compile("foo");
    /// ```
    pub fn includes<P>(&mut self, dirs: P) -> &mut Build
    where
        P: IntoIterator,
        P::Item: AsRef<Path>,
    {
        for dir in dirs {
            self.include(dir);
        }
        self
    }

    /// Specify a `-D` variable with an optional value.
    ///
    /// # Example
    ///
    /// ```no_run
    /// cc::Build::new()
    ///     .file("src/foo.c")
    ///     .define("FOO", "BAR")
    ///     .define("BAZ", None)
    ///     .compile("foo");
    /// ```
    pub fn define<'a, V: Into<Option<&'a str>>>(&mut self, var: &str, val: V) -> &mut Build {
        self.definitions
            .push((var.into(), val.into().map(Into::into)));
        self
    }

    /// Add an arbitrary object file to link in
    pub fn object<P: AsRef<Path>>(&mut self, obj: P) -> &mut Build {
        self.objects.push(obj.as_ref().into());
        self
    }

    /// Add arbitrary object files to link in
    pub fn objects<P>(&mut self, objs: P) -> &mut Build
    where
        P: IntoIterator,
        P::Item: AsRef<Path>,
    {
        for obj in objs {
            self.object(obj);
        }
        self
    }

    /// Add an arbitrary flag to the invocation of the compiler
    ///
    /// # Example
    ///
    /// ```no_run
    /// cc::Build::new()
    ///     .file("src/foo.c")
    ///     .flag("-ffunction-sections")
    ///     .compile("foo");
    /// ```
    pub fn flag(&mut self, flag: impl AsRef<OsStr>) -> &mut Build {
        self.flags.push(flag.as_ref().into());
        self
    }

    /// Removes a compiler flag that was added by [`Build::flag`].
    ///
    /// Will not remove flags added by other means (default flags,
    /// flags from env, and so on).
    ///
    /// # Example
    /// ```
    /// cc::Build::new()
    ///     .file("src/foo.c")
    ///     .flag("unwanted_flag")
    ///     .remove_flag("unwanted_flag");
    /// ```

    pub fn remove_flag(&mut self, flag: &str) -> &mut Build {
        self.flags.retain(|other_flag| &**other_flag != flag);
        self
    }

    /// Add a flag to the invocation of the ar
    ///
    /// # Example
    ///
    /// ```no_run
    /// cc::Build::new()
    ///     .file("src/foo.c")
    ///     .file("src/bar.c")
    ///     .ar_flag("/NODEFAULTLIB:libc.dll")
    ///     .compile("foo");
    /// ```
    pub fn ar_flag(&mut self, flag: impl AsRef<OsStr>) -> &mut Build {
        self.ar_flags.push(flag.as_ref().into());
        self
    }

    /// Add a flag that will only be used with assembly files.
    ///
    /// The flag will be applied to input files with either a `.s` or
    /// `.asm` extension (case insensitive).
    ///
    /// # Example
    ///
    /// ```no_run
    /// cc::Build::new()
    ///     .asm_flag("-Wa,-defsym,abc=1")
    ///     .file("src/foo.S")  // The asm flag will be applied here
    ///     .file("src/bar.c")  // The asm flag will not be applied here
    ///     .compile("foo");
    /// ```
    pub fn asm_flag(&mut self, flag: impl AsRef<OsStr>) -> &mut Build {
        self.asm_flags.push(flag.as_ref().into());
        self
    }

    fn ensure_check_file(&self) -> Result<PathBuf, Error> {
        let out_dir = self.get_out_dir()?;
        let src = if self.cuda {
            assert!(self.cpp);
            out_dir.join("flag_check.cu")
        } else if self.cpp {
            out_dir.join("flag_check.cpp")
        } else {
            out_dir.join("flag_check.c")
        };

        if !src.exists() {
            let mut f = fs::File::create(&src)?;
            write!(f, "int main(void) {{ return 0; }}")?;
        }

        Ok(src)
    }

    /// Run the compiler to test if it accepts the given flag.
    ///
    /// For a convenience method for setting flags conditionally,
    /// see `flag_if_supported()`.
    ///
    /// It may return error if it's unable to run the compiler with a test file
    /// (e.g. the compiler is missing or a write to the `out_dir` failed).
    ///
    /// Note: Once computed, the result of this call is stored in the
    /// `known_flag_support` field. If `is_flag_supported(flag)`
    /// is called again, the result will be read from the hash table.
    pub fn is_flag_supported(&self, flag: impl AsRef<OsStr>) -> Result<bool, Error> {
        self.is_flag_supported_inner(
            flag.as_ref(),
            self.get_base_compiler()?.path(),
            &self.get_target()?,
        )
    }

    fn is_flag_supported_inner(
        &self,
        flag: &OsStr,
        compiler_path: &Path,
        target: &str,
    ) -> Result<bool, Error> {
        let compiler_flag = CompilerFlag {
            compiler: compiler_path.into(),
            flag: flag.into(),
        };

        if let Some(is_supported) = self
            .known_flag_support_status_cache
            .read()
            .unwrap()
            .get(&compiler_flag)
            .cloned()
        {
            return Ok(is_supported);
        }

        let out_dir = self.get_out_dir()?;
        let src = self.ensure_check_file()?;
        let obj = out_dir.join("flag_check");

        let mut compiler = {
            let mut cfg = Build::new();
            cfg.flag(flag)
                .compiler(compiler_path)
                .cargo_metadata(self.cargo_output.metadata)
                .target(target)
                .opt_level(0)
                .host(&self.get_host()?)
                .debug(false)
                .cpp(self.cpp)
                .cuda(self.cuda)
                .emit_rerun_if_env_changed(self.emit_rerun_if_env_changed);
            cfg.try_get_compiler()?
        };

        // Clang uses stderr for verbose output, which yields a false positive
        // result if the CFLAGS/CXXFLAGS include -v to aid in debugging.
        if compiler.family.verbose_stderr() {
            compiler.remove_arg("-v".into());
        }
        if compiler.is_like_clang() {
            // Avoid reporting that the arg is unsupported just because the
            // compiler complains that it wasn't used.
            compiler.push_cc_arg("-Wno-unused-command-line-argument".into());
        }

        let mut cmd = compiler.to_command();
        let is_arm = target.contains("aarch64") || target.contains("arm");
        let clang = compiler.is_like_clang();
        let gnu = compiler.family == ToolFamily::Gnu;
        command_add_output_file(
            &mut cmd,
            &obj,
            CmdAddOutputFileArgs {
                cuda: self.cuda,
                is_assembler_msvc: false,
                msvc: compiler.is_like_msvc(),
                clang,
                gnu,
                is_asm: false,
                is_arm,
            },
        );

        // Checking for compiler flags does not require linking
        cmd.arg("-c");

        cmd.arg(&src);

        let output = cmd.output()?;
        let is_supported = output.status.success() && output.stderr.is_empty();

        self.known_flag_support_status_cache
            .write()
            .unwrap()
            .insert(compiler_flag, is_supported);

        Ok(is_supported)
    }

    /// Add an arbitrary flag to the invocation of the compiler if it supports it
    ///
    /// # Example
    ///
    /// ```no_run
    /// cc::Build::new()
    ///     .file("src/foo.c")
    ///     .flag_if_supported("-Wlogical-op") // only supported by GCC
    ///     .flag_if_supported("-Wunreachable-code") // only supported by clang
    ///     .compile("foo");
    /// ```
    pub fn flag_if_supported(&mut self, flag: impl AsRef<OsStr>) -> &mut Build {
        self.flags_supported.push(flag.as_ref().into());
        self
    }

    /// Add flags from the specified environment variable.
    ///
    /// Normally the `cc` crate will consult with the standard set of environment
    /// variables (such as `CFLAGS` and `CXXFLAGS`) to construct the compiler invocation. Use of
    /// this method provides additional levers for the end user to use when configuring the build
    /// process.
    ///
    /// Just like the standard variables, this method will search for an environment variable with
    /// appropriate target prefixes, when appropriate.
    ///
    /// # Examples
    ///
    /// This method is particularly beneficial in introducing the ability to specify crate-specific
    /// flags.
    ///
    /// ```no_run
    /// cc::Build::new()
    ///     .file("src/foo.c")
    ///     .try_flags_from_environment(concat!(env!("CARGO_PKG_NAME"), "_CFLAGS"))
    ///     .expect("the environment variable must be specified and UTF-8")
    ///     .compile("foo");
    /// ```
    ///
    pub fn try_flags_from_environment(&mut self, environ_key: &str) -> Result<&mut Build, Error> {
        let flags = self.envflags(environ_key)?;
        self.flags.extend(
            flags
                .into_iter()
                .map(|flag| Arc::from(OsString::from(flag).as_os_str())),
        );
        Ok(self)
    }

    /// Set the `-shared` flag.
    ///
    /// When enabled, the compiler will produce a shared object which can
    /// then be linked with other objects to form an executable.
    ///
    /// # Example
    ///
    /// ```no_run
    /// cc::Build::new()
    ///     .file("src/foo.c")
    ///     .shared_flag(true)
    ///     .compile("libfoo.so");
    /// ```
    pub fn shared_flag(&mut self, shared_flag: bool) -> &mut Build {
        self.shared_flag = Some(shared_flag);
        self
    }

    /// Set the `-static` flag.
    ///
    /// When enabled on systems that support dynamic linking, this prevents
    /// linking with the shared libraries.
    ///
    /// # Example
    ///
    /// ```no_run
    /// cc::Build::new()
    ///     .file("src/foo.c")
    ///     .shared_flag(true)
    ///     .static_flag(true)
    ///     .compile("foo");
    /// ```
    pub fn static_flag(&mut self, static_flag: bool) -> &mut Build {
        self.static_flag = Some(static_flag);
        self
    }

    /// Disables the generation of default compiler flags. The default compiler
    /// flags may cause conflicts in some cross compiling scenarios.
    ///
    /// Setting the `CRATE_CC_NO_DEFAULTS` environment variable has the same
    /// effect as setting this to `true`. The presence of the environment
    /// variable and the value of `no_default_flags` will be OR'd together.
    pub fn no_default_flags(&mut self, no_default_flags: bool) -> &mut Build {
        self.no_default_flags = no_default_flags;
        self
    }

    /// Add a file which will be compiled
    pub fn file<P: AsRef<Path>>(&mut self, p: P) -> &mut Build {
        self.files.push(p.as_ref().into());
        self
    }

    /// Add files which will be compiled
    pub fn files<P>(&mut self, p: P) -> &mut Build
    where
        P: IntoIterator,
        P::Item: AsRef<Path>,
    {
        for file in p.into_iter() {
            self.file(file);
        }
        self
    }

    /// Get the files which will be compiled
    pub fn get_files(&self) -> impl Iterator<Item = &Path> {
        self.files.iter().map(AsRef::as_ref)
    }

    /// Set C++ support.
    ///
    /// The other `cpp_*` options will only become active if this is set to
    /// `true`.
    ///
    /// The name of the C++ standard library to link is decided by:
    /// 1. If [`cpp_link_stdlib`](Build::cpp_link_stdlib) is set, use its value.
    /// 2. Else if the `CXXSTDLIB` environment variable is set, use its value.
    /// 3. Else the default is `libc++` for OS X and BSDs, `libc++_shared` for Android,
    ///    `None` for MSVC and `libstdc++` for anything else.
    pub fn cpp(&mut self, cpp: bool) -> &mut Build {
        self.cpp = cpp;
        self
    }

    /// Set CUDA C++ support.
    ///
    /// Enabling CUDA will invoke the CUDA compiler, NVCC. While NVCC accepts
    /// the most common compiler flags, e.g. `-std=c++17`, some project-specific
    /// flags might have to be prefixed with "-Xcompiler" flag, for example as
    /// `.flag("-Xcompiler").flag("-fpermissive")`. See the documentation for
    /// `nvcc`, the CUDA compiler driver, at <https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/>
    /// for more information.
    ///
    /// If enabled, this also implicitly enables C++ support.
    pub fn cuda(&mut self, cuda: bool) -> &mut Build {
        self.cuda = cuda;
        if cuda {
            self.cpp = true;
            self.cudart = Some("static".into());
        }
        self
    }

    /// Link CUDA run-time.
    ///
    /// This option mimics the `--cudart` NVCC command-line option. Just like
    /// the original it accepts `{none|shared|static}`, with default being
    /// `static`. The method has to be invoked after `.cuda(true)`, or not
    /// at all, if the default is right for the project.
    pub fn cudart(&mut self, cudart: &str) -> &mut Build {
        if self.cuda {
            self.cudart = Some(cudart.into());
        }
        self
    }

    /// Set CUDA host compiler.
    ///
    /// By default, a `-ccbin` flag will be passed to NVCC to specify the
    /// underlying host compiler. The value of `-ccbin` is the same as the
    /// chosen C++ compiler. This is not always desired, because NVCC might
    /// not support that compiler. In this case, you can remove the `-ccbin`
    /// flag so that NVCC will choose the host compiler by itself.
    pub fn ccbin(&mut self, ccbin: bool) -> &mut Build {
        self.ccbin = ccbin;
        self
    }

    /// Specify the C or C++ language standard version.
    ///
    /// These values are common to modern versions of GCC, Clang and MSVC:
    /// - `c11` for ISO/IEC 9899:2011
    /// - `c17` for ISO/IEC 9899:2018
    /// - `c++14` for ISO/IEC 14882:2014
    /// - `c++17` for ISO/IEC 14882:2017
    /// - `c++20` for ISO/IEC 14882:2020
    ///
    /// Other values have less broad support, e.g. MSVC does not support `c++11`
    /// (`c++14` is the minimum), `c89` (omit the flag instead) or `c99`.
    ///
    /// For compiling C++ code, you should also set `.cpp(true)`.
    ///
    /// The default is that no standard flag is passed to the compiler, so the
    /// language version will be the compiler's default.
    ///
    /// # Example
    ///
    /// ```no_run
    /// cc::Build::new()
    ///     .file("src/modern.cpp")
    ///     .cpp(true)
    ///     .std("c++17")
    ///     .compile("modern");
    /// ```
    pub fn std(&mut self, std: &str) -> &mut Build {
        self.std = Some(std.into());
        self
    }

    /// Set warnings into errors flag.
    ///
    /// Disabled by default.
    ///
    /// Warning: turning warnings into errors only make sense
    /// if you are a developer of the crate using cc-rs.
    /// Some warnings only appear on some architecture or
    /// specific version of the compiler. Any user of this crate,
    /// or any other crate depending on it, could fail during
    /// compile time.
    ///
    /// # Example
    ///
    /// ```no_run
    /// cc::Build::new()
    ///     .file("src/foo.c")
    ///     .warnings_into_errors(true)
    ///     .compile("libfoo.a");
    /// ```
    pub fn warnings_into_errors(&mut self, warnings_into_errors: bool) -> &mut Build {
        self.warnings_into_errors = warnings_into_errors;
        self
    }

    /// Set warnings flags.
    ///
    /// Adds some flags:
    /// - "-Wall" for MSVC.
    /// - "-Wall", "-Wextra" for GNU and Clang.
    ///
    /// Enabled by default.
    ///
    /// # Example
    ///
    /// ```no_run
    /// cc::Build::new()
    ///     .file("src/foo.c")
    ///     .warnings(false)
    ///     .compile("libfoo.a");
    /// ```
    pub fn warnings(&mut self, warnings: bool) -> &mut Build {
        self.warnings = Some(warnings);
        self.extra_warnings = Some(warnings);
        self
    }

    /// Set extra warnings flags.
    ///
    /// Adds some flags:
    /// - nothing for MSVC.
    /// - "-Wextra" for GNU and Clang.
    ///
    /// Enabled by default.
    ///
    /// # Example
    ///
    /// ```no_run
    /// // Disables -Wextra, -Wall remains enabled:
    /// cc::Build::new()
    ///     .file("src/foo.c")
    ///     .extra_warnings(false)
    ///     .compile("libfoo.a");
    /// ```
    pub fn extra_warnings(&mut self, warnings: bool) -> &mut Build {
        self.extra_warnings = Some(warnings);
        self
    }

    /// Set the standard library to link against when compiling with C++
    /// support.
    ///
    /// If the `CXXSTDLIB` environment variable is set, its value will
    /// override the default value, but not the value explicitly set by calling
    /// this function.
    ///
    /// A value of `None` indicates that no automatic linking should happen,
    /// otherwise cargo will link against the specified library.
    ///
    /// The given library name must not contain the `lib` prefix.
    ///
    /// Common values:
    /// - `stdc++` for GNU
    /// - `c++` for Clang
    /// - `c++_shared` or `c++_static` for Android
    ///
    /// # Example
    ///
    /// ```no_run
    /// cc::Build::new()
    ///     .file("src/foo.c")
    ///     .shared_flag(true)
    ///     .cpp_link_stdlib("stdc++")
    ///     .compile("libfoo.so");
    /// ```
    pub fn cpp_link_stdlib<'a, V: Into<Option<&'a str>>>(
        &mut self,
        cpp_link_stdlib: V,
    ) -> &mut Build {
        self.cpp_link_stdlib = Some(cpp_link_stdlib.into().map(Arc::from));
        self
    }

    /// Force the C++ compiler to use the specified standard library.
    ///
    /// Setting this option will automatically set `cpp_link_stdlib` to the same
    /// value.
    ///
    /// The default value of this option is always `None`.
    ///
    /// This option has no effect when compiling for a Visual Studio based
    /// target.
    ///
    /// This option sets the `-stdlib` flag, which is only supported by some
    /// compilers (clang, icc) but not by others (gcc). The library will not
    /// detect which compiler is used, as such it is the responsibility of the
    /// caller to ensure that this option is only used in conjunction with a
    /// compiler which supports the `-stdlib` flag.
    ///
    /// A value of `None` indicates that no specific C++ standard library should
    /// be used, otherwise `-stdlib` is added to the compile invocation.
    ///
    /// The given library name must not contain the `lib` prefix.
    ///
    /// Common values:
    /// - `stdc++` for GNU
    /// - `c++` for Clang
    ///
    /// # Example
    ///
    /// ```no_run
    /// cc::Build::new()
    ///     .file("src/foo.c")
    ///     .cpp_set_stdlib("c++")
    ///     .compile("libfoo.a");
    /// ```
    pub fn cpp_set_stdlib<'a, V: Into<Option<&'a str>>>(
        &mut self,
        cpp_set_stdlib: V,
    ) -> &mut Build {
        let cpp_set_stdlib = cpp_set_stdlib.into().map(Arc::from);
        self.cpp_set_stdlib.clone_from(&cpp_set_stdlib);
        self.cpp_link_stdlib = Some(cpp_set_stdlib);
        self
    }

    /// Configures the target this configuration will be compiling for.
    ///
    /// This option is automatically scraped from the `TARGET` environment
    /// variable by build scripts, so it's not required to call this function.
    ///
    /// # Example
    ///
    /// ```no_run
    /// cc::Build::new()
    ///     .file("src/foo.c")
    ///     .target("aarch64-linux-android")
    ///     .compile("foo");
    /// ```
    pub fn target(&mut self, target: &str) -> &mut Build {
        self.target = Some(target.into());
        self
    }

    /// Configures the host assumed by this configuration.
    ///
    /// This option is automatically scraped from the `HOST` environment
    /// variable by build scripts, so it's not required to call this function.
    ///
    /// # Example
    ///
    /// ```no_run
    /// cc::Build::new()
    ///     .file("src/foo.c")
    ///     .host("arm-linux-gnueabihf")
    ///     .compile("foo");
    /// ```
    pub fn host(&mut self, host: &str) -> &mut Build {
        self.host = Some(host.into());
        self
    }

    /// Configures the optimization level of the generated object files.
    ///
    /// This option is automatically scraped from the `OPT_LEVEL` environment
    /// variable by build scripts, so it's not required to call this function.
    pub fn opt_level(&mut self, opt_level: u32) -> &mut Build {
        self.opt_level = Some(opt_level.to_string().into());
        self
    }

    /// Configures the optimization level of the generated object files.
    ///
    /// This option is automatically scraped from the `OPT_LEVEL` environment
    /// variable by build scripts, so it's not required to call this function.
    pub fn opt_level_str(&mut self, opt_level: &str) -> &mut Build {
        self.opt_level = Some(opt_level.into());
        self
    }

    /// Configures whether the compiler will emit debug information when
    /// generating object files.
    ///
    /// This option is automatically scraped from the `DEBUG` environment
    /// variable by build scripts, so it's not required to call this function.
    pub fn debug(&mut self, debug: bool) -> &mut Build {
        self.debug = Some(debug);
        self
    }

    /// Configures whether the compiler will emit instructions to store
    /// frame pointers during codegen.
    ///
    /// This option is automatically enabled when debug information is emitted.
    /// Otherwise the target platform compiler's default will be used.
    /// You can use this option to force a specific setting.
    pub fn force_frame_pointer(&mut self, force: bool) -> &mut Build {
        self.force_frame_pointer = Some(force);
        self
    }

    /// Configures the output directory where all object files and static
    /// libraries will be located.
    ///
    /// This option is automatically scraped from the `OUT_DIR` environment
    /// variable by build scripts, so it's not required to call this function.
    pub fn out_dir<P: AsRef<Path>>(&mut self, out_dir: P) -> &mut Build {
        self.out_dir = Some(out_dir.as_ref().into());
        self
    }

    /// Configures the compiler to be used to produce output.
    ///
    /// This option is automatically determined from the target platform or a
    /// number of environment variables, so it's not required to call this
    /// function.
    pub fn compiler<P: AsRef<Path>>(&mut self, compiler: P) -> &mut Build {
        self.compiler = Some(compiler.as_ref().into());
        self
    }

    /// Configures the tool used to assemble archives.
    ///
    /// This option is automatically determined from the target platform or a
    /// number of environment variables, so it's not required to call this
    /// function.
    pub fn archiver<P: AsRef<Path>>(&mut self, archiver: P) -> &mut Build {
        self.archiver = Some(archiver.as_ref().into());
        self
    }

    /// Configures the tool used to index archives.
    ///
    /// This option is automatically determined from the target platform or a
    /// number of environment variables, so it's not required to call this
    /// function.
    pub fn ranlib<P: AsRef<Path>>(&mut self, ranlib: P) -> &mut Build {
        self.ranlib = Some(ranlib.as_ref().into());
        self
    }

    /// Define whether metadata should be emitted for cargo allowing it to
    /// automatically link the binary. Defaults to `true`.
    ///
    /// The emitted metadata is:
    ///
    ///  - `rustc-link-lib=static=`*compiled lib*
    ///  - `rustc-link-search=native=`*target folder*
    ///  - When target is MSVC, the ATL-MFC libs are added via `rustc-link-search=native=`
    ///  - When C++ is enabled, the C++ stdlib is added via `rustc-link-lib`
    ///  - If `emit_rerun_if_env_changed` is not `false`, `rerun-if-env-changed=`*env*
    ///
    pub fn cargo_metadata(&mut self, cargo_metadata: bool) -> &mut Build {
        self.cargo_output.metadata = cargo_metadata;
        self
    }

    /// Define whether compile warnings should be emitted for cargo. Defaults to
    /// `true`.
    ///
    /// If disabled, compiler messages will not be printed.
    /// Issues unrelated to the compilation will always produce cargo warnings regardless of this setting.
    pub fn cargo_warnings(&mut self, cargo_warnings: bool) -> &mut Build {
        self.cargo_output.warnings = cargo_warnings;
        self
    }

    /// Define whether debug information should be emitted for cargo. Defaults to whether
    /// or not the environment variable `CC_ENABLE_DEBUG_OUTPUT` is set.
    ///
    /// If enabled, the compiler will emit debug information when generating object files,
    /// such as the command invoked and the exit status.
    pub fn cargo_debug(&mut self, cargo_debug: bool) -> &mut Build {
        self.cargo_output.debug = cargo_debug;
        self
    }

    /// Define whether compiler output (to stdout) should be emitted. Defaults to `true`
    /// (forward compiler stdout to this process' stdout)
    ///
    /// Some compilers emit errors to stdout, so if you *really* need stdout to be clean
    /// you should also set this to `false`.
    pub fn cargo_output(&mut self, cargo_output: bool) -> &mut Build {
        self.cargo_output.output = if cargo_output {
            OutputKind::Forward
        } else {
            OutputKind::Discard
        };
        self
    }

    /// Adds a native library modifier that will be added to the
    /// `rustc-link-lib=static:MODIFIERS=LIBRARY_NAME` metadata line
    /// emitted for cargo if `cargo_metadata` is enabled.
    /// See <https://doc.rust-lang.org/rustc/command-line-arguments.html#-l-link-the-generated-crate-to-a-native-library>
    /// for the list of modifiers accepted by rustc.
    pub fn link_lib_modifier(&mut self, link_lib_modifier: impl AsRef<OsStr>) -> &mut Build {
        self.link_lib_modifiers
            .push(link_lib_modifier.as_ref().into());
        self
    }

    /// Configures whether the compiler will emit position independent code.
    ///
    /// This option defaults to `false` for `windows-gnu` and bare metal targets and
    /// to `true` for all other targets.
    pub fn pic(&mut self, pic: bool) -> &mut Build {
        self.pic = Some(pic);
        self
    }

    /// Configures whether the Procedure Linkage Table is used for indirect
    /// calls into shared libraries.
    ///
    /// The PLT is used to provide features like lazy binding, but introduces
    /// a small performance loss due to extra pointer indirection. Setting
    /// `use_plt` to `false` can provide a small performance increase.
    ///
    /// Note that skipping the PLT requires a recent version of GCC/Clang.
    ///
    /// This only applies to ELF targets. It has no effect on other platforms.
    pub fn use_plt(&mut self, use_plt: bool) -> &mut Build {
        self.use_plt = Some(use_plt);
        self
    }

    /// Define whether metadata should be emitted for cargo to detect environment
    /// changes that should trigger a rebuild.
    ///
    /// NOTE that cc does not emit metadata to detect changes for `PATH`, since it could
    /// be changed every comilation yet does not affect the result of compilation
    /// (i.e. rust-analyzer adds temporary directory to `PATH`).
    ///
    /// cc in general, has no way detecting changes to compiler, as there are so many ways to
    /// change it and sidestep the detection, for example the compiler might be wrapped in a script
    /// so detecting change of the file, or using checksum won't work.
    ///
    /// We recommend users to decide for themselves, if they want rebuild if the compiler has been upgraded
    /// or changed, and how to detect that.
    ///
    /// This has no effect if the `cargo_metadata` option is `false`.
    ///
    /// This option defaults to `true`.
    pub fn emit_rerun_if_env_changed(&mut self, emit_rerun_if_env_changed: bool) -> &mut Build {
        self.emit_rerun_if_env_changed = emit_rerun_if_env_changed;
        self
    }

    /// Configures whether the /MT flag or the /MD flag will be passed to msvc build tools.
    ///
    /// This option defaults to `false`, and affect only msvc targets.
    pub fn static_crt(&mut self, static_crt: bool) -> &mut Build {
        self.static_crt = Some(static_crt);
        self
    }

    /// Configure whether *FLAGS variables are parsed using `shlex`, similarly to `make` and
    /// `cmake`.
    ///
    /// This option defaults to `false`.
    pub fn shell_escaped_flags(&mut self, shell_escaped_flags: bool) -> &mut Build {
        self.shell_escaped_flags = Some(shell_escaped_flags);
        self
    }

    #[doc(hidden)]
    pub fn __set_env<A, B>(&mut self, a: A, b: B) -> &mut Build
    where
        A: AsRef<OsStr>,
        B: AsRef<OsStr>,
    {
        self.env.push((a.as_ref().into(), b.as_ref().into()));
        self
    }

    /// Run the compiler, generating the file `output`
    ///
    /// This will return a result instead of panicking; see [`Self::compile()`] for
    /// the complete description.
    pub fn try_compile(&self, output: &str) -> Result<(), Error> {
        let mut output_components = Path::new(output).components();
        match (output_components.next(), output_components.next()) {
            (Some(Component::Normal(_)), None) => {}
            _ => {
                return Err(Error::new(
                    ErrorKind::InvalidArgument,
                    "argument of `compile` must be a single normal path component",
                ));
            }
        }

        let (lib_name, gnu_lib_name) = if output.starts_with("lib") && output.ends_with(".a") {
            (&output[3..output.len() - 2], output.to_owned())
        } else {
            let mut gnu = String::with_capacity(5 + output.len());
            gnu.push_str("lib");
            gnu.push_str(output);
            gnu.push_str(".a");
            (output, gnu)
        };
        let dst = self.get_out_dir()?;

        let objects = objects_from_files(&self.files, &dst)?;

        self.compile_objects(&objects)?;
        self.assemble(lib_name, &dst.join(gnu_lib_name), &objects)?;

        let target = self.get_target()?;
        if target.contains("msvc") {
            let compiler = self.get_base_compiler()?;
            let atlmfc_lib = compiler
                .env()
                .iter()
                .find(|&(var, _)| var.as_os_str() == OsStr::new("LIB"))
                .and_then(|(_, lib_paths)| {
                    env::split_paths(lib_paths).find(|path| {
                        let sub = Path::new("atlmfc/lib");
                        path.ends_with(sub) || path.parent().map_or(false, |p| p.ends_with(sub))
                    })
                });

            if let Some(atlmfc_lib) = atlmfc_lib {
                self.cargo_output.print_metadata(&format_args!(
                    "cargo:rustc-link-search=native={}",
                    atlmfc_lib.display()
                ));
            }
        }

        if self.link_lib_modifiers.is_empty() {
            self.cargo_output
                .print_metadata(&format_args!("cargo:rustc-link-lib=static={}", lib_name));
        } else {
            self.cargo_output.print_metadata(&format_args!(
                "cargo:rustc-link-lib=static:{}={}",
                JoinOsStrs {
                    slice: &self.link_lib_modifiers,
                    delimiter: ','
                },
                lib_name
            ));
        }
        self.cargo_output.print_metadata(&format_args!(
            "cargo:rustc-link-search=native={}",
            dst.display()
        ));

        // Add specific C++ libraries, if enabled.
        if self.cpp {
            if let Some(stdlib) = self.get_cpp_link_stdlib()? {
                self.cargo_output
                    .print_metadata(&format_args!("cargo:rustc-link-lib={}", stdlib.display()));
            }
            // Link c++ lib from WASI sysroot
            if Build::is_wasi_target(target.as_ref()) {
                if let Ok(wasi_sysroot) = self.wasi_sysroot() {
                    self.cargo_output.print_metadata(&format_args!(
                        "cargo:rustc-flags=-L {}/lib/{} -lstatic=c++ -lstatic=c++abi",
                        Path::new(&wasi_sysroot).display(),
                        target
                    ));
                }
            }
        }

        let cudart = match &self.cudart {
            Some(opt) => opt, // {none|shared|static}
            None => "none",
        };
        if cudart != "none" {
            if let Some(nvcc) = self.which(&self.get_compiler().path, None) {
                // Try to figure out the -L search path. If it fails,
                // it's on user to specify one by passing it through
                // RUSTFLAGS environment variable.
                let mut libtst = false;
                let mut libdir = nvcc;
                libdir.pop(); // remove 'nvcc'
                libdir.push("..");
                let target_arch = self.getenv_unwrap_str("CARGO_CFG_TARGET_ARCH")?;
                if cfg!(target_os = "linux") {
                    libdir.push("targets");
                    libdir.push(target_arch.to_owned() + "-linux");
                    libdir.push("lib");
                    libtst = true;
                } else if cfg!(target_env = "msvc") {
                    libdir.push("lib");
                    match target_arch.as_str() {
                        "x86_64" => {
                            libdir.push("x64");
                            libtst = true;
                        }
                        "x86" => {
                            libdir.push("Win32");
                            libtst = true;
                        }
                        _ => libtst = false,
                    }
                }
                if libtst && libdir.is_dir() {
                    self.cargo_output.print_metadata(&format_args!(
                        "cargo:rustc-link-search=native={}",
                        libdir.to_str().unwrap()
                    ));
                }

                // And now the -l flag.
                let lib = match cudart {
                    "shared" => "cudart",
                    "static" => "cudart_static",
                    bad => panic!("unsupported cudart option: {}", bad),
                };
                self.cargo_output
                    .print_metadata(&format_args!("cargo:rustc-link-lib={}", lib));
            }
        }

        Ok(())
    }

    /// Run the compiler, generating the file `output`
    ///
    /// # Library name
    ///
    /// The `output` string argument determines the file name for the compiled
    /// library. The Rust compiler will create an assembly named "lib"+output+".a".
    /// MSVC will create a file named output+".lib".
    ///
    /// The choice of `output` is close to arbitrary, but:
    ///
    /// - must be nonempty,
    /// - must not contain a path separator (`/`),
    /// - must be unique across all `compile` invocations made by the same build
    ///   script.
    ///
    /// If your build script compiles a single source file, the base name of
    /// that source file would usually be reasonable:
    ///
    /// ```no_run
    /// cc::Build::new().file("blobstore.c").compile("blobstore");
    /// ```
    ///
    /// Compiling multiple source files, some people use their crate's name, or
    /// their crate's name + "-cc".
    ///
    /// Otherwise, please use your imagination.
    ///
    /// For backwards compatibility, if `output` starts with "lib" *and* ends
    /// with ".a", a second "lib" prefix and ".a" suffix do not get added on,
    /// but this usage is deprecated; please omit `lib` and `.a` in the argument
    /// that you pass.
    ///
    /// # Panics
    ///
    /// Panics if `output` is not formatted correctly or if one of the underlying
    /// compiler commands fails. It can also panic if it fails reading file names
    /// or creating directories.
    pub fn compile(&self, output: &str) {
        if let Err(e) = self.try_compile(output) {
            fail(&e.message);
        }
    }

    /// Run the compiler, generating intermediate files, but without linking
    /// them into an archive file.
    ///
    /// This will return a list of compiled object files, in the same order
    /// as they were passed in as `file`/`files` methods.
    pub fn compile_intermediates(&self) -> Vec<PathBuf> {
        match self.try_compile_intermediates() {
            Ok(v) => v,
            Err(e) => fail(&e.message),
        }
    }

    /// Run the compiler, generating intermediate files, but without linking
    /// them into an archive file.
    ///
    /// This will return a result instead of panicking; see `compile_intermediates()` for the complete description.
    pub fn try_compile_intermediates(&self) -> Result<Vec<PathBuf>, Error> {
        let dst = self.get_out_dir()?;
        let objects = objects_from_files(&self.files, &dst)?;

        self.compile_objects(&objects)?;

        Ok(objects.into_iter().map(|v| v.dst).collect())
    }

    #[cfg(feature = "parallel")]
    fn compile_objects(&self, objs: &[Object]) -> Result<(), Error> {
        use std::cell::Cell;

        use parallel::async_executor::{block_on, YieldOnce};

        if objs.len() <= 1 {
            for obj in objs {
                let (mut cmd, name) = self.create_compile_object_cmd(obj)?;
                run(&mut cmd, &name, &self.cargo_output)?;
            }

            return Ok(());
        }

        // Limit our parallelism globally with a jobserver.
        let mut tokens = parallel::job_token::ActiveJobTokenServer::new();

        // When compiling objects in parallel we do a few dirty tricks to speed
        // things up:
        //
        // * First is that we use the `jobserver` crate to limit the parallelism
        //   of this build script. The `jobserver` crate will use a jobserver
        //   configured by Cargo for build scripts to ensure that parallelism is
        //   coordinated across C compilations and Rust compilations. Before we
        //   compile anything we make sure to wait until we acquire a token.
        //
        //   Note that this jobserver is cached globally so we only used one per
        //   process and only worry about creating it once.
        //
        // * Next we use spawn the process to actually compile objects in
        //   parallel after we've acquired a token to perform some work
        //
        // With all that in mind we compile all objects in a loop here, after we
        // acquire the appropriate tokens, Once all objects have been compiled
        // we wait on all the processes and propagate the results of compilation.

        let pendings = Cell::new(Vec::<(
            Command,
            Cow<'static, Path>,
            KillOnDrop,
            parallel::job_token::JobToken,
        )>::new());
        let is_disconnected = Cell::new(false);
        let has_made_progress = Cell::new(false);

        let wait_future = async {
            let mut error = None;
            // Buffer the stdout
            let mut stdout = io::BufWriter::with_capacity(128, io::stdout());

            loop {
                // If the other end of the pipe is already disconnected, then we're not gonna get any new jobs,
                // so it doesn't make sense to reuse the tokens; in fact,
                // releasing them as soon as possible (once we know that the other end is disconnected) is beneficial.
                // Imagine that the last file built takes an hour to finish; in this scenario,
                // by not releasing the tokens before that last file is done we would effectively block other processes from
                // starting sooner - even though we only need one token for that last file, not N others that were acquired.

                let mut pendings_is_empty = false;

                cell_update(&pendings, |mut pendings| {
                    // Try waiting on them.
                    pendings.retain_mut(|(cmd, program, child, _token)| {
                        match try_wait_on_child(
                            cmd,
                            program,
                            &mut child.0,
                            &mut stdout,
                            &mut child.1,
                        ) {
                            Ok(Some(())) => {
                                // Task done, remove the entry
                                has_made_progress.set(true);
                                false
                            }
                            Ok(None) => true, // Task still not finished, keep the entry
                            Err(err) => {
                                // Task fail, remove the entry.
                                // Since we can only return one error, log the error to make
                                // sure users always see all the compilation failures.
                                has_made_progress.set(true);

                                if self.cargo_output.warnings {
                                    let _ = writeln!(stdout, "cargo:warning={}", err);
                                }
                                error = Some(err);

                                false
                            }
                        }
                    });
                    pendings_is_empty = pendings.is_empty();
                    pendings
                });

                if pendings_is_empty && is_disconnected.get() {
                    break if let Some(err) = error {
                        Err(err)
                    } else {
                        Ok(())
                    };
                }

                YieldOnce::default().await;
            }
        };
        let spawn_future = async {
            for obj in objs {
                let (mut cmd, program) = self.create_compile_object_cmd(obj)?;
                let token = tokens.acquire().await?;
                let mut child = spawn(&mut cmd, &program, &self.cargo_output)?;
                let mut stderr_forwarder = StderrForwarder::new(&mut child);
                stderr_forwarder.set_non_blocking()?;

                cell_update(&pendings, |mut pendings| {
                    pendings.push((cmd, program, KillOnDrop(child, stderr_forwarder), token));
                    pendings
                });

                has_made_progress.set(true);
            }
            is_disconnected.set(true);

            Ok::<_, Error>(())
        };

        return block_on(wait_future, spawn_future, &has_made_progress);

        struct KillOnDrop(Child, StderrForwarder);

        impl Drop for KillOnDrop {
            fn drop(&mut self) {
                let child = &mut self.0;

                child.kill().ok();
            }
        }

        fn cell_update<T, F>(cell: &Cell<T>, f: F)
        where
            T: Default,
            F: FnOnce(T) -> T,
        {
            let old = cell.take();
            let new = f(old);
            cell.set(new);
        }
    }

    #[cfg(not(feature = "parallel"))]
    fn compile_objects(&self, objs: &[Object]) -> Result<(), Error> {
        for obj in objs {
            let (mut cmd, name) = self.create_compile_object_cmd(obj)?;
            run(&mut cmd, &name, &self.cargo_output)?;
        }

        Ok(())
    }

    fn create_compile_object_cmd(
        &self,
        obj: &Object,
    ) -> Result<(Command, Cow<'static, Path>), Error> {
        let asm_ext = AsmFileExt::from_path(&obj.src);
        let is_asm = asm_ext.is_some();
        let target = self.get_target()?;
        let msvc = target.contains("msvc");
        let compiler = self.try_get_compiler()?;
        let clang = compiler.is_like_clang();
        let gnu = compiler.family == ToolFamily::Gnu;

        let is_assembler_msvc = msvc && asm_ext == Some(AsmFileExt::DotAsm);
        let (mut cmd, name) = if is_assembler_msvc {
            let (cmd, name) = self.msvc_macro_assembler()?;
            (cmd, Cow::Borrowed(Path::new(name)))
        } else {
            let mut cmd = compiler.to_command();
            for (a, b) in self.env.iter() {
                cmd.env(a, b);
            }
            (
                cmd,
                compiler
                    .path
                    .file_name()
                    .ok_or_else(|| Error::new(ErrorKind::IOError, "Failed to get compiler path."))
                    .map(PathBuf::from)
                    .map(Cow::Owned)?,
            )
        };
        let is_arm = target.contains("aarch64") || target.contains("arm");
        command_add_output_file(
            &mut cmd,
            &obj.dst,
            CmdAddOutputFileArgs {
                cuda: self.cuda,
                is_assembler_msvc,
                msvc: compiler.is_like_msvc(),
                clang,
                gnu,
                is_asm,
                is_arm,
            },
        );
        // armasm and armasm64 don't requrie -c option
        if !is_assembler_msvc || !is_arm {
            cmd.arg("-c");
        }
        if self.cuda && self.cuda_file_count() > 1 {
            cmd.arg("--device-c");
        }
        if is_asm {
            cmd.args(self.asm_flags.iter().map(std::ops::Deref::deref));
        }
        if compiler.family == (ToolFamily::Msvc { clang_cl: true }) && !is_assembler_msvc {
            // #513: For `clang-cl`, separate flags/options from the input file.
            // When cross-compiling macOS -> Windows, this avoids interpreting
            // common `/Users/...` paths as the `/U` flag and triggering
            // `-Wslash-u-filename` warning.
            cmd.arg("--");
        }
        cmd.arg(&obj.src);
        if cfg!(target_os = "macos") {
            self.fix_env_for_apple_os(&mut cmd)?;
        }

        Ok((cmd, name))
    }

    /// This will return a result instead of panicking; see [`Self::expand()`] for
    /// the complete description.
    pub fn try_expand(&self) -> Result<Vec<u8>, Error> {
        let compiler = self.try_get_compiler()?;
        let mut cmd = compiler.to_command();
        for (a, b) in self.env.iter() {
            cmd.env(a, b);
        }
        cmd.arg("-E");

        assert!(
            self.files.len() <= 1,
            "Expand may only be called for a single file"
        );

        let is_asm = self
            .files
            .iter()
            .map(std::ops::Deref::deref)
            .find_map(AsmFileExt::from_path)
            .is_some();

        if compiler.family == (ToolFamily::Msvc { clang_cl: true }) && !is_asm {
            // #513: For `clang-cl`, separate flags/options from the input file.
            // When cross-compiling macOS -> Windows, this avoids interpreting
            // common `/Users/...` paths as the `/U` flag and triggering
            // `-Wslash-u-filename` warning.
            cmd.arg("--");
        }

        cmd.args(self.files.iter().map(std::ops::Deref::deref));

        let name = compiler
            .path
            .file_name()
            .ok_or_else(|| Error::new(ErrorKind::IOError, "Failed to get compiler path."))?;

        run_output(&mut cmd, name, &self.cargo_output)
    }

    /// Run the compiler, returning the macro-expanded version of the input files.
    ///
    /// This is only relevant for C and C++ files.
    ///
    /// # Panics
    /// Panics if more than one file is present in the config, or if compiler
    /// path has an invalid file name.
    ///
    /// # Example
    /// ```no_run
    /// let out = cc::Build::new().file("src/foo.c").expand();
    /// ```
    pub fn expand(&self) -> Vec<u8> {
        match self.try_expand() {
            Err(e) => fail(&e.message),
            Ok(v) => v,
        }
    }

    /// Get the compiler that's in use for this configuration.
    ///
    /// This function will return a `Tool` which represents the culmination
    /// of this configuration at a snapshot in time. The returned compiler can
    /// be inspected (e.g. the path, arguments, environment) to forward along to
    /// other tools, or the `to_command` method can be used to invoke the
    /// compiler itself.
    ///
    /// This method will take into account all configuration such as debug
    /// information, optimization level, include directories, defines, etc.
    /// Additionally, the compiler binary in use follows the standard
    /// conventions for this path, e.g. looking at the explicitly set compiler,
    /// environment variables (a number of which are inspected here), and then
    /// falling back to the default configuration.
    ///
    /// # Panics
    ///
    /// Panics if an error occurred while determining the architecture.
    pub fn get_compiler(&self) -> Tool {
        match self.try_get_compiler() {
            Ok(tool) => tool,
            Err(e) => fail(&e.message),
        }
    }

    /// Get the compiler that's in use for this configuration.
    ///
    /// This will return a result instead of panicking; see
    /// [`get_compiler()`](Self::get_compiler) for the complete description.
    pub fn try_get_compiler(&self) -> Result<Tool, Error> {
        let opt_level = self.get_opt_level()?;
        let target = self.get_target()?;

        let mut cmd = self.get_base_compiler()?;

        // Disable default flag generation via `no_default_flags` or environment variable
        let no_defaults = self.no_default_flags || self.getenv("CRATE_CC_NO_DEFAULTS").is_some();

        if !no_defaults {
            self.add_default_flags(&mut cmd, &target, &opt_level)?;
        }

        if let Some(ref std) = self.std {
            let separator = match cmd.family {
                ToolFamily::Msvc { .. } => ':',
                ToolFamily::Gnu | ToolFamily::Clang { .. } => '=',
            };
            cmd.push_cc_arg(format!("-std{}{}", separator, std).into());
        }

        for directory in self.include_directories.iter() {
            cmd.args.push("-I".into());
            cmd.args.push(directory.as_os_str().into());
        }

        if let Ok(flags) = self.envflags(if self.cpp { "CXXFLAGS" } else { "CFLAGS" }) {
            for arg in flags {
                cmd.push_cc_arg(arg.into());
            }
        }

        // If warnings and/or extra_warnings haven't been explicitly set,
        // then we set them only if the environment doesn't already have
        // CFLAGS/CXXFLAGS, since those variables presumably already contain
        // the desired set of warnings flags.

        if self.warnings.unwrap_or(!self.has_flags()) {
            let wflags = cmd.family.warnings_flags().into();
            cmd.push_cc_arg(wflags);
        }

        if self.extra_warnings.unwrap_or(!self.has_flags()) {
            if let Some(wflags) = cmd.family.extra_warnings_flags() {
                cmd.push_cc_arg(wflags.into());
            }
        }

        for flag in self.flags.iter() {
            cmd.args.push((**flag).into());
        }

        for flag in self.flags_supported.iter() {
            if self
                .is_flag_supported_inner(flag, &cmd.path, &target)
                .unwrap_or(false)
            {
                cmd.push_cc_arg((**flag).into());
            }
        }

        for (key, value) in self.definitions.iter() {
            if let Some(ref value) = *value {
                cmd.args.push(format!("-D{}={}", key, value).into());
            } else {
                cmd.args.push(format!("-D{}", key).into());
            }
        }

        if self.warnings_into_errors {
            let warnings_to_errors_flag = cmd.family.warnings_to_errors_flag().into();
            cmd.push_cc_arg(warnings_to_errors_flag);
        }

        Ok(cmd)
    }

    fn add_default_flags(
        &self,
        cmd: &mut Tool,
        target: &str,
        opt_level: &str,
    ) -> Result<(), Error> {
        // Non-target flags
        // If the flag is not conditioned on target variable, it belongs here :)
        match cmd.family {
            ToolFamily::Msvc { .. } => {
                cmd.push_cc_arg("-nologo".into());

                let crt_flag = match self.static_crt {
                    Some(true) => "-MT",
                    Some(false) => "-MD",
                    None => {
                        let features = self.getenv("CARGO_CFG_TARGET_FEATURE");
                        let features = features.as_deref().unwrap_or_default();
                        if features.to_string_lossy().contains("crt-static") {
                            "-MT"
                        } else {
                            "-MD"
                        }
                    }
                };
                cmd.push_cc_arg(crt_flag.into());

                match opt_level {
                    // Msvc uses /O1 to enable all optimizations that minimize code size.
                    "z" | "s" | "1" => cmd.push_opt_unless_duplicate("-O1".into()),
                    // -O3 is a valid value for gcc and clang compilers, but not msvc. Cap to /O2.
                    "2" | "3" => cmd.push_opt_unless_duplicate("-O2".into()),
                    _ => {}
                }
            }
            ToolFamily::Gnu | ToolFamily::Clang { .. } => {
                // arm-linux-androideabi-gcc 4.8 shipped with Android NDK does
                // not support '-Oz'
                if opt_level == "z" && !cmd.is_like_clang() {
                    cmd.push_opt_unless_duplicate("-Os".into());
                } else {
                    cmd.push_opt_unless_duplicate(format!("-O{}", opt_level).into());
                }

                if cmd.is_like_clang() && target.contains("windows") {
                    // Disambiguate mingw and msvc on Windows. Problem is that
                    // depending on the origin clang can default to a mismatchig
                    // run-time.
                    cmd.push_cc_arg(format!("--target={}", target).into());
                }

                if cmd.is_like_clang() && target.contains("android") {
                    // For compatibility with code that doesn't use pre-defined `__ANDROID__` macro.
                    // If compiler used via ndk-build or cmake (officially supported build methods)
                    // this macros is defined.
                    // See https://android.googlesource.com/platform/ndk/+/refs/heads/ndk-release-r21/build/cmake/android.toolchain.cmake#456
                    // https://android.googlesource.com/platform/ndk/+/refs/heads/ndk-release-r21/build/core/build-binary.mk#141
                    cmd.push_opt_unless_duplicate("-DANDROID".into());
                }

                if !target.contains("apple-ios")
                    && !target.contains("apple-watchos")
                    && !target.contains("apple-tvos")
                    && !target.contains("apple-visionos")
                {
                    cmd.push_cc_arg("-ffunction-sections".into());
                    cmd.push_cc_arg("-fdata-sections".into());
                }
                // Disable generation of PIC on bare-metal for now: rust-lld doesn't support this yet
                if self.pic.unwrap_or(
                    !target.contains("windows")
                        && !target.contains("-none-")
                        && !target.ends_with("-none")
                        && !target.contains("uefi"),
                ) {
                    cmd.push_cc_arg("-fPIC".into());
                    // PLT only applies if code is compiled with PIC support,
                    // and only for ELF targets.
                    if target.contains("linux") && !self.use_plt.unwrap_or(true) {
                        cmd.push_cc_arg("-fno-plt".into());
                    }
                }
                if Build::is_wasi_target(target) {
                    // WASI does not support exceptions yet.
                    // https://github.com/WebAssembly/exception-handling
                    cmd.push_cc_arg("-fno-exceptions".into());
                    // Link clang sysroot
                    if let Ok(wasi_sysroot) = self.wasi_sysroot() {
                        cmd.push_cc_arg(
                            format!("--sysroot={}", Path::new(&wasi_sysroot).display()).into(),
                        );
                    }
                }
            }
        }

        if self.get_debug() {
            if self.cuda {
                // NVCC debug flag
                cmd.args.push("-G".into());
            }
            let family = cmd.family;
            family.add_debug_flags(cmd, self.get_dwarf_version());
        }

        if self.get_force_frame_pointer() {
            let family = cmd.family;
            family.add_force_frame_pointer(cmd);
        }

        if !cmd.is_like_msvc() {
            if target.contains("i686") || target.contains("i586") {
                cmd.args.push("-m32".into());
            } else if target == "x86_64-unknown-linux-gnux32" {
                cmd.args.push("-mx32".into());
            } else if target.contains("x86_64") || target.contains("powerpc64") {
                cmd.args.push("-m64".into());
            }
        }

        // Target flags
        match cmd.family {
            ToolFamily::Clang { .. } => {
                if !(cmd.has_internal_target_arg
                    || (target.contains("android")
                        && android_clang_compiler_uses_target_arg_internally(&cmd.path)))
                {
                    let (arch, rest) = target.split_once('-').ok_or_else(|| {
                        Error::new(
                            ErrorKind::InvalidTarget,
                            format!("Invalid target `{}`: no `-` in it", target),
                        )
                    })?;

                    if target.contains("darwin") {
                        if let Some(arch) =
                            map_darwin_target_from_rust_to_compiler_architecture(target)
                        {
                            cmd.args
                                .push(format!("--target={}-apple-darwin", arch).into());
                        }
                    } else if target.contains("macabi") {
                        if let Some(arch) =
                            map_darwin_target_from_rust_to_compiler_architecture(target)
                        {
                            cmd.args
                                .push(format!("--target={}-apple-ios-macabi", arch).into());
                        }
                    } else if target.contains("ios-sim") {
                        if let Some(arch) =
                            map_darwin_target_from_rust_to_compiler_architecture(target)
                        {
                            let sdk_details =
                                apple_os_sdk_parts(AppleOs::Ios, &AppleArchSpec::Simulator(""));
                            let deployment_target =
                                self.apple_deployment_version(AppleOs::Ios, None, &sdk_details.sdk);
                            cmd.args.push(
                                format!(
                                    "--target={}-apple-ios{}-simulator",
                                    arch, deployment_target
                                )
                                .into(),
                            );
                        }
                    } else if target.contains("watchos-sim") {
                        if let Some(arch) =
                            map_darwin_target_from_rust_to_compiler_architecture(target)
                        {
                            let sdk_details =
                                apple_os_sdk_parts(AppleOs::WatchOs, &AppleArchSpec::Simulator(""));
                            let deployment_target = self.apple_deployment_version(
                                AppleOs::WatchOs,
                                None,
                                &sdk_details.sdk,
                            );
                            cmd.args.push(
                                format!(
                                    "--target={}-apple-watchos{}-simulator",
                                    arch, deployment_target
                                )
                                .into(),
                            );
                        }
                    } else if target.contains("tvos-sim") || target.contains("x86_64-apple-tvos") {
                        if let Some(arch) =
                            map_darwin_target_from_rust_to_compiler_architecture(target)
                        {
                            let sdk_details =
                                apple_os_sdk_parts(AppleOs::TvOs, &AppleArchSpec::Simulator(""));
                            let deployment_target = self.apple_deployment_version(
                                AppleOs::TvOs,
                                None,
                                &sdk_details.sdk,
                            );
                            cmd.args.push(
                                format!(
                                    "--target={}-apple-tvos{}-simulator",
                                    arch, deployment_target
                                )
                                .into(),
                            );
                        }
                    } else if target.contains("aarch64-apple-tvos") {
                        if let Some(arch) =
                            map_darwin_target_from_rust_to_compiler_architecture(target)
                        {
                            let sdk_details =
                                apple_os_sdk_parts(AppleOs::TvOs, &AppleArchSpec::Device(""));
                            let deployment_target = self.apple_deployment_version(
                                AppleOs::TvOs,
                                None,
                                &sdk_details.sdk,
                            );
                            cmd.args.push(
                                format!("--target={}-apple-tvos{}", arch, deployment_target).into(),
                            );
                        }
                    } else if target.contains("visionos-sim") {
                        if let Some(arch) =
                            map_darwin_target_from_rust_to_compiler_architecture(target)
                        {
                            let sdk_details = apple_os_sdk_parts(
                                AppleOs::VisionOS,
                                &AppleArchSpec::Simulator(""),
                            );
                            let deployment_target = self.apple_deployment_version(
                                AppleOs::VisionOS,
                                None,
                                &sdk_details.sdk,
                            );
                            cmd.args.push(
                                format!(
                                    "--target={}-apple-xros{}-simulator",
                                    arch, deployment_target
                                )
                                .into(),
                            );
                        }
                    } else if target.contains("visionos") {
                        if let Some(arch) =
                            map_darwin_target_from_rust_to_compiler_architecture(target)
                        {
                            let sdk_details =
                                apple_os_sdk_parts(AppleOs::VisionOS, &AppleArchSpec::Device(""));
                            let deployment_target = self.apple_deployment_version(
                                AppleOs::VisionOS,
                                None,
                                &sdk_details.sdk,
                            );
                            cmd.args.push(
                                format!("--target={}-apple-xros{}", arch, deployment_target).into(),
                            );
                        }
                    } else if let Ok(index) = target_info::RISCV_ARCH_MAPPING
                        .binary_search_by_key(&arch, |(arch, _)| arch)
                    {
                        cmd.args.push(
                            format!(
                                "--target={}-{}",
                                target_info::RISCV_ARCH_MAPPING[index].1,
                                rest
                            )
                            .into(),
                        );
                    } else if target.contains("uefi") {
                        if target.contains("x86_64") {
                            cmd.args.push("--target=x86_64-unknown-windows-gnu".into());
                        } else if target.contains("i686") {
                            cmd.args.push("--target=i686-unknown-windows-gnu".into())
                        } else if target.contains("aarch64") {
                            cmd.args.push("--target=aarch64-unknown-windows-gnu".into())
                        }
                    } else if target.ends_with("-freebsd") {
                        // FreeBSD only supports C++11 and above when compiling against libc++
                        // (available from FreeBSD 10 onwards). Under FreeBSD, clang uses libc++ by
                        // default on FreeBSD 10 and newer unless `--target` is manually passed to
                        // the compiler, in which case its default behavior differs:
                        // * If --target=xxx-unknown-freebsdX(.Y) is specified and X is greater than
                        //   or equal to 10, clang++ uses libc++
                        // * If --target=xxx-unknown-freebsd is specified (without a version),
                        //   clang++ cannot assume libc++ is available and reverts to a default of
                        //   libstdc++ (this behavior was changed in llvm 14).
                        //
                        // This breaks C++11 (or greater) builds if targeting FreeBSD with the
                        // generic xxx-unknown-freebsd triple on clang 13 or below *without*
                        // explicitly specifying that libc++ should be used.
                        // When cross-compiling, we can't infer from the rust/cargo target triple
                        // which major version of FreeBSD we are targeting, so we need to make sure
                        // that libc++ is used (unless the user has explicitly specified otherwise).
                        // There's no compelling reason to use a different approach when compiling
                        // natively.
                        if self.cpp && self.cpp_set_stdlib.is_none() {
                            cmd.push_cc_arg("-stdlib=libc++".into());
                        }

                        cmd.push_cc_arg(format!("--target={}", target).into());
                    } else if let Ok(index) = target_info::WINDOWS_TRIPLE_MAPPING
                        .binary_search_by_key(&target, |(target, _)| target)
                    {
                        cmd.args.push(
                            format!(
                                "--target={}-{}",
                                target_info::WINDOWS_TRIPLE_MAPPING[index].1,
                                rest
                            )
                            .into(),
                        )
                    } else {
                        cmd.push_cc_arg(format!("--target={}", target).into());
                    }
                }
            }
            ToolFamily::Msvc { clang_cl } => {
                // This is an undocumented flag from MSVC but helps with making
                // builds more reproducible by avoiding putting timestamps into
                // files.
                cmd.push_cc_arg("-Brepro".into());

                if clang_cl {
                    if target.contains("x86_64") {
                        cmd.push_cc_arg("-m64".into());
                    } else if target.contains("86") {
                        cmd.push_cc_arg("-m32".into());
                        cmd.push_cc_arg("-arch:IA32".into());
                    } else {
                        cmd.push_cc_arg(format!("--target={}", target).into());
                    }
                } else if target.contains("i586") {
                    cmd.push_cc_arg("-arch:IA32".into());
                } else if target.contains("arm64ec") {
                    cmd.push_cc_arg("-arm64EC".into());
                }
                // There is a check in corecrt.h that will generate a
                // compilation error if
                // _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE is
                // not defined to 1. The check was added in Windows
                // 8 days because only store apps were allowed on ARM.
                // This changed with the release of Windows 10 IoT Core.
                // The check will be going away in future versions of
                // the SDK, but for all released versions of the
                // Windows SDK it is required.
                if target.contains("arm") || target.contains("thumb") {
                    cmd.args
                        .push("-D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1".into());
                }
            }
            ToolFamily::Gnu => {
                if target.contains("darwin") {
                    if let Some(arch) = map_darwin_target_from_rust_to_compiler_architecture(target)
                    {
                        cmd.args.push("-arch".into());
                        cmd.args.push(arch.into());
                    }
                }

                if target.contains("-kmc-solid_") {
                    cmd.args.push("-finput-charset=utf-8".into());
                }

                if self.static_flag.is_none() {
                    let features = self.getenv("CARGO_CFG_TARGET_FEATURE");
                    let features = features.as_deref().unwrap_or_default();
                    if features.to_string_lossy().contains("crt-static") {
                        cmd.args.push("-static".into());
                    }
                }

                // armv7 targets get to use armv7 instructions
                if (target.starts_with("armv7") || target.starts_with("thumbv7"))
                    && (target.contains("-linux-") || target.contains("-kmc-solid_"))
                {
                    cmd.args.push("-march=armv7-a".into());

                    if target.ends_with("eabihf") {
                        // lowest common denominator FPU
                        cmd.args.push("-mfpu=vfpv3-d16".into());
                    }
                }

                // (x86 Android doesn't say "eabi")
                if target.contains("-androideabi") && target.contains("v7") {
                    // -march=armv7-a handled above
                    cmd.args.push("-mthumb".into());
                    if !target.contains("neon") {
                        // On android we can guarantee some extra float instructions
                        // (specified in the android spec online)
                        // NEON guarantees even more; see below.
                        cmd.args.push("-mfpu=vfpv3-d16".into());
                    }
                    cmd.args.push("-mfloat-abi=softfp".into());
                }

                if target.contains("neon") {
                    cmd.args.push("-mfpu=neon-vfpv4".into());
                }

                if target.starts_with("armv4t-unknown-linux-") {
                    cmd.args.push("-march=armv4t".into());
                    cmd.args.push("-marm".into());
                    cmd.args.push("-mfloat-abi=soft".into());
                }

                if target.starts_with("armv5te-unknown-linux-") {
                    cmd.args.push("-march=armv5te".into());
                    cmd.args.push("-marm".into());
                    cmd.args.push("-mfloat-abi=soft".into());
                }

                // For us arm == armv6 by default
                if target.starts_with("arm-unknown-linux-") {
                    cmd.args.push("-march=armv6".into());
                    cmd.args.push("-marm".into());
                    if target.ends_with("hf") {
                        cmd.args.push("-mfpu=vfp".into());
                    } else {
                        cmd.args.push("-mfloat-abi=soft".into());
                    }
                }

                // We can guarantee some settings for FRC
                if target.starts_with("arm-frc-") {
                    cmd.args.push("-march=armv7-a".into());
                    cmd.args.push("-mcpu=cortex-a9".into());
                    cmd.args.push("-mfpu=vfpv3".into());
                    cmd.args.push("-mfloat-abi=softfp".into());
                    cmd.args.push("-marm".into());
                }

                // Turn codegen down on i586 to avoid some instructions.
                if target.starts_with("i586-unknown-linux-") {
                    cmd.args.push("-march=pentium".into());
                }

                // Set codegen level for i686 correctly
                if target.starts_with("i686-unknown-linux-") {
                    cmd.args.push("-march=i686".into());
                }

                // Looks like `musl-gcc` makes it hard for `-m32` to make its way
                // all the way to the linker, so we need to actually instruct the
                // linker that we're generating 32-bit executables as well. This'll
                // typically only be used for build scripts which transitively use
                // these flags that try to compile executables.
                if target == "i686-unknown-linux-musl" || target == "i586-unknown-linux-musl" {
                    cmd.args.push("-Wl,-melf_i386".into());
                }

                if (target.starts_with("arm") || target.starts_with("thumb"))
                    && target.ends_with("-none-eabihf")
                {
                    cmd.args.push("-mfloat-abi=hard".into())
                }
                if target.starts_with("thumb") {
                    cmd.args.push("-mthumb".into());
                }
                if target.starts_with("thumbv6m") {
                    cmd.args.push("-march=armv6s-m".into());
                }
                if target.starts_with("thumbv7em") {
                    cmd.args.push("-march=armv7e-m".into());

                    if target.ends_with("eabihf") {
                        cmd.args.push("-mfpu=fpv4-sp-d16".into())
                    }
                }
                if target.starts_with("thumbv7m") {
                    cmd.args.push("-march=armv7-m".into());
                }
                if target.starts_with("thumbv8m.base") {
                    cmd.args.push("-march=armv8-m.base".into());
                }
                if target.starts_with("thumbv8m.main") {
                    cmd.args.push("-march=armv8-m.main".into());

                    if target.ends_with("eabihf") {
                        cmd.args.push("-mfpu=fpv5-sp-d16".into())
                    }
                }
                if target.starts_with("armebv7r") | target.starts_with("armv7r") {
                    if target.starts_with("armeb") {
                        cmd.args.push("-mbig-endian".into());
                    } else {
                        cmd.args.push("-mlittle-endian".into());
                    }

                    // ARM mode
                    cmd.args.push("-marm".into());

                    // R Profile
                    cmd.args.push("-march=armv7-r".into());

                    if target.ends_with("eabihf") {
                        // lowest common denominator FPU
                        // (see Cortex-R4 technical reference manual)
                        cmd.args.push("-mfpu=vfpv3-d16".into())
                    }
                }
                if target.starts_with("armv7a") {
                    cmd.args.push("-march=armv7-a".into());

                    if target.ends_with("eabihf") {
                        // lowest common denominator FPU
                        cmd.args.push("-mfpu=vfpv3-d16".into());
                    }
                }
                if target.starts_with("riscv32") || target.starts_with("riscv64") {
                    // get the 32i/32imac/32imc/64gc/64imac/... part
                    let mut parts = target.split('-');
                    if let Some(arch) = parts.next() {
                        let arch = &arch[5..];
                        if arch.starts_with("64") {
                            if target.contains("linux")
                                | target.contains("freebsd")
                                | target.contains("netbsd")
                                | target.contains("linux")
                            {
                                cmd.args.push(("-march=rv64gc").into());
                                cmd.args.push("-mabi=lp64d".into());
                            } else {
                                cmd.args.push(("-march=rv".to_owned() + arch).into());
                                cmd.args.push("-mabi=lp64".into());
                            }
                        } else if arch.starts_with("32") {
                            if target.contains("linux") {
                                cmd.args.push(("-march=rv32gc").into());
                                cmd.args.push("-mabi=ilp32d".into());
                            } else {
                                cmd.args.push(("-march=rv".to_owned() + arch).into());
                                cmd.args.push("-mabi=ilp32".into());
                            }
                        } else {
                            cmd.args.push("-mcmodel=medany".into());
                        }
                    }
                }
            }
        }

        if target.contains("-apple-") {
            self.apple_flags(cmd)?;
        }

        if self.static_flag.unwrap_or(false) {
            cmd.args.push("-static".into());
        }
        if self.shared_flag.unwrap_or(false) {
            cmd.args.push("-shared".into());
        }

        if self.cpp {
            match (self.cpp_set_stdlib.as_ref(), cmd.family) {
                (None, _) => {}
                (Some(stdlib), ToolFamily::Gnu) | (Some(stdlib), ToolFamily::Clang { .. }) => {
                    cmd.push_cc_arg(format!("-stdlib=lib{}", stdlib).into());
                }
                _ => {
                    self.cargo_output.print_warning(&format_args!("cpp_set_stdlib is specified, but the {:?} compiler does not support this option, ignored", cmd.family));
                }
            }
        }

        Ok(())
    }

    fn has_flags(&self) -> bool {
        let flags_env_var_name = if self.cpp { "CXXFLAGS" } else { "CFLAGS" };
        let flags_env_var_value = self.getenv_with_target_prefixes(flags_env_var_name);
        flags_env_var_value.is_ok()
    }

    fn msvc_macro_assembler(&self) -> Result<(Command, &'static str), Error> {
        let target = self.get_target()?;
        let tool = if target.contains("x86_64") {
            "ml64.exe"
        } else if target.contains("arm") {
            "armasm.exe"
        } else if target.contains("aarch64") {
            "armasm64.exe"
        } else {
            "ml.exe"
        };
        let mut cmd = self
            .windows_registry_find(&target, tool)
            .unwrap_or_else(|| self.cmd(tool));
        cmd.arg("-nologo"); // undocumented, yet working with armasm[64]
        for directory in self.include_directories.iter() {
            cmd.arg("-I").arg(&**directory);
        }
        if target.contains("aarch64") || target.contains("arm") {
            if self.get_debug() {
                cmd.arg("-g");
            }

            for (key, value) in self.definitions.iter() {
                cmd.arg("-PreDefine");
                if let Some(ref value) = *value {
                    if let Ok(i) = value.parse::<i32>() {
                        cmd.arg(format!("{} SETA {}", key, i));
                    } else if value.starts_with('"') && value.ends_with('"') {
                        cmd.arg(format!("{} SETS {}", key, value));
                    } else {
                        cmd.arg(format!("{} SETS \"{}\"", key, value));
                    }
                } else {
                    cmd.arg(format!("{} SETL {}", key, "{TRUE}"));
                }
            }
        } else {
            if self.get_debug() {
                cmd.arg("-Zi");
            }

            for (key, value) in self.definitions.iter() {
                if let Some(ref value) = *value {
                    cmd.arg(format!("-D{}={}", key, value));
                } else {
                    cmd.arg(format!("-D{}", key));
                }
            }
        }

        if target.contains("i686") || target.contains("i586") {
            cmd.arg("-safeseh");
        }

        Ok((cmd, tool))
    }

    fn assemble(&self, lib_name: &str, dst: &Path, objs: &[Object]) -> Result<(), Error> {
        // Delete the destination if it exists as we want to
        // create on the first iteration instead of appending.
        let _ = fs::remove_file(dst);

        // Add objects to the archive in limited-length batches. This helps keep
        // the length of the command line within a reasonable length to avoid
        // blowing system limits on limiting platforms like Windows.
        let objs: Vec<_> = objs
            .iter()
            .map(|o| o.dst.as_path())
            .chain(self.objects.iter().map(std::ops::Deref::deref))
            .collect();
        for chunk in objs.chunks(100) {
            self.assemble_progressive(dst, chunk)?;
        }

        if self.cuda && self.cuda_file_count() > 0 {
            // Link the device-side code and add it to the target library,
            // so that non-CUDA linker can link the final binary.

            let out_dir = self.get_out_dir()?;
            let dlink = out_dir.join(lib_name.to_owned() + "_dlink.o");
            let mut nvcc = self.get_compiler().to_command();
            nvcc.arg("--device-link").arg("-o").arg(&dlink).arg(dst);
            run(&mut nvcc, "nvcc", &self.cargo_output)?;
            self.assemble_progressive(dst, &[dlink.as_path()])?;
        }

        let target = self.get_target()?;
        if target.contains("msvc") {
            // The Rust compiler will look for libfoo.a and foo.lib, but the
            // MSVC linker will also be passed foo.lib, so be sure that both
            // exist for now.

            let lib_dst = dst.with_file_name(format!("{}.lib", lib_name));
            let _ = fs::remove_file(&lib_dst);
            match fs::hard_link(dst, &lib_dst).or_else(|_| {
                // if hard-link fails, just copy (ignoring the number of bytes written)
                fs::copy(dst, &lib_dst).map(|_| ())
            }) {
                Ok(_) => (),
                Err(_) => {
                    return Err(Error::new(
                        ErrorKind::IOError,
                        "Could not copy or create a hard-link to the generated lib file.",
                    ));
                }
            };
        } else {
            // Non-msvc targets (those using `ar`) need a separate step to add
            // the symbol table to archives since our construction command of
            // `cq` doesn't add it for us.
            let (mut ar, cmd, _any_flags) = self.get_ar()?;

            // NOTE: We add `s` even if flags were passed using $ARFLAGS/ar_flag, because `s`
            // here represents a _mode_, not an arbitrary flag. Further discussion of this choice
            // can be seen in https://github.com/rust-lang/cc-rs/pull/763.
            run(ar.arg("s").arg(dst), &cmd, &self.cargo_output)?;
        }

        Ok(())
    }

    fn assemble_progressive(&self, dst: &Path, objs: &[&Path]) -> Result<(), Error> {
        let target = self.get_target()?;

        let (mut cmd, program, any_flags) = self.get_ar()?;
        if target.contains("msvc") && !program.to_string_lossy().contains("llvm-ar") {
            // NOTE: -out: here is an I/O flag, and so must be included even if $ARFLAGS/ar_flag is
            // in use. -nologo on the other hand is just a regular flag, and one that we'll skip if
            // the caller has explicitly dictated the flags they want. See
            // https://github.com/rust-lang/cc-rs/pull/763 for further discussion.
            let mut out = OsString::from("-out:");
            out.push(dst);
            cmd.arg(out);
            if !any_flags {
                cmd.arg("-nologo");
            }
            // If the library file already exists, add the library name
            // as an argument to let lib.exe know we are appending the objs.
            if dst.exists() {
                cmd.arg(dst);
            }
            cmd.args(objs);
            run(&mut cmd, &program, &self.cargo_output)?;
        } else {
            // Set an environment variable to tell the OSX archiver to ensure
            // that all dates listed in the archive are zero, improving
            // determinism of builds. AFAIK there's not really official
            // documentation of this but there's a lot of references to it if
            // you search google.
            //
            // You can reproduce this locally on a mac with:
            //
            //      $ touch foo.c
            //      $ cc -c foo.c -o foo.o
            //
            //      # Notice that these two checksums are different
            //      $ ar crus libfoo1.a foo.o && sleep 2 && ar crus libfoo2.a foo.o
            //      $ md5sum libfoo*.a
            //
            //      # Notice that these two checksums are the same
            //      $ export ZERO_AR_DATE=1
            //      $ ar crus libfoo1.a foo.o && sleep 2 && touch foo.o && ar crus libfoo2.a foo.o
            //      $ md5sum libfoo*.a
            //
            // In any case if this doesn't end up getting read, it shouldn't
            // cause that many issues!
            cmd.env("ZERO_AR_DATE", "1");

            // NOTE: We add cq here regardless of whether $ARFLAGS/ar_flag have been used because
            // it dictates the _mode_ ar runs in, which the setter of $ARFLAGS/ar_flag can't
            // dictate. See https://github.com/rust-lang/cc-rs/pull/763 for further discussion.
            run(
                cmd.arg("cq").arg(dst).args(objs),
                &program,
                &self.cargo_output,
            )?;
        }

        Ok(())
    }

    fn apple_flags(&self, cmd: &mut Tool) -> Result<(), Error> {
        let target = self.get_target()?;
        let os = if target.contains("-darwin") {
            AppleOs::MacOs
        } else if target.contains("-watchos") {
            AppleOs::WatchOs
        } else if target.contains("-tvos") {
            AppleOs::TvOs
        } else if target.contains("-visionos") {
            AppleOs::VisionOS
        } else {
            AppleOs::Ios
        };
        let is_mac = matches!(os, AppleOs::MacOs);

        let arch_str = target.split('-').nth(0).ok_or_else(|| {
            Error::new(
                ErrorKind::ArchitectureInvalid,
                format!("Unknown architecture for {:?} target.", os),
            )
        })?;

        let is_catalyst = match target.split('-').nth(3) {
            Some(v) => v == "macabi",
            None => false,
        };

        let is_arm_sim = match target.split('-').nth(3) {
            Some(v) => v == "sim",
            None => false,
        };

        let arch = if is_mac {
            match arch_str {
                "i686" => AppleArchSpec::Device("-m32"),
                "x86_64" | "x86_64h" | "aarch64" | "arm64e" => AppleArchSpec::Device("-m64"),
                _ => {
                    return Err(Error::new(
                        ErrorKind::ArchitectureInvalid,
                        "Unknown architecture for macOS target.",
                    ));
                }
            }
        } else if is_catalyst {
            match arch_str {
                "arm64e" => AppleArchSpec::Catalyst("arm64e"),
                "arm64" | "aarch64" => AppleArchSpec::Catalyst("arm64"),
                "x86_64" | "x86_64h" => AppleArchSpec::Catalyst("-m64"),
                _ => {
                    return Err(Error::new(
                        ErrorKind::ArchitectureInvalid,
                        "Unknown architecture for iOS target.",
                    ));
                }
            }
        } else if is_arm_sim {
            match arch_str {
                "arm64" | "aarch64" => AppleArchSpec::Simulator("arm64"),
                "x86_64" | "x86_64h" => AppleArchSpec::Simulator("-m64"),
                _ => {
                    return Err(Error::new(
                        ErrorKind::ArchitectureInvalid,
                        "Unknown architecture for simulator target.",
                    ));
                }
            }
        } else {
            match arch_str {
                "arm" | "armv7" | "thumbv7" => AppleArchSpec::Device("armv7"),
                "armv7k" => AppleArchSpec::Device("armv7k"),
                "armv7s" | "thumbv7s" => AppleArchSpec::Device("armv7s"),
                "arm64e" => AppleArchSpec::Device("arm64e"),
                "arm64" | "aarch64" => AppleArchSpec::Device("arm64"),
                "arm64_32" => AppleArchSpec::Device("arm64_32"),
                "i386" | "i686" => AppleArchSpec::Simulator("-m32"),
                "x86_64" | "x86_64h" => AppleArchSpec::Simulator("-m64"),
                _ => {
                    return Err(Error::new(
                        ErrorKind::ArchitectureInvalid,
                        format!("Unknown architecture for {:?} target.", os),
                    ));
                }
            }
        };

        let sdk_details = apple_os_sdk_parts(os, &arch);
        let min_version = self.apple_deployment_version(os, Some(arch_str), &sdk_details.sdk);

        match arch {
            AppleArchSpec::Device(_) if is_mac => {
                cmd.args
                    .push(format!("-mmacosx-version-min={}", min_version).into());
            }
            AppleArchSpec::Device(arch) => {
                cmd.args.push("-arch".into());
                cmd.args.push(arch.into());
                // `-mxros-version-min` does not exist
                // https://github.com/llvm/llvm-project/issues/88271
                if os != AppleOs::VisionOS {
                    cmd.args.push(
                        format!("-m{}os-version-min={}", sdk_details.sdk_prefix, min_version)
                            .into(),
                    );
                }
            }
            AppleArchSpec::Simulator(arch) => {
                if arch.starts_with('-') {
                    // -m32 or -m64
                    cmd.args.push(arch.into());
                } else {
                    cmd.args.push("-arch".into());
                    cmd.args.push(arch.into());
                }
                if os != AppleOs::VisionOS {
                    cmd.args.push(
                        format!(
                            "-m{}simulator-version-min={}",
                            sdk_details.sim_prefix, min_version
                        )
                        .into(),
                    );
                }
            }
            AppleArchSpec::Catalyst(_) => {}
        };

        // AppleClang sometimes requires sysroot even for darwin
        if cmd.is_xctoolchain_clang() || !target.ends_with("-darwin") {
            self.cargo_output.print_metadata(&format_args!(
                "Detecting {:?} SDK path for {}",
                os, sdk_details.sdk
            ));
            let sdk_path = self.apple_sdk_root(&sdk_details.sdk)?;

            cmd.args.push("-isysroot".into());
            cmd.args.push(OsStr::new(&sdk_path).to_owned());

            if let AppleArchSpec::Catalyst(_) = arch {
                // Mac Catalyst uses the macOS SDK, but to compile against and
                // link to iOS-specific frameworks, we should have the support
                // library stubs in the include and library search path.
                let ios_support = Path::new(&sdk_path).join("System/iOSSupport");

                cmd.args.extend([
                    // Header search path
                    OsString::from("-isystem"),
                    ios_support.join("usr/include").into(),
                    // Framework header search path
                    OsString::from("-iframework"),
                    ios_support.join("System/Library/Frameworks").into(),
                    // Library search path
                    {
                        let mut s = OsString::from("-L");
                        s.push(ios_support.join("usr/lib"));
                        s
                    },
                    // Framework linker search path
                    {
                        // Technically, we _could_ avoid emitting `-F`, as
                        // `-iframework` implies it, but let's keep it in for
                        // clarity.
                        let mut s = OsString::from("-F");
                        s.push(ios_support.join("System/Library/Frameworks"));
                        s
                    },
                ]);
            }
        }

        Ok(())
    }

    fn cmd<P: AsRef<OsStr>>(&self, prog: P) -> Command {
        let mut cmd = Command::new(prog);
        for (a, b) in self.env.iter() {
            cmd.env(a, b);
        }
        cmd
    }

    fn get_base_compiler(&self) -> Result<Tool, Error> {
        let out_dir = self.get_out_dir().ok();
        let out_dir = out_dir.as_deref();

        if let Some(c) = &self.compiler {
            return Ok(Tool::new(
                (**c).to_owned(),
                &self.cached_compiler_family,
                &self.cargo_output,
                out_dir,
            ));
        }
        let host = self.get_host()?;
        let target = self.get_target()?;
        let target = &*target;
        let (env, msvc, gnu, traditional, clang) = if self.cpp {
            ("CXX", "cl.exe", "g++", "c++", "clang++")
        } else {
            ("CC", "cl.exe", "gcc", "cc", "clang")
        };

        // On historical Solaris systems, "cc" may have been Sun Studio, which
        // is not flag-compatible with "gcc".  This history casts a long shadow,
        // and many modern illumos distributions today ship GCC as "gcc" without
        // also making it available as "cc".
        let default = if host.contains("solaris") || host.contains("illumos") {
            gnu
        } else {
            traditional
        };

        let cl_exe = self.windows_registry_find_tool(target, "cl.exe");

        let tool_opt: Option<Tool> = self
            .env_tool(env)
            .map(|(tool, wrapper, args)| {
                // find the driver mode, if any
                const DRIVER_MODE: &str = "--driver-mode=";
                let driver_mode = args
                    .iter()
                    .find(|a| a.starts_with(DRIVER_MODE))
                    .map(|a| &a[DRIVER_MODE.len()..]);
                // Chop off leading/trailing whitespace to work around
                // semi-buggy build scripts which are shared in
                // makefiles/configure scripts (where spaces are far more
                // lenient)
                let mut t = Tool::with_clang_driver(
                    tool,
                    driver_mode,
                    &self.cached_compiler_family,
                    &self.cargo_output,
                    out_dir,
                );
                if let Some(cc_wrapper) = wrapper {
                    t.cc_wrapper_path = Some(Path::new(&cc_wrapper).to_owned());
                }
                for arg in args {
                    t.cc_wrapper_args.push(arg.into());
                }
                t
            })
            .or_else(|| {
                if target.contains("emscripten") {
                    let tool = if self.cpp { "em++" } else { "emcc" };
                    // Windows uses bat file so we have to be a bit more specific
                    if cfg!(windows) {
                        let mut t = Tool::with_family(
                            PathBuf::from("cmd"),
                            ToolFamily::Clang { zig_cc: false },
                        );
                        t.args.push("/c".into());
                        t.args.push(format!("{}.bat", tool).into());
                        Some(t)
                    } else {
                        Some(Tool::new(
                            PathBuf::from(tool),
                            &self.cached_compiler_family,
                            &self.cargo_output,
                            out_dir,
                        ))
                    }
                } else {
                    None
                }
            })
            .or_else(|| cl_exe.clone());

        let tool = match tool_opt {
            Some(t) => t,
            None => {
                let compiler = if host.contains("windows") && target.contains("windows") {
                    if target.contains("msvc") {
                        msvc.to_string()
                    } else {
                        let cc = if target.contains("llvm") { clang } else { gnu };
                        format!("{}.exe", cc)
                    }
                } else if target.contains("apple-ios")
                    | target.contains("apple-watchos")
                    | target.contains("apple-tvos")
                    | target.contains("apple-visionos")
                {
                    clang.to_string()
                } else if target.contains("android") {
                    autodetect_android_compiler(target, &host, gnu, clang)
                } else if target.contains("cloudabi") {
                    format!("{}-{}", target, traditional)
                } else if Build::is_wasi_target(target) {
                    if self.cpp {
                        "clang++".to_string()
                    } else {
                        "clang".to_string()
                    }
                } else if target.contains("vxworks") {
                    if self.cpp {
                        "wr-c++".to_string()
                    } else {
                        "wr-cc".to_string()
                    }
                } else if target.starts_with("armv7a-kmc-solid_") {
                    format!("arm-kmc-eabi-{}", gnu)
                } else if target.starts_with("aarch64-kmc-solid_") {
                    format!("aarch64-kmc-elf-{}", gnu)
                } else if &*self.get_host()? != target {
                    let prefix = self.prefix_for_target(target);
                    match prefix {
                        Some(prefix) => {
                            let cc = if target.contains("llvm") { clang } else { gnu };
                            format!("{}-{}", prefix, cc)
                        }
                        None => default.to_string(),
                    }
                } else {
                    default.to_string()
                };

                let mut t = Tool::new(
                    PathBuf::from(compiler),
                    &self.cached_compiler_family,
                    &self.cargo_output,
                    out_dir,
                );
                if let Some(cc_wrapper) = self.rustc_wrapper_fallback() {
                    t.cc_wrapper_path = Some(Path::new(&cc_wrapper).to_owned());
                }
                t
            }
        };

        let mut tool = if self.cuda {
            assert!(
                tool.args.is_empty(),
                "CUDA compilation currently assumes empty pre-existing args"
            );
            let nvcc = match self.getenv_with_target_prefixes("NVCC") {
                Err(_) => PathBuf::from("nvcc"),
                Ok(nvcc) => PathBuf::from(&*nvcc),
            };
            let mut nvcc_tool = Tool::with_features(
                nvcc,
                None,
                self.cuda,
                &self.cached_compiler_family,
                &self.cargo_output,
                out_dir,
            );
            if self.ccbin {
                nvcc_tool
                    .args
                    .push(format!("-ccbin={}", tool.path.display()).into());
            }
            nvcc_tool.family = tool.family;
            nvcc_tool
        } else {
            tool
        };

        // New "standalone" C/C++ cross-compiler executables from recent Android NDK
        // are just shell scripts that call main clang binary (from Android NDK) with
        // proper `--target` argument.
        //
        // For example, armv7a-linux-androideabi16-clang passes
        // `--target=armv7a-linux-androideabi16` to clang.
        //
        // As the shell script calls the main clang binary, the command line limit length
        // on Windows is restricted to around 8k characters instead of around 32k characters.
        // To remove this limit, we call the main clang binary directly and construct the
        // `--target=` ourselves.
        if host.contains("windows") && android_clang_compiler_uses_target_arg_internally(&tool.path)
        {
            if let Some(path) = tool.path.file_name() {
                let file_name = path.to_str().unwrap().to_owned();
                let (target, clang) = file_name.split_at(file_name.rfind('-').unwrap());

                tool.has_internal_target_arg = true;
                tool.path.set_file_name(clang.trim_start_matches('-'));
                tool.path.set_extension("exe");
                tool.args.push(format!("--target={}", target).into());

                // Additionally, shell scripts for target i686-linux-android versions 16 to 24
                // pass the `mstackrealign` option so we do that here as well.
                if target.contains("i686-linux-android") {
                    let (_, version) = target.split_at(target.rfind('d').unwrap() + 1);
                    if let Ok(version) = version.parse::<u32>() {
                        if version > 15 && version < 25 {
                            tool.args.push("-mstackrealign".into());
                        }
                    }
                }
            };
        }

        // If we found `cl.exe` in our environment, the tool we're returning is
        // an MSVC-like tool, *and* no env vars were set then set env vars for
        // the tool that we're returning.
        //
        // Env vars are needed for things like `link.exe` being put into PATH as
        // well as header include paths sometimes. These paths are automatically
        // included by default but if the `CC` or `CXX` env vars are set these
        // won't be used. This'll ensure that when the env vars are used to
        // configure for invocations like `clang-cl` we still get a "works out
        // of the box" experience.
        if let Some(cl_exe) = cl_exe {
            if tool.family == (ToolFamily::Msvc { clang_cl: true })
                && tool.env.is_empty()
                && target.contains("msvc")
            {
                for (k, v) in cl_exe.env.iter() {
                    tool.env.push((k.to_owned(), v.to_owned()));
                }
            }
        }

        if target.contains("msvc") && tool.family == ToolFamily::Gnu {
            self.cargo_output
                .print_warning(&"GNU compiler is not supported for this target");
        }

        Ok(tool)
    }

    /// Returns a fallback `cc_compiler_wrapper` by introspecting `RUSTC_WRAPPER`
    fn rustc_wrapper_fallback(&self) -> Option<Arc<OsStr>> {
        // No explicit CC wrapper was detected, but check if RUSTC_WRAPPER
        // is defined and is a build accelerator that is compatible with
        // C/C++ compilers (e.g. sccache)
        const VALID_WRAPPERS: &[&str] = &["sccache", "cachepot", "buildcache"];

        let rustc_wrapper = self.getenv("RUSTC_WRAPPER")?;
        let wrapper_path = Path::new(&rustc_wrapper);
        let wrapper_stem = wrapper_path.file_stem()?;

        if VALID_WRAPPERS.contains(&wrapper_stem.to_str()?) {
            Some(rustc_wrapper)
        } else {
            None
        }
    }

    /// Returns compiler path, optional modifier name from whitelist, and arguments vec
    fn env_tool(&self, name: &str) -> Option<(PathBuf, Option<Arc<OsStr>>, Vec<String>)> {
        let tool = self.getenv_with_target_prefixes(name).ok()?;
        let tool = tool.to_string_lossy();
        let tool = tool.trim();

        if tool.is_empty() {
            return None;
        }

        // If this is an exact path on the filesystem we don't want to do any
        // interpretation at all, just pass it on through. This'll hopefully get
        // us to support spaces-in-paths.
        if Path::new(tool).exists() {
            return Some((
                PathBuf::from(tool),
                self.rustc_wrapper_fallback(),
                Vec::new(),
            ));
        }

        // Ok now we want to handle a couple of scenarios. We'll assume from
        // here on out that spaces are splitting separate arguments. Two major
        // features we want to support are:
        //
        //      CC='sccache cc'
        //
        // aka using `sccache` or any other wrapper/caching-like-thing for
        // compilations. We want to know what the actual compiler is still,
        // though, because our `Tool` API support introspection of it to see
        // what compiler is in use.
        //
        // additionally we want to support
        //
        //      CC='cc -flag'
        //
        // where the CC env var is used to also pass default flags to the C
        // compiler.
        //
        // It's true that everything here is a bit of a pain, but apparently if
        // you're not literally make or bash then you get a lot of bug reports.
        let mut known_wrappers = vec![
            "ccache",
            "distcc",
            "sccache",
            "icecc",
            "cachepot",
            "buildcache",
        ];
        let custom_wrapper = self.getenv("CC_KNOWN_WRAPPER_CUSTOM");
        if custom_wrapper.is_some() {
            known_wrappers.push(custom_wrapper.as_deref().unwrap().to_str().unwrap());
        }

        let mut parts = tool.split_whitespace();
        let maybe_wrapper = match parts.next() {
            Some(s) => s,
            None => return None,
        };

        let file_stem = Path::new(maybe_wrapper).file_stem()?.to_str()?;
        if known_wrappers.contains(&file_stem) {
            if let Some(compiler) = parts.next() {
                return Some((
                    compiler.into(),
                    Some(Arc::<OsStr>::from(OsStr::new(&maybe_wrapper))),
                    parts.map(|s| s.to_string()).collect(),
                ));
            }
        }

        Some((
            maybe_wrapper.into(),
            self.rustc_wrapper_fallback(),
            parts.map(|s| s.to_string()).collect(),
        ))
    }

    /// Returns the C++ standard library:
    /// 1. If [`cpp_link_stdlib`](cc::Build::cpp_link_stdlib) is set, uses its value.
    /// 2. Else if the `CXXSTDLIB` environment variable is set, uses its value.
    /// 3. Else the default is `libc++` for OS X and BSDs, `libc++_shared` for Android,
    ///    `None` for MSVC and `libstdc++` for anything else.
    fn get_cpp_link_stdlib(&self) -> Result<Option<Cow<'_, Path>>, Error> {
        match &self.cpp_link_stdlib {
            Some(s) => Ok(s.as_deref().map(Path::new).map(Cow::Borrowed)),
            None => {
                if let Ok(stdlib) = self.getenv_with_target_prefixes("CXXSTDLIB") {
                    if stdlib.is_empty() {
                        Ok(None)
                    } else {
                        Ok(Some(Cow::Owned(Path::new(&stdlib).to_owned())))
                    }
                } else {
                    let target = self.get_target()?;
                    if target.contains("msvc") {
                        Ok(None)
                    } else if target.contains("apple")
                        | target.contains("freebsd")
                        | target.contains("openbsd")
                        | target.contains("aix")
                        | target.contains("linux-ohos")
                        | target.contains("-wasi")
                    {
                        Ok(Some(Cow::Borrowed(Path::new("c++"))))
                    } else if target.contains("android") {
                        Ok(Some(Cow::Borrowed(Path::new("c++_shared"))))
                    } else {
                        Ok(Some(Cow::Borrowed(Path::new("stdc++"))))
                    }
                }
            }
        }
    }

    fn get_ar(&self) -> Result<(Command, PathBuf, bool), Error> {
        self.try_get_archiver_and_flags()
    }

    /// Get the archiver (ar) that's in use for this configuration.
    ///
    /// You can use [`Command::get_program`] to get just the path to the command.
    ///
    /// This method will take into account all configuration such as debug
    /// information, optimization level, include directories, defines, etc.
    /// Additionally, the compiler binary in use follows the standard
    /// conventions for this path, e.g. looking at the explicitly set compiler,
    /// environment variables (a number of which are inspected here), and then
    /// falling back to the default configuration.
    ///
    /// # Panics
    ///
    /// Panics if an error occurred while determining the architecture.
    pub fn get_archiver(&self) -> Command {
        match self.try_get_archiver() {
            Ok(tool) => tool,
            Err(e) => fail(&e.message),
        }
    }

    /// Get the archiver that's in use for this configuration.
    ///
    /// This will return a result instead of panicking;
    /// see [`Self::get_archiver`] for the complete description.
    pub fn try_get_archiver(&self) -> Result<Command, Error> {
        Ok(self.try_get_archiver_and_flags()?.0)
    }

    fn try_get_archiver_and_flags(&self) -> Result<(Command, PathBuf, bool), Error> {
        let (mut cmd, name) = self.get_base_archiver()?;
        let mut any_flags = false;
        if let Ok(flags) = self.envflags("ARFLAGS") {
            any_flags |= !flags.is_empty();
            cmd.args(flags);
        }
        for flag in &self.ar_flags {
            any_flags = true;
            cmd.arg(&**flag);
        }
        Ok((cmd, name, any_flags))
    }

    fn get_base_archiver(&self) -> Result<(Command, PathBuf), Error> {
        if let Some(ref a) = self.archiver {
            let archiver = &**a;
            return Ok((self.cmd(archiver), archiver.into()));
        }

        self.get_base_archiver_variant("AR", "ar")
    }

    /// Get the ranlib that's in use for this configuration.
    ///
    /// You can use [`Command::get_program`] to get just the path to the command.
    ///
    /// This method will take into account all configuration such as debug
    /// information, optimization level, include directories, defines, etc.
    /// Additionally, the compiler binary in use follows the standard
    /// conventions for this path, e.g. looking at the explicitly set compiler,
    /// environment variables (a number of which are inspected here), and then
    /// falling back to the default configuration.
    ///
    /// # Panics
    ///
    /// Panics if an error occurred while determining the architecture.
    pub fn get_ranlib(&self) -> Command {
        match self.try_get_ranlib() {
            Ok(tool) => tool,
            Err(e) => fail(&e.message),
        }
    }

    /// Get the ranlib that's in use for this configuration.
    ///
    /// This will return a result instead of panicking;
    /// see [`Self::get_ranlib`] for the complete description.
    pub fn try_get_ranlib(&self) -> Result<Command, Error> {
        let mut cmd = self.get_base_ranlib()?;
        if let Ok(flags) = self.envflags("RANLIBFLAGS") {
            cmd.args(flags);
        }
        Ok(cmd)
    }

    fn get_base_ranlib(&self) -> Result<Command, Error> {
        if let Some(ref r) = self.ranlib {
            return Ok(self.cmd(&**r));
        }

        Ok(self.get_base_archiver_variant("RANLIB", "ranlib")?.0)
    }

    fn get_base_archiver_variant(
        &self,
        env: &str,
        tool: &str,
    ) -> Result<(Command, PathBuf), Error> {
        let target = self.get_target()?;
        let mut name = PathBuf::new();
        let tool_opt: Option<Command> = self
            .env_tool(env)
            .map(|(tool, _wrapper, args)| {
                name.clone_from(&tool);
                let mut cmd = self.cmd(tool);
                cmd.args(args);
                cmd
            })
            .or_else(|| {
                if target.contains("emscripten") {
                    // Windows use bat files so we have to be a bit more specific
                    if cfg!(windows) {
                        let mut cmd = self.cmd("cmd");
                        name = format!("em{}.bat", tool).into();
                        cmd.arg("/c").arg(&name);
                        Some(cmd)
                    } else {
                        name = format!("em{}", tool).into();
                        Some(self.cmd(&name))
                    }
                } else if target.starts_with("wasm32") {
                    // Formally speaking one should be able to use this approach,
                    // parsing -print-search-dirs output, to cover all clang targets,
                    // including Android SDKs and other cross-compilation scenarios...
                    // And even extend it to gcc targets by searching for "ar" instead
                    // of "llvm-ar"...
                    let compiler = self.get_base_compiler().ok()?;
                    if compiler.is_like_clang() {
                        name = format!("llvm-{}", tool).into();
                        self.search_programs(
                            &mut self.cmd(&compiler.path),
                            &name,
                            &self.cargo_output,
                        )
                        .map(|name| self.cmd(name))
                    } else {
                        None
                    }
                } else {
                    None
                }
            });

        let default = tool.to_string();
        let tool = match tool_opt {
            Some(t) => t,
            None => {
                if target.contains("android") {
                    name = format!("llvm-{}", tool).into();
                    match Command::new(&name).arg("--version").status() {
                        Ok(status) if status.success() => (),
                        _ => name = format!("{}-{}", target.replace("armv7", "arm"), tool).into(),
                    }
                    self.cmd(&name)
                } else if target.contains("msvc") {
                    // NOTE: There isn't really a ranlib on msvc, so arguably we should return
                    // `None` somehow here. But in general, callers will already have to be aware
                    // of not running ranlib on Windows anyway, so it feels okay to return lib.exe
                    // here.

                    let compiler = self.get_base_compiler()?;
                    let mut lib = String::new();
                    if compiler.family == (ToolFamily::Msvc { clang_cl: true }) {
                        // See if there is 'llvm-lib' next to 'clang-cl'
                        // Another possibility could be to see if there is 'clang'
                        // next to 'clang-cl' and use 'search_programs()' to locate
                        // 'llvm-lib'. This is because 'clang-cl' doesn't support
                        // the -print-search-dirs option.
                        if let Some(mut cmd) = self.which(&compiler.path, None) {
                            cmd.pop();
                            cmd.push("llvm-lib.exe");
                            if let Some(llvm_lib) = self.which(&cmd, None) {
                                llvm_lib.to_str().unwrap().clone_into(&mut lib);
                            }
                        }
                    }

                    if lib.is_empty() {
                        name = PathBuf::from("lib.exe");
                        let mut cmd = match self.windows_registry_find(&target, "lib.exe") {
                            Some(t) => t,
                            None => self.cmd("lib.exe"),
                        };
                        if target.contains("arm64ec") {
                            cmd.arg("/machine:arm64ec");
                        }
                        cmd
                    } else {
                        name = lib.into();
                        self.cmd(&name)
                    }
                } else if target.contains("illumos") {
                    // The default 'ar' on illumos uses a non-standard flags,
                    // but the OS comes bundled with a GNU-compatible variant.
                    //
                    // Use the GNU-variant to match other Unix systems.
                    name = format!("g{}", tool).into();
                    self.cmd(&name)
                } else if self.get_host()? != target {
                    match self.prefix_for_target(&target) {
                        Some(p) => {
                            // GCC uses $target-gcc-ar, whereas binutils uses $target-ar -- try both.
                            // Prefer -ar if it exists, as builds of `-gcc-ar` have been observed to be
                            // outright broken (such as when targeting freebsd with `--disable-lto`
                            // toolchain where the archiver attempts to load the LTO plugin anyway but
                            // fails to find one).
                            //
                            // The same applies to ranlib.
                            let mut chosen = default;
                            for &infix in &["", "-gcc"] {
                                let target_p = format!("{}{}-{}", p, infix, tool);
                                if Command::new(&target_p).output().is_ok() {
                                    chosen = target_p;
                                    break;
                                }
                            }
                            name = chosen.into();
                            self.cmd(&name)
                        }
                        None => {
                            name = default.into();
                            self.cmd(&name)
                        }
                    }
                } else {
                    name = default.into();
                    self.cmd(&name)
                }
            }
        };

        Ok((tool, name))
    }

    fn prefix_for_target(&self, target: &str) -> Option<Cow<'static, str>> {
        // CROSS_COMPILE is of the form: "arm-linux-gnueabi-"
        self.getenv("CROSS_COMPILE")
            .as_deref()
            .map(|s| s.to_string_lossy().trim_end_matches('-').to_owned())
            .map(Cow::Owned)
            .or_else(|| {
                // Put aside RUSTC_LINKER's prefix to be used as second choice, after CROSS_COMPILE
                self.getenv("RUSTC_LINKER").and_then(|var| {
                    var.to_string_lossy()
                        .strip_suffix("-gcc")
                        .map(str::to_string)
                        .map(Cow::Owned)
                })
            })
            .or_else(|| {
                match target {
                    // Note: there is no `aarch64-pc-windows-gnu` target, only `-gnullvm`
                    "aarch64-pc-windows-gnullvm" => Some("aarch64-w64-mingw32"),
                    "aarch64-uwp-windows-gnu" => Some("aarch64-w64-mingw32"),
                    "aarch64-unknown-linux-gnu" => Some("aarch64-linux-gnu"),
                    "aarch64-unknown-linux-musl" => Some("aarch64-linux-musl"),
                    "aarch64-unknown-netbsd" => Some("aarch64--netbsd"),
                    "arm-unknown-linux-gnueabi" => Some("arm-linux-gnueabi"),
                    "armv4t-unknown-linux-gnueabi" => Some("arm-linux-gnueabi"),
                    "armv5te-unknown-linux-gnueabi" => Some("arm-linux-gnueabi"),
                    "armv5te-unknown-linux-musleabi" => Some("arm-linux-gnueabi"),
                    "arm-frc-linux-gnueabi" => Some("arm-frc-linux-gnueabi"),
                    "arm-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
                    "arm-unknown-linux-musleabi" => Some("arm-linux-musleabi"),
                    "arm-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"),
                    "arm-unknown-netbsd-eabi" => Some("arm--netbsdelf-eabi"),
                    "armv6-unknown-netbsd-eabihf" => Some("armv6--netbsdelf-eabihf"),
                    "armv7-unknown-linux-gnueabi" => Some("arm-linux-gnueabi"),
                    "armv7-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
                    "armv7-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"),
                    "armv7neon-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
                    "armv7neon-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"),
                    "thumbv7-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
                    "thumbv7-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"),
                    "thumbv7neon-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
                    "thumbv7neon-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"),
                    "armv7-unknown-netbsd-eabihf" => Some("armv7--netbsdelf-eabihf"),
                    "hexagon-unknown-linux-musl" => Some("hexagon-linux-musl"),
                    "i586-unknown-linux-musl" => Some("musl"),
                    "i686-pc-windows-gnu" => Some("i686-w64-mingw32"),
                    "i686-uwp-windows-gnu" => Some("i686-w64-mingw32"),
                    "i686-unknown-linux-gnu" => self.find_working_gnu_prefix(&[
                        "i686-linux-gnu",
                        "x86_64-linux-gnu", // transparently support gcc-multilib
                    ]), // explicit None if not found, so caller knows to fall back
                    "i686-unknown-linux-musl" => Some("musl"),
                    "i686-unknown-netbsd" => Some("i486--netbsdelf"),
                    "loongarch64-unknown-linux-gnu" => Some("loongarch64-linux-gnu"),
                    "mips-unknown-linux-gnu" => Some("mips-linux-gnu"),
                    "mips-unknown-linux-musl" => Some("mips-linux-musl"),
                    "mipsel-unknown-linux-gnu" => Some("mipsel-linux-gnu"),
                    "mipsel-unknown-linux-musl" => Some("mipsel-linux-musl"),
                    "mips64-unknown-linux-gnuabi64" => Some("mips64-linux-gnuabi64"),
                    "mips64el-unknown-linux-gnuabi64" => Some("mips64el-linux-gnuabi64"),
                    "mipsisa32r6-unknown-linux-gnu" => Some("mipsisa32r6-linux-gnu"),
                    "mipsisa32r6el-unknown-linux-gnu" => Some("mipsisa32r6el-linux-gnu"),
                    "mipsisa64r6-unknown-linux-gnuabi64" => Some("mipsisa64r6-linux-gnuabi64"),
                    "mipsisa64r6el-unknown-linux-gnuabi64" => Some("mipsisa64r6el-linux-gnuabi64"),
                    "powerpc-unknown-linux-gnu" => Some("powerpc-linux-gnu"),
                    "powerpc-unknown-linux-gnuspe" => Some("powerpc-linux-gnuspe"),
                    "powerpc-unknown-netbsd" => Some("powerpc--netbsd"),
                    "powerpc64-unknown-linux-gnu" => Some("powerpc-linux-gnu"),
                    "powerpc64le-unknown-linux-gnu" => Some("powerpc64le-linux-gnu"),
                    "riscv32i-unknown-none-elf" => self.find_working_gnu_prefix(&[
                        "riscv32-unknown-elf",
                        "riscv64-unknown-elf",
                        "riscv-none-embed",
                    ]),
                    "riscv32imac-esp-espidf" => Some("riscv32-esp-elf"),
                    "riscv32imac-unknown-none-elf" => self.find_working_gnu_prefix(&[
                        "riscv32-unknown-elf",
                        "riscv64-unknown-elf",
                        "riscv-none-embed",
                    ]),
                    "riscv32imac-unknown-xous-elf" => self.find_working_gnu_prefix(&[
                        "riscv32-unknown-elf",
                        "riscv64-unknown-elf",
                        "riscv-none-embed",
                    ]),
                    "riscv32imc-esp-espidf" => Some("riscv32-esp-elf"),
                    "riscv32imc-unknown-none-elf" => self.find_working_gnu_prefix(&[
                        "riscv32-unknown-elf",
                        "riscv64-unknown-elf",
                        "riscv-none-embed",
                    ]),
                    "riscv64gc-unknown-none-elf" => self.find_working_gnu_prefix(&[
                        "riscv64-unknown-elf",
                        "riscv32-unknown-elf",
                        "riscv-none-embed",
                    ]),
                    "riscv64imac-unknown-none-elf" => self.find_working_gnu_prefix(&[
                        "riscv64-unknown-elf",
                        "riscv32-unknown-elf",
                        "riscv-none-embed",
                    ]),
                    "riscv64gc-unknown-linux-gnu" => Some("riscv64-linux-gnu"),
                    "riscv32gc-unknown-linux-gnu" => Some("riscv32-linux-gnu"),
                    "riscv64gc-unknown-linux-musl" => Some("riscv64-linux-musl"),
                    "riscv32gc-unknown-linux-musl" => Some("riscv32-linux-musl"),
                    "riscv64gc-unknown-netbsd" => Some("riscv64--netbsd"),
                    "s390x-unknown-linux-gnu" => Some("s390x-linux-gnu"),
                    "sparc-unknown-linux-gnu" => Some("sparc-linux-gnu"),
                    "sparc64-unknown-linux-gnu" => Some("sparc64-linux-gnu"),
                    "sparc64-unknown-netbsd" => Some("sparc64--netbsd"),
                    "sparcv9-sun-solaris" => Some("sparcv9-sun-solaris"),
                    "armv7a-none-eabi" => Some("arm-none-eabi"),
                    "armv7a-none-eabihf" => Some("arm-none-eabi"),
                    "armebv7r-none-eabi" => Some("arm-none-eabi"),
                    "armebv7r-none-eabihf" => Some("arm-none-eabi"),
                    "armv7r-none-eabi" => Some("arm-none-eabi"),
                    "armv7r-none-eabihf" => Some("arm-none-eabi"),
                    "armv8r-none-eabihf" => Some("arm-none-eabi"),
                    "thumbv6m-none-eabi" => Some("arm-none-eabi"),
                    "thumbv7em-none-eabi" => Some("arm-none-eabi"),
                    "thumbv7em-none-eabihf" => Some("arm-none-eabi"),
                    "thumbv7m-none-eabi" => Some("arm-none-eabi"),
                    "thumbv8m.base-none-eabi" => Some("arm-none-eabi"),
                    "thumbv8m.main-none-eabi" => Some("arm-none-eabi"),
                    "thumbv8m.main-none-eabihf" => Some("arm-none-eabi"),
                    "x86_64-pc-windows-gnu" => Some("x86_64-w64-mingw32"),
                    "x86_64-pc-windows-gnullvm" => Some("x86_64-w64-mingw32"),
                    "x86_64-uwp-windows-gnu" => Some("x86_64-w64-mingw32"),
                    "x86_64-rumprun-netbsd" => Some("x86_64-rumprun-netbsd"),
                    "x86_64-unknown-linux-gnu" => self.find_working_gnu_prefix(&[
                        "x86_64-linux-gnu", // rustfmt wrap
                    ]), // explicit None if not found, so caller knows to fall back
                    "x86_64-unknown-linux-musl" => Some("musl"),
                    "x86_64-unknown-netbsd" => Some("x86_64--netbsd"),
                    _ => None,
                }
                .map(Cow::Borrowed)
            })
    }

    /// Some platforms have multiple, compatible, canonical prefixes. Look through
    /// each possible prefix for a compiler that exists and return it. The prefixes
    /// should be ordered from most-likely to least-likely.
    fn find_working_gnu_prefix(&self, prefixes: &[&'static str]) -> Option<&'static str> {
        let suffix = if self.cpp { "-g++" } else { "-gcc" };
        let extension = std::env::consts::EXE_SUFFIX;

        // Loop through PATH entries searching for each toolchain. This ensures that we
        // are more likely to discover the toolchain early on, because chances are good
        // that the desired toolchain is in one of the higher-priority paths.
        self.getenv("PATH")
            .as_ref()
            .and_then(|path_entries| {
                env::split_paths(path_entries).find_map(|path_entry| {
                    for prefix in prefixes {
                        let target_compiler = format!("{}{}{}", prefix, suffix, extension);
                        if path_entry.join(&target_compiler).exists() {
                            return Some(prefix);
                        }
                    }
                    None
                })
            })
            .copied()
            // If no toolchain was found, provide the first toolchain that was passed in.
            // This toolchain has been shown not to exist, however it will appear in the
            // error that is shown to the user which should make it easier to search for
            // where it should be obtained.
            .or_else(|| prefixes.first().copied())
    }

    fn get_target(&self) -> Result<Cow<'_, str>, Error> {
        match &self.target {
            Some(t) => Ok(Cow::Borrowed(t)),
            None => self.getenv_unwrap_str("TARGET").map(Cow::Owned),
        }
    }

    fn get_host(&self) -> Result<Cow<'_, str>, Error> {
        match &self.host {
            Some(h) => Ok(Cow::Borrowed(h)),
            None => self.getenv_unwrap_str("HOST").map(Cow::Owned),
        }
    }

    fn get_opt_level(&self) -> Result<Cow<'_, str>, Error> {
        match &self.opt_level {
            Some(ol) => Ok(Cow::Borrowed(ol)),
            None => self.getenv_unwrap_str("OPT_LEVEL").map(Cow::Owned),
        }
    }

    fn get_debug(&self) -> bool {
        self.debug.unwrap_or_else(|| match self.getenv("DEBUG") {
            Some(s) => &*s != "false",
            None => false,
        })
    }

    fn get_shell_escaped_flags(&self) -> bool {
        self.shell_escaped_flags
            .unwrap_or_else(|| self.getenv("CC_SHELL_ESCAPED_FLAGS").is_some())
    }

    fn get_dwarf_version(&self) -> Option<u32> {
        // Tentatively matches the DWARF version defaults as of rustc 1.62.
        let target = self.get_target().ok()?;
        if target.contains("android")
            || target.contains("apple")
            || target.contains("dragonfly")
            || target.contains("freebsd")
            || target.contains("netbsd")
            || target.contains("openbsd")
            || target.contains("windows-gnu")
        {
            Some(2)
        } else if target.contains("linux") {
            Some(4)
        } else {
            None
        }
    }

    fn get_force_frame_pointer(&self) -> bool {
        self.force_frame_pointer.unwrap_or_else(|| self.get_debug())
    }

    fn get_out_dir(&self) -> Result<Cow<'_, Path>, Error> {
        match &self.out_dir {
            Some(p) => Ok(Cow::Borrowed(&**p)),
            None => self
                .getenv("OUT_DIR")
                .as_deref()
                .map(PathBuf::from)
                .map(Cow::Owned)
                .ok_or_else(|| {
                    Error::new(
                        ErrorKind::EnvVarNotFound,
                        "Environment variable OUT_DIR not defined.",
                    )
                }),
        }
    }

    #[allow(clippy::disallowed_methods)]
    fn getenv(&self, v: &str) -> Option<Arc<OsStr>> {
        // Returns true for environment variables cargo sets for build scripts:
        // https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts
        //
        // This handles more of the vars than we actually use (it tries to check
        // complete-ish set), just to avoid needing maintenance if/when new
        // calls to `getenv`/`getenv_unwrap` are added.
        fn provided_by_cargo(envvar: &str) -> bool {
            match envvar {
                v if v.starts_with("CARGO") || v.starts_with("RUSTC") => true,
                "HOST" | "TARGET" | "RUSTDOC" | "OUT_DIR" | "OPT_LEVEL" | "DEBUG" | "PROFILE"
                | "NUM_JOBS" | "RUSTFLAGS" => true,
                _ => false,
            }
        }
        if let Some(val) = self.env_cache.read().unwrap().get(v).cloned() {
            return val;
        }
        if self.emit_rerun_if_env_changed && !provided_by_cargo(v) && v != "PATH" {
            self.cargo_output
                .print_metadata(&format_args!("cargo:rerun-if-env-changed={}", v));
        }
        let r = env::var_os(v).map(Arc::from);
        self.cargo_output.print_metadata(&format_args!(
            "{} = {}",
            v,
            OptionOsStrDisplay(r.as_deref())
        ));
        self.env_cache.write().unwrap().insert(v.into(), r.clone());
        r
    }

    fn getenv_unwrap(&self, v: &str) -> Result<Arc<OsStr>, Error> {
        match self.getenv(v) {
            Some(s) => Ok(s),
            None => Err(Error::new(
                ErrorKind::EnvVarNotFound,
                format!("Environment variable {} not defined.", v),
            )),
        }
    }

    fn getenv_unwrap_str(&self, v: &str) -> Result<String, Error> {
        let env = self.getenv_unwrap(v)?;
        env.to_str().map(String::from).ok_or_else(|| {
            Error::new(
                ErrorKind::EnvVarNotFound,
                format!("Environment variable {} is not valid utf-8.", v),
            )
        })
    }

    fn getenv_with_target_prefixes(&self, var_base: &str) -> Result<Arc<OsStr>, Error> {
        let target = self.get_target()?;
        let host = self.get_host()?;
        let kind = if host == target { "HOST" } else { "TARGET" };
        let target_u = target.replace('-', "_");
        let res = self
            .getenv(&format!("{}_{}", var_base, target))
            .or_else(|| self.getenv(&format!("{}_{}", var_base, target_u)))
            .or_else(|| self.getenv(&format!("{}_{}", kind, var_base)))
            .or_else(|| self.getenv(var_base));

        match res {
            Some(res) => Ok(res),
            None => Err(Error::new(
                ErrorKind::EnvVarNotFound,
                format!("Could not find environment variable {}.", var_base),
            )),
        }
    }

    fn envflags(&self, name: &str) -> Result<Vec<String>, Error> {
        let env_os = self.getenv_with_target_prefixes(name)?;
        let env = env_os.to_string_lossy();

        if self.get_shell_escaped_flags() {
            Ok(Shlex::new(&env).collect())
        } else {
            Ok(env
                .split_ascii_whitespace()
                .map(ToString::to_string)
                .collect())
        }
    }

    fn fix_env_for_apple_os(&self, cmd: &mut Command) -> Result<(), Error> {
        let target = self.get_target()?;
        let host = self.get_host()?;
        if host.contains("apple-darwin") && target.contains("apple-darwin") {
            // Additionally, `IPHONEOS_DEPLOYMENT_TARGET` must not be set when using the Xcode linker at
            // "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld",
            // although this is apparently ignored when using the linker at "/usr/bin/ld".
            cmd.env_remove("IPHONEOS_DEPLOYMENT_TARGET");
        }
        Ok(())
    }

    fn apple_sdk_root_inner(&self, sdk: &str) -> Result<Arc<OsStr>, Error> {
        // Code copied from rustc's compiler/rustc_codegen_ssa/src/back/link.rs.
        if let Some(sdkroot) = self.getenv("SDKROOT") {
            let p = Path::new(&sdkroot);
            let does_sdkroot_contain = |strings: &[&str]| {
                let sdkroot_str = p.to_string_lossy();
                strings.iter().any(|s| sdkroot_str.contains(s))
            };
            match sdk {
                // Ignore `SDKROOT` if it's clearly set for the wrong platform.
                "appletvos"
                    if does_sdkroot_contain(&["TVSimulator.platform", "MacOSX.platform"]) => {}
                "appletvsimulator"
                    if does_sdkroot_contain(&["TVOS.platform", "MacOSX.platform"]) => {}
                "iphoneos"
                    if does_sdkroot_contain(&["iPhoneSimulator.platform", "MacOSX.platform"]) => {}
                "iphonesimulator"
                    if does_sdkroot_contain(&["iPhoneOS.platform", "MacOSX.platform"]) => {}
                "macosx10.15"
                    if does_sdkroot_contain(&["iPhoneOS.platform", "iPhoneSimulator.platform"]) => {
                }
                "watchos"
                    if does_sdkroot_contain(&["WatchSimulator.platform", "MacOSX.platform"]) => {}
                "watchsimulator"
                    if does_sdkroot_contain(&["WatchOS.platform", "MacOSX.platform"]) => {}
                "xros" if does_sdkroot_contain(&["XRSimulator.platform", "MacOSX.platform"]) => {}
                "xrsimulator" if does_sdkroot_contain(&["XROS.platform", "MacOSX.platform"]) => {}
                // Ignore `SDKROOT` if it's not a valid path.
                _ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {}
                _ => return Ok(sdkroot),
            }
        }

        let sdk_path = run_output(
            self.cmd("xcrun")
                .arg("--show-sdk-path")
                .arg("--sdk")
                .arg(sdk),
            "xcrun",
            &self.cargo_output,
        )?;

        let sdk_path = match String::from_utf8(sdk_path) {
            Ok(p) => p,
            Err(_) => {
                return Err(Error::new(
                    ErrorKind::IOError,
                    "Unable to determine Apple SDK path.",
                ));
            }
        };
        Ok(Arc::from(OsStr::new(sdk_path.trim())))
    }

    fn apple_sdk_root(&self, sdk: &str) -> Result<Arc<OsStr>, Error> {
        if let Some(ret) = self
            .apple_sdk_root_cache
            .read()
            .expect("apple_sdk_root_cache lock failed")
            .get(sdk)
            .cloned()
        {
            return Ok(ret);
        }
        let sdk_path = self.apple_sdk_root_inner(sdk)?;
        self.apple_sdk_root_cache
            .write()
            .expect("apple_sdk_root_cache lock failed")
            .insert(sdk.into(), sdk_path.clone());
        Ok(sdk_path)
    }

    fn apple_deployment_version(&self, os: AppleOs, arch_str: Option<&str>, sdk: &str) -> Arc<str> {
        if let Some(ret) = self
            .apple_versions_cache
            .read()
            .expect("apple_versions_cache lock failed")
            .get(sdk)
            .cloned()
        {
            return ret;
        }

        let default_deployment_from_sdk = || -> Option<Arc<str>> {
            let version = run_output(
                self.cmd("xcrun")
                    .arg("--show-sdk-version")
                    .arg("--sdk")
                    .arg(sdk),
                "xcrun",
                &self.cargo_output,
            )
            .ok()?;

            Some(Arc::from(std::str::from_utf8(&version).ok()?.trim()))
        };

        let deployment_from_env = |name: &str| -> Option<Arc<str>> {
            // note that self.env isn't hit in production codepaths, its mostly just for tests which don't
            // set the real env
            self.env
                .iter()
                .find(|(k, _)| &**k == OsStr::new(name))
                .map(|(_, v)| v)
                .cloned()
                .or_else(|| self.getenv(name))?
                .to_str()
                .map(Arc::from)
        };

        // Determines if the acquired deployment target is too low to support modern C++ on some Apple platform.
        //
        // A long time ago they used libstdc++, but since macOS 10.9 and iOS 7 libc++ has been the library the SDKs provide to link against.
        // If a `cc`` config wants to use C++, we round up to these versions as the baseline.
        let maybe_cpp_version_baseline = |deployment_target_ver: Arc<str>| -> Option<Arc<str>> {
            if !self.cpp {
                return Some(deployment_target_ver);
            }

            let mut deployment_target = deployment_target_ver
                .split('.')
                .map(|v| v.parse::<u32>().expect("integer version"));

            match os {
                AppleOs::MacOs => {
                    let major = deployment_target.next().unwrap_or(0);
                    let minor = deployment_target.next().unwrap_or(0);

                    // If below 10.9, we ignore it and let the SDK's target definitions handle it.
                    if major == 10 && minor < 9 {
                        self.cargo_output.print_warning(&format_args!(
                            "macOS deployment target ({}) too low, it will be increased",
                            deployment_target_ver
                        ));
                        return None;
                    }
                }
                AppleOs::Ios => {
                    let major = deployment_target.next().unwrap_or(0);

                    // If below 10.7, we ignore it and let the SDK's target definitions handle it.
                    if major < 7 {
                        self.cargo_output.print_warning(&format_args!(
                            "iOS deployment target ({}) too low, it will be increased",
                            deployment_target_ver
                        ));
                        return None;
                    }
                }
                // watchOS, tvOS, visionOS, and others are all new enough that libc++ is their baseline.
                _ => {}
            }

            // If the deployment target met or exceeded the C++ baseline
            Some(deployment_target_ver)
        };

        // The hardcoded minimums here are subject to change in a future compiler release,
        // and only exist as last resort fallbacks. Don't consider them stable.
        // `cc` doesn't use rustc's `--print deployment-target`` because the compiler's defaults
        // don't align well with Apple's SDKs and other third-party libraries that require ~generally~ higher
        // deployment targets. rustc isn't interested in those by default though so its fine to be different here.
        //
        // If no explicit target is passed, `cc` defaults to the current Xcode SDK's `DefaultDeploymentTarget` for better
        // compatibility. This is also the crate's historical behavior and what has become a relied-on value.
        //
        // The ordering of env -> XCode SDK -> old rustc defaults is intentional for performance when using
        // an explicit target.
        let version: Arc<str> = match os {
            AppleOs::MacOs => deployment_from_env("MACOSX_DEPLOYMENT_TARGET")
                .and_then(maybe_cpp_version_baseline)
                .or_else(default_deployment_from_sdk)
                .unwrap_or_else(|| {
                    if arch_str == Some("aarch64") {
                        "11.0".into()
                    } else {
                        let default: Arc<str> = Arc::from("10.7");
                        maybe_cpp_version_baseline(default.clone()).unwrap_or(default)
                    }
                }),

            AppleOs::Ios => deployment_from_env("IPHONEOS_DEPLOYMENT_TARGET")
                .and_then(maybe_cpp_version_baseline)
                .or_else(default_deployment_from_sdk)
                .unwrap_or_else(|| "7.0".into()),

            AppleOs::WatchOs => deployment_from_env("WATCHOS_DEPLOYMENT_TARGET")
                .or_else(default_deployment_from_sdk)
                .unwrap_or_else(|| "5.0".into()),

            AppleOs::TvOs => deployment_from_env("TVOS_DEPLOYMENT_TARGET")
                .or_else(default_deployment_from_sdk)
                .unwrap_or_else(|| "9.0".into()),

            AppleOs::VisionOS => deployment_from_env("XROS_DEPLOYMENT_TARGET")
                .or_else(default_deployment_from_sdk)
                .unwrap_or_else(|| "1.0".into()),
        };

        self.apple_versions_cache
            .write()
            .expect("apple_versions_cache lock failed")
            .insert(sdk.into(), version.clone());

        version
    }

    fn wasi_sysroot(&self) -> Result<Arc<OsStr>, Error> {
        if let Some(wasi_sysroot_path) = self.getenv("WASI_SYSROOT") {
            Ok(wasi_sysroot_path)
        } else {
            Err(Error::new(
                ErrorKind::EnvVarNotFound,
                "Environment variable WASI_SYSROOT not defined. Download sysroot from GitHub & setup environment variable WASI_SYSROOT targeting the folder.",
            ))
        }
    }
    fn is_wasi_target(target: &str) -> bool {
        const TARGETS: [&str; 7] = [
            "wasm32-wasi",
            "wasm32-wasip1",
            "wasm32-wasip1-threads",
            "wasm32-wasip2",
            "wasm32-wasi-threads",
            "wasm32-unknown-wasi",
            "wasm32-unknown-unknown",
        ];
        TARGETS.contains(&target)
    }

    fn cuda_file_count(&self) -> usize {
        self.files
            .iter()
            .filter(|file| file.extension() == Some(OsStr::new("cu")))
            .count()
    }

    fn which(&self, tool: &Path, path_entries: Option<&OsStr>) -> Option<PathBuf> {
        fn check_exe(mut exe: PathBuf) -> Option<PathBuf> {
            let exe_ext = std::env::consts::EXE_EXTENSION;
            let check =
                exe.exists() || (!exe_ext.is_empty() && exe.set_extension(exe_ext) && exe.exists());
            check.then_some(exe)
        }

        // Loop through PATH entries searching for the |tool|.
        let find_exe_in_path = |path_entries: &OsStr| -> Option<PathBuf> {
            env::split_paths(path_entries).find_map(|path_entry| check_exe(path_entry.join(tool)))
        };

        // If |tool| is not just one "word," assume it's an actual path...
        if tool.components().count() > 1 {
            check_exe(PathBuf::from(tool))
        } else {
            path_entries
                .and_then(find_exe_in_path)
                .or_else(|| find_exe_in_path(&self.getenv("PATH")?))
        }
    }

    /// search for |prog| on 'programs' path in '|cc| -print-search-dirs' output
    fn search_programs(
        &self,
        cc: &mut Command,
        prog: &Path,
        cargo_output: &CargoOutput,
    ) -> Option<PathBuf> {
        let search_dirs = run_output(
            cc.arg("-print-search-dirs"),
            "cc",
            // this doesn't concern the compilation so we always want to show warnings.
            cargo_output,
        )
        .ok()?;
        // clang driver appears to be forcing UTF-8 output even on Windows,
        // hence from_utf8 is assumed to be usable in all cases.
        let search_dirs = std::str::from_utf8(&search_dirs).ok()?;
        for dirs in search_dirs.split(['\r', '\n']) {
            if let Some(path) = dirs.strip_prefix("programs: =") {
                return self.which(prog, Some(OsStr::new(path)));
            }
        }
        None
    }

    fn windows_registry_find(&self, target: &str, tool: &str) -> Option<Command> {
        self.windows_registry_find_tool(target, tool)
            .map(|c| c.to_command())
    }

    fn windows_registry_find_tool(&self, target: &str, tool: &str) -> Option<Tool> {
        struct BuildEnvGetter<'s>(&'s Build);

        impl windows_registry::EnvGetter for BuildEnvGetter<'_> {
            fn get_env(&self, name: &str) -> Option<windows_registry::Env> {
                self.0.getenv(name).map(windows_registry::Env::Arced)
            }
        }

        windows_registry::find_tool_inner(target, tool, &BuildEnvGetter(self))
    }
}

impl Default for Build {
    fn default() -> Build {
        Build::new()
    }
}

fn fail(s: &str) -> ! {
    eprintln!("\n\nerror occurred: {}\n\n", s);
    std::process::exit(1);
}

#[derive(Clone, Copy, PartialEq)]
enum AppleOs {
    MacOs,
    Ios,
    WatchOs,
    TvOs,
    VisionOS,
}

impl std::fmt::Debug for AppleOs {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        match self {
            AppleOs::MacOs => f.write_str("macOS"),
            AppleOs::Ios => f.write_str("iOS"),
            AppleOs::WatchOs => f.write_str("WatchOS"),
            AppleOs::TvOs => f.write_str("AppleTVOS"),
            AppleOs::VisionOS => f.write_str("visionOS"),
        }
    }
}

struct AppleSdkTargetParts {
    sdk_prefix: &'static str,
    sim_prefix: &'static str,
    sdk: Cow<'static, str>,
}

fn apple_os_sdk_parts(os: AppleOs, arch: &AppleArchSpec) -> AppleSdkTargetParts {
    let (sdk_prefix, sim_prefix) = match os {
        AppleOs::MacOs => ("macosx", ""),
        AppleOs::Ios => ("iphone", "ios-"),
        AppleOs::WatchOs => ("watch", "watch"),
        AppleOs::TvOs => ("appletv", "appletv"),
        AppleOs::VisionOS => ("xr", "xr"),
    };
    let sdk = match arch {
        AppleArchSpec::Device(_) if os == AppleOs::MacOs => Cow::Borrowed("macosx"),
        AppleArchSpec::Device(_) => format!("{}os", sdk_prefix).into(),
        AppleArchSpec::Simulator(_) => format!("{}simulator", sdk_prefix).into(),
        AppleArchSpec::Catalyst(_) => Cow::Borrowed("macosx"),
    };

    AppleSdkTargetParts {
        sdk_prefix,
        sim_prefix,
        sdk,
    }
}

#[allow(dead_code)]
enum AppleArchSpec {
    Device(&'static str),
    Simulator(&'static str),
    #[allow(dead_code)]
    Catalyst(&'static str),
}

// Use by default minimum available API level
// See note about naming here
// https://android.googlesource.com/platform/ndk/+/refs/heads/ndk-release-r21/docs/BuildSystemMaintainers.md#Clang
static NEW_STANDALONE_ANDROID_COMPILERS: [&str; 4] = [
    "aarch64-linux-android21-clang",
    "armv7a-linux-androideabi16-clang",
    "i686-linux-android16-clang",
    "x86_64-linux-android21-clang",
];

// New "standalone" C/C++ cross-compiler executables from recent Android NDK
// are just shell scripts that call main clang binary (from Android NDK) with
// proper `--target` argument.
//
// For example, armv7a-linux-androideabi16-clang passes
// `--target=armv7a-linux-androideabi16` to clang.
// So to construct proper command line check if
// `--target` argument would be passed or not to clang
fn android_clang_compiler_uses_target_arg_internally(clang_path: &Path) -> bool {
    if let Some(filename) = clang_path.file_name() {
        if let Some(filename_str) = filename.to_str() {
            if let Some(idx) = filename_str.rfind('-') {
                return filename_str.split_at(idx).0.contains("android");
            }
        }
    }
    false
}

fn autodetect_android_compiler(target: &str, host: &str, gnu: &str, clang: &str) -> String {
    let new_clang_key = match target {
        "aarch64-linux-android" => Some("aarch64"),
        "armv7-linux-androideabi" => Some("armv7a"),
        "i686-linux-android" => Some("i686"),
        "x86_64-linux-android" => Some("x86_64"),
        _ => None,
    };

    let new_clang = new_clang_key
        .map(|key| {
            NEW_STANDALONE_ANDROID_COMPILERS
                .iter()
                .find(|x| x.starts_with(key))
        })
        .unwrap_or(None);

    if let Some(new_clang) = new_clang {
        if Command::new(new_clang).output().is_ok() {
            return (*new_clang).into();
        }
    }

    let target = target
        .replace("armv7neon", "arm")
        .replace("armv7", "arm")
        .replace("thumbv7neon", "arm")
        .replace("thumbv7", "arm");
    let gnu_compiler = format!("{}-{}", target, gnu);
    let clang_compiler = format!("{}-{}", target, clang);

    // On Windows, the Android clang compiler is provided as a `.cmd` file instead
    // of a `.exe` file. `std::process::Command` won't run `.cmd` files unless the
    // `.cmd` is explicitly appended to the command name, so we do that here.
    let clang_compiler_cmd = format!("{}-{}.cmd", target, clang);

    // Check if gnu compiler is present
    // if not, use clang
    if Command::new(&gnu_compiler).output().is_ok() {
        gnu_compiler
    } else if host.contains("windows") && Command::new(&clang_compiler_cmd).output().is_ok() {
        clang_compiler_cmd
    } else {
        clang_compiler
    }
}

// Rust and clang/cc don't agree on how to name the target.
fn map_darwin_target_from_rust_to_compiler_architecture(target: &str) -> Option<&'static str> {
    if target.contains("x86_64h") {
        Some("x86_64h")
    } else if target.contains("x86_64") {
        Some("x86_64")
    } else if target.contains("arm64e") {
        Some("arm64e")
    } else if target.contains("aarch64") {
        Some("arm64")
    } else if target.contains("i686") {
        Some("i386")
    } else if target.contains("powerpc") {
        Some("ppc")
    } else if target.contains("powerpc64") {
        Some("ppc64")
    } else {
        None
    }
}

#[derive(Clone, Copy, PartialEq)]
enum AsmFileExt {
    /// `.asm` files. On MSVC targets, we assume these should be passed to MASM
    /// (`ml{,64}.exe`).
    DotAsm,
    /// `.s` or `.S` files, which do not have the special handling on MSVC targets.
    DotS,
}

impl AsmFileExt {
    fn from_path(file: &Path) -> Option<Self> {
        if let Some(ext) = file.extension() {
            if let Some(ext) = ext.to_str() {
                let ext = ext.to_lowercase();
                match &*ext {
                    "asm" => return Some(AsmFileExt::DotAsm),
                    "s" => return Some(AsmFileExt::DotS),
                    _ => return None,
                }
            }
        }
        None
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_android_clang_compiler_uses_target_arg_internally() {
        for version in 16..21 {
            assert!(android_clang_compiler_uses_target_arg_internally(
                &PathBuf::from(format!("armv7a-linux-androideabi{}-clang", version))
            ));
            assert!(android_clang_compiler_uses_target_arg_internally(
                &PathBuf::from(format!("armv7a-linux-androideabi{}-clang++", version))
            ));
        }
        assert!(!android_clang_compiler_uses_target_arg_internally(
            &PathBuf::from("clang-i686-linux-android")
        ));
        assert!(!android_clang_compiler_uses_target_arg_internally(
            &PathBuf::from("clang")
        ));
        assert!(!android_clang_compiler_uses_target_arg_internally(
            &PathBuf::from("clang++")
        ));
    }
}
