Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions boring-sys/build/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@ pub(crate) struct Env {
}

impl Config {
pub(crate) fn from_env() -> Self {
let manifest_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap().into();
let out_dir = env::var_os("OUT_DIR").unwrap().into();
pub(crate) fn from_env() -> Result<Self, &'static str> {
let manifest_dir = env::var_os("CARGO_MANIFEST_DIR")
.ok_or("CARGO_MANIFEST_DIR")?
.into();
let out_dir = env::var_os("OUT_DIR").ok_or("OUT_DIR")?.into();
let host = env::var("HOST").unwrap();
let target = env::var("TARGET").unwrap();
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
Expand Down Expand Up @@ -81,24 +83,24 @@ impl Config {
env,
};

config.check_feature_compatibility();
config.check_feature_compatibility()?;

config
Ok(config)
}

fn check_feature_compatibility(&self) {
fn check_feature_compatibility(&self) -> Result<(), &'static str> {
if self.features.fips && self.features.rpk {
panic!("`fips` and `rpk` features are mutually exclusive");
return Err("`fips` and `rpk` features are mutually exclusive");
}

let is_precompiled_native_lib = self.env.path.is_some();
let is_external_native_lib_source =
!is_precompiled_native_lib && self.env.source_path.is_none();

if self.env.assume_patched && is_external_native_lib_source {
panic!(
return Err(
"`BORING_BSSL_{{,_FIPS}}_ASSUME_PATCHED` env variable is supposed to be used with\
`BORING_BSSL{{,_FIPS}}_PATH` or `BORING_BSSL{{,_FIPS}}_SOURCE_PATH` env variables"
`BORING_BSSL{{,_FIPS}}_PATH` or `BORING_BSSL{{,_FIPS}}_SOURCE_PATH` env variables",
);
}

Expand All @@ -111,6 +113,7 @@ impl Config {
"cargo:warning=precompiled BoringSSL was provided, so patches will be ignored"
);
}
Ok(())
}
}

Expand Down
78 changes: 52 additions & 26 deletions boring-sys/build/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::fs;
use std::io;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::ExitCode;
use std::process::{Command, Output};
use std::sync::OnceLock;

Expand Down Expand Up @@ -360,7 +361,7 @@ fn get_boringssl_cmake_config(config: &Config) -> cmake::Config {
boringssl_cmake
}

fn pick_best_android_ndk_toolchain(toolchains_dir: &Path) -> std::io::Result<OsString> {
fn pick_best_android_ndk_toolchain(toolchains_dir: &Path) -> io::Result<OsString> {
let toolchains = std::fs::read_dir(toolchains_dir)?.collect::<Result<Vec<_>, _>>()?;
// First look for one of the toolchains that Google has documented.
// https://developer.android.com/ndk/guides/other_build_systems
Expand Down Expand Up @@ -589,13 +590,27 @@ fn get_cpp_runtime_lib(config: &Config) -> Option<String> {
}
}

fn main() {
let config = Config::from_env();
ensure_patches_applied(&config).unwrap();
fn main() -> ExitCode {
if let Err(e) = run() {
eprintln!("boring-sys failed: {e}");
println!(
"cargo::error={}",
e.to_string().trim_ascii().replace("\n", "\ncargo::error=")
);
ExitCode::FAILURE
} else {
ExitCode::SUCCESS
}
}

fn run() -> Result<(), Box<dyn std::error::Error>> {
let config = Config::from_env()?;
ensure_patches_applied(&config)?;
if !config.env.docs_rs {
emit_link_directives(&config);
}
generate_bindings(&config);
generate_bindings(&config).map_err(|e| format!("could not generate bindings: {e}"))?;
Ok(())
}

fn emit_link_directives(config: &Config) {
Expand Down Expand Up @@ -646,21 +661,25 @@ fn check_include_path(path: PathBuf) -> Result<PathBuf, String> {
}
}

fn generate_bindings(config: &Config) {
let include_path = config.env.include_path.clone().unwrap_or_else(|| {
if let Some(bssl_path) = &config.env.path {
return check_include_path(bssl_path.join("include"))
.expect("config has invalid include path");
}
fn get_include_path(config: &Config) -> Result<PathBuf, String> {
if let Some(path) = &config.env.include_path {
return check_include_path(path.to_owned());
}

let src_path = get_boringssl_source_path(config);
check_include_path(src_path.join("include"))
.or_else(|_| check_include_path(src_path.join("src").join("include")))
.expect("can't find usable include path")
});
if let Some(bssl_path) = &config.env.path {
return check_include_path(bssl_path.join("include"));
}

let src_path = get_boringssl_source_path(config);
check_include_path(src_path.join("include"))
.or_else(|_| check_include_path(src_path.join("src").join("include")))
}

let target_rust_version =
bindgen::RustTarget::stable(77, 0).expect("bindgen does not recognize target rust version");
fn generate_bindings(config: &Config) -> Result<PathBuf, Box<dyn std::error::Error>> {
let include_path = get_include_path(config)?;

let target_rust_version = bindgen::RustTarget::stable(77, 0)
.map_err(|e| format!("bindgen does not recognize target rust version: {e}"))?;

let mut builder = bindgen::Builder::default()
.rust_target(target_rust_version) // bindgen MSRV is 1.70, so this is enough
Expand All @@ -678,6 +697,7 @@ fn generate_bindings(config: &Config) {
.fit_macro_constants(false)
.size_t_is_usize(true)
.layout_tests(config.env.debug.is_some())
.merge_extern_blocks(true)
.prepend_enum_name(true)
.blocklist_type("max_align_t") // Not supported by bindgen on all targets, not used by BoringSSL
.clang_args(get_extra_clang_args_for_bindgen(config))
Expand Down Expand Up @@ -744,21 +764,27 @@ fn generate_bindings(config: &Config) {
builder = builder.header(header_path.to_str().unwrap());
} else {
let err = format!("'openssl/{header}' is missing from '{}'. The include path may be incorrect or contain an outdated version of OpenSSL/BoringSSL", include_path.display());
let required = i < must_have_headers.len();
println!(
"cargo::{}={err}",
if required { "error" } else { "warning" }
);
if i < must_have_headers.len() {
return Err(err.into());
}
println!("cargo::warning={err}");
}
}

let bindings = builder.generate().expect("Unable to generate bindings");
let bindings = builder.generate()?;
let mut source_code = Vec::new();
bindings
.write(Box::new(&mut source_code))
.expect("Couldn't serialize bindings!");
.map_err(|e| format!("Couldn't serialize bindings: {e}"))?;
ensure_err_lib_enum_is_named(&mut source_code);
fs::write(config.out_dir.join("bindings.rs"), source_code).expect("Couldn't write bindings!");
let bindings_path = config.out_dir.join("bindings.rs");
fs::write(&bindings_path, source_code).map_err(|e| {
format!(
"Couldn't write bindings to {}: {e}",
bindings_path.display()
)
})?;
Ok(bindings_path)
}

/// err.h has anonymous `enum { ERR_LIB_NONE = 1 }`, which makes a dodgy `_bindgen_ty_1` name
Expand Down
Loading