@@ -4,40 +4,42 @@ use std::{
44 fs,
55 io:: { self , BufRead } ,
66 path:: { Path , PathBuf } ,
7+ process:: Command ,
78} ;
89
9- /// A library found in system
1010#[ derive( Debug , Clone ) ]
11- pub enum Library {
12- PkgConfig {
13- config : Config ,
14- lib : pkg_config:: Library ,
15- } ,
16- Directory {
17- config : Config ,
18- /// Directory where `mkl.h` and `mkl_version.h` exists
19- include_dir : PathBuf ,
20- /// Directory where `libmkl_core.a` or `libmkl_rt.so` exists
21- library_dir : PathBuf ,
22- /// Directory where `libiomp5.a` or `libiomp5.so` exists
23- ///
24- /// They are sometimes placed in different position.
25- /// Returns `None` if they exist on `library_dir`.
26- iomp5_dir : Option < PathBuf > ,
27- } ,
11+ pub struct Library {
12+ config : Config ,
13+ /// Directory where `mkl.h` and `mkl_version.h` exists
14+ include_dir : PathBuf ,
15+ /// Directory where `libmkl_core.a` or `libmkl_rt.so` exists
16+ library_dir : PathBuf ,
17+ /// Directory where `libiomp5.a` or `libiomp5.so` exists
18+ ///
19+ /// They are sometimes placed in different position.
20+ /// Returns `None` if they exist on `library_dir`.
21+ iomp5_dir : Option < PathBuf > ,
2822}
2923
3024impl Library {
3125 /// Try to find MKL using pkg-config
32- pub fn pkg_config ( config : Config ) -> Option < Self > {
33- if let Ok ( lib ) = pkg_config :: Config :: new ( )
34- . cargo_metadata ( false )
35- . env_metadata ( false )
36- . probe ( & config . to_string ( ) )
26+ pub fn pkg_config ( config : Config ) -> Result < Option < Self > > {
27+ if let Ok ( out ) = Command :: new ( "pkg-config" )
28+ . arg ( "--variable=prefix" )
29+ . arg ( config . to_string ( ) )
30+ . output ( )
3731 {
38- Some ( Library :: PkgConfig { config, lib } )
32+ if out. status . success ( ) {
33+ let path = String :: from_utf8 ( out. stdout ) . context ( "Non-UTF8 MKL prefix" ) ?;
34+ let prefix = Path :: new ( path. trim ( ) ) ;
35+ Self :: seek_directory ( config, prefix)
36+ } else {
37+ // pkg-config does not find MKL
38+ Ok ( None )
39+ }
3940 } else {
40- None
41+ // pkg-config is not found
42+ Ok ( None )
4143 }
4244 }
4345
@@ -136,7 +138,7 @@ impl Library {
136138 iomp5_dir = None ;
137139 }
138140 Ok ( match ( library_dir, include_dir) {
139- ( Some ( library_dir) , Some ( include_dir) ) => Some ( Library :: Directory {
141+ ( Some ( library_dir) , Some ( include_dir) ) => Some ( Library {
140142 config,
141143 include_dir,
142144 library_dir,
@@ -157,7 +159,7 @@ impl Library {
157159 /// - `C:/Program Files (x86)/IntelSWTools/` for Windows
158160 ///
159161 pub fn new ( config : Config ) -> Result < Self > {
160- if let Some ( lib) = Self :: pkg_config ( config) {
162+ if let Some ( lib) = Self :: pkg_config ( config) ? {
161163 return Ok ( lib) ;
162164 }
163165 if let Ok ( mklroot) = std:: env:: var ( "MKLROOT" ) {
@@ -182,10 +184,7 @@ impl Library {
182184 }
183185
184186 pub fn config ( & self ) -> & Config {
185- match self {
186- Library :: PkgConfig { config, .. } => config,
187- Library :: Directory { config, .. } => config,
188- }
187+ & self . config
189188 }
190189
191190 /// Found MKL version parsed from `mkl_version.h`
@@ -201,19 +200,7 @@ impl Library {
201200 /// and this corresponds to `(2020, 0, 1)`
202201 ///
203202 pub fn version ( & self ) -> Result < ( u32 , u32 , u32 ) > {
204- let version_h = match self {
205- Library :: PkgConfig { lib, .. } => {
206- let mut version_h = None ;
207- for path in & lib. include_paths {
208- let candidate = path. join ( "mkl_version.h" ) ;
209- if candidate. exists ( ) {
210- version_h = Some ( candidate) ;
211- }
212- }
213- version_h. context ( "mkl_version.h not found in pkg-config" ) ?
214- }
215- Library :: Directory { include_dir, .. } => include_dir. join ( "mkl_version.h" ) ,
216- } ;
203+ let version_h = self . include_dir . join ( "mkl_version.h" ) ;
217204
218205 let f = fs:: File :: open ( version_h) . context ( "Failed to open mkl_version.h" ) ?;
219206 let f = io:: BufReader :: new ( f) ;
@@ -242,29 +229,17 @@ impl Library {
242229
243230 /// Print `cargo:rustc-link-*` metadata to stdout
244231 pub fn print_cargo_metadata ( & self ) -> Result < ( ) > {
245- match self {
246- Library :: PkgConfig { config, .. } => {
247- pkg_config:: probe_library ( & config. to_string ( ) ) ?;
248- }
249- Library :: Directory {
250- config,
251- library_dir,
252- iomp5_dir,
253- ..
254- } => {
255- println ! ( "cargo:rustc-link-search={}" , library_dir. display( ) ) ;
256- if let Some ( iomp5_dir) = iomp5_dir {
257- println ! ( "cargo:rustc-link-search={}" , iomp5_dir. display( ) ) ;
232+ println ! ( "cargo:rustc-link-search={}" , self . library_dir. display( ) ) ;
233+ if let Some ( iomp5_dir) = & self . iomp5_dir {
234+ println ! ( "cargo:rustc-link-search={}" , iomp5_dir. display( ) ) ;
235+ }
236+ for lib in self . config . libs ( ) {
237+ match self . config . link {
238+ LinkType :: Static => {
239+ println ! ( "cargo:rustc-link-lib=static={}" , lib) ;
258240 }
259- for lib in config. libs ( ) {
260- match config. link {
261- LinkType :: Static => {
262- println ! ( "cargo:rustc-link-lib=static={}" , lib) ;
263- }
264- LinkType :: Dynamic => {
265- println ! ( "cargo:rustc-link-lib=dylib={}" , lib) ;
266- }
267- }
241+ LinkType :: Dynamic => {
242+ println ! ( "cargo:rustc-link-lib=dylib={}" , lib) ;
268243 }
269244 }
270245 }
@@ -290,7 +265,7 @@ mod tests {
290265 #[ test]
291266 fn pkg_config ( ) {
292267 for cfg in Config :: possibles ( ) {
293- let lib = Library :: pkg_config ( cfg) . unwrap ( ) ;
268+ let lib = Library :: pkg_config ( cfg) . unwrap ( ) . unwrap ( ) ;
294269 dbg ! ( lib. version( ) . unwrap( ) ) ;
295270 }
296271 }
0 commit comments