Rust wrapper: look for either lib or lib64 under WOLFSSL_PREFIX

pull/11312/head
Josh Holtrop 2026-08-31 09:39:50 -04:00
parent e37f75acf1
commit 34753a8535
1 changed files with 46 additions and 23 deletions

View File

@ -38,39 +38,61 @@ fn wolfssl_repo_lib_dir() -> Result<String> {
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<Option<String>> = OnceLock::new();
PREFIX.get_or_init(compute_wolfssl_prefix).as_deref()
fn wolfssl_prefix_dirs() -> Option<&'static WolfsslPrefixDirs> {
static DIRS: OnceLock<Option<WolfsslPrefixDirs>> = 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<String> {
/// 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<WolfsslPrefixDirs> {
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<String> {
/// 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<Option<String>> {
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<Option<String>> {
/// 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<Option<String>> {
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() {