Copy bindings to OUT_DIR in bssl-sys build.rs

This avoids the need for a custom environment variable in Cargo or GN
builds, including under the soong build. Then Chromium will also be able
to generate bindgen into the OUT_DIR for a sys crate via its GN rules,
as boringssl is the only crate we can find which relies on a custom
environment variable in its sys crate library's include statement.

The idea to copy from a pre-generated location comes from libsqlite3-sys
https://github.com/rusqlite/rusqlite/blob/master/libsqlite3-sys/build.rs

Bazel does not support the OUT_DIR system that is used by Cargo and
every bindgen-based crate that we could find (that didn't write to the
source dir directly). So we keep a cfg around that Bazel rules can
pass when building the bssl-sys crate.

Bug: b/373864033
Change-Id: If8a8aa8a1d8a00ead2e9935a5319bcac2aa09d1f
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/72487
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/rust/bssl-sys/build.rs b/rust/bssl-sys/build.rs
index ede6411..ab580ef 100644
--- a/rust/bssl-sys/build.rs
+++ b/rust/bssl-sys/build.rs
@@ -99,10 +99,18 @@
     let bssl_build_dir = get_bssl_build_dir();
     let bssl_sys_build_dir = bssl_build_dir.join("rust/bssl-sys");
     let target = env::var("TARGET").unwrap();
+    let out_dir = env::var("OUT_DIR").unwrap();
+    let bindgen_out_file = Path::new(&out_dir).join("bindgen.rs");
 
-    // Find the bindgen generated target platform bindings file and set BINDGEN_RS_FILE
-    let bindgen_file = bssl_sys_build_dir.join(format!("wrapper_{}.rs", target));
-    println!("cargo:rustc-env=BINDGEN_RS_FILE={}", bindgen_file.display());
+    // Find the bindgen generated target platform bindings file and put it into
+    // OUT_DIR/bindgen.rs.
+    let bindgen_source_file = bssl_sys_build_dir.join(format!("wrapper_{}.rs", target));
+    std::fs::copy(&bindgen_source_file, &bindgen_out_file).expect(&format!(
+        "Could not copy bindings from '{}' to '{}'",
+        bindgen_source_file.display(),
+        bindgen_out_file.display()
+    ));
+    println!("cargo:rerun-if-changed={}", bindgen_source_file.display());
 
     // Statically link libraries.
     println!(
diff --git a/rust/bssl-sys/src/lib.rs b/rust/bssl-sys/src/lib.rs
index b8d0397..8f97e6a 100644
--- a/rust/bssl-sys/src/lib.rs
+++ b/rust/bssl-sys/src/lib.rs
@@ -9,13 +9,13 @@
 // Wrap the bindgen output in a module and re-export it, so we can override it
 // as needed.
 mod bindgen {
-    #[cfg(not(soong))]
+    #[cfg(not(bindgen_rs_file))]
+    include!(concat!(env!("OUT_DIR"), "/bindgen.rs"));
+    // Some static build systems (e.g. bazel) do not support the `OUT_DIR`
+    // configuration used by Cargo. They can specify a complete path to the
+    // generated bindings as an environment variable.
+    #[cfg(bindgen_rs_file)]
     include!(env!("BINDGEN_RS_FILE"));
-    // Soong, Android's build tool, does not support configuring environment
-    // variables like other Rust build systems too. However, it does support
-    // some hardcoded behavior with the OUT_DIR variable.
-    #[cfg(soong)]
-    include!(concat!(env!("OUT_DIR"), "/bssl_sys_bindings.rs"));
 }
 pub use bindgen::*;