2
2
3
3
use crate :: { check:: * , error:: * } ;
4
4
use std:: { env, fs, path:: * , process:: Command , str:: FromStr } ;
5
- use walkdir:: WalkDir ;
6
5
7
6
/// Interface for 32-bit interger (LP64) and 64-bit integer (ILP64)
8
7
#[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
@@ -345,12 +344,6 @@ impl Default for Configure {
345
344
}
346
345
}
347
346
348
- /// Deliverables of `make` command
349
- pub struct Deliverables {
350
- /// Inspection what `make` command really show.
351
- pub make_conf : MakeConf ,
352
- }
353
-
354
347
impl Configure {
355
348
fn make_args ( & self ) -> Vec < String > {
356
349
let mut args = Vec :: new ( ) ;
@@ -396,37 +389,6 @@ impl Configure {
396
389
args
397
390
}
398
391
399
- /// Inspect existing build deliverables, and validate them.
400
- ///
401
- /// Error
402
- /// ------
403
- /// - No build deliverables exist
404
- /// - Build deliverables are not valid
405
- /// - e.g. `self.no_lapack == false`, but the existing library does not contains LAPACK symbols.
406
- ///
407
- pub fn inspect ( & self , out_dir : impl AsRef < Path > ) -> Result < Deliverables , Error > {
408
- let out_dir = out_dir. as_ref ( ) ;
409
- let make_conf = MakeConf :: new ( out_dir. join ( "Makefile.conf" ) ) ?;
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
- }
415
- }
416
- if !self . no_shared {
417
- let lib_path = if cfg ! ( target_os = "macos" ) {
418
- out_dir. join ( "libopenblas.dylib" )
419
- } else {
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 } )
428
- }
429
-
430
392
/// Build OpenBLAS
431
393
///
432
394
/// Libraries are created directly under `out_dir` e.g. `out_dir/libopenblas.a`
@@ -437,42 +399,11 @@ impl Configure {
437
399
/// This means that the system environment is not appropriate to execute `make`,
438
400
/// e.g. LAPACK is required but there is no Fortran compiler.
439
401
///
440
- pub fn build (
441
- self ,
442
- openblas_root : impl AsRef < Path > ,
443
- out_dir : impl AsRef < Path > ,
444
- ) -> Result < Deliverables , Error > {
445
- let out_dir = out_dir. as_ref ( ) ;
446
- if !out_dir. exists ( ) {
447
- fs:: create_dir_all ( out_dir) ?;
448
- }
449
-
450
- // Do not build if libraries and Makefile.conf already exist and are valid
451
- if let Ok ( deliv) = self . inspect ( out_dir) {
452
- return Ok ( deliv) ;
453
- }
454
-
455
- // Copy OpenBLAS sources from this crate to `out_dir`
402
+ pub fn build < P : AsRef < Path > > ( self , openblas_root : P ) -> Result < MakeConf , Error > {
456
403
let root = openblas_root. as_ref ( ) ;
457
- for entry in WalkDir :: new ( root) {
458
- let entry = entry. expect ( "Unknown IO error while walkdir" ) ;
459
- let dest = out_dir. join (
460
- entry
461
- . path ( )
462
- . strip_prefix ( root)
463
- . expect ( "Directory entry is not under root" ) ,
464
- ) ;
465
- if dest. exists ( ) {
466
- // Do not overwrite
467
- // Cache of previous build should be cleaned by `cargo clean`
468
- continue ;
469
- }
470
- if entry. file_type ( ) . is_dir ( ) {
471
- fs:: create_dir ( & dest) ?;
472
- }
473
- if entry. file_type ( ) . is_file ( ) {
474
- fs:: copy ( entry. path ( ) , & dest) ?;
475
- }
404
+ // Do not build if libraries and Makefile.conf already exist and are valid
405
+ if let Ok ( make_conf) = MakeConf :: new ( root. join ( "Makefile.conf" ) ) {
406
+ return Ok ( make_conf) ;
476
407
}
477
408
478
409
// check if cross compile is needed
@@ -491,10 +422,10 @@ impl Configure {
491
422
// - cargo sets `TARGET` environment variable as target triple (e.g. x86_64-unknown-linux-gnu)
492
423
// while binding build.rs, but `make` read it as CPU target specification.
493
424
//
494
- let out = fs:: File :: create ( out_dir . join ( "out.log" ) ) . expect ( "Cannot create log file" ) ;
495
- let err = fs:: File :: create ( out_dir . join ( "err.log" ) ) . expect ( "Cannot create log file" ) ;
425
+ let out = fs:: File :: create ( root . join ( "out.log" ) ) . expect ( "Cannot create log file" ) ;
426
+ let err = fs:: File :: create ( root . join ( "err.log" ) ) . expect ( "Cannot create log file" ) ;
496
427
match Command :: new ( "make" )
497
- . current_dir ( out_dir )
428
+ . current_dir ( root )
498
429
. stdout ( out)
499
430
. stderr ( err)
500
431
. args ( self . make_args ( ) )
@@ -506,15 +437,16 @@ impl Configure {
506
437
Err ( err @ Error :: NonZeroExitStatus { .. } ) => {
507
438
eprintln ! (
508
439
"{}" ,
509
- fs:: read_to_string( out_dir . join( "err.log" ) ) . expect( "Cannot read log file" )
440
+ fs:: read_to_string( root . join( "err.log" ) ) . expect( "Cannot read log file" )
510
441
) ;
511
442
return Err ( err) ;
512
443
}
513
444
Err ( e) => {
514
445
return Err ( e) ;
515
446
}
516
447
}
517
- self . inspect ( out_dir)
448
+
449
+ MakeConf :: new ( root. join ( "Makefile.conf" ) )
518
450
}
519
451
}
520
452
@@ -531,62 +463,96 @@ mod tests {
531
463
) ) ;
532
464
}
533
465
534
- fn get_openblas_source ( ) -> PathBuf {
535
- let openblas_src_root = PathBuf :: from ( env ! ( "CARGO_MANIFEST_DIR" ) ) . join ( "../openblas-src" ) ;
536
- crate :: download ( & openblas_src_root) . unwrap ( )
466
+ fn get_openblas_source < P : AsRef < Path > > ( out_dir : P ) -> PathBuf {
467
+ let openblas_src_root = PathBuf :: from ( env ! ( "CARGO_MANIFEST_DIR" ) ) . join ( "../openblas-src/" ) ;
468
+ let source = crate :: download ( & openblas_src_root) . unwrap ( ) ;
469
+ // copy files to the target directory
470
+ let out_dir = out_dir. as_ref ( ) ;
471
+ fs:: create_dir_all ( out_dir) . unwrap ( ) ;
472
+ for entry in walkdir:: WalkDir :: new ( & source) {
473
+ let entry = entry. unwrap ( ) ;
474
+ let src = entry. path ( ) ;
475
+ let dest = out_dir. join ( src. strip_prefix ( & source) . unwrap ( ) ) ;
476
+ if entry. file_type ( ) . is_dir ( ) {
477
+ fs:: create_dir_all ( & dest) . unwrap ( ) ;
478
+ } else {
479
+ fs:: copy ( src, dest) . unwrap ( ) ;
480
+ }
481
+ }
482
+ out_dir. to_path_buf ( )
537
483
}
538
484
539
485
#[ ignore]
540
486
#[ test]
541
487
fn build_default ( ) {
542
488
let root = PathBuf :: from ( env ! ( "CARGO_MANIFEST_DIR" ) ) ;
489
+ let out_dir = root. join ( "test_build/build_default" ) ;
543
490
let opt = Configure :: default ( ) ;
544
- let _detail = opt
545
- . build ( get_openblas_source ( ) , root. join ( "test_build/build_default" ) )
546
- . unwrap ( ) ;
491
+ let _ = opt. build ( get_openblas_source ( & out_dir) ) . unwrap ( ) ;
547
492
}
548
493
549
494
#[ ignore]
550
495
#[ test]
551
496
fn build_no_shared ( ) {
552
497
let root = PathBuf :: from ( env ! ( "CARGO_MANIFEST_DIR" ) ) ;
498
+ let out_dir = root. join ( "test_build/build_no_shared" ) ;
553
499
let mut opt = Configure :: default ( ) ;
554
500
opt. no_shared = true ;
555
- let detail = opt
556
- . build (
557
- get_openblas_source ( ) ,
558
- root. join ( "test_build/build_no_shared" ) ,
559
- )
560
- . unwrap ( ) ;
561
- assert ! ( detail. shared_lib. is_none( ) ) ;
501
+ opt. build ( get_openblas_source ( & out_dir) ) . unwrap ( ) ;
502
+ let _ = LibInspect :: new ( out_dir. join ( "libopenblas.a" ) ) . unwrap ( ) ;
562
503
}
563
504
564
505
#[ ignore]
565
506
#[ test]
566
507
fn build_no_lapacke ( ) {
567
508
let root = PathBuf :: from ( env ! ( "CARGO_MANIFEST_DIR" ) ) ;
509
+ let out_dir = root. join ( "test_build/build_no_lapacke" ) ;
568
510
let mut opt = Configure :: default ( ) ;
569
511
opt. no_lapacke = true ;
570
- let detail = opt
571
- . build (
572
- get_openblas_source ( ) ,
573
- root. join ( "test_build/build_no_lapacke" ) ,
574
- )
575
- . unwrap ( ) ;
576
- let shared_lib = detail. shared_lib . unwrap ( ) ;
577
- assert ! ( shared_lib. has_lapack( ) ) ;
578
- assert ! ( !shared_lib. has_lapacke( ) ) ;
512
+ let _ = opt. build ( get_openblas_source ( & out_dir) ) . unwrap ( ) ;
513
+ let lib_name = if cfg ! ( target_os = "macos" ) {
514
+ "libopenblas.dylib"
515
+ } else {
516
+ "libopenblas.so"
517
+ } ;
518
+ let lib_inspect = LibInspect :: new ( out_dir. join ( lib_name) ) . unwrap ( ) ;
519
+
520
+ assert ! ( lib_inspect. has_lapack( ) ) ;
521
+ assert ! ( !lib_inspect. has_lapacke( ) ) ;
522
+ }
523
+
524
+ #[ ignore]
525
+ #[ test]
526
+ fn build_no_cblas ( ) {
527
+ let root = PathBuf :: from ( env ! ( "CARGO_MANIFEST_DIR" ) ) ;
528
+ let out_dir = root. join ( "test_build/build_no_cblas" ) ;
529
+ let mut opt = Configure :: default ( ) ;
530
+ opt. no_lapacke = true ;
531
+ let _ = opt. build ( get_openblas_source ( & out_dir) ) . unwrap ( ) ;
532
+ let lib_name = if cfg ! ( target_os = "macos" ) {
533
+ "libopenblas.dylib"
534
+ } else {
535
+ "libopenblas.so"
536
+ } ;
537
+ let lib_inspect = LibInspect :: new ( out_dir. join ( lib_name) ) . unwrap ( ) ;
538
+
539
+ assert ! ( !lib_inspect. has_cblas( ) ) ;
579
540
}
580
541
581
542
#[ ignore]
582
543
#[ test]
583
544
fn build_openmp ( ) {
584
545
let root = PathBuf :: from ( env ! ( "CARGO_MANIFEST_DIR" ) ) ;
546
+ let out_dir = root. join ( "test_build/build_openmp" ) ;
585
547
let mut opt = Configure :: default ( ) ;
586
548
opt. use_openmp = true ;
587
- let detail = opt
588
- . build ( get_openblas_source ( ) , root. join ( "test_build/build_openmp" ) )
589
- . unwrap ( ) ;
590
- assert ! ( detail. shared_lib. unwrap( ) . has_lib( "gomp" ) ) ;
549
+ let _ = opt. build ( get_openblas_source ( & out_dir) ) . unwrap ( ) ;
550
+ let lib_name = if cfg ! ( target_os = "macos" ) {
551
+ "libopenblas.dylib"
552
+ } else {
553
+ "libopenblas.so"
554
+ } ;
555
+ let lib_inspect = LibInspect :: new ( out_dir. join ( lib_name) ) . unwrap ( ) ;
556
+ assert ! ( lib_inspect. has_lib( "gomp" ) ) ;
591
557
}
592
558
}
0 commit comments