Skip to content

Commit a12e707

Browse files
committed
refactor code ande remove the check of fortran
1 parent c79abe9 commit a12e707

File tree

3 files changed

+55
-139
lines changed

3 files changed

+55
-139
lines changed

openblas-build/src/build.rs

Lines changed: 46 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Execute make of OpenBLAS, and its options
22
33
use crate::{check::*, error::*};
4-
use std::{fs, path::*, process::Command, str::FromStr};
4+
use std::{env, fs, path::*, process::Command, str::FromStr};
55
use walkdir::WalkDir;
66

77
/// Interface for 32-bit interger (LP64) and 64-bit integer (ILP64)
@@ -303,6 +303,14 @@ impl FromStr for Target {
303303
}
304304
}
305305

306+
#[derive(Default, Debug, Clone, PartialEq, Eq, Hash)]
307+
pub struct Compilers {
308+
pub cc: Option<String>,
309+
pub fc: Option<String>,
310+
pub hostcc: Option<String>,
311+
pub ranlib: Option<String>,
312+
}
313+
306314
/// make option generator
307315
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
308316
pub struct Configure {
@@ -316,6 +324,7 @@ pub struct Configure {
316324
pub dynamic_arch: bool,
317325
pub interface: Interface,
318326
pub target: Option<Target>,
327+
pub compilers: Compilers,
319328
}
320329

321330
impl Default for Configure {
@@ -331,45 +340,18 @@ impl Default for Configure {
331340
dynamic_arch: false,
332341
interface: Interface::LP64,
333342
target: None,
343+
compilers: Compilers::default(),
334344
}
335345
}
336346
}
337347

338348
/// Deliverables of `make` command
339349
pub struct Deliverables {
340-
/// None if `no_static`
341-
pub static_lib: Option<LibInspect>,
342-
/// None if `no_shared`
343-
pub shared_lib: Option<LibInspect>,
344350
/// Inspection what `make` command really show.
345351
pub make_conf: MakeConf,
346352
}
347353

348354
impl Configure {
349-
fn cross_compile_args(&self) -> Result<Vec<String>, Error> {
350-
let mut args = Vec::new();
351-
for name in ["CC", "FC", "HOSTCC"] {
352-
if let Ok(value) = std::env::var(format!("OPENBLAS_{}", name)) {
353-
args.push(format!("{}={}", name, value));
354-
eprintln!("{}={}", name, value);
355-
} else {
356-
eprintln!("not found {}", name);
357-
}
358-
}
359-
// for successful compile all 3 env-vars must be set
360-
if !args.is_empty() && args.len() != 3 {
361-
return Err(Error::MissingCrossCompileInfo);
362-
}
363-
// optional flags
364-
for name in ["RANLIB"] {
365-
if let Ok(value) = std::env::var(format!("OPENBLAS_{}", name)) {
366-
args.push(format!("{}={}", name, value));
367-
eprintln!("{}={}", name, value);
368-
}
369-
}
370-
Ok(args)
371-
}
372-
373355
fn make_args(&self) -> Vec<String> {
374356
let mut args = Vec::new();
375357
if self.no_static {
@@ -399,13 +381,18 @@ impl Configure {
399381
if let Some(target) = self.target.as_ref() {
400382
args.push(format!("TARGET={:?}", target))
401383
}
402-
403-
for name in ["CC", "FC", "HOSTCC"] {
404-
if let Ok(value) = std::env::var(format!("OPENBLAS_{}", name)) {
405-
args.push(format!("{}={}", name, value));
406-
}
384+
if let Some(compiler_cc) = self.compilers.cc.as_ref() {
385+
args.push(format!("CC={}", compiler_cc))
386+
}
387+
if let Some(compiler_fc) = self.compilers.fc.as_ref() {
388+
args.push(format!("FC={}", compiler_fc))
389+
}
390+
if let Some(compiler_hostcc) = self.compilers.hostcc.as_ref() {
391+
args.push(format!("HOSTCC={}", compiler_hostcc))
392+
}
393+
if let Some(compiler_ranlib) = self.compilers.ranlib.as_ref() {
394+
args.push(format!("RANLIB={}", compiler_ranlib))
407395
}
408-
409396
args
410397
}
411398

@@ -420,28 +407,24 @@ impl Configure {
420407
pub fn inspect(&self, out_dir: impl AsRef<Path>) -> Result<Deliverables, Error> {
421408
let out_dir = out_dir.as_ref();
422409
let make_conf = MakeConf::new(out_dir.join("Makefile.conf"))?;
423-
424-
if !self.no_lapack && make_conf.no_fortran {
425-
return Err(Error::FortranCompilerNotFound);
410+
if !self.no_static {
411+
let lib_path = out_dir.join("libopenblas.a");
412+
if !lib_path.exists() {
413+
return Err(Error::LibraryNotExist { path: lib_path });
414+
}
426415
}
427-
428-
Ok(Deliverables {
429-
static_lib: if !self.no_static {
430-
Some(LibInspect::new(out_dir.join("libopenblas.a"))?)
431-
} else {
432-
None
433-
},
434-
shared_lib: if !self.no_shared {
435-
Some(LibInspect::new(if cfg!(target_os = "macos") {
436-
out_dir.join("libopenblas.dylib")
437-
} else {
438-
out_dir.join("libopenblas.so")
439-
})?)
416+
if !self.no_shared {
417+
let lib_path = if cfg!(target_os = "macos") {
418+
out_dir.join("libopenblas.dylib")
440419
} else {
441-
None
442-
},
443-
make_conf,
444-
})
420+
out_dir.join("libopenblas.so")
421+
};
422+
if !lib_path.exists() {
423+
return Err(Error::LibraryNotExist { path: lib_path });
424+
}
425+
}
426+
427+
Ok(Deliverables { make_conf })
445428
}
446429

447430
/// Build OpenBLAS
@@ -492,6 +475,14 @@ impl Configure {
492475
}
493476
}
494477

478+
// check if cross compile is needed
479+
let build_target = env::var("TARGET").unwrap_or_default();
480+
let build_host = env::var("HOST").unwrap_or_default();
481+
let is_cross_compile = build_target != build_host;
482+
if is_cross_compile && (self.compilers.cc.is_none() || self.compilers.hostcc.is_none()) {
483+
return Err(Error::MissingCrossCompileInfo);
484+
}
485+
495486
// Run `make` as an subprocess
496487
//
497488
// - This will automatically run in parallel without `-j` flag
@@ -507,7 +498,6 @@ impl Configure {
507498
.stdout(out)
508499
.stderr(err)
509500
.args(self.make_args())
510-
.args(self.cross_compile_args()?)
511501
.args(["all"])
512502
.env_remove("TARGET")
513503
.check_call()
@@ -524,7 +514,6 @@ impl Configure {
524514
return Err(e);
525515
}
526516
}
527-
528517
self.inspect(out_dir)
529518
}
530519
}

openblas-build/src/check.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ impl MakeConf {
9393
"FEXTRALIB" => detail.f_extra_libs = LinkFlags::parse(entry[1])?,
9494
_ => continue,
9595
}
96+
#[cfg(target_os = "macos")]
97+
detail.c_extra_libs.libs.retain(|lib| lib != "to_library");
9698
}
9799
Ok(detail)
98100
}
@@ -103,11 +105,13 @@ impl MakeConf {
103105
/// - Linked shared libraries using `objdump -p` external command.
104106
/// - Global "T" symbols in the text (code) section of library using `nm -g` external command.
105107
#[derive(Debug, Clone)]
108+
#[allow(dead_code)]
106109
pub struct LibInspect {
107110
pub libs: Vec<String>,
108111
pub symbols: Vec<String>,
109112
}
110113

114+
#[allow(dead_code)]
111115
impl LibInspect {
112116
/// Inspect library file
113117
///

openblas-src/build.rs

Lines changed: 5 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ fn main() {
122122
}
123123

124124
/// Build OpenBLAS using openblas-build crate
125-
#[cfg(target_os = "linux")]
126125
fn build() {
127126
println!("cargo:rerun-if-env-changed=OPENBLAS_TARGET");
128127
println!("cargo:rerun-if-env-changed=OPENBLAS_CC");
@@ -150,6 +149,10 @@ fn build() {
150149
// Do not default to the native target (represented by `cfg.target == None`)
151150
// because most user set `$OPENBLAS_TARGET` explicitly will hope not to use the native target.
152151
}
152+
cfg.compilers.cc = env::var("OPENBLAS_CC").ok();
153+
cfg.compilers.hostcc = env::var("OPENBLAS_HOSTCC").ok();
154+
cfg.compilers.fc = env::var("OPENBLAS_FC").ok();
155+
cfg.compilers.ranlib = env::var("OPENBLAS_RANLIB").ok();
153156

154157
let output = if feature_enabled("cache") {
155158
use std::hash::*;
@@ -183,7 +186,7 @@ fn build() {
183186
//
184187
// Be sure that `cargo:warning` is shown only when openblas-src is build as path dependency...
185188
// https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargowarningmessage
186-
if !feature_enabled("static") {
189+
if !feature_enabled("static") && cfg!(not(target_os = "macos")) {
187190
println!(
188191
"cargo:warning=OpenBLAS is built as a shared library. You need to set LD_LIBRARY_PATH={}",
189192
output.display()
@@ -207,83 +210,3 @@ fn build() {
207210
println!("cargo:rustc-link-lib={}", lib);
208211
}
209212
}
210-
211-
/// openblas-src 0.9.0 compatible `make` runner
212-
///
213-
/// This cannot detect that OpenBLAS skips LAPACK build due to the absense of Fortran compiler.
214-
/// openblas-build crate can detect it by sneaking OpenBLAS build system, but only works on Linux.
215-
///
216-
#[cfg(not(target_os = "linux"))]
217-
fn build() {
218-
use std::fs;
219-
220-
let output = PathBuf::from(env::var("OUT_DIR").unwrap().replace(r"\", "/"));
221-
let mut make = Command::new("make");
222-
make.args(&["all"])
223-
.arg(format!("BINARY={}", binary()))
224-
.arg(format!(
225-
"{}_CBLAS=1",
226-
if feature_enabled("cblas") {
227-
"YES"
228-
} else {
229-
"NO"
230-
}
231-
))
232-
.arg(format!(
233-
"{}_LAPACKE=1",
234-
if feature_enabled("lapacke") {
235-
"YES"
236-
} else {
237-
"NO"
238-
}
239-
));
240-
match env::var("OPENBLAS_ARGS") {
241-
Ok(args) => {
242-
make.args(args.split_whitespace());
243-
}
244-
_ => (),
245-
};
246-
if let Ok(num_jobs) = env::var("NUM_JOBS") {
247-
make.arg(format!("-j{}", num_jobs));
248-
}
249-
let target = match env::var("OPENBLAS_TARGET") {
250-
Ok(target) => {
251-
make.arg(format!("TARGET={}", target));
252-
target
253-
}
254-
_ => env::var("TARGET").unwrap(),
255-
};
256-
env::remove_var("TARGET");
257-
let source = if feature_enabled("cache") {
258-
PathBuf::from(format!("source_{}", target.to_lowercase()))
259-
} else {
260-
output.join(format!("source_{}", target.to_lowercase()))
261-
};
262-
263-
if !source.exists() {
264-
let source_tmp = openblas_build::download(&output).unwrap();
265-
fs::rename(&source_tmp, &source).unwrap();
266-
}
267-
for name in &vec!["CC", "FC", "HOSTCC"] {
268-
if let Ok(value) = env::var(format!("OPENBLAS_{}", name)) {
269-
make.arg(format!("{}={}", name, value));
270-
}
271-
}
272-
run(&mut make.current_dir(&source));
273-
run(Command::new("make")
274-
.arg("install")
275-
.arg(format!("DESTDIR={}", output.display()))
276-
.current_dir(&source));
277-
println!(
278-
"cargo:rustc-link-search={}",
279-
output.join("opt/OpenBLAS/lib").display(),
280-
);
281-
282-
fn binary() -> &'static str {
283-
if cfg!(target_pointer_width = "32") {
284-
"32"
285-
} else {
286-
"64"
287-
}
288-
}
289-
}

0 commit comments

Comments
 (0)