From a571647564f84a71031770864ff0dc094a9e1fb9 Mon Sep 17 00:00:00 2001
From: Lawrence Tang <Lawrence.Tang@arm.com>
Date: Mon, 22 Jan 2024 11:33:02 +0000
Subject: [PATCH] Add support for custom JSON targets when using build-std.

Currently, when building with `build-std`, some library build scripts
check properties of the target by inspecting the target triple at
`env::TARGET`, which is simply set to the filename of the JSON file
when using JSON target files.

This patch alters these build scripts to use `env::CARGO_CFG_*` to
fetch target information instead, allowing JSON target files
describing platforms without `restricted_std` to build correctly when
using `-Z build-std`.

Fixes wg-cargo-std-aware/#60.
---
 library/profiler_builtins/build.rs |  7 +--
 library/std/build.rs               | 78 ++++++++++++++++--------------
 2 files changed, 46 insertions(+), 39 deletions(-)

diff --git a/library/profiler_builtins/build.rs b/library/profiler_builtins/build.rs
index d14d0b82229a1..8e7b72f837220 100644
--- a/library/profiler_builtins/build.rs
+++ b/library/profiler_builtins/build.rs
@@ -12,7 +12,8 @@ fn main() {
         return;
     }
 
-    let target = env::var("TARGET").expect("TARGET was not set");
+    let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS was not set");
+    let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set");
     let cfg = &mut cc::Build::new();
 
     // FIXME: `rerun-if-changed` directives are not currently emitted and the build script
@@ -40,7 +41,7 @@ fn main() {
         "InstrProfilingBiasVar.c",
     ];
 
-    if target.contains("msvc") {
+    if target_env == "msvc" {
         // Don't pull in extra libraries on MSVC
         cfg.flag("/Zl");
         profile_sources.push("WindowsMMap.c");
@@ -55,7 +56,7 @@ fn main() {
         cfg.flag("-fno-builtin");
         cfg.flag("-fomit-frame-pointer");
         cfg.define("VISIBILITY_HIDDEN", None);
-        if !target.contains("windows") {
+        if target_os != "windows" {
             cfg.flag("-fvisibility=hidden");
             cfg.define("COMPILER_RT_HAS_UNAME", Some("1"));
         } else {
diff --git a/library/std/build.rs b/library/std/build.rs
index 60c097db2f4bf..fc4960d791a47 100644
--- a/library/std/build.rs
+++ b/library/std/build.rs
@@ -2,41 +2,47 @@ use std::env;
 
 fn main() {
     println!("cargo:rerun-if-changed=build.rs");
-    let target = env::var("TARGET").expect("TARGET was not set");
-    if target.contains("linux")
-        || target.contains("netbsd")
-        || target.contains("dragonfly")
-        || target.contains("openbsd")
-        || target.contains("freebsd")
-        || target.contains("solaris")
-        || target.contains("illumos")
-        || target.contains("apple-darwin")
-        || target.contains("apple-ios")
-        || target.contains("apple-tvos")
-        || target.contains("apple-watchos")
-        || target.contains("uwp")
-        || target.contains("windows")
-        || target.contains("fuchsia")
-        || (target.contains("sgx") && target.contains("fortanix"))
-        || target.contains("hermit")
-        || target.contains("l4re")
-        || target.contains("redox")
-        || target.contains("haiku")
-        || target.contains("vxworks")
-        || target.contains("wasm32")
-        || target.contains("wasm64")
-        || target.contains("espidf")
-        || target.contains("solid")
-        || target.contains("nintendo-3ds")
-        || target.contains("vita")
-        || target.contains("aix")
-        || target.contains("nto")
-        || target.contains("xous")
-        || target.contains("hurd")
-        || target.contains("uefi")
-        || target.contains("teeos")
-        || target.contains("zkvm")
-        // See src/bootstrap/synthetic_targets.rs
+    let target_arch = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH was not set");
+    let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS was not set");
+    let target_vendor =
+        env::var("CARGO_CFG_TARGET_VENDOR").expect("CARGO_CFG_TARGET_VENDOR was not set");
+    let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set");
+
+    if target_os == "linux"
+        || target_os == "android"
+        || target_os == "netbsd"
+        || target_os == "dragonfly"
+        || target_os == "openbsd"
+        || target_os == "freebsd"
+        || target_os == "solaris"
+        || target_os == "illumos"
+        || target_os == "macos"
+        || target_os == "ios"
+        || target_os == "tvos"
+        || target_os == "watchos"
+        || target_os == "windows"
+        || target_os == "fuchsia"
+        || (target_vendor == "fortanix" && target_env == "sgx")
+        || target_os == "hermit"
+        || target_os == "l4re"
+        || target_os == "redox"
+        || target_os == "haiku"
+        || target_os == "vxworks"
+        || target_arch == "wasm32"
+        || target_arch == "wasm64"
+        || target_os == "espidf"
+        || target_os.starts_with("solid")
+        || (target_vendor == "nintendo" && target_env == "newlib")
+        || target_os == "vita"
+        || target_os == "aix"
+        || target_os == "nto"
+        || target_os == "xous"
+        || target_os == "hurd"
+        || target_os == "uefi"
+        || target_os == "teeos"
+        || target_os == "zkvm"
+
+        // See src/bootstrap/src/core/build_steps/synthetic_targets.rs
         || env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
     {
         // These platforms don't have any special requirements.
@@ -48,7 +54,7 @@ fn main() {
         // - mipsel-sony-psp
         // - nvptx64-nvidia-cuda
         // - arch=avr
-        // - JSON targets
+        // - JSON targets not describing an excluded target above.
         // - Any new targets that have not been explicitly added above.
         println!("cargo:rustc-cfg=feature=\"restricted-std\"");
     }