Put Rust binding generation behind an explicit flag and only build bindings for the targeted Arch

Change-Id: I8ccd53bce0d73bd9d79f65770e544a75753ce4f8
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/51025
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7f02b29..f74e233 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,7 +31,6 @@
 else()
   find_package(Perl REQUIRED)
   find_program(GO_EXECUTABLE go)
-  find_program(BINDGEN_EXECUTABLE bindgen)
 endif()
 
 if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT CMAKE_CROSSCOMPILING)
@@ -52,12 +51,6 @@
   message(FATAL_ERROR "Could not find Go")
 endif()
 
-if(NOT BINDGEN_EXECUTABLE)
-  message("Could not find bindgen. Not generating Rust bindings.")
-else()
-  add_subdirectory(rust)
-endif()
-
 if(USE_CUSTOM_LIBCXX)
   set(BORINGSSL_ALLOW_CXX_RUNTIME 1)
 endif()
@@ -615,6 +608,15 @@
   add_subdirectory(fuzz)
 endif()
 
+if(RUST_BINDINGS)
+  find_program(BINDGEN_EXECUTABLE bindgen)
+  if(NOT BINDGEN_EXECUTABLE)
+    message(FATAL_ERROR "Could not find bindgen but was asked to generate Rust bindings.")
+  else()
+    add_subdirectory(rust)
+  endif()
+endif()
+
 if(UNIX AND NOT APPLE AND NOT ANDROID)
   set(HANDSHAKER_ARGS "-handshaker-path" $<TARGET_FILE:handshaker>)
 endif()
diff --git a/rust/CMakeLists.txt b/rust/CMakeLists.txt
index d830bdd..f60ad47 100644
--- a/rust/CMakeLists.txt
+++ b/rust/CMakeLists.txt
@@ -6,57 +6,46 @@
 )
 
 # generate architecture specific wrappers
-foreach(TARGET
-    aarch64-unknown-linux-gnu
-    i686-pc-windows-gnu
-    x86_64-unknown-linux-gnu
-  )
+set(WRAPPER_TARGET ${CMAKE_BINARY_DIR}/rust/src/wrapper_${RUST_BINDINGS}.rs)
+set(COMMAND ${BINDGEN_EXECUTABLE} "wrapper.h"
+            -o ${WRAPPER_TARGET}
+            --no-derive-default
+            --enable-function-attribute-detection
+            --use-core
+            --size_t-is-usize
+            --default-macro-constant-type="signed"
+            --rustified-enum="point_conversion_form_t"
+            # These are not BoringSSL symbols, they are from glibc
+            # and are not relevant to the build besides throwing warnings
+            # about their 'long double' (aka u128) not being FFI safe.
+            # We block those functions so that the build doesn't
+            # spam warnings.
+            #
+            # https://github.com/rust-lang/rust-bindgen/issues/1549 describes the current problem
+            # and other folks' solutions.
+            #
+            # We will explore migrating to https://github.com/rust-lang/rust-bindgen/pull/2122
+            # when it lands
+            --blocklist-function="strtold"
+            --blocklist-function="qecvt"
+            --blocklist-function="qecvt_r"
+            --blocklist-function="qgcvt"
+            --blocklist-function="qfcvt"
+            --blocklist-function="qfcvt_r"
+            -- # these are LLVM arg passthroughs
+            -I../include
+            # https://doc.rust-lang.org/nightly/rustc/platform-support.html
+            --target=${RUST_BINDINGS})
 
-  set(WRAPPER_TARGET ${CMAKE_BINARY_DIR}/rust/src/wrapper_${TARGET}.rs)
-  set(COMMAND ${BINDGEN_EXECUTABLE} "wrapper.h"
-              -o ${WRAPPER_TARGET}
-              --no-derive-default
-              --enable-function-attribute-detection
-              --use-core
-              --size_t-is-usize
-              --default-macro-constant-type="signed"
-              --rustified-enum="point_conversion_form_t"
-              # These are not BoringSSL symbols, they are from glibc
-              # and are not relevant to the build besides throwing warnings
-              # about their 'long double' (aka u128) not being FFI safe.
-              # We block those functions so that the build doesn't
-              # spam warnings.
-              #
-              # https://github.com/rust-lang/rust-bindgen/issues/1549 describes the current problem
-              # and other folks' solutions.
-              #
-              # We will explore migrating to https://github.com/rust-lang/rust-bindgen/pull/2122
-              # when it lands
-              --blocklist-function="strtold"
-              --blocklist-function="qecvt"
-              --blocklist-function="qecvt_r"
-              --blocklist-function="qgcvt"
-              --blocklist-function="qfcvt"
-              --blocklist-function="qfcvt_r"
-              -- # these are LLVM arg passthroughs
-              -I../include
-              --target=${TARGET})
+set(INCLUDES "include!(\"wrapper_${RUST_BINDINGS}.rs\");\n")
 
-  add_custom_target(
-    bindgen_rust_${TARGET}
-    ALL
-    ${COMMAND}
-    BYPRODUCTS ${WRAPPER_TARGET}
-    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-  )
-  string(REPLACE "-" ";" TARGET_LIST ${TARGET})
-  list(GET TARGET_LIST 0 ARCH)
-  list(GET TARGET_LIST 1 VENDOR)
-
-  set(INCLUDES "${INCLUDES}\
-  #[cfg(all(target_arch = \"${ARCH}\", target_vendor = \"${VENDOR}\"))]\n\
-  include!(\"wrapper_${TARGET}.rs\");\n")
-endforeach()
+add_custom_target(
+  bindgen_rust_${RUST_BINDINGS}
+  ALL
+  ${COMMAND}
+  BYPRODUCTS ${WRAPPER_TARGET}
+  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+)
 
 # move files into build directory
 configure_file("src/lib.rs" "src/lib.rs")
diff --git a/rust/README.md b/rust/README.md
index 271d4d5..fb5230a 100644
--- a/rust/README.md
+++ b/rust/README.md
@@ -4,5 +4,10 @@
 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 each supported target platform. It is important to generate it for each 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. These files are then packaged into a Rust crate.
+
+### To Use
+Build `boringssl` with `-DRUST_BINDINGS=<rust-triple>` and ensure that you have `bindgen` installed.
+
+The `rust-triple` option should be one of the supported targets at https://doc.rust-lang.org/nightly/rustc/platform-support.html.