From a84d75b358b6e203e14dc497980949544076f94e Mon Sep 17 00:00:00 2001 From: sachiang Date: Fri, 18 Nov 2022 15:00:33 -0800 Subject: [PATCH 1/7] move binding generation out of aws-lc-sys --- bindings/rust/aws-lc-sys-template/Cargo.toml | 5 +- bindings/rust/aws-lc-sys-template/build.rs | 98 +------------- .../rust/aws-lc-sys-template/build_bindgen.rs | 103 +++++++++++++++ bindings/rust/aws-lc-sys-template/src/lib.rs | 23 +++- .../aws-lc-sys-template/tests/sanity-tests.rs | 2 +- bindings/rust/generate/Cargo.toml | 12 ++ .../_generate_all_bindings_flavors.sh | 57 ++++++++ bindings/rust/generate/_generate_bindings.sh | 18 +++ bindings/rust/generate/generate.sh | 5 +- bindings/rust/generate/src/main.rs | 122 ++++++++++++++++++ .../docker_images/rust/linux-arm64/Dockerfile | 8 ++ 11 files changed, 356 insertions(+), 97 deletions(-) create mode 100644 bindings/rust/aws-lc-sys-template/build_bindgen.rs create mode 100644 bindings/rust/generate/Cargo.toml create mode 100755 bindings/rust/generate/_generate_all_bindings_flavors.sh create mode 100755 bindings/rust/generate/_generate_bindings.sh create mode 100644 bindings/rust/generate/src/main.rs diff --git a/bindings/rust/aws-lc-sys-template/Cargo.toml b/bindings/rust/aws-lc-sys-template/Cargo.toml index 6f18547f66..3dfb687193 100644 --- a/bindings/rust/aws-lc-sys-template/Cargo.toml +++ b/bindings/rust/aws-lc-sys-template/Cargo.toml @@ -5,7 +5,7 @@ version = "__AWS_LC_SYS_VERSION__" authors = ["AWS-LC"] edition = "2021" repository = "https://github.com/awslabs/aws-lc" -license = "Apache-2.0" +license = "Apache-2.0 OR ISC" rust-version = "1.57.0" include = [ "build.rs", @@ -25,9 +25,10 @@ include = [ [features] asan = [] +bindgen = ["dep:bindgen"] [build-dependencies] -bindgen = "0.61" +bindgen = { version ="0.61", optional = true } regex = "1" dunce = "1.0" diff --git a/bindings/rust/aws-lc-sys-template/build.rs b/bindings/rust/aws-lc-sys-template/build.rs index 58c6ea1b88..ca54ff2343 100644 --- a/bindings/rust/aws-lc-sys-template/build.rs +++ b/bindings/rust/aws-lc-sys-template/build.rs @@ -15,99 +15,18 @@ // SPDX-License-Identifier: Apache-2.0 OR ISC // Modifications Copyright Amazon.com, Inc. or its affiliates. See GitHub history for details. -use bindgen::callbacks::ParseCallbacks; use std::ffi::{OsStr, OsString}; -use std::fmt::Debug; use std::path::{Path, PathBuf}; use std::process::Command; use std::{env, fs}; -#[derive(Debug)] -struct StripPrefixCallback { - remove_prefix: Option, -} - -impl StripPrefixCallback { - fn new(prefix: &str) -> StripPrefixCallback { - StripPrefixCallback { - remove_prefix: Some(prefix.to_string()), - } - } -} +#[cfg(feature = "bindgen")] +mod build_bindgen; -impl ParseCallbacks for StripPrefixCallback { - fn generated_name_override(&self, name: &str) -> Option { - self.remove_prefix.as_ref().and_then(|s| { - let prefix = format!("{}_", s); - name.strip_prefix(prefix.as_str()).map(String::from) - }) - } -} - -fn get_include_path(manifest_dir: &Path) -> PathBuf { +pub(crate) fn get_include_path(manifest_dir: &Path) -> PathBuf { manifest_dir.join("deps").join("aws-lc").join("include") } -fn prepare_clang_args(manifest_dir: &Path, build_prefix: Option<&str>) -> Vec { - let mut clang_args: Vec = vec![ - "-I".to_string(), - get_include_path(manifest_dir).display().to_string(), - ]; - - if let Some(prefix) = build_prefix { - clang_args.push(format!("-DBORINGSSL_PREFIX={}", prefix)); - } - - clang_args -} - -const COPYRIGHT: &str = r#" -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 OR ISC -"#; - -const PRELUDE: &str = r#" -#![allow(unused_imports, non_camel_case_types, non_snake_case, non_upper_case_globals, improper_ctypes)] -"#; - -fn prepare_bindings_builder(manifest_dir: &Path, build_prefix: Option<&str>) -> bindgen::Builder { - let clang_args = prepare_clang_args(manifest_dir, build_prefix); - - let mut builder = bindgen::Builder::default() - .derive_copy(true) - .derive_debug(true) - .derive_default(true) - .derive_eq(true) - .allowlist_file(".*/openssl/[^/]+\\.h") - .allowlist_file(".*/rust_wrapper\\.h") - .default_enum_style(bindgen::EnumVariation::NewType { - is_bitfield: false, - is_global: false, - }) - .default_macro_constant_type(bindgen::MacroTypeVariation::Signed) - .generate_comments(true) - .fit_macro_constants(false) - .size_t_is_usize(true) - .layout_tests(true) - .prepend_enum_name(true) - .rustfmt_bindings(true) - .clang_args(clang_args) - .raw_line(COPYRIGHT) - .raw_line(PRELUDE) - .header( - get_include_path(manifest_dir) - .join("rust_wrapper.h") - .display() - .to_string(), - ); - - if let Some(ps) = build_prefix { - builder = builder.parse_callbacks(Box::new(StripPrefixCallback::new(ps))); - } - - builder -} - const AWS_LC_PATH: &str = "deps/aws-lc"; #[allow(dead_code)] @@ -321,16 +240,11 @@ fn main() -> Result<(), String> { let manifest_dir = dunce::canonicalize(Path::new(&manifest_dir)).unwrap(); let prefix = prefix_string(); - let bindings_file = manifest_dir.join("src").join("bindings.rs"); - - let builder = prepare_bindings_builder(&manifest_dir, Some(&prefix)); - let bindings = builder.generate().expect("Unable to generate bindings."); - bindings - .write_to_file(bindings_file) - .expect("Unable to write bindings to file."); + #[cfg(feature = "bindgen")] + build_bindgen::generate_bindings(&manifest_dir, Some(&prefix)) + .expect("Unable to generate bindings."); let aws_lc_dir = build_aws_lc()?; - let lib_file = Crypto.locate_file(&aws_lc_dir, Static, None); let prefixed_lib_file = Crypto.locate_file(&aws_lc_dir, Static, Some(&prefix)); fs::rename(lib_file, prefixed_lib_file).expect("Unexpected error: Library not found"); diff --git a/bindings/rust/aws-lc-sys-template/build_bindgen.rs b/bindings/rust/aws-lc-sys-template/build_bindgen.rs new file mode 100644 index 0000000000..3fc0c8cf54 --- /dev/null +++ b/bindings/rust/aws-lc-sys-template/build_bindgen.rs @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: Apache-2.0 OR ISC +// Modifications Copyright Amazon.com, Inc. or its affiliates. See GitHub history for details. + +use crate::get_include_path; +use bindgen::callbacks::ParseCallbacks; +use std::fmt::Debug; +use std::path::Path; + +#[derive(Debug)] +struct StripPrefixCallback { + remove_prefix: Option, +} + +impl StripPrefixCallback { + fn new(prefix: &str) -> StripPrefixCallback { + StripPrefixCallback { + remove_prefix: Some(prefix.to_string()), + } + } +} + +#[cfg(feature = "bindgen")] +impl ParseCallbacks for StripPrefixCallback { + fn generated_name_override(&self, name: &str) -> Option { + self.remove_prefix.as_ref().and_then(|s| { + let prefix = format!("{}_", s); + name.strip_prefix(prefix.as_str()).map(String::from) + }) + } +} + +fn prepare_clang_args(manifest_dir: &Path, build_prefix: Option<&str>) -> Vec { + let mut clang_args: Vec = vec![ + "-I".to_string(), + get_include_path(manifest_dir).display().to_string(), + ]; + + if let Some(prefix) = build_prefix { + clang_args.push(format!("-DBORINGSSL_PREFIX={}", prefix)); + } + + clang_args +} + +const COPYRIGHT: &str = r#" +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC +"#; + +const PRELUDE: &str = r#" +#![allow(unused_imports, non_camel_case_types, non_snake_case, non_upper_case_globals, improper_ctypes)] +"#; + +fn prepare_bindings_builder(manifest_dir: &Path, build_prefix: Option<&str>) -> bindgen::Builder { + let clang_args = prepare_clang_args(manifest_dir, build_prefix); + + let mut builder = bindgen::Builder::default() + .derive_copy(true) + .derive_debug(true) + .derive_default(true) + .derive_eq(true) + .allowlist_file(".*/openssl/[^/]+\\.h") + .allowlist_file(".*/rust_wrapper\\.h") + .default_enum_style(bindgen::EnumVariation::NewType { + is_bitfield: false, + is_global: false, + }) + .default_macro_constant_type(bindgen::MacroTypeVariation::Signed) + .generate_comments(true) + .fit_macro_constants(false) + .size_t_is_usize(true) + .layout_tests(true) + .prepend_enum_name(true) + .rustfmt_bindings(true) + .clang_args(clang_args) + .raw_line(COPYRIGHT) + .raw_line(PRELUDE) + .header( + get_include_path(manifest_dir) + .join("rust_wrapper.h") + .display() + .to_string(), + ); + + if let Some(ps) = build_prefix { + builder = builder.parse_callbacks(Box::new(StripPrefixCallback::new(ps))); + } + + builder +} + +pub(crate) fn generate_bindings( + manifest_dir: &Path, + build_prefix: Option<&str>, +) -> Result<(), &'static str> { + let bindings_file = manifest_dir.join("src").join("bindings.rs"); + + let builder = prepare_bindings_builder(&manifest_dir, build_prefix); + let bindings = builder.generate().expect("Unable to generate bindings."); + Ok(bindings + .write_to_file(bindings_file) + .expect("Unable to write bindings to file.")) +} diff --git a/bindings/rust/aws-lc-sys-template/src/lib.rs b/bindings/rust/aws-lc-sys-template/src/lib.rs index fe9a1a883e..7e172a0a9a 100644 --- a/bindings/rust/aws-lc-sys-template/src/lib.rs +++ b/bindings/rust/aws-lc-sys-template/src/lib.rs @@ -1,8 +1,29 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 OR ISC -pub use bindings::*; +#[cfg(all(not(feature = "bindgen"), target_os = "linux", target_arch = "x86"))] +pub use linux_x86_bindings::*; +#[cfg(all(not(feature = "bindgen"), target_os = "linux", target_arch = "x86"))] +mod linux_x86_bindings; + +#[cfg(all(not(feature = "bindgen"), target_os = "linux", target_arch = "x86_64"))] +pub use linux_x86_64_bindings::*; +#[cfg(all(not(feature = "bindgen"), target_os = "linux", target_arch = "x86_64"))] +mod linux_x86_64_bindings; + +#[cfg(all(not(feature = "bindgen"), target_os = "linux", target_arch = "aarch64"))] +pub use linux_aarch64_bindings::*; +#[cfg(all(not(feature = "bindgen"), target_os = "linux", target_arch = "aarch64"))] +mod linux_aarch64_bindings; +#[cfg(all(not(feature = "bindgen"), target_os = "macos", target_arch = "x86_64"))] +pub use macos_x86_64_bindings::*; +#[cfg(all(not(feature = "bindgen"), target_os = "macos", target_arch = "x86_64"))] +mod macos_x86_64_bindings; + +#[cfg(feature = "bindgen")] +pub use bindings::*; +#[cfg(feature = "bindgen")] mod bindings; #[allow(non_snake_case)] diff --git a/bindings/rust/aws-lc-sys-template/tests/sanity-tests.rs b/bindings/rust/aws-lc-sys-template/tests/sanity-tests.rs index 1d7ffcf493..844db66656 100644 --- a/bindings/rust/aws-lc-sys-template/tests/sanity-tests.rs +++ b/bindings/rust/aws-lc-sys-template/tests/sanity-tests.rs @@ -1,7 +1,7 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 OR ISC -use std::mem::MaybeUninit; use aws_lc_sys; +use std::mem::MaybeUninit; use openssl; diff --git a/bindings/rust/generate/Cargo.toml b/bindings/rust/generate/Cargo.toml new file mode 100644 index 0000000000..222dcfbacc --- /dev/null +++ b/bindings/rust/generate/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "generate" +version = "__AWS_LC_SYS_VERSION__" +authors = ["AWS-LC"] +edition = "2021" +license = "Apache-2.0 OR ISC" +# this is an internal tool for generating bindings +publish = false + +[dependencies] +bindgen = "0.61" +dunce = "1.0" diff --git a/bindings/rust/generate/_generate_all_bindings_flavors.sh b/bindings/rust/generate/_generate_all_bindings_flavors.sh new file mode 100755 index 0000000000..9ffe096694 --- /dev/null +++ b/bindings/rust/generate/_generate_all_bindings_flavors.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 OR ISC + +set -e + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +AWS_LC_DIR=$( cd -- "${SCRIPT_DIR}/../../../" &> /dev/null && pwd) + +echo ARGS: "${@}" + +IGNORE_MACOS=0 + +while getopts "m" option; do + case ${option} in + m ) + IGNORE_MACOS=1 + ;; + * ) + echo "$(basename "${0}")" - Invalid argument: -"${?}" + echo + exit 1 + ;; + esac +done + +## macos x86_64 bindings +if [[ ! "${OSTYPE}" == "darwin"* ]]; then + echo This script is not running on MacOS. + if [[ ${IGNORE_MACOS} -eq 0 ]]; then + echo Aborting. Use '-m' to ignore. + echo + exit 1 + else + echo Ignoring non-MacOS. Bindings will not be generated for Mac. + echo + fi +else + "${SCRIPT_DIR}"/_generate_bindings.sh +fi + +pushd "${AWS_LC_DIR}" + +## +## These docker image can be built from Dockerfiles under: /tests/ci/docker_images/rust +## + +## 386 build +docker run -v "${AWS_LC_DIR}":"${AWS_LC_DIR}" -w "${AWS_LC_DIR}" --rm --platform linux/386 rust:linux-386 /bin/bash "${SCRIPT_DIR}"/_generate_bindings.sh + +## linux x86_64 build +docker run -v "${AWS_LC_DIR}":"${AWS_LC_DIR}" -w "${AWS_LC_DIR}" --rm --platform linux/amd64 rust:linux-x86_64 /bin/bash "${SCRIPT_DIR}"/_generate_bindings.sh + +## linux aarch64 build +docker run -v "${AWS_LC_DIR}":"${AWS_LC_DIR}" -w "${AWS_LC_DIR}" --rm --platform linux/arm64 rust:linux-arm64 /bin/bash "${SCRIPT_DIR}"/_generate_bindings.sh + +popd diff --git a/bindings/rust/generate/_generate_bindings.sh b/bindings/rust/generate/_generate_bindings.sh new file mode 100755 index 0000000000..1a0765ffd0 --- /dev/null +++ b/bindings/rust/generate/_generate_bindings.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 OR ISC + +set -e -x + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +AWS_LC_DIR=$( cd -- "${SCRIPT_DIR}/../../../" &> /dev/null && pwd) +GEN_DIR="${AWS_LC_DIR}"/bindings/rust/generate +TMP_DIR="${AWS_LC_DIR}"/bindings/rust/tmp + +pushd "${GEN_DIR}" + +cargo clean +cargo run "${TMP_DIR}"/aws-lc-sys +cargo clean + +popd diff --git a/bindings/rust/generate/generate.sh b/bindings/rust/generate/generate.sh index f9e0ea82af..162f3fff8c 100755 --- a/bindings/rust/generate/generate.sh +++ b/bindings/rust/generate/generate.sh @@ -111,7 +111,7 @@ if [[ ! "${OSTYPE}" == "darwin"* ]]; then echo exit 1 else - echo Ignoring non-MacOS. Crate will not be tested for Mac. + echo Ignoring non-MacOS. Crate will not be tested and bindings will not be generated for Mac. echo fi fi @@ -188,6 +188,9 @@ function prepare_crate_dir { prepare_crate_dir create_prefix_headers +perl -pi -e "s/__AWS_LC_SYS_VERSION__/${AWS_LC_SYS_VERSION}/g" "${SCRIPT_DIR}"/Cargo.toml +"${SCRIPT_DIR}"/_generate_all_bindings_flavors.sh + if [[ ${SKIP_TEST} -eq 1 ]]; then echo Aborting. Crate generated but not tested. exit 1 diff --git a/bindings/rust/generate/src/main.rs b/bindings/rust/generate/src/main.rs new file mode 100644 index 0000000000..023c345ac1 --- /dev/null +++ b/bindings/rust/generate/src/main.rs @@ -0,0 +1,122 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC + +use bindgen::callbacks::ParseCallbacks; +use std::fmt::Debug; +use std::path::{Path, PathBuf}; +use std::env; + +#[derive(Debug)] +struct StripPrefixCallback { + remove_prefix: Option, +} + +impl StripPrefixCallback { + fn new(prefix: &str) -> StripPrefixCallback { + StripPrefixCallback { + remove_prefix: Some(prefix.to_string()), + } + } +} + +impl ParseCallbacks for StripPrefixCallback { + fn generated_name_override(&self, name: &str) -> Option { + self.remove_prefix.as_ref().and_then(|s| { + let prefix = format!("{}_", s); + name.strip_prefix(prefix.as_str()).map(String::from) + }) + } +} + +fn get_include_path(manifest_dir: &Path) -> PathBuf { + manifest_dir.join("deps").join("aws-lc").join("include") +} + +fn prepare_clang_args(manifest_dir: &Path, build_prefix: Option<&str>) -> Vec { + let mut clang_args: Vec = vec![ + "-I".to_string(), + get_include_path(manifest_dir).display().to_string(), + ]; + + if let Some(prefix) = build_prefix { + clang_args.push(format!("-DBORINGSSL_PREFIX={}", prefix)); + } + + clang_args +} + +const COPYRIGHT: &str = r#" +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC +"#; + +const PRELUDE: &str = r#" +#![allow(unused_imports, non_camel_case_types, non_snake_case, non_upper_case_globals, improper_ctypes)] +"#; + +fn prepare_bindings_builder(manifest_dir: &Path, build_prefix: Option<&str>) -> bindgen::Builder { + let clang_args = prepare_clang_args(manifest_dir, build_prefix); + + let mut builder = bindgen::Builder::default() + .derive_copy(true) + .derive_debug(true) + .derive_default(true) + .derive_eq(true) + .allowlist_file(".*/openssl/[^/]+\\.h") + .allowlist_file(".*/rust_wrapper\\.h") + .default_enum_style(bindgen::EnumVariation::NewType { + is_bitfield: false, + is_global: false, + }) + .default_macro_constant_type(bindgen::MacroTypeVariation::Signed) + .generate_comments(true) + .fit_macro_constants(false) + .size_t_is_usize(true) + .layout_tests(true) + .prepend_enum_name(true) + .rustfmt_bindings(true) + .clang_args(clang_args) + .raw_line(COPYRIGHT) + .raw_line(PRELUDE) + .header( + get_include_path(manifest_dir) + .join("rust_wrapper.h") + .display() + .to_string(), + ); + + if let Some(ps) = build_prefix { + builder = builder.parse_callbacks(Box::new(StripPrefixCallback::new(ps))); + } + + builder +} + +const VERSION: &str = env!("CARGO_PKG_VERSION"); + +fn prefix_string() -> String { + format!("aws_lc_{}", VERSION.to_string().replace('.', "_")) +} + +fn target_platform_bindings_string() -> String { + format!("{}_{}_bindings.rs" + ,std::env::consts::OS + ,std::env::consts::ARCH) +} + +fn main() -> Result<(), String> { + // Expects aws-lc-sys directory as argument. + let manifest_dir = env::args().nth(1).expect("missing sys dir"); + let manifest_dir = dunce::canonicalize(Path::new(&manifest_dir)).unwrap(); + let prefix = prefix_string(); + + let bindings_file = manifest_dir.join("src").join(target_platform_bindings_string()); + + let builder = prepare_bindings_builder(&manifest_dir, Some(&prefix)); + let bindings = builder.generate().expect("Unable to generate bindings."); + bindings + .write_to_file(bindings_file) + .expect("Unable to write bindings to file."); + + Ok(()) +} diff --git a/tests/ci/docker_images/rust/linux-arm64/Dockerfile b/tests/ci/docker_images/rust/linux-arm64/Dockerfile index d9a81ee9f3..b8eaac38d9 100644 --- a/tests/ci/docker_images/rust/linux-arm64/Dockerfile +++ b/tests/ci/docker_images/rust/linux-arm64/Dockerfile @@ -1,6 +1,10 @@ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 OR ISC +# Download exactly what is needed using the sparse registry. +# https://github.com/rust-lang/cargo/issues/10781 +# https://blog.rust-lang.org/2022/06/22/sparse-registry-testing.html + FROM --platform=linux/arm64 rust:latest SHELL ["/bin/bash", "-c"] @@ -8,10 +12,14 @@ SHELL ["/bin/bash", "-c"] RUN apt-get update && \ apt-get -y install clang cmake golang && \ rustup update && \ + rustup toolchain install nightly && \ + rustup default nightly && \ rustup component add rustfmt clippy && \ + cargo +nightly install -Z sparse-registry --debug cargo-ament-build && \ apt-get autoremove --purge -y && \ apt-get clean && \ apt-get autoclean && \ rm -rf /var/lib/apt/lists/* && \ rm -rf /tmp/* +ENV CARGO_UNSTABLE_SPARSE_REGISTRY=true From 10bc3064832147a3dcb46a6216b2ab27014e9573 Mon Sep 17 00:00:00 2001 From: sachiang Date: Mon, 21 Nov 2022 17:40:20 -0800 Subject: [PATCH 2/7] backport cmake dependency removal and add option removals --- bindings/rust/aws-lc-sys-template/Cargo.toml | 1 + bindings/rust/aws-lc-sys-template/build.rs | 122 ++++++------------- 2 files changed, 36 insertions(+), 87 deletions(-) diff --git a/bindings/rust/aws-lc-sys-template/Cargo.toml b/bindings/rust/aws-lc-sys-template/Cargo.toml index 3dfb687193..514fc35372 100644 --- a/bindings/rust/aws-lc-sys-template/Cargo.toml +++ b/bindings/rust/aws-lc-sys-template/Cargo.toml @@ -28,6 +28,7 @@ asan = [] bindgen = ["dep:bindgen"] [build-dependencies] +cmake = "0.1.48" bindgen = { version ="0.61", optional = true } regex = "1" dunce = "1.0" diff --git a/bindings/rust/aws-lc-sys-template/build.rs b/bindings/rust/aws-lc-sys-template/build.rs index ca54ff2343..04dcea6bc1 100644 --- a/bindings/rust/aws-lc-sys-template/build.rs +++ b/bindings/rust/aws-lc-sys-template/build.rs @@ -15,7 +15,7 @@ // SPDX-License-Identifier: Apache-2.0 OR ISC // Modifications Copyright Amazon.com, Inc. or its affiliates. See GitHub history for details. -use std::ffi::{OsStr, OsString}; +use std::ffi::OsStr; use std::path::{Path, PathBuf}; use std::process::Command; use std::{env, fs}; @@ -115,108 +115,56 @@ fn find_cmake_command() -> Option<&'static OsStr> { } } -fn prepare_cmake_args( - aws_lc_path: &Path, - build_prefix: Option<&str>, -) -> Result, &'static str> { - let mut args: Vec = vec![ - OsString::from("-DBUILD_TESTING=OFF"), - OsString::from("-DBUILD_LIBSSL=OFF"), - OsString::from("-DDISABLE_PERL=ON"), - OsString::from("-DDISABLE_GO=ON"), - aws_lc_path.as_os_str().into(), - ]; +fn get_cmake_config() -> cmake::Config { + let pwd = env::current_dir().unwrap(); + + cmake::Config::new(pwd.join(AWS_LC_PATH)) +} + +fn prepare_cmake_build(build_prefix: Option<&str>) -> cmake::Config { + let mut cmake_cfg = get_cmake_config(); let opt_level = env::var("OPT_LEVEL").unwrap_or_else(|_| "0".to_string()); - if opt_level.eq("0") { - args.push(OsString::from("-DCMAKE_BUILD_TYPE=debug")); - } else if opt_level.eq("1") || opt_level.eq("2") { - args.push(OsString::from("-DCMAKE_BUILD_TYPE=relwithdebinfo")); - } else { - args.push(OsString::from("-DCMAKE_BUILD_TYPE=release")); + if opt_level.ne("0") { + if opt_level.eq("1") || opt_level.eq("2") { + cmake_cfg.define("CMAKE_BUILD_TYPE", "relwithdebinfo"); + } else { + cmake_cfg.define("CMAKE_BUILD_TYPE", "release"); + } } if let Some(symbol_prefix) = build_prefix { - args.push(OsString::from(format!( - "-DBORINGSSL_PREFIX={}", - symbol_prefix - ))); - let include_path = aws_lc_path.join("include"); - args.push(OsString::from(format!( - "-DBORINGSSL_PREFIX_HEADERS={}", - include_path.display() - ))); + cmake_cfg.define("BORINGSSL_PREFIX", symbol_prefix); + let pwd = env::current_dir().unwrap(); + let include_path = pwd.join(AWS_LC_PATH).join("include"); + cmake_cfg.define( + "BORINGSSL_PREFIX_HEADERS", + include_path.display().to_string(), + ); } + // Build flags that minimize our crate size. + cmake_cfg.define("BUILD_TESTING", "OFF"); + cmake_cfg.define("BUILD_LIBSSL", "OFF"); + // Build flags that minimize our dependencies. + cmake_cfg.define("DISABLE_PERL", "ON"); + cmake_cfg.define("DISABLE_GO", "ON"); + if cfg!(feature = "asan") { env::set_var("CC", "/usr/bin/clang"); env::set_var("CXX", "/usr/bin/clang++"); env::set_var("ASM", "/usr/bin/clang"); - args.push(OsString::from("-DASAN=1")); + cmake_cfg.define("ASAN", "1"); } - Ok(args) -} - -fn load_env_var(var_name: &str) -> String { - env::var(var_name).unwrap_or_else(|_| panic!("Missing Environment variable: {}", var_name)) + cmake_cfg } -fn build_aws_lc() -> Result { - let cmake_cmd: &OsStr; - if let Some(cmd) = find_cmake_command() { - // This can be a let-else as-of Rust 1.65 - cmake_cmd = cmd; - } else { - return Err("Missing dependency: cmake"); - }; - - let pwd = env::current_dir().unwrap_or_else(|_| PathBuf::from(".")); - let aws_lc_path = pwd.join(AWS_LC_PATH); - - let out_dir = PathBuf::from(load_env_var("OUT_DIR")); - let build_dir = out_dir.join("build"); - if !build_dir.exists() { - fs::create_dir_all(build_dir.clone()).unwrap(); - } - - let mut setup_command = Command::new(cmake_cmd); - - setup_command.args(prepare_cmake_args(&aws_lc_path, Some(&prefix_string()))?); - setup_command.current_dir(&build_dir); - println!("running: {:?}", setup_command); - let output = setup_command - .output() - .map_err(|_| "cmake setup command failed")?; - - if !output.status.success() { - eprintln!("{}", String::from_utf8(output.stderr).unwrap()); - return Err("cmake setup command unsuccessful"); - } - - let mut build_command = Command::new(cmake_cmd); - build_command.args(&[ - OsString::from("--build"), - OsString::from("."), - OsString::from("--target"), - OsString::from("crypto"), - ]); - build_command.current_dir(&build_dir); - - println!("running: {:?}", build_command); - let output = build_command - .output() - .map_err(|_| "cmake build command failed")?; - if !output.status.success() { - eprintln!("-- stdout --"); - eprintln!("{}", String::from_utf8(output.stdout).unwrap()); - eprintln!("-- stderr --"); - eprintln!("{}", String::from_utf8(output.stderr).unwrap()); - return Err("cmake build command unsuccessful."); - } +fn build_aws_lc() -> PathBuf { + let mut cmake_cfg = prepare_cmake_build(Some(&prefix_string())); - Ok(out_dir) + cmake_cfg.build_target("crypto").build() } fn main() -> Result<(), String> { @@ -244,7 +192,7 @@ fn main() -> Result<(), String> { build_bindgen::generate_bindings(&manifest_dir, Some(&prefix)) .expect("Unable to generate bindings."); - let aws_lc_dir = build_aws_lc()?; + let aws_lc_dir = build_aws_lc(); let lib_file = Crypto.locate_file(&aws_lc_dir, Static, None); let prefixed_lib_file = Crypto.locate_file(&aws_lc_dir, Static, Some(&prefix)); fs::rename(lib_file, prefixed_lib_file).expect("Unexpected error: Library not found"); From 28cd662c9b9aa73fa3b6b240098eb42ea06251f2 Mon Sep 17 00:00:00 2001 From: sachiang Date: Tue, 22 Nov 2022 17:16:28 -0800 Subject: [PATCH 3/7] update Readme for aws-lc-sys crate generation --- bindings/rust/README.md | 16 +++++++++++++++- bindings/rust/aws-lc-sys-template/Cargo.toml | 2 +- bindings/rust/generate/generate.sh | 2 +- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/bindings/rust/README.md b/bindings/rust/README.md index 6f9010d351..32e0d2b944 100644 --- a/bindings/rust/README.md +++ b/bindings/rust/README.md @@ -6,9 +6,23 @@ Low-level AWS-LC bindings crate for Rust. ### How it works `aws-lc-sys` uses `bindgen` 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. +### Installation + +In order to generate the `aws-lc-sys` crate, you need to have the following installed: + +* Rust - installable with [rustup](https://rustup.rs/) +* libclang +* docker +* C compilation tools to build AWS-LC. We pull in [generated-src](https://github.com/awslabs/aws-lc/tree/main/generated-src) into `aws-lc-sys`, so Go and Perl aren't needed (for non-FIPS). +* CMake3.16 or above. [`cmake-rs`](https://docs.rs/cmake/latest/cmake/) appends build options after the path, which isn't supported in older versions of cmake. + ### To Use The `aws-lc-sys` create can be built by running the [generate.sh](./generate/generate.sh) script. The script requires the [docker images](../../tests/ci/docker_images/rust) to -be [built](../../tests/ci/docker_images/rust/build_images.sh) and available locally. +be [built](../../tests/ci/docker_images/rust/build_images.sh) and available locally. Bindings for `macos-x86_64` are generated on the native MacOS x86_64 platform. Bindings are generated for `linux-x86_64`, `linux-aarch64`, `linux-x86` using the corresponding docker images. + +``` +./bindings/rust/generate/generate.sh +``` See AWS-LC build documentation for more details: https://github.com/awslabs/aws-lc/blob/main/BUILDING.md diff --git a/bindings/rust/aws-lc-sys-template/Cargo.toml b/bindings/rust/aws-lc-sys-template/Cargo.toml index 514fc35372..853fe04384 100644 --- a/bindings/rust/aws-lc-sys-template/Cargo.toml +++ b/bindings/rust/aws-lc-sys-template/Cargo.toml @@ -25,7 +25,7 @@ include = [ [features] asan = [] -bindgen = ["dep:bindgen"] +run_bindgen = ["bindgen"] [build-dependencies] cmake = "0.1.48" diff --git a/bindings/rust/generate/generate.sh b/bindings/rust/generate/generate.sh index 162f3fff8c..1e963218e8 100755 --- a/bindings/rust/generate/generate.sh +++ b/bindings/rust/generate/generate.sh @@ -6,7 +6,7 @@ set -e function usage { echo - echo "Usage: $(basename "${0}") [-d] [-b] [-u] [-m]" + echo "Usage: $(basename "${0}") [-d] [-b] [-u] [-m] [-s]" echo } From 3d712c99eab73c9d185a16cd2a9d9e1c46107250 Mon Sep 17 00:00:00 2001 From: sachiang Date: Mon, 28 Nov 2022 18:07:19 -0800 Subject: [PATCH 4/7] leverage bindings generation in aws-lc-sys for pre-generation --- bindings/rust/README.md | 2 +- bindings/rust/aws-lc-sys-template/Cargo.toml | 7 +- .../rust/aws-lc-sys-template/build_bindgen.rs | 12 +- bindings/rust/aws-lc-sys-template/src/lib.rs | 45 +++---- bindings/rust/generate/Cargo.toml | 12 -- .../_generate_all_bindings_flavors.sh | 2 + bindings/rust/generate/_generate_bindings.sh | 6 +- bindings/rust/generate/generate.sh | 3 +- bindings/rust/generate/src/main.rs | 122 ------------------ 9 files changed, 45 insertions(+), 166 deletions(-) delete mode 100644 bindings/rust/generate/Cargo.toml delete mode 100644 bindings/rust/generate/src/main.rs diff --git a/bindings/rust/README.md b/bindings/rust/README.md index 32e0d2b944..d681c7d7df 100644 --- a/bindings/rust/README.md +++ b/bindings/rust/README.md @@ -14,7 +14,7 @@ In order to generate the `aws-lc-sys` crate, you need to have the following inst * libclang * docker * C compilation tools to build AWS-LC. We pull in [generated-src](https://github.com/awslabs/aws-lc/tree/main/generated-src) into `aws-lc-sys`, so Go and Perl aren't needed (for non-FIPS). -* CMake3.16 or above. [`cmake-rs`](https://docs.rs/cmake/latest/cmake/) appends build options after the path, which isn't supported in older versions of cmake. +* CMake3 or above. [`cmake-rs`](https://docs.rs/cmake/latest/cmake/) appends build options after the path, which isn't supported in older versions of cmake. ### To Use The `aws-lc-sys` create can be built by running the [generate.sh](./generate/generate.sh) script. diff --git a/bindings/rust/aws-lc-sys-template/Cargo.toml b/bindings/rust/aws-lc-sys-template/Cargo.toml index 853fe04384..e0b9f9a038 100644 --- a/bindings/rust/aws-lc-sys-template/Cargo.toml +++ b/bindings/rust/aws-lc-sys-template/Cargo.toml @@ -25,7 +25,12 @@ include = [ [features] asan = [] -run_bindgen = ["bindgen"] +# Generate the bindings on the targetted platform as a fallback mechanism. +native_bindings = ["bindgen"] +# Pre-generate the bindings for crate publishing. Cannot be used simultaneously with the +# native_bindings feature. This feature is only intended for internal usage. +generate = ["bindgen"] + [build-dependencies] cmake = "0.1.48" diff --git a/bindings/rust/aws-lc-sys-template/build_bindgen.rs b/bindings/rust/aws-lc-sys-template/build_bindgen.rs index 3fc0c8cf54..887e4e2008 100644 --- a/bindings/rust/aws-lc-sys-template/build_bindgen.rs +++ b/bindings/rust/aws-lc-sys-template/build_bindgen.rs @@ -89,11 +89,21 @@ fn prepare_bindings_builder(manifest_dir: &Path, build_prefix: Option<&str>) -> builder } +#[cfg(feature = "generate")] +pub(crate) fn target_platform_bindings_string() -> String { + format!("{}_{}_bindings.rs" + ,std::env::consts::OS + ,std::env::consts::ARCH) +} + pub(crate) fn generate_bindings( manifest_dir: &Path, - build_prefix: Option<&str>, + build_prefix: Option<&str> ) -> Result<(), &'static str> { + #[cfg(feature = "native_bindings")] let bindings_file = manifest_dir.join("src").join("bindings.rs"); + #[cfg(feature = "generate")] + let bindings_file = manifest_dir.join("src").join(target_platform_bindings_string()); let builder = prepare_bindings_builder(&manifest_dir, build_prefix); let bindings = builder.generate().expect("Unable to generate bindings."); diff --git a/bindings/rust/aws-lc-sys-template/src/lib.rs b/bindings/rust/aws-lc-sys-template/src/lib.rs index 7e172a0a9a..1d457046be 100644 --- a/bindings/rust/aws-lc-sys-template/src/lib.rs +++ b/bindings/rust/aws-lc-sys-template/src/lib.rs @@ -1,30 +1,27 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 OR ISC -#[cfg(all(not(feature = "bindgen"), target_os = "linux", target_arch = "x86"))] -pub use linux_x86_bindings::*; -#[cfg(all(not(feature = "bindgen"), target_os = "linux", target_arch = "x86"))] -mod linux_x86_bindings; - -#[cfg(all(not(feature = "bindgen"), target_os = "linux", target_arch = "x86_64"))] -pub use linux_x86_64_bindings::*; -#[cfg(all(not(feature = "bindgen"), target_os = "linux", target_arch = "x86_64"))] -mod linux_x86_64_bindings; - -#[cfg(all(not(feature = "bindgen"), target_os = "linux", target_arch = "aarch64"))] -pub use linux_aarch64_bindings::*; -#[cfg(all(not(feature = "bindgen"), target_os = "linux", target_arch = "aarch64"))] -mod linux_aarch64_bindings; - -#[cfg(all(not(feature = "bindgen"), target_os = "macos", target_arch = "x86_64"))] -pub use macos_x86_64_bindings::*; -#[cfg(all(not(feature = "bindgen"), target_os = "macos", target_arch = "x86_64"))] -mod macos_x86_64_bindings; - -#[cfg(feature = "bindgen")] -pub use bindings::*; -#[cfg(feature = "bindgen")] -mod bindings; +macro_rules! use_bindings { + ($bindings:ident) => { + mod $bindings; + pub use $bindings::*; + } +} + +#[cfg(all(not(feature = "native_bindings"), target_os = "linux", target_arch = "x86"))] +use_bindings!(linux_x86_bindings); + +#[cfg(all(not(feature = "native_bindings"), target_os = "linux", target_arch = "x86_64"))] +use_bindings!(linux_x86_64_bindings); + +#[cfg(all(not(feature = "native_bindings"), target_os = "linux", target_arch = "aarch64"))] +use_bindings!(linux_aarch64_bindings); + +#[cfg(all(not(feature = "native_bindings"), target_os = "macos", target_arch = "x86_64"))] +use_bindings!(macos_x86_64_bindings); + +#[cfg(feature = "native_bindings")] +use_bindings!(bindings); #[allow(non_snake_case)] /// # Safety diff --git a/bindings/rust/generate/Cargo.toml b/bindings/rust/generate/Cargo.toml deleted file mode 100644 index 222dcfbacc..0000000000 --- a/bindings/rust/generate/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "generate" -version = "__AWS_LC_SYS_VERSION__" -authors = ["AWS-LC"] -edition = "2021" -license = "Apache-2.0 OR ISC" -# this is an internal tool for generating bindings -publish = false - -[dependencies] -bindgen = "0.61" -dunce = "1.0" diff --git a/bindings/rust/generate/_generate_all_bindings_flavors.sh b/bindings/rust/generate/_generate_all_bindings_flavors.sh index 9ffe096694..819664b898 100755 --- a/bindings/rust/generate/_generate_all_bindings_flavors.sh +++ b/bindings/rust/generate/_generate_all_bindings_flavors.sh @@ -41,6 +41,8 @@ fi pushd "${AWS_LC_DIR}" +## TODO: Find a way to pre-generate bindings for macos-aarch64 on the fly. + ## ## These docker image can be built from Dockerfiles under: /tests/ci/docker_images/rust ## diff --git a/bindings/rust/generate/_generate_bindings.sh b/bindings/rust/generate/_generate_bindings.sh index 1a0765ffd0..f6deb6a25e 100755 --- a/bindings/rust/generate/_generate_bindings.sh +++ b/bindings/rust/generate/_generate_bindings.sh @@ -6,13 +6,13 @@ set -e -x SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) AWS_LC_DIR=$( cd -- "${SCRIPT_DIR}/../../../" &> /dev/null && pwd) -GEN_DIR="${AWS_LC_DIR}"/bindings/rust/generate TMP_DIR="${AWS_LC_DIR}"/bindings/rust/tmp +CRATE_DIR="${TMP_DIR}"/aws-lc-sys -pushd "${GEN_DIR}" +pushd "${CRATE_DIR}" cargo clean -cargo run "${TMP_DIR}"/aws-lc-sys +cargo build --features generate cargo clean popd diff --git a/bindings/rust/generate/generate.sh b/bindings/rust/generate/generate.sh index 1e963218e8..3e693fa3f9 100755 --- a/bindings/rust/generate/generate.sh +++ b/bindings/rust/generate/generate.sh @@ -188,8 +188,7 @@ function prepare_crate_dir { prepare_crate_dir create_prefix_headers -perl -pi -e "s/__AWS_LC_SYS_VERSION__/${AWS_LC_SYS_VERSION}/g" "${SCRIPT_DIR}"/Cargo.toml -"${SCRIPT_DIR}"/_generate_all_bindings_flavors.sh +"${SCRIPT_DIR}"/_generate_all_bindings_flavors.sh "$( [ ${IGNORE_MACOS} -eq 1 ] && echo '-m' )" if [[ ${SKIP_TEST} -eq 1 ]]; then echo Aborting. Crate generated but not tested. diff --git a/bindings/rust/generate/src/main.rs b/bindings/rust/generate/src/main.rs deleted file mode 100644 index 023c345ac1..0000000000 --- a/bindings/rust/generate/src/main.rs +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 OR ISC - -use bindgen::callbacks::ParseCallbacks; -use std::fmt::Debug; -use std::path::{Path, PathBuf}; -use std::env; - -#[derive(Debug)] -struct StripPrefixCallback { - remove_prefix: Option, -} - -impl StripPrefixCallback { - fn new(prefix: &str) -> StripPrefixCallback { - StripPrefixCallback { - remove_prefix: Some(prefix.to_string()), - } - } -} - -impl ParseCallbacks for StripPrefixCallback { - fn generated_name_override(&self, name: &str) -> Option { - self.remove_prefix.as_ref().and_then(|s| { - let prefix = format!("{}_", s); - name.strip_prefix(prefix.as_str()).map(String::from) - }) - } -} - -fn get_include_path(manifest_dir: &Path) -> PathBuf { - manifest_dir.join("deps").join("aws-lc").join("include") -} - -fn prepare_clang_args(manifest_dir: &Path, build_prefix: Option<&str>) -> Vec { - let mut clang_args: Vec = vec![ - "-I".to_string(), - get_include_path(manifest_dir).display().to_string(), - ]; - - if let Some(prefix) = build_prefix { - clang_args.push(format!("-DBORINGSSL_PREFIX={}", prefix)); - } - - clang_args -} - -const COPYRIGHT: &str = r#" -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 OR ISC -"#; - -const PRELUDE: &str = r#" -#![allow(unused_imports, non_camel_case_types, non_snake_case, non_upper_case_globals, improper_ctypes)] -"#; - -fn prepare_bindings_builder(manifest_dir: &Path, build_prefix: Option<&str>) -> bindgen::Builder { - let clang_args = prepare_clang_args(manifest_dir, build_prefix); - - let mut builder = bindgen::Builder::default() - .derive_copy(true) - .derive_debug(true) - .derive_default(true) - .derive_eq(true) - .allowlist_file(".*/openssl/[^/]+\\.h") - .allowlist_file(".*/rust_wrapper\\.h") - .default_enum_style(bindgen::EnumVariation::NewType { - is_bitfield: false, - is_global: false, - }) - .default_macro_constant_type(bindgen::MacroTypeVariation::Signed) - .generate_comments(true) - .fit_macro_constants(false) - .size_t_is_usize(true) - .layout_tests(true) - .prepend_enum_name(true) - .rustfmt_bindings(true) - .clang_args(clang_args) - .raw_line(COPYRIGHT) - .raw_line(PRELUDE) - .header( - get_include_path(manifest_dir) - .join("rust_wrapper.h") - .display() - .to_string(), - ); - - if let Some(ps) = build_prefix { - builder = builder.parse_callbacks(Box::new(StripPrefixCallback::new(ps))); - } - - builder -} - -const VERSION: &str = env!("CARGO_PKG_VERSION"); - -fn prefix_string() -> String { - format!("aws_lc_{}", VERSION.to_string().replace('.', "_")) -} - -fn target_platform_bindings_string() -> String { - format!("{}_{}_bindings.rs" - ,std::env::consts::OS - ,std::env::consts::ARCH) -} - -fn main() -> Result<(), String> { - // Expects aws-lc-sys directory as argument. - let manifest_dir = env::args().nth(1).expect("missing sys dir"); - let manifest_dir = dunce::canonicalize(Path::new(&manifest_dir)).unwrap(); - let prefix = prefix_string(); - - let bindings_file = manifest_dir.join("src").join(target_platform_bindings_string()); - - let builder = prepare_bindings_builder(&manifest_dir, Some(&prefix)); - let bindings = builder.generate().expect("Unable to generate bindings."); - bindings - .write_to_file(bindings_file) - .expect("Unable to write bindings to file."); - - Ok(()) -} From daff023c7be5a0fd869d0c4b675d28b2e8c09b6b Mon Sep 17 00:00:00 2001 From: sachiang Date: Tue, 29 Nov 2022 16:19:54 -0800 Subject: [PATCH 5/7] warn when prebuilt bindings aren't available --- bindings/rust/aws-lc-sys-template/Cargo.toml | 1 - bindings/rust/aws-lc-sys-template/src/lib.rs | 44 +++++++++++++++++--- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/bindings/rust/aws-lc-sys-template/Cargo.toml b/bindings/rust/aws-lc-sys-template/Cargo.toml index e0b9f9a038..963a4ae426 100644 --- a/bindings/rust/aws-lc-sys-template/Cargo.toml +++ b/bindings/rust/aws-lc-sys-template/Cargo.toml @@ -31,7 +31,6 @@ native_bindings = ["bindgen"] # native_bindings feature. This feature is only intended for internal usage. generate = ["bindgen"] - [build-dependencies] cmake = "0.1.48" bindgen = { version ="0.61", optional = true } diff --git a/bindings/rust/aws-lc-sys-template/src/lib.rs b/bindings/rust/aws-lc-sys-template/src/lib.rs index 1d457046be..ae3d39ee7d 100644 --- a/bindings/rust/aws-lc-sys-template/src/lib.rs +++ b/bindings/rust/aws-lc-sys-template/src/lib.rs @@ -1,23 +1,57 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 OR ISC +// Warn to use feature native_bindings if building on a platform where prebuilt-bindings +// aren't available +#[cfg(all( + not(feature = "native_bindings"), + not(any( + all(target_os = "linux", target_arch = "x86"), + all(target_os = "linux", target_arch = "x86_64"), + all(target_os = "linux", target_arch = "aarch64"), + all(target_os = "macos", target_arch = "x86_64") + )) +))] +compile_error!("Prebuilt-bindings aren't available. Turn on feature native_bindings to build."); + +#[cfg(all(feature = "native_bindings", feature = "generate"))] +compile_error!( + "Generate is only for internal usage. Only turn on feature native_bindings to build." +); + macro_rules! use_bindings { ($bindings:ident) => { mod $bindings; pub use $bindings::*; - } + }; } -#[cfg(all(not(feature = "native_bindings"), target_os = "linux", target_arch = "x86"))] +#[cfg(all( + not(feature = "native_bindings"), + target_os = "linux", + target_arch = "x86" +))] use_bindings!(linux_x86_bindings); -#[cfg(all(not(feature = "native_bindings"), target_os = "linux", target_arch = "x86_64"))] +#[cfg(all( + not(feature = "native_bindings"), + target_os = "linux", + target_arch = "x86_64" +))] use_bindings!(linux_x86_64_bindings); -#[cfg(all(not(feature = "native_bindings"), target_os = "linux", target_arch = "aarch64"))] +#[cfg(all( + not(feature = "native_bindings"), + target_os = "linux", + target_arch = "aarch64" +))] use_bindings!(linux_aarch64_bindings); -#[cfg(all(not(feature = "native_bindings"), target_os = "macos", target_arch = "x86_64"))] +#[cfg(all( + not(feature = "native_bindings"), + target_os = "macos", + target_arch = "x86_64" +))] use_bindings!(macos_x86_64_bindings); #[cfg(feature = "native_bindings")] From bc1e09558aeb4ef46e397a1e79eefb4def4c9ae6 Mon Sep 17 00:00:00 2001 From: sachiang Date: Wed, 30 Nov 2022 12:12:48 -0800 Subject: [PATCH 6/7] apply cfg_aliases and clear up feature names --- bindings/rust/aws-lc-sys-template/Cargo.toml | 5 +++-- bindings/rust/aws-lc-sys-template/build.rs | 9 +++++++++ .../rust/aws-lc-sys-template/build_bindgen.rs | 20 +++++++++++-------- bindings/rust/generate/_generate_bindings.sh | 2 +- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/bindings/rust/aws-lc-sys-template/Cargo.toml b/bindings/rust/aws-lc-sys-template/Cargo.toml index 963a4ae426..870b2f872c 100644 --- a/bindings/rust/aws-lc-sys-template/Cargo.toml +++ b/bindings/rust/aws-lc-sys-template/Cargo.toml @@ -26,16 +26,17 @@ include = [ [features] asan = [] # Generate the bindings on the targetted platform as a fallback mechanism. -native_bindings = ["bindgen"] +generate_bindings = ["bindgen"] # Pre-generate the bindings for crate publishing. Cannot be used simultaneously with the # native_bindings feature. This feature is only intended for internal usage. -generate = ["bindgen"] +internal_generate = ["bindgen"] [build-dependencies] cmake = "0.1.48" bindgen = { version ="0.61", optional = true } regex = "1" dunce = "1.0" +cfg_aliases = "0.1.1" [dependencies] libc = "0.2" diff --git a/bindings/rust/aws-lc-sys-template/build.rs b/bindings/rust/aws-lc-sys-template/build.rs index 04dcea6bc1..ef919dc86c 100644 --- a/bindings/rust/aws-lc-sys-template/build.rs +++ b/bindings/rust/aws-lc-sys-template/build.rs @@ -19,6 +19,7 @@ use std::ffi::OsStr; use std::path::{Path, PathBuf}; use std::process::Command; use std::{env, fs}; +use cfg_aliases::cfg_aliases; #[cfg(feature = "bindgen")] mod build_bindgen; @@ -171,6 +172,14 @@ fn main() -> Result<(), String> { use crate::OutputLib::Crypto; use crate::OutputLibType::Static; + cfg_aliases! { + linux_x86_bindings: { all(not(feature = "bindgen"), target_os = "linux", target_arch = "x86") }, + linux_x86_64_bindings: { all(not(feature = "bindgen"), target_os = "linux", target_arch = "x86_64") }, + linux_aarch64_bindings: { all(not(feature = "bindgen"), target_os = "linux", target_arch = "aarch64") }, + macos_x86_64_bindings: { all(not(feature = "bindgen"), target_os = "macos", target_arch = "x86_64") }, + not_pregenerated: { not(any(linux_x86_bindings, linux_aarch64_bindings, linux_x86_64_bindings, macos_x86_64_bindings)) }, + } + let mut missing_dependency = false; if let Some(cmake_cmd) = find_cmake_command() { diff --git a/bindings/rust/aws-lc-sys-template/build_bindgen.rs b/bindings/rust/aws-lc-sys-template/build_bindgen.rs index 887e4e2008..cb493cfff0 100644 --- a/bindings/rust/aws-lc-sys-template/build_bindgen.rs +++ b/bindings/rust/aws-lc-sys-template/build_bindgen.rs @@ -89,21 +89,25 @@ fn prepare_bindings_builder(manifest_dir: &Path, build_prefix: Option<&str>) -> builder } -#[cfg(feature = "generate")] +#[cfg(feature = "internal_generate")] pub(crate) fn target_platform_bindings_string() -> String { - format!("{}_{}_bindings.rs" - ,std::env::consts::OS - ,std::env::consts::ARCH) + format!( + "{}_{}_bindings.rs", + std::env::consts::OS, + std::env::consts::ARCH + ) } pub(crate) fn generate_bindings( manifest_dir: &Path, - build_prefix: Option<&str> + build_prefix: Option<&str>, ) -> Result<(), &'static str> { - #[cfg(feature = "native_bindings")] + #[cfg(any(feature = "generate_bindings", not_pregenerated))] let bindings_file = manifest_dir.join("src").join("bindings.rs"); - #[cfg(feature = "generate")] - let bindings_file = manifest_dir.join("src").join(target_platform_bindings_string()); + #[cfg(feature = "internal_generate")] + let bindings_file = manifest_dir + .join("src") + .join(target_platform_bindings_string()); let builder = prepare_bindings_builder(&manifest_dir, build_prefix); let bindings = builder.generate().expect("Unable to generate bindings."); diff --git a/bindings/rust/generate/_generate_bindings.sh b/bindings/rust/generate/_generate_bindings.sh index f6deb6a25e..5054912bb7 100755 --- a/bindings/rust/generate/_generate_bindings.sh +++ b/bindings/rust/generate/_generate_bindings.sh @@ -12,7 +12,7 @@ CRATE_DIR="${TMP_DIR}"/aws-lc-sys pushd "${CRATE_DIR}" cargo clean -cargo build --features generate +cargo build --features internal_generate cargo clean popd From 91e1db4c0a5c8b040d2d1b022ea106823bff3933 Mon Sep 17 00:00:00 2001 From: sachiang Date: Wed, 30 Nov 2022 18:20:48 -0800 Subject: [PATCH 7/7] small fixes for internal_generation --- bindings/rust/aws-lc-sys-template/Cargo.toml | 11 ++--- bindings/rust/aws-lc-sys-template/build.rs | 22 ++++++++-- .../rust/aws-lc-sys-template/build_bindgen.rs | 18 +------- bindings/rust/aws-lc-sys-template/src/lib.rs | 44 +++++-------------- bindings/rust/generate/_generate_bindings.sh | 3 ++ bindings/rust/publish/publish.sh | 11 +++++ 6 files changed, 49 insertions(+), 60 deletions(-) diff --git a/bindings/rust/aws-lc-sys-template/Cargo.toml b/bindings/rust/aws-lc-sys-template/Cargo.toml index 870b2f872c..1110dc4ce4 100644 --- a/bindings/rust/aws-lc-sys-template/Cargo.toml +++ b/bindings/rust/aws-lc-sys-template/Cargo.toml @@ -25,15 +25,12 @@ include = [ [features] asan = [] -# Generate the bindings on the targetted platform as a fallback mechanism. -generate_bindings = ["bindgen"] -# Pre-generate the bindings for crate publishing. Cannot be used simultaneously with the -# native_bindings feature. This feature is only intended for internal usage. -internal_generate = ["bindgen"] +generate_bindings = ["bindgen"] # Generate the bindings on the targetted platform as a fallback mechanism. +internal_generate = ["bindgen"] # Only for internal use, this line is removed prior to publishing. [build-dependencies] cmake = "0.1.48" -bindgen = { version ="0.61", optional = true } +bindgen = { version = "0.61", optional = true } regex = "1" dunce = "1.0" cfg_aliases = "0.1.1" @@ -42,4 +39,4 @@ cfg_aliases = "0.1.1" libc = "0.2" [dev-dependencies] -openssl = { version = "0.10", features = ["vendored"] } +openssl = { version = "0.10", features = ["vendored"] } \ No newline at end of file diff --git a/bindings/rust/aws-lc-sys-template/build.rs b/bindings/rust/aws-lc-sys-template/build.rs index ef919dc86c..59e4c863d3 100644 --- a/bindings/rust/aws-lc-sys-template/build.rs +++ b/bindings/rust/aws-lc-sys-template/build.rs @@ -15,11 +15,11 @@ // SPDX-License-Identifier: Apache-2.0 OR ISC // Modifications Copyright Amazon.com, Inc. or its affiliates. See GitHub history for details. +use cfg_aliases::cfg_aliases; use std::ffi::OsStr; use std::path::{Path, PathBuf}; use std::process::Command; use std::{env, fs}; -use cfg_aliases::cfg_aliases; #[cfg(feature = "bindgen")] mod build_bindgen; @@ -99,6 +99,15 @@ fn prefix_string() -> String { format!("aws_lc_{}", VERSION.to_string().replace('.', "_")) } +#[cfg(feature = "internal_generate")] +fn target_platform_bindings_string() -> String { + format!( + "{}_{}_bindings.rs", + std::env::consts::OS, + std::env::consts::ARCH + ) +} + fn test_command(executable: &OsStr, args: &[&OsStr]) -> bool { if let Ok(output) = Command::new(executable).args(args).output() { return output.status.success(); @@ -197,9 +206,16 @@ fn main() -> Result<(), String> { let manifest_dir = dunce::canonicalize(Path::new(&manifest_dir)).unwrap(); let prefix = prefix_string(); - #[cfg(feature = "bindgen")] - build_bindgen::generate_bindings(&manifest_dir, Some(&prefix)) + #[cfg(any(feature = "bindgen", not_pregenerated))] + build_bindgen::generate_bindings(&manifest_dir, Some(&prefix), "bindings.rs") .expect("Unable to generate bindings."); + #[cfg(feature = "internal_generate")] + build_bindgen::generate_bindings( + &manifest_dir, + Some(&prefix), + &target_platform_bindings_string().to_string(), + ) + .expect("Unable to generate bindings."); let aws_lc_dir = build_aws_lc(); let lib_file = Crypto.locate_file(&aws_lc_dir, Static, None); diff --git a/bindings/rust/aws-lc-sys-template/build_bindgen.rs b/bindings/rust/aws-lc-sys-template/build_bindgen.rs index cb493cfff0..da322a3600 100644 --- a/bindings/rust/aws-lc-sys-template/build_bindgen.rs +++ b/bindings/rust/aws-lc-sys-template/build_bindgen.rs @@ -89,26 +89,12 @@ fn prepare_bindings_builder(manifest_dir: &Path, build_prefix: Option<&str>) -> builder } -#[cfg(feature = "internal_generate")] -pub(crate) fn target_platform_bindings_string() -> String { - format!( - "{}_{}_bindings.rs", - std::env::consts::OS, - std::env::consts::ARCH - ) -} - pub(crate) fn generate_bindings( manifest_dir: &Path, build_prefix: Option<&str>, + output_name: &str, ) -> Result<(), &'static str> { - #[cfg(any(feature = "generate_bindings", not_pregenerated))] - let bindings_file = manifest_dir.join("src").join("bindings.rs"); - #[cfg(feature = "internal_generate")] - let bindings_file = manifest_dir - .join("src") - .join(target_platform_bindings_string()); - + let bindings_file = manifest_dir.join("src").join(&output_name); let builder = prepare_bindings_builder(&manifest_dir, build_prefix); let bindings = builder.generate().expect("Unable to generate bindings."); Ok(bindings diff --git a/bindings/rust/aws-lc-sys-template/src/lib.rs b/bindings/rust/aws-lc-sys-template/src/lib.rs index ae3d39ee7d..ad2490c547 100644 --- a/bindings/rust/aws-lc-sys-template/src/lib.rs +++ b/bindings/rust/aws-lc-sys-template/src/lib.rs @@ -1,22 +1,14 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 OR ISC -// Warn to use feature native_bindings if building on a platform where prebuilt-bindings +// Warn to use feature generate_bindings if building on a platform where prebuilt-bindings // aren't available -#[cfg(all( - not(feature = "native_bindings"), - not(any( - all(target_os = "linux", target_arch = "x86"), - all(target_os = "linux", target_arch = "x86_64"), - all(target_os = "linux", target_arch = "aarch64"), - all(target_os = "macos", target_arch = "x86_64") - )) -))] -compile_error!("Prebuilt-bindings aren't available. Turn on feature native_bindings to build."); +#[cfg(all(not(feature = "bindgen"), not_pregenerated))] +compile_error!("Prebuilt-bindings aren't available. Turn on feature generate_bindings to build."); -#[cfg(all(feature = "native_bindings", feature = "generate"))] +#[cfg(all(feature = "generate_bindings", feature = "internal_generate"))] compile_error!( - "Generate is only for internal usage. Only turn on feature native_bindings to build." + "internal_generate is only for internal usage and does not work with the generate_bindings feature." ); macro_rules! use_bindings { @@ -26,35 +18,19 @@ macro_rules! use_bindings { }; } -#[cfg(all( - not(feature = "native_bindings"), - target_os = "linux", - target_arch = "x86" -))] +#[cfg(linux_x86_bindings)] use_bindings!(linux_x86_bindings); -#[cfg(all( - not(feature = "native_bindings"), - target_os = "linux", - target_arch = "x86_64" -))] +#[cfg(linux_x86_64_bindings)] use_bindings!(linux_x86_64_bindings); -#[cfg(all( - not(feature = "native_bindings"), - target_os = "linux", - target_arch = "aarch64" -))] +#[cfg(linux_aarch64_bindings)] use_bindings!(linux_aarch64_bindings); -#[cfg(all( - not(feature = "native_bindings"), - target_os = "macos", - target_arch = "x86_64" -))] +#[cfg(macos_x86_64_bindings)] use_bindings!(macos_x86_64_bindings); -#[cfg(feature = "native_bindings")] +#[cfg(any(feature = "bindgen", not_pregenerated))] use_bindings!(bindings); #[allow(non_snake_case)] diff --git a/bindings/rust/generate/_generate_bindings.sh b/bindings/rust/generate/_generate_bindings.sh index 5054912bb7..328dd30f39 100755 --- a/bindings/rust/generate/_generate_bindings.sh +++ b/bindings/rust/generate/_generate_bindings.sh @@ -12,7 +12,10 @@ CRATE_DIR="${TMP_DIR}"/aws-lc-sys pushd "${CRATE_DIR}" cargo clean +# internal_generate pre-generates the bindings for a specific platform. This feature +# is only intended for internal use and is removed prior to crate publishing. cargo build --features internal_generate +rm "${CRATE_DIR}"/src/bindings.rs cargo clean popd diff --git a/bindings/rust/publish/publish.sh b/bindings/rust/publish/publish.sh index ea1cdf4e69..000aad920b 100755 --- a/bindings/rust/publish/publish.sh +++ b/bindings/rust/publish/publish.sh @@ -34,11 +34,21 @@ while getopts "d:sp" option; do esac done +# Remove the internal_generation feature for bindings pre-generation before publishing. +function remove_internal_feature { + if [[ "$(uname)" == "Darwin" ]]; then + find ./ -type f -name "Cargo.toml" | xargs sed -i '' -e "s|${INTERNAL_FEATURE_STRING}||g" + else + find ./ -type f -name "Cargo.toml" | xargs sed -i -e "s|${INTERNAL_FEATURE_STRING}||g" + fi +} + SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) AWS_LC_DIR=$( cd -- "${SCRIPT_DIR}/../../../" &> /dev/null && pwd) TMP_DIR="${AWS_LC_DIR}"/bindings/rust/tmp CRATE_DIR="${TMP_DIR}"/aws-lc-sys COMPLETION_MARKER="${CRATE_DIR}"/.generation_complete +INTERNAL_FEATURE_STRING="^internal_generate .*" if [[ ! -f "${COMPLETION_MARKER}" ]]; then echo @@ -48,6 +58,7 @@ if [[ ! -f "${COMPLETION_MARKER}" ]]; then fi pushd "${CRATE_DIR}" +remove_internal_feature cargo clean cargo clippy --fix --allow-no-vcs cargo fmt