fn search_lib_dir()

in include/pyo3/pyo3-build-config/src/impl_.rs [1453:1513]


fn search_lib_dir(path: impl AsRef<Path>, cross: &CrossCompileConfig) -> Result<Vec<PathBuf>> {
    let mut sysconfig_paths = vec![];
    for f in fs::read_dir(path.as_ref()).with_context(|| {
        format!(
            "failed to list the entries in '{}'",
            path.as_ref().display()
        )
    })? {
        sysconfig_paths.extend(match &f {
            // Python 3.7+ sysconfigdata with platform specifics
            Ok(f) if starts_with(f, "_sysconfigdata_") && ends_with(f, "py") => vec![f.path()],
            Ok(f) if f.metadata().map_or(false, |metadata| metadata.is_dir()) => {
                let file_name = f.file_name();
                let file_name = file_name.to_string_lossy();
                if file_name == "build" || file_name == "lib" {
                    search_lib_dir(f.path(), cross)?
                } else if file_name.starts_with("lib.") {
                    // check if right target os
                    if !file_name.contains(&cross.target.operating_system.to_string()) {
                        continue;
                    }
                    // Check if right arch
                    if !file_name.contains(&cross.target.architecture.to_string()) {
                        continue;
                    }
                    search_lib_dir(f.path(), cross)?
                } else if is_cpython_lib_dir(&file_name, &cross.version)
                    || is_pypy_lib_dir(&file_name, &cross.version)
                    || is_graalpy_lib_dir(&file_name, &cross.version)
                {
                    search_lib_dir(f.path(), cross)?
                } else {
                    continue;
                }
            }
            _ => continue,
        });
    }
    // If we got more than one file, only take those that contain the arch name.
    // For ubuntu 20.04 with host architecture x86_64 and a foreign architecture of armhf
    // this reduces the number of candidates to 1:
    //
    // $ find /usr/lib/python3.8/ -name '_sysconfigdata*.py' -not -lname '*'
    //  /usr/lib/python3.8/_sysconfigdata__x86_64-linux-gnu.py
    //  /usr/lib/python3.8/_sysconfigdata__arm-linux-gnueabihf.py
    if sysconfig_paths.len() > 1 {
        let temp = sysconfig_paths
            .iter()
            .filter(|p| {
                p.to_string_lossy()
                    .contains(&cross.target.architecture.to_string())
            })
            .cloned()
            .collect::<Vec<PathBuf>>();
        if !temp.is_empty() {
            sysconfig_paths = temp;
        }
    }

    Ok(sysconfig_paths)
}