Skip to content

Commit

Permalink
Drop LAPACK symbol inspection
Browse files Browse the repository at this point in the history
  • Loading branch information
Dirreke committed Nov 29, 2024
1 parent a12e707 commit 99d72ec
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 234 deletions.
1 change: 0 additions & 1 deletion openblas-build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,4 @@ ureq = { version = "2.5.0", default-features = false, features = [
"gzip",
] }
native-tls = { version = "0.2.11" }
walkdir = "2.3.1"

44 changes: 0 additions & 44 deletions openblas-build/nofortran.conf

This file was deleted.

101 changes: 31 additions & 70 deletions openblas-build/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
use crate::{check::*, error::*};
use std::{env, fs, path::*, process::Command, str::FromStr};
use walkdir::WalkDir;

/// Interface for 32-bit interger (LP64) and 64-bit integer (ILP64)
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -345,12 +344,6 @@ impl Default for Configure {
}
}

/// Deliverables of `make` command
pub struct Deliverables {
/// Inspection what `make` command really show.
pub make_conf: MakeConf,
}

impl Configure {
fn make_args(&self) -> Vec<String> {
let mut args = Vec::new();
Expand Down Expand Up @@ -396,37 +389,6 @@ impl Configure {
args
}

/// Inspect existing build deliverables, and validate them.
///
/// Error
/// ------
/// - No build deliverables exist
/// - Build deliverables are not valid
/// - e.g. `self.no_lapack == false`, but the existing library does not contains LAPACK symbols.
///
pub fn inspect(&self, out_dir: impl AsRef<Path>) -> Result<Deliverables, Error> {
let out_dir = out_dir.as_ref();
let make_conf = MakeConf::new(out_dir.join("Makefile.conf"))?;
if !self.no_static {
let lib_path = out_dir.join("libopenblas.a");
if !lib_path.exists() {
return Err(Error::LibraryNotExist { path: lib_path });
}
}
if !self.no_shared {
let lib_path = if cfg!(target_os = "macos") {
out_dir.join("libopenblas.dylib")
} else {
out_dir.join("libopenblas.so")
};
if !lib_path.exists() {
return Err(Error::LibraryNotExist { path: lib_path });
}
}

Ok(Deliverables { make_conf })
}

/// Build OpenBLAS
///
/// Libraries are created directly under `out_dir` e.g. `out_dir/libopenblas.a`
Expand All @@ -441,38 +403,12 @@ impl Configure {
self,
openblas_root: impl AsRef<Path>,
out_dir: impl AsRef<Path>,
) -> Result<Deliverables, Error> {
) -> Result<MakeConf, Error> {
let root = openblas_root.as_ref();
let out_dir = out_dir.as_ref();
if !out_dir.exists() {
fs::create_dir_all(out_dir)?;
}

// Do not build if libraries and Makefile.conf already exist and are valid
if let Ok(deliv) = self.inspect(out_dir) {
return Ok(deliv);
}

// Copy OpenBLAS sources from this crate to `out_dir`
let root = openblas_root.as_ref();
for entry in WalkDir::new(root) {
let entry = entry.expect("Unknown IO error while walkdir");
let dest = out_dir.join(
entry
.path()
.strip_prefix(root)
.expect("Directory entry is not under root"),
);
if dest.exists() {
// Do not overwrite
// Cache of previous build should be cleaned by `cargo clean`
continue;
}
if entry.file_type().is_dir() {
fs::create_dir(&dest)?;
}
if entry.file_type().is_file() {
fs::copy(entry.path(), &dest)?;
}
if let Ok(make_conf) = MakeConf::new(out_dir.join("Makefile.conf")) {
return Ok(make_conf);
}

// check if cross compile is needed
Expand All @@ -494,7 +430,7 @@ impl Configure {
let out = fs::File::create(out_dir.join("out.log")).expect("Cannot create log file");
let err = fs::File::create(out_dir.join("err.log")).expect("Cannot create log file");
match Command::new("make")
.current_dir(out_dir)
.current_dir(root)
.stdout(out)
.stderr(err)
.args(self.make_args())
Expand All @@ -514,7 +450,32 @@ impl Configure {
return Err(e);
}
}
self.inspect(out_dir)

// Copy OpenBLAS and Makefile.conf from this crate to `out_dir`
let mut file_names = Vec::new();
if !self.no_static {
file_names.push("libopenblas.a");
}
if !self.no_shared {
if cfg!(target_os = "macos") {
file_names.push("libopenblas.dylib");
} else {
file_names.push("libopenblas.so");
}
}
file_names.push("Makefile.conf");
for file_name in file_names {
let src = root.join(file_name);
let dest = out_dir.join(file_name);
if dest.exists() {
// Do not overwrite
// Cache of previous build should be cleaned by `cargo clean`
continue;
}
fs::copy(src, dest)?;
}

MakeConf::new(out_dir.join("Makefile.conf"))
}
}

Expand Down
114 changes: 0 additions & 114 deletions openblas-build/src/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use std::{
hash::Hash,
io::{self, BufRead},
path::*,
process::Command,
};

/// Parse compiler linker flags, `-L` and `-l`
Expand Down Expand Up @@ -100,111 +99,6 @@ impl MakeConf {
}
}

/// Library inspection using binutils (`nm` and `objdump`) as external command
///
/// - Linked shared libraries using `objdump -p` external command.
/// - Global "T" symbols in the text (code) section of library using `nm -g` external command.
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct LibInspect {
pub libs: Vec<String>,
pub symbols: Vec<String>,
}

#[allow(dead_code)]
impl LibInspect {
/// Inspect library file
///
/// Be sure that `nm -g` and `objdump -p` are executed in this function
pub fn new<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
let path = path.as_ref();
if !path.exists() {
return Err(Error::LibraryNotExist {
path: path.to_owned(),
});
}

let nm_out = Command::new("nm").arg("-g").arg(path).output()?;

// assumes `nm` output like following:
//
// ```
// 0000000000909b30 T zupmtr_
// ```
let mut symbols: Vec<_> = nm_out
.stdout
.lines()
.flat_map(|line| {
let line = line.expect("nm output should not include non-UTF8 output");
let entry: Vec<_> = line.trim().split(' ').collect();
if entry.len() == 3 && entry[1] == "T" {
Some(entry[2].into())
} else {
None
}
})
.collect();
symbols.sort(); // sort alphabetically

let mut libs: Vec<_> = Command::new("objdump")
.arg("-p")
.arg(path)
.output()?
.stdout
.lines()
.flat_map(|line| {
let line = line.expect("objdump output should not include non-UTF8 output");
if line.trim().starts_with("NEEDED") {
Some(line.trim().trim_start_matches("NEEDED").trim().to_string())
} else {
None
}
})
.collect();
libs.sort();

Ok(LibInspect { libs, symbols })
}

pub fn has_cblas(&self) -> bool {
for sym in &self.symbols {
if sym.starts_with("cblas_") {
return true;
}
}
false
}

pub fn has_lapack(&self) -> bool {
for sym in &self.symbols {
if sym == "dsyev_" {
return true;
}
}
false
}

pub fn has_lapacke(&self) -> bool {
for sym in &self.symbols {
if sym.starts_with("LAPACKE_") {
return true;
}
}
false
}

pub fn has_lib(&self, name: &str) -> bool {
for lib in &self.libs {
if let Some(stem) = lib.split('.').next() {
if stem == format!("lib{}", name) {
return true;
}
};
}
false
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -216,12 +110,4 @@ mod tests {
let detail = MakeConf::new(path).unwrap();
assert!(!detail.no_fortran);
}

#[test]
fn detail_from_nofortran_conf() {
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("nofortran.conf");
assert!(path.exists());
let detail = MakeConf::new(path).unwrap();
assert!(detail.no_fortran);
}
}
10 changes: 5 additions & 5 deletions openblas-src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,19 +194,19 @@ fn build() {
}

let source = openblas_build::download(&output).unwrap();
let deliv = cfg.build(source, &output).unwrap();
let make_conf = cfg.build(source, &output).unwrap();

println!("cargo:rustc-link-search={}", output.display());
for search_path in &deliv.make_conf.c_extra_libs.search_paths {
for search_path in &make_conf.c_extra_libs.search_paths {
println!("cargo:rustc-link-search={}", search_path.display());
}
for lib in &deliv.make_conf.c_extra_libs.libs {
for lib in &make_conf.c_extra_libs.libs {
println!("cargo:rustc-link-lib={}", lib);
}
for search_path in &deliv.make_conf.f_extra_libs.search_paths {
for search_path in &make_conf.f_extra_libs.search_paths {
println!("cargo:rustc-link-search={}", search_path.display());
}
for lib in &deliv.make_conf.f_extra_libs.libs {
for lib in &make_conf.f_extra_libs.libs {
println!("cargo:rustc-link-lib={}", lib);
}
}

0 comments on commit 99d72ec

Please sign in to comment.