192f3ab15Sopenharmony_ci#[cfg(feature = "bindgen")] 292f3ab15Sopenharmony_ciextern crate bindgen; 392f3ab15Sopenharmony_ciextern crate cc; 492f3ab15Sopenharmony_ci#[cfg(feature = "vendored")] 592f3ab15Sopenharmony_ciextern crate openssl_src; 692f3ab15Sopenharmony_ciextern crate pkg_config; 792f3ab15Sopenharmony_ciextern crate vcpkg; 892f3ab15Sopenharmony_ci 992f3ab15Sopenharmony_ciuse std::collections::HashSet; 1092f3ab15Sopenharmony_ciuse std::env; 1192f3ab15Sopenharmony_ciuse std::ffi::OsString; 1292f3ab15Sopenharmony_ciuse std::path::{Path, PathBuf}; 1392f3ab15Sopenharmony_cimod cfgs; 1492f3ab15Sopenharmony_ci 1592f3ab15Sopenharmony_cimod find_normal; 1692f3ab15Sopenharmony_ci#[cfg(feature = "vendored")] 1792f3ab15Sopenharmony_cimod find_vendored; 1892f3ab15Sopenharmony_cimod run_bindgen; 1992f3ab15Sopenharmony_ci 2092f3ab15Sopenharmony_ci#[derive(PartialEq)] 2192f3ab15Sopenharmony_cienum Version { 2292f3ab15Sopenharmony_ci Openssl3xx, 2392f3ab15Sopenharmony_ci Openssl11x, 2492f3ab15Sopenharmony_ci Openssl10x, 2592f3ab15Sopenharmony_ci Libressl, 2692f3ab15Sopenharmony_ci Boringssl, 2792f3ab15Sopenharmony_ci} 2892f3ab15Sopenharmony_ci 2992f3ab15Sopenharmony_cifn env_inner(name: &str) -> Option<OsString> { 3092f3ab15Sopenharmony_ci let var = env::var_os(name); 3192f3ab15Sopenharmony_ci println!("cargo:rerun-if-env-changed={}", name); 3292f3ab15Sopenharmony_ci 3392f3ab15Sopenharmony_ci match var { 3492f3ab15Sopenharmony_ci Some(ref v) => println!("{} = {}", name, v.to_string_lossy()), 3592f3ab15Sopenharmony_ci None => println!("{} unset", name), 3692f3ab15Sopenharmony_ci } 3792f3ab15Sopenharmony_ci 3892f3ab15Sopenharmony_ci var 3992f3ab15Sopenharmony_ci} 4092f3ab15Sopenharmony_ci 4192f3ab15Sopenharmony_cifn env(name: &str) -> Option<OsString> { 4292f3ab15Sopenharmony_ci let prefix = env::var("TARGET").unwrap().to_uppercase().replace('-', "_"); 4392f3ab15Sopenharmony_ci let prefixed = format!("{}_{}", prefix, name); 4492f3ab15Sopenharmony_ci env_inner(&prefixed).or_else(|| env_inner(name)) 4592f3ab15Sopenharmony_ci} 4692f3ab15Sopenharmony_ci 4792f3ab15Sopenharmony_cifn find_openssl(target: &str) -> (Vec<PathBuf>, PathBuf) { 4892f3ab15Sopenharmony_ci #[cfg(feature = "vendored")] 4992f3ab15Sopenharmony_ci { 5092f3ab15Sopenharmony_ci // vendor if the feature is present, unless 5192f3ab15Sopenharmony_ci // OPENSSL_NO_VENDOR exists and isn't `0` 5292f3ab15Sopenharmony_ci if env("OPENSSL_NO_VENDOR").map_or(true, |s| s == "0") { 5392f3ab15Sopenharmony_ci return find_vendored::get_openssl(target); 5492f3ab15Sopenharmony_ci } 5592f3ab15Sopenharmony_ci } 5692f3ab15Sopenharmony_ci find_normal::get_openssl(target) 5792f3ab15Sopenharmony_ci} 5892f3ab15Sopenharmony_ci 5992f3ab15Sopenharmony_cifn check_ssl_kind() { 6092f3ab15Sopenharmony_ci if cfg!(feature = "unstable_boringssl") { 6192f3ab15Sopenharmony_ci println!("cargo:rustc-cfg=boringssl"); 6292f3ab15Sopenharmony_ci println!("cargo:boringssl=true"); 6392f3ab15Sopenharmony_ci // BoringSSL does not have any build logic, exit early 6492f3ab15Sopenharmony_ci std::process::exit(0); 6592f3ab15Sopenharmony_ci } 6692f3ab15Sopenharmony_ci} 6792f3ab15Sopenharmony_ci 6892f3ab15Sopenharmony_cifn main() { 6992f3ab15Sopenharmony_ci check_ssl_kind(); 7092f3ab15Sopenharmony_ci 7192f3ab15Sopenharmony_ci let target = env::var("TARGET").unwrap(); 7292f3ab15Sopenharmony_ci 7392f3ab15Sopenharmony_ci let (lib_dirs, include_dir) = find_openssl(&target); 7492f3ab15Sopenharmony_ci 7592f3ab15Sopenharmony_ci if !lib_dirs.iter().all(|p| Path::new(p).exists()) { 7692f3ab15Sopenharmony_ci panic!("OpenSSL library directory does not exist: {:?}", lib_dirs); 7792f3ab15Sopenharmony_ci } 7892f3ab15Sopenharmony_ci if !Path::new(&include_dir).exists() { 7992f3ab15Sopenharmony_ci panic!( 8092f3ab15Sopenharmony_ci "OpenSSL include directory does not exist: {}", 8192f3ab15Sopenharmony_ci include_dir.to_string_lossy() 8292f3ab15Sopenharmony_ci ); 8392f3ab15Sopenharmony_ci } 8492f3ab15Sopenharmony_ci 8592f3ab15Sopenharmony_ci for lib_dir in lib_dirs.iter() { 8692f3ab15Sopenharmony_ci println!( 8792f3ab15Sopenharmony_ci "cargo:rustc-link-search=native={}", 8892f3ab15Sopenharmony_ci lib_dir.to_string_lossy() 8992f3ab15Sopenharmony_ci ); 9092f3ab15Sopenharmony_ci } 9192f3ab15Sopenharmony_ci println!("cargo:include={}", include_dir.to_string_lossy()); 9292f3ab15Sopenharmony_ci 9392f3ab15Sopenharmony_ci let version = postprocess(&[include_dir]); 9492f3ab15Sopenharmony_ci 9592f3ab15Sopenharmony_ci let libs_env = env("OPENSSL_LIBS"); 9692f3ab15Sopenharmony_ci let libs = match libs_env.as_ref().and_then(|s| s.to_str()) { 9792f3ab15Sopenharmony_ci Some(v) => { 9892f3ab15Sopenharmony_ci if v.is_empty() { 9992f3ab15Sopenharmony_ci vec![] 10092f3ab15Sopenharmony_ci } else { 10192f3ab15Sopenharmony_ci v.split(':').collect() 10292f3ab15Sopenharmony_ci } 10392f3ab15Sopenharmony_ci } 10492f3ab15Sopenharmony_ci None => match version { 10592f3ab15Sopenharmony_ci Version::Openssl10x if target.contains("windows") => vec!["ssleay32", "libeay32"], 10692f3ab15Sopenharmony_ci Version::Openssl3xx | Version::Openssl11x if target.contains("windows-msvc") => { 10792f3ab15Sopenharmony_ci vec!["libssl", "libcrypto"] 10892f3ab15Sopenharmony_ci } 10992f3ab15Sopenharmony_ci _ => vec!["ssl", "crypto"], 11092f3ab15Sopenharmony_ci }, 11192f3ab15Sopenharmony_ci }; 11292f3ab15Sopenharmony_ci 11392f3ab15Sopenharmony_ci let kind = determine_mode(&lib_dirs, &libs); 11492f3ab15Sopenharmony_ci for lib in libs.into_iter() { 11592f3ab15Sopenharmony_ci println!("cargo:rustc-link-lib={}={}", kind, lib); 11692f3ab15Sopenharmony_ci } 11792f3ab15Sopenharmony_ci 11892f3ab15Sopenharmony_ci if kind == "static" && target.contains("windows") { 11992f3ab15Sopenharmony_ci println!("cargo:rustc-link-lib=dylib=gdi32"); 12092f3ab15Sopenharmony_ci println!("cargo:rustc-link-lib=dylib=user32"); 12192f3ab15Sopenharmony_ci println!("cargo:rustc-link-lib=dylib=crypt32"); 12292f3ab15Sopenharmony_ci println!("cargo:rustc-link-lib=dylib=ws2_32"); 12392f3ab15Sopenharmony_ci println!("cargo:rustc-link-lib=dylib=advapi32"); 12492f3ab15Sopenharmony_ci } 12592f3ab15Sopenharmony_ci} 12692f3ab15Sopenharmony_ci 12792f3ab15Sopenharmony_cifn postprocess(include_dirs: &[PathBuf]) -> Version { 12892f3ab15Sopenharmony_ci let version = validate_headers(include_dirs); 12992f3ab15Sopenharmony_ci 13092f3ab15Sopenharmony_ci // Never run bindgen for BoringSSL, if it was needed we already ran it. 13192f3ab15Sopenharmony_ci if version != Version::Boringssl { 13292f3ab15Sopenharmony_ci #[cfg(feature = "bindgen")] 13392f3ab15Sopenharmony_ci run_bindgen::run(&include_dirs); 13492f3ab15Sopenharmony_ci } 13592f3ab15Sopenharmony_ci 13692f3ab15Sopenharmony_ci version 13792f3ab15Sopenharmony_ci} 13892f3ab15Sopenharmony_ci 13992f3ab15Sopenharmony_ci/// Validates the header files found in `include_dir` and then returns the 14092f3ab15Sopenharmony_ci/// version string of OpenSSL. 14192f3ab15Sopenharmony_ci#[allow(clippy::unusual_byte_groupings)] 14292f3ab15Sopenharmony_cifn validate_headers(include_dirs: &[PathBuf]) -> Version { 14392f3ab15Sopenharmony_ci // This `*-sys` crate only works with OpenSSL 1.0.1, 1.0.2, 1.1.0, 1.1.1 and 3.0.0. 14492f3ab15Sopenharmony_ci // To correctly expose the right API from this crate, take a look at 14592f3ab15Sopenharmony_ci // `opensslv.h` to see what version OpenSSL claims to be. 14692f3ab15Sopenharmony_ci // 14792f3ab15Sopenharmony_ci // OpenSSL has a number of build-time configuration options which affect 14892f3ab15Sopenharmony_ci // various structs and such. Since OpenSSL 1.1.0 this isn't really a problem 14992f3ab15Sopenharmony_ci // as the library is much more FFI-friendly, but 1.0.{1,2} suffer this problem. 15092f3ab15Sopenharmony_ci // 15192f3ab15Sopenharmony_ci // To handle all this conditional compilation we slurp up the configuration 15292f3ab15Sopenharmony_ci // file of OpenSSL, `opensslconf.h`, and then dump out everything it defines 15392f3ab15Sopenharmony_ci // as our own #[cfg] directives. That way the `ossl10x.rs` bindings can 15492f3ab15Sopenharmony_ci // account for compile differences and such. 15592f3ab15Sopenharmony_ci println!("cargo:rerun-if-changed=build/expando.c"); 15692f3ab15Sopenharmony_ci let mut gcc = cc::Build::new(); 15792f3ab15Sopenharmony_ci gcc.includes(include_dirs); 15892f3ab15Sopenharmony_ci let expanded = match gcc.file("build/expando.c").try_expand() { 15992f3ab15Sopenharmony_ci Ok(expanded) => expanded, 16092f3ab15Sopenharmony_ci Err(e) => { 16192f3ab15Sopenharmony_ci panic!( 16292f3ab15Sopenharmony_ci " 16392f3ab15Sopenharmony_ciHeader expansion error: 16492f3ab15Sopenharmony_ci{:?} 16592f3ab15Sopenharmony_ci 16692f3ab15Sopenharmony_ciFailed to find OpenSSL development headers. 16792f3ab15Sopenharmony_ci 16892f3ab15Sopenharmony_ciYou can try fixing this setting the `OPENSSL_DIR` environment variable 16992f3ab15Sopenharmony_cipointing to your OpenSSL installation or installing OpenSSL headers package 17092f3ab15Sopenharmony_cispecific to your distribution: 17192f3ab15Sopenharmony_ci 17292f3ab15Sopenharmony_ci # On Ubuntu 17392f3ab15Sopenharmony_ci sudo apt-get install libssl-dev 17492f3ab15Sopenharmony_ci # On Arch Linux 17592f3ab15Sopenharmony_ci sudo pacman -S openssl 17692f3ab15Sopenharmony_ci # On Fedora 17792f3ab15Sopenharmony_ci sudo dnf install openssl-devel 17892f3ab15Sopenharmony_ci # On Alpine Linux 17992f3ab15Sopenharmony_ci apk add openssl-dev 18092f3ab15Sopenharmony_ci 18192f3ab15Sopenharmony_ciSee rust-openssl documentation for more information: 18292f3ab15Sopenharmony_ci 18392f3ab15Sopenharmony_ci https://docs.rs/openssl 18492f3ab15Sopenharmony_ci", 18592f3ab15Sopenharmony_ci e 18692f3ab15Sopenharmony_ci ); 18792f3ab15Sopenharmony_ci } 18892f3ab15Sopenharmony_ci }; 18992f3ab15Sopenharmony_ci let expanded = String::from_utf8(expanded).unwrap(); 19092f3ab15Sopenharmony_ci 19192f3ab15Sopenharmony_ci let mut enabled = vec![]; 19292f3ab15Sopenharmony_ci let mut openssl_version = None; 19392f3ab15Sopenharmony_ci let mut libressl_version = None; 19492f3ab15Sopenharmony_ci let mut is_boringssl = false; 19592f3ab15Sopenharmony_ci for line in expanded.lines() { 19692f3ab15Sopenharmony_ci let line = line.trim(); 19792f3ab15Sopenharmony_ci 19892f3ab15Sopenharmony_ci let openssl_prefix = "RUST_VERSION_OPENSSL_"; 19992f3ab15Sopenharmony_ci let new_openssl_prefix = "RUST_VERSION_NEW_OPENSSL_"; 20092f3ab15Sopenharmony_ci let libressl_prefix = "RUST_VERSION_LIBRESSL_"; 20192f3ab15Sopenharmony_ci let boringsl_prefix = "RUST_OPENSSL_IS_BORINGSSL"; 20292f3ab15Sopenharmony_ci let conf_prefix = "RUST_CONF_"; 20392f3ab15Sopenharmony_ci if let Some(version) = line.strip_prefix(openssl_prefix) { 20492f3ab15Sopenharmony_ci openssl_version = Some(parse_version(version)); 20592f3ab15Sopenharmony_ci } else if let Some(version) = line.strip_prefix(new_openssl_prefix) { 20692f3ab15Sopenharmony_ci openssl_version = Some(parse_new_version(version)); 20792f3ab15Sopenharmony_ci } else if let Some(version) = line.strip_prefix(libressl_prefix) { 20892f3ab15Sopenharmony_ci libressl_version = Some(parse_version(version)); 20992f3ab15Sopenharmony_ci } else if let Some(conf) = line.strip_prefix(conf_prefix) { 21092f3ab15Sopenharmony_ci enabled.push(conf); 21192f3ab15Sopenharmony_ci } else if line.starts_with(boringsl_prefix) { 21292f3ab15Sopenharmony_ci is_boringssl = true; 21392f3ab15Sopenharmony_ci } 21492f3ab15Sopenharmony_ci } 21592f3ab15Sopenharmony_ci 21692f3ab15Sopenharmony_ci if is_boringssl { 21792f3ab15Sopenharmony_ci println!("cargo:rustc-cfg=boringssl"); 21892f3ab15Sopenharmony_ci println!("cargo:boringssl=true"); 21992f3ab15Sopenharmony_ci run_bindgen::run_boringssl(include_dirs); 22092f3ab15Sopenharmony_ci return Version::Boringssl; 22192f3ab15Sopenharmony_ci } 22292f3ab15Sopenharmony_ci 22392f3ab15Sopenharmony_ci // We set this for any non-BoringSSL lib. 22492f3ab15Sopenharmony_ci println!("cargo:rustc-cfg=openssl"); 22592f3ab15Sopenharmony_ci 22692f3ab15Sopenharmony_ci for enabled in &enabled { 22792f3ab15Sopenharmony_ci println!("cargo:rustc-cfg=osslconf=\"{}\"", enabled); 22892f3ab15Sopenharmony_ci } 22992f3ab15Sopenharmony_ci println!("cargo:conf={}", enabled.join(",")); 23092f3ab15Sopenharmony_ci 23192f3ab15Sopenharmony_ci for cfg in cfgs::get(openssl_version, libressl_version) { 23292f3ab15Sopenharmony_ci println!("cargo:rustc-cfg={}", cfg); 23392f3ab15Sopenharmony_ci } 23492f3ab15Sopenharmony_ci 23592f3ab15Sopenharmony_ci if let Some(libressl_version) = libressl_version { 23692f3ab15Sopenharmony_ci println!("cargo:libressl_version_number={:x}", libressl_version); 23792f3ab15Sopenharmony_ci 23892f3ab15Sopenharmony_ci let major = (libressl_version >> 28) as u8; 23992f3ab15Sopenharmony_ci let minor = (libressl_version >> 20) as u8; 24092f3ab15Sopenharmony_ci let fix = (libressl_version >> 12) as u8; 24192f3ab15Sopenharmony_ci let (major, minor, fix) = match (major, minor, fix) { 24292f3ab15Sopenharmony_ci (2, 5, 0) => ('2', '5', '0'), 24392f3ab15Sopenharmony_ci (2, 5, 1) => ('2', '5', '1'), 24492f3ab15Sopenharmony_ci (2, 5, 2) => ('2', '5', '2'), 24592f3ab15Sopenharmony_ci (2, 5, _) => ('2', '5', 'x'), 24692f3ab15Sopenharmony_ci (2, 6, 0) => ('2', '6', '0'), 24792f3ab15Sopenharmony_ci (2, 6, 1) => ('2', '6', '1'), 24892f3ab15Sopenharmony_ci (2, 6, 2) => ('2', '6', '2'), 24992f3ab15Sopenharmony_ci (2, 6, _) => ('2', '6', 'x'), 25092f3ab15Sopenharmony_ci (2, 7, _) => ('2', '7', 'x'), 25192f3ab15Sopenharmony_ci (2, 8, 0) => ('2', '8', '0'), 25292f3ab15Sopenharmony_ci (2, 8, 1) => ('2', '8', '1'), 25392f3ab15Sopenharmony_ci (2, 8, _) => ('2', '8', 'x'), 25492f3ab15Sopenharmony_ci (2, 9, 0) => ('2', '9', '0'), 25592f3ab15Sopenharmony_ci (2, 9, _) => ('2', '9', 'x'), 25692f3ab15Sopenharmony_ci (3, 0, 0) => ('3', '0', '0'), 25792f3ab15Sopenharmony_ci (3, 0, 1) => ('3', '0', '1'), 25892f3ab15Sopenharmony_ci (3, 0, _) => ('3', '0', 'x'), 25992f3ab15Sopenharmony_ci (3, 1, 0) => ('3', '1', '0'), 26092f3ab15Sopenharmony_ci (3, 1, _) => ('3', '1', 'x'), 26192f3ab15Sopenharmony_ci (3, 2, 0) => ('3', '2', '0'), 26292f3ab15Sopenharmony_ci (3, 2, 1) => ('3', '2', '1'), 26392f3ab15Sopenharmony_ci (3, 2, _) => ('3', '2', 'x'), 26492f3ab15Sopenharmony_ci (3, 3, 0) => ('3', '3', '0'), 26592f3ab15Sopenharmony_ci (3, 3, 1) => ('3', '3', '1'), 26692f3ab15Sopenharmony_ci (3, 3, _) => ('3', '3', 'x'), 26792f3ab15Sopenharmony_ci (3, 4, 0) => ('3', '4', '0'), 26892f3ab15Sopenharmony_ci (3, 4, _) => ('3', '4', 'x'), 26992f3ab15Sopenharmony_ci (3, 5, _) => ('3', '5', 'x'), 27092f3ab15Sopenharmony_ci (3, 6, 0) => ('3', '6', '0'), 27192f3ab15Sopenharmony_ci (3, 6, _) => ('3', '6', 'x'), 27292f3ab15Sopenharmony_ci (3, 7, 0) => ('3', '7', '0'), 27392f3ab15Sopenharmony_ci (3, 7, 1) => ('3', '7', '1'), 27492f3ab15Sopenharmony_ci (3, 7, _) => ('3', '7', 'x'), 27592f3ab15Sopenharmony_ci (3, 8, 0) => ('3', '8', '0'), 27692f3ab15Sopenharmony_ci _ => version_error(), 27792f3ab15Sopenharmony_ci }; 27892f3ab15Sopenharmony_ci 27992f3ab15Sopenharmony_ci println!("cargo:libressl=true"); 28092f3ab15Sopenharmony_ci println!("cargo:libressl_version={}{}{}", major, minor, fix); 28192f3ab15Sopenharmony_ci println!("cargo:version=101"); 28292f3ab15Sopenharmony_ci Version::Libressl 28392f3ab15Sopenharmony_ci } else { 28492f3ab15Sopenharmony_ci let openssl_version = openssl_version.unwrap(); 28592f3ab15Sopenharmony_ci println!("cargo:version_number={:x}", openssl_version); 28692f3ab15Sopenharmony_ci 28792f3ab15Sopenharmony_ci if openssl_version >= 0x4_00_00_00_0 { 28892f3ab15Sopenharmony_ci version_error() 28992f3ab15Sopenharmony_ci } else if openssl_version >= 0x3_00_00_00_0 { 29092f3ab15Sopenharmony_ci Version::Openssl3xx 29192f3ab15Sopenharmony_ci } else if openssl_version >= 0x1_01_01_00_0 { 29292f3ab15Sopenharmony_ci println!("cargo:version=111"); 29392f3ab15Sopenharmony_ci Version::Openssl11x 29492f3ab15Sopenharmony_ci } else if openssl_version >= 0x1_01_00_06_0 { 29592f3ab15Sopenharmony_ci println!("cargo:version=110"); 29692f3ab15Sopenharmony_ci println!("cargo:patch=f"); 29792f3ab15Sopenharmony_ci Version::Openssl11x 29892f3ab15Sopenharmony_ci } else if openssl_version >= 0x1_01_00_00_0 { 29992f3ab15Sopenharmony_ci println!("cargo:version=110"); 30092f3ab15Sopenharmony_ci Version::Openssl11x 30192f3ab15Sopenharmony_ci } else if openssl_version >= 0x1_00_02_00_0 { 30292f3ab15Sopenharmony_ci println!("cargo:version=102"); 30392f3ab15Sopenharmony_ci Version::Openssl10x 30492f3ab15Sopenharmony_ci } else if openssl_version >= 0x1_00_01_00_0 { 30592f3ab15Sopenharmony_ci println!("cargo:version=101"); 30692f3ab15Sopenharmony_ci Version::Openssl10x 30792f3ab15Sopenharmony_ci } else { 30892f3ab15Sopenharmony_ci version_error() 30992f3ab15Sopenharmony_ci } 31092f3ab15Sopenharmony_ci } 31192f3ab15Sopenharmony_ci} 31292f3ab15Sopenharmony_ci 31392f3ab15Sopenharmony_cifn version_error() -> ! { 31492f3ab15Sopenharmony_ci panic!( 31592f3ab15Sopenharmony_ci " 31692f3ab15Sopenharmony_ci 31792f3ab15Sopenharmony_ciThis crate is only compatible with OpenSSL (version 1.0.1 through 1.1.1, or 3.0.0), or LibreSSL 2.5 31892f3ab15Sopenharmony_cithrough 3.8.0, but a different version of OpenSSL was found. The build is now aborting 31992f3ab15Sopenharmony_cidue to this version mismatch. 32092f3ab15Sopenharmony_ci 32192f3ab15Sopenharmony_ci" 32292f3ab15Sopenharmony_ci ); 32392f3ab15Sopenharmony_ci} 32492f3ab15Sopenharmony_ci 32592f3ab15Sopenharmony_ci// parses a string that looks like "0x100020cfL" 32692f3ab15Sopenharmony_cifn parse_version(version: &str) -> u64 { 32792f3ab15Sopenharmony_ci // cut off the 0x prefix 32892f3ab15Sopenharmony_ci assert!(version.starts_with("0x")); 32992f3ab15Sopenharmony_ci let version = &version[2..]; 33092f3ab15Sopenharmony_ci 33192f3ab15Sopenharmony_ci // and the type specifier suffix 33292f3ab15Sopenharmony_ci let version = version.trim_end_matches(|c: char| !c.is_ascii_hexdigit()); 33392f3ab15Sopenharmony_ci 33492f3ab15Sopenharmony_ci u64::from_str_radix(version, 16).unwrap() 33592f3ab15Sopenharmony_ci} 33692f3ab15Sopenharmony_ci 33792f3ab15Sopenharmony_ci// parses a string that looks like 3_0_0 33892f3ab15Sopenharmony_cifn parse_new_version(version: &str) -> u64 { 33992f3ab15Sopenharmony_ci println!("version: {}", version); 34092f3ab15Sopenharmony_ci let mut it = version.split('_'); 34192f3ab15Sopenharmony_ci let major = it.next().unwrap().parse::<u64>().unwrap(); 34292f3ab15Sopenharmony_ci let minor = it.next().unwrap().parse::<u64>().unwrap(); 34392f3ab15Sopenharmony_ci let patch = it.next().unwrap().parse::<u64>().unwrap(); 34492f3ab15Sopenharmony_ci 34592f3ab15Sopenharmony_ci (major << 28) | (minor << 20) | (patch << 4) 34692f3ab15Sopenharmony_ci} 34792f3ab15Sopenharmony_ci 34892f3ab15Sopenharmony_ci/// Given a libdir for OpenSSL (where artifacts are located) as well as the name 34992f3ab15Sopenharmony_ci/// of the libraries we're linking to, figure out whether we should link them 35092f3ab15Sopenharmony_ci/// statically or dynamically. 35192f3ab15Sopenharmony_cifn determine_mode(libdirs: &[PathBuf], libs: &[&str]) -> &'static str { 35292f3ab15Sopenharmony_ci // First see if a mode was explicitly requested 35392f3ab15Sopenharmony_ci let kind = env("OPENSSL_STATIC"); 35492f3ab15Sopenharmony_ci match kind.as_ref().and_then(|s| s.to_str()) { 35592f3ab15Sopenharmony_ci Some("0") => return "dylib", 35692f3ab15Sopenharmony_ci Some(_) => return "static", 35792f3ab15Sopenharmony_ci None => {} 35892f3ab15Sopenharmony_ci } 35992f3ab15Sopenharmony_ci 36092f3ab15Sopenharmony_ci // Next, see what files we actually have to link against, and see what our 36192f3ab15Sopenharmony_ci // possibilities even are. 36292f3ab15Sopenharmony_ci let mut files = HashSet::new(); 36392f3ab15Sopenharmony_ci for dir in libdirs { 36492f3ab15Sopenharmony_ci for path in dir 36592f3ab15Sopenharmony_ci .read_dir() 36692f3ab15Sopenharmony_ci .unwrap() 36792f3ab15Sopenharmony_ci .map(|e| e.unwrap()) 36892f3ab15Sopenharmony_ci .map(|e| e.file_name()) 36992f3ab15Sopenharmony_ci .filter_map(|e| e.into_string().ok()) 37092f3ab15Sopenharmony_ci { 37192f3ab15Sopenharmony_ci files.insert(path); 37292f3ab15Sopenharmony_ci } 37392f3ab15Sopenharmony_ci } 37492f3ab15Sopenharmony_ci let can_static = libs 37592f3ab15Sopenharmony_ci .iter() 37692f3ab15Sopenharmony_ci .all(|l| files.contains(&format!("lib{}.a", l)) || files.contains(&format!("{}.lib", l))); 37792f3ab15Sopenharmony_ci let can_dylib = libs.iter().all(|l| { 37892f3ab15Sopenharmony_ci files.contains(&format!("lib{}.so", l)) 37992f3ab15Sopenharmony_ci || files.contains(&format!("{}.dll", l)) 38092f3ab15Sopenharmony_ci || files.contains(&format!("lib{}.dylib", l)) 38192f3ab15Sopenharmony_ci }); 38292f3ab15Sopenharmony_ci match (can_static, can_dylib) { 38392f3ab15Sopenharmony_ci (true, false) => return "static", 38492f3ab15Sopenharmony_ci (false, true) => return "dylib", 38592f3ab15Sopenharmony_ci (false, false) => { 38692f3ab15Sopenharmony_ci panic!( 38792f3ab15Sopenharmony_ci "OpenSSL libdir at `{:?}` does not contain the required files \ 38892f3ab15Sopenharmony_ci to either statically or dynamically link OpenSSL", 38992f3ab15Sopenharmony_ci libdirs 39092f3ab15Sopenharmony_ci ); 39192f3ab15Sopenharmony_ci } 39292f3ab15Sopenharmony_ci (true, true) => {} 39392f3ab15Sopenharmony_ci } 39492f3ab15Sopenharmony_ci 39592f3ab15Sopenharmony_ci // Ok, we've got not explicit preference and can *either* link statically or 39692f3ab15Sopenharmony_ci // link dynamically. In the interest of "security upgrades" and/or "best 39792f3ab15Sopenharmony_ci // practices with security libs", let's link dynamically. 39892f3ab15Sopenharmony_ci "dylib" 39992f3ab15Sopenharmony_ci} 400