target-lexicon OS sometimes doesn't match rustc target jsons
I've been playing around with target-lexicon a bit and it seems like while most of the time it is pretty faithful to the rustc target json, some of the time the result diverges.
For example, i686-linux-android has this rustc target JSON:
$ RUSTC_BOOTSTRAP=1 rustc -Z unstable-options --target=i686-linux-android --print target-spec-json
{
"arch": "x86",
"cpu": "pentiumpro",
"data-layout": "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128",
"default-uwtable": true,
"dwarf-version": 2,
"dynamic-linking": true,
"env": "gnu",
"executables": true,
"features": "+mmx,+sse,+sse2,+sse3,+ssse3",
"has-rpath": true,
"is-builtin": true,
"llvm-target": "i686-linux-android",
"max-atomic-width": 64,
"os": "android",
"position-independent-executables": true,
"pre-link-args": {
"gcc": [
"-Wl,--allow-multiple-definition"
]
},
"relro-level": "full",
"stack-probes": {
"kind": "call"
},
"target-family": [
"unix"
],
"target-pointer-width": "32"
}
However, target-lexicon parses the same triple as having the OS Linux rather than Android.
Somewhat related, for "aarch64-apple-darwin":
- rustc has
"os": "macos" - target-lexicon parses this as Darwin
I'm not sure exactly what behavior is desired here but I thought it might be useful to flag this. Thanks!
For i686-linux-android the target triple does indeed say that the os is linux and for aarch64-apple-darwin that the os is darwin. Target triples are of the form arch-vendor-os-env-binfmt where any part may be missing and would be parsed as "unknown" in that case. For i686-linux-android is sees arch=i686, vendor=unknown, os=linux, env=android, binfmt=unknown. For aarch64-apple-darwin it sees arch=aarch64, vendor=apple, os=darwin, env=unknown, binfmt=unknown.
Target-lexicon doesn't read rustc target specs. If you want the target os rustc specifies, you can run rustc --target i686-linux-android --print cfg and then look for target_os="..." in the output, same for any other builtin cfg. This is what cargo does too.
I think the current behavior is the desired one, but @sunfishcode may disagree.
I think target-lexicon may have taken the wrong path with android, and should consider it an OS instead of an Environment, as Rust does. Target-lexicon does have a number of special cases already, so it wouldn't be the worst to add more to be able to parse "linux-android" specially.
In general, I think it makes sense for target-lexicon to aspire to be compatible with the rustc target json categories, including mapping "darwin" => "macos" as mentioned above. This may mean becoming less compatible with rust target names, but my understanding of the relationship between rust target names and rustc target json categories has evolved, and I now think this makes sense. This should also help with #63.
May I ask which one is preferable to avoid confusion on selecting between OperatingSystem::Darwin and OperatingSystem::MacOSX{...} ? Because I put MacOSX in my build.rs' library hoping that it will detect macbook user. But instead, it detect Darwin.
target-lexicon was designed to be used by compilers and compiler-like tools. The use of OperatingSystem::Darwin reflects how the Rust compiler calls macOS targets "darwin".
In hindsight, OperatingSystem::Darwin has caused confusion, however the conclusion above is that target-lexicon should ideally be changed to map "darwin" to a new OperatingSystem::MacOS, which would correspond with the Rust compilert's use of cfg(target_os = "macos").
That would reduce confusion in one area, thought it may cause some new confusion in another, because it would mean having both OperatingSystem::MacOS and OperatingSystem::MacOSX. MacOS would represent a Mac target name specified as a Rust target like x86_64-apple-darwin with no version number, and MacOSX would represent a Mac target name specified as an LLVM target like x86_64-apple-macosx10.7.0 with a version number.