diff --git a/wrapper/rust/wolfssl-wolfcrypt/build.rs b/wrapper/rust/wolfssl-wolfcrypt/build.rs index 5feec53959..76a043fca0 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/build.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/build.rs @@ -38,39 +38,61 @@ fn wolfssl_repo_lib_dir() -> Result { Ok(format!("{}/src/.libs", wolfssl_repo_base_dir()?)) } -/// Returns the validated `WOLFSSL_PREFIX` installation prefix, if usable. +/// Directories located under a validated `WOLFSSL_PREFIX` installation. +struct WolfsslPrefixDirs { + include: String, + lib: String, +} + +/// Returns the directories of the `WOLFSSL_PREFIX` installation, if usable. /// /// A prefix is only accepted if it provides both halves of an installation: -/// a `lib` directory and an `include/wolfssl` directory. A prefix holding -/// only one of them is rejected outright, so that the headers and the library -/// we build against always come from the same place. +/// a library directory (`lib` or `lib64`) and an `include/wolfssl` directory. +/// A prefix holding only one of them is rejected outright, so that the headers +/// and the library we build against always come from the same place. /// /// The result is computed once and cached, so any warning is printed once. -fn wolfssl_prefix() -> Option<&'static str> { - static PREFIX: OnceLock> = OnceLock::new(); - PREFIX.get_or_init(compute_wolfssl_prefix).as_deref() +fn wolfssl_prefix_dirs() -> Option<&'static WolfsslPrefixDirs> { + static DIRS: OnceLock> = OnceLock::new(); + DIRS.get_or_init(compute_wolfssl_prefix_dirs).as_ref() } /// Read `WOLFSSL_PREFIX` from the environment and validate its layout. /// -/// Returns `None` (after warning) if the variable is unset, malformed, or -/// does not point at a directory containing both `lib` and `include/wolfssl`. -fn compute_wolfssl_prefix() -> Option { +/// Returns `None` (after warning) if the variable is unset, malformed, or does +/// not point at a directory containing both `include/wolfssl` and a library +/// directory. +fn compute_wolfssl_prefix_dirs() -> Option { let prefix = env::var("WOLFSSL_PREFIX").ok()?; if prefix.is_empty() || prefix.contains('\n') { println!("cargo:warning=ignoring WOLFSSL_PREFIX"); return None; } let prefix_path = Path::new(&prefix); - for subdir in [prefix_path.join("lib"), - prefix_path.join("include").join("wolfssl")] { - if !subdir.is_dir() { - println!("cargo:warning=ignoring WOLFSSL_PREFIX: {} is not a directory", - subdir.display()); - return None; - } + + let include_dir = prefix_path.join("include"); + if !include_dir.join("wolfssl").is_dir() { + println!("cargo:warning=ignoring WOLFSSL_PREFIX: {} is not a directory", + include_dir.join("wolfssl").display()); + return None; } - Some(prefix) + + // Installations are found under either lib/ or lib64/ depending on the + // platform and how wolfSSL was configured. + let lib_names = ["lib", "lib64"]; + let Some(lib_dir) = lib_names.iter() + .map(|name| prefix_path.join(name)) + .find(|dir| dir.is_dir()) else { + println!("cargo:warning=ignoring WOLFSSL_PREFIX: none of {} are directories", + lib_names.map(|name| prefix_path.join(name).display().to_string()) + .join(", ")); + return None; + }; + + Some(WolfsslPrefixDirs { + include: include_dir.display().to_string(), + lib: lib_dir.display().to_string(), + }) } /// Returns the include directory for wolfssl headers. @@ -78,8 +100,8 @@ fn compute_wolfssl_prefix() -> Option { /// If `WOLFSSL_PREFIX` is usable, returns `{WOLFSSL_PREFIX}/include`. /// Otherwise falls back to the repo root if it exists (for in-tree host builds). fn wolfssl_include_dir() -> Result> { - if let Some(prefix) = wolfssl_prefix() { - Ok(Some(format!("{}/include", prefix))) + if let Some(dirs) = wolfssl_prefix_dirs() { + Ok(Some(dirs.include.clone())) } else { let base = wolfssl_repo_base_dir()?; let base_path = Path::new(&base); @@ -96,11 +118,12 @@ fn wolfssl_include_dir() -> Result> { /// Returns the library directory for libwolfssl. /// -/// If `WOLFSSL_PREFIX` is usable, returns `{WOLFSSL_PREFIX}/lib`. +/// If `WOLFSSL_PREFIX` is usable, returns `{WOLFSSL_PREFIX}/lib` or +/// `{WOLFSSL_PREFIX}/lib64`, whichever exists. /// Otherwise falls back to the in-tree build output directory if it exists. fn wolfssl_lib_dir() -> Result> { - if let Some(prefix) = wolfssl_prefix() { - Ok(Some(format!("{}/lib", prefix))) + if let Some(dirs) = wolfssl_prefix_dirs() { + Ok(Some(dirs.lib.clone())) } else { let repo_lib_dir = wolfssl_repo_lib_dir()?; if Path::new(&repo_lib_dir).exists() {