rust-lang / cc-rs

Rust library for build scripts to compile C/C++ code into a Rust library
https://docs.rs/cc
Apache License 2.0
1.76k stars 425 forks source link

Support custom target-spec #1120

Open boozook opened 4 days ago

boozook commented 4 days ago

Could be great to support custom target-specs (json files).

As we all know, env TARGET contains rustc's "short target name", not exactly target-triple. It can be triple only if builtin target requested. So cc couldn't use it directly if some custom target requested, e.g. for --target=my-spec.json env TARGET will be "my-spec".

How to do it:

  1. change there target type - wrap into something like enum Target { Builtin(...), Custom(...) }
  2. probe target to determine is it builtin or not and get details:
    • we have env RUSTC by cargo
    • $RUSTC --print cfg --target {target-short-name}.json
    • $RUSTC --print target-spec-json --target {target-short-name}.json -Zunstable-options (nightly only) From this step we can get llvm-target

But actually we already have almost all we need by cargo's env:

_Note, CARGO_CFG_TARGET_FEATURE contains features added in the my-spec.json too, so it really useful._

So, could be great to support target-json-specs, use info from them. Also to respect and use all available data from vars CARGO_CFG_TARGET_ - translate and pass to compiler if possible.

Example of env vars given by cargo _In my case, my target.json contains `"llvm-target": "thumbv7em-none-eabihf"`, uses it as base target, but overrides features and some more._ ``` TARGET: "my-spec" CARGO_CFG_OVERFLOW_CHECKS: "" CARGO_CFG_PANIC: "abort" CARGO_CFG_RELOCATION_MODEL: "pic" CARGO_CFG_TARGET_ABI: "eabihf" CARGO_CFG_TARGET_ARCH: "arm" CARGO_CFG_TARGET_ENDIAN: "little" CARGO_CFG_TARGET_ENV: "elf" CARGO_CFG_TARGET_FEATURE: "dsp,mclass,thumb-mode,thumb2,v5te,v6,v6k,v6t2,v7,neon" CARGO_CFG_TARGET_HAS_ATOMIC: "16,32,8,ptr" CARGO_CFG_TARGET_HAS_ATOMIC_EQUAL_ALIGNMENT: "16,32,8,ptr" CARGO_CFG_TARGET_HAS_ATOMIC_LOAD_STORE: "16,32,8,ptr" CARGO_CFG_TARGET_OS: "myneatos" CARGO_CFG_TARGET_POINTER_WIDTH: "32" CARGO_CFG_TARGET_THREAD_LOCAL: "" CARGO_CFG_TARGET_VENDOR: "custom" CARGO_CFG_UB_CHECKS: "" CARGO_ENCODED_RUSTFLAGS: "" RUSTC: "path/to/rustc" ```

Probably related issue: https://github.com/rust-lang/cc-rs/issues/994

NobodyXu commented 4 days ago

Also to respect and use all available data from vars CARGO_CFGTARGET - translate and pass to compiler if possible.

Yeah that sounds reasonable.

Supporting target spec json query though is a bit more complicated, I suppose we can add the API to pass that information to cc, and do the parsing in another crate, since it would require JSON parsing and maybe nightly compiler.

boozook commented 4 days ago

That could be really helpful!

boozook commented 4 days ago

Also things like that is not work for target with custom names, definitely. Imagine I'll name my target arch-foo-bar-like-msvc or more funny same-but-not-msvc :))) , or better for realistic example msvc-plugin-for-arch-gnu :).

That things could be good practice to determine by compiler (print), or by cargo (env), or directly from json.

Anyway about that concert msvc - I suppose will be better to get it from CARGO_CFG_TARGET_ENV - if value is known, so ok; otherwise just ignoring unknown value.

Wow, just search in the lib.rs for target.contains. I see 125 findings.


Also cc fails on target-names that doesn't contains dash, e.g. "strangecpu", trying to split it by -.

NobodyXu commented 3 days ago

Wow, just search in the lib.rs for target.contains. I see 125 findings.

Yeah it is a bit messy