Don't copy all of bssl-sys into the CMake build directory

Instead, just have it look for the files it needs via a
BORINGSSL_BUILD_DIR environment variable. This avoids hardcoding
"../../build" anywhere that cannot be easily overriden by the user.

Although this puts logic in a build.rs file, which is problematic for
repositories with more coherent build stories like Android or Chromium,
those are already driving the bindgen and link process themselves,
without calling CMake. I.e. this file should already only be used for
standalone development and testing and not directly impact them. (Though
we'd like to keep it vaguely analogous to better predict without a
change will impact downstream folks.)

For now, I've kept bindgen generated from CMake, mostly in anticipation
of using the inline functions feature. Building the synthesized C file
from CMake seems less of a headache than Cargo. Additionally, calling
bindgen from the command-line is closer to how those consumers will do
it, so this forces us to stick to bindgen invocations that can be
expressed via command-line arguments. (E.g. the mess that is regexes and
escaping.)

As part of this, I've removed the messy "find the first matching wrapper
file" behavior in build.rs. Instead, it knows the expected TARGET and
just finds the file with matching name. This means we'll be stricter
about matching the two. (Otherwise there's no point in naming it by
target name anyway.)

Fixed: 598
Change-Id: I07fa74f7e5f5f008d6f0ceec648a2378df7d317a
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/59105
Reviewed-by: Matthew Maurer <mmaurer@google.com>
Reviewed-by: Nabil Wadih <nwadih@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
diff --git a/rust/bssl-crypto/Cargo.toml b/rust/bssl-crypto/Cargo.toml
index 7822767..c60e9ca 100644
--- a/rust/bssl-crypto/Cargo.toml
+++ b/rust/bssl-crypto/Cargo.toml
@@ -6,6 +6,4 @@
 license = "MIT"
 
 [dependencies]
-# the crate will need to be generated at this path by running this command at root
-# `cmake -G Ninja -B build -DRUST_BINDINGS="$(gcc -dumpmachine)" && ninja -C build`
-bssl-sys = {path = "../../build/rust/bssl-sys"}
+bssl-sys = {path = "../bssl-sys"}
diff --git a/rust/bssl-crypto/README.md b/rust/bssl-crypto/README.md
index 0d52053..dff669b 100644
--- a/rust/bssl-crypto/README.md
+++ b/rust/bssl-crypto/README.md
@@ -1,12 +1,7 @@
 bssl-crypto
 ============
 
-rust bindings to boringssl which wrap bssl-sys, a low level autogenerated binding
-
-Before using this crate, first generate the bssl-sys bindings by running this command from the root of the repo:
-```
-cmake -G Ninja -B build -DRUST_BINDINGS="$(gcc -dumpmachine)" && ninja -C build
-```
+Rust bindings to BoringSSL which wrap bssl-sys. Before using this crate, first [set up `bssl-sys`](../bssl-sys/README.md).
 
 Then to run all tests:
 ```
diff --git a/rust/bssl-sys/CMakeLists.txt b/rust/bssl-sys/CMakeLists.txt
index 5e5f446..d17a8f1 100644
--- a/rust/bssl-sys/CMakeLists.txt
+++ b/rust/bssl-sys/CMakeLists.txt
@@ -6,7 +6,7 @@
 # ${CMAKE_BINARY_DIR}, with the output path as a relative path. bindgen writes
 # the depfile using the same syntax as the command-line argument, and ninja
 # requires a path relative to the top-level build directory.
-set(wrapper src/wrapper_${RUST_BINDINGS}.rs)
+set(wrapper wrapper_${RUST_BINDINGS}.rs)
 binary_dir_relative_path(${wrapper} wrapper_relative)
 binary_dir_relative_path(${wrapper}.d depfile_relative)
 
@@ -47,12 +47,3 @@
   WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
 )
 add_custom_target(bssl_sys ALL DEPENDS ${wrapper})
-
-# move files into build directory
-configure_file("src/lib.rs" "src/lib.rs")
-
-if(NOT BUILD_SHARED_LIBS)
-  configure_file("build.rs" "build.rs" COPYONLY)
-endif()
-
-configure_file("Cargo.toml" "Cargo.toml" COPYONLY)
diff --git a/rust/bssl-sys/README.md b/rust/bssl-sys/README.md
index fb5230a..e2efd6c 100644
--- a/rust/bssl-sys/README.md
+++ b/rust/bssl-sys/README.md
@@ -4,10 +4,9 @@
 A low-level binding crate for Rust that moves in lockstop with BoringSSL. BoringSSL explicitly does not have a stable ABI, `bssl-sys` is the solution for preventing subtle-memory corruption bugs due to version skew.
 
 ### How it works
-`bssl-sys` uses `bindgen` as part of the cmake build process to generate Rust compatibility shims for the targeted platform. It is important to generate it for the correct platform because `bindgen` uses LLVM information for alignment which varies depending on architecture. These files are then packaged into a Rust crate.
+`bssl-sys` uses `bindgen` as part of the cmake build process to generate Rust compatibility shims for the targeted platform. It is important to generate it for the correct platform because `bindgen` uses LLVM information for alignment which varies depending on architecture.
 
 ### To Use
-Build `boringssl` with `-DRUST_BINDINGS=<rust-triple>` and ensure that you have `bindgen` installed.
+Build `boringssl` with `-DRUST_BINDINGS=<rust-triple>` and ensure that you have `bindgen` installed. The `rust-triple` option should match the [Rust target triple](https://doc.rust-lang.org/nightly/rustc/platform-support.html) when building `bssl-sys`.
 
-The `rust-triple` option should be one of the supported targets at https://doc.rust-lang.org/nightly/rustc/platform-support.html.
-
+From there, the `bssl-sys` crate can be built. By default, it looks for `bindgen` output and BoringSSL static libraries in the `build` directory. This can be reconfigured with `BORINGSSL_BUILD_DIR` environment variable. Note the environment variable is evaluated relative to `rust/bssl-sys/src`, so using an absolute path may be more convenient.
diff --git a/rust/bssl-sys/build.rs b/rust/bssl-sys/build.rs
index e540702..2d7461a 100644
--- a/rust/bssl-sys/build.rs
+++ b/rust/bssl-sys/build.rs
@@ -15,38 +15,43 @@
 
 use std::env;
 use std::path::Path;
+use std::path::PathBuf;
+
+fn get_bssl_build_dir() -> PathBuf {
+    println!("cargo:rerun-if-env-changed=BORINGSSL_BUILD_DIR");
+    if let Some(build_dir) = env::var_os("BORINGSSL_BUILD_DIR") {
+        return PathBuf::from(build_dir);
+    }
+
+    let crate_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap();
+    return Path::new(&crate_dir).join("../../build");
+}
 
 fn main() {
-    let dir = env::var("CARGO_MANIFEST_DIR").unwrap();
-    let crate_path = Path::new(&dir);
+    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();
 
     // Find the bindgen generated target platform bindings file and set BINDGEN_RS_FILE
-    let bindgen_file = crate_path
-        .join("src")
-        .read_dir()
-        .unwrap()
-        .map(|file| file.unwrap().file_name().into_string().unwrap())
-        .find(|file| file.starts_with("wrapper_"))
-        .unwrap();
-    println!("cargo:rustc-env=BINDGEN_RS_FILE={}", bindgen_file);
-
-    // building bssl-sys with: `cmake -G Ninja -B build -DRUST_BINDINGS="$(gcc -dumpmachine)" && ninja -C build`
-    // outputs this crate to /build/rust/bssl-sys/ so need to go up 3 levels to the root of the repo
-    let repo_root = crate_path.parent().unwrap().parent().unwrap();
+    let bindgen_file = bssl_sys_build_dir.join(format!("wrapper_{}.rs", target));
+    println!("cargo:rustc-env=BINDGEN_RS_FILE={}", bindgen_file.display());
 
     // Statically link libraries.
     println!(
         "cargo:rustc-link-search=native={}",
-        repo_root.join("crypto").display()
+        bssl_build_dir.join("crypto").display()
     );
     println!("cargo:rustc-link-lib=static=crypto");
 
     println!(
         "cargo:rustc-link-search=native={}",
-        repo_root.join("ssl").display()
+        bssl_build_dir.join("ssl").display()
     );
     println!("cargo:rustc-link-lib=static=ssl");
 
-    println!("cargo:rustc-link-search=native={}", crate_path.display());
+    println!(
+        "cargo:rustc-link-search=native={}",
+        bssl_sys_build_dir.display()
+    );
     println!("cargo:rustc-link-lib=static=rust_wrapper");
 }