Skip to content

Add Build::from_cargo or similar to make it very explicit when in a build script #1219

Closed
@madsmtm

Description

@madsmtm

cc's code is littered with brittle checks centered on rustc target triple. A lot of this is unnecessary though, since Cargo sets cfg values for the target as environment variables, see the docs for more examples. cc can't actually use those in most cases though, since it doesn't know whether it's being run inside a Cargo build script, or outside of it.

A prominent example is that CARGO_CFG_TARGET_ABI would be very useful for detecting Apple's simulator targets (doing it based on the target name is misery, and I think we're currently doing it wrong some places).

So I got to thinking, would it make sense to "split" cc's entry point into two, and deprecated cc::Build::new? Something like:

// build.rs
fn main() {
    // Emits all the rerun-if-changed flags, `cargo_metadata` defaults to true, etc.
    // Reads from `CARGO_CFG_TARGET_*` to initialize target data.
    cc::Build::from_cargo()
        .file("foo.c")
        .file("bar.c")
        .compile("foo");
}

// main.rs
fn main() {
    // Does not print needless Cargo metadata.
    // Using cc from outside build.rs, so has to specify target.
    // The target is parsed eagerly into some internal structure that represents it,
    // maybe using `target-lexicon`, and behind a feature flag? In any case, we
    // can say that this use-case is less supported, and the support burden will
    // perhaps be lessened?
    cc::Build::from_target("aarch64-unknown-linux-gnu")
        .file("foo.c")
        .file("bar.c")
        .compile("foo");
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions