@@ -94,7 +94,6 @@ fn main() {
94
94
/// Build OpenBLAS using openblas-build crate
95
95
#[ cfg( target_os = "linux" ) ]
96
96
fn build ( ) {
97
- let output = PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) ;
98
97
let mut cfg = openblas_build:: Configure :: default ( ) ;
99
98
if !feature_enabled ( "cblas" ) {
100
99
cfg. no_cblas = true ;
@@ -107,6 +106,46 @@ fn build() {
107
106
} else {
108
107
cfg. no_static = true ;
109
108
}
109
+
110
+ let output = if feature_enabled ( "cache" ) {
111
+ use std:: { collections:: hash_map:: DefaultHasher , hash:: * } ;
112
+ // Build OpenBLAS on user's data directory.
113
+ // See https://docs.rs/dirs/3.0.1/dirs/fn.data_dir.html
114
+ //
115
+ // On Linux, `data_dir` returns `$XDG_DATA_HOME` or `$HOME/.local/share`.
116
+ // This build script creates a directory based on the hash value of `cfg`,
117
+ // i.e. `$XDG_DATA_HOME/openblas_build/[Hash of cfg]`, and build OpenBLAS there.
118
+ //
119
+ // This build will be shared among several projects using openblas-src crate.
120
+ // It makes users not to build OpenBLAS in every `cargo build`.
121
+ let mut hasher = DefaultHasher :: new ( ) ;
122
+ cfg. hash ( & mut hasher) ;
123
+ let output = dirs:: data_dir ( )
124
+ . expect ( "Cannot get user's data directory" )
125
+ . join ( "openblas_build" )
126
+ . join ( format ! ( "{:x}" , hasher. finish( ) ) ) ;
127
+ output
128
+ } else {
129
+ PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) )
130
+ } ;
131
+
132
+ // If OpenBLAS is build as shared, user of openblas-src will have to find `libopenblas.so` at runtime.
133
+ //
134
+ // `cargo run` appends the link paths to `LD_LIBRARY_PATH` specified by `cargo:rustc-link-search`,
135
+ // and user's crate can find it then.
136
+ //
137
+ // However, when user try to run it directly like `./target/release/user_crate_exe`, it will say
138
+ // "error while loading shared libraries: libopenblas.so: cannot open shared object file: No such file or directory".
139
+ //
140
+ // Be sure that `cargo:warning` is shown only when openblas-src is build as path dependency...
141
+ // https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargowarningmessage
142
+ if !feature_enabled ( "static" ) {
143
+ println ! (
144
+ "cargo:warning=OpenBLAS is built as a shared library. You need to set LD_LIBRARY_PATH={}" ,
145
+ output. display( )
146
+ ) ;
147
+ }
148
+
110
149
let deliv = cfg. build ( & output) . unwrap ( ) ;
111
150
112
151
for search_path in & deliv. make_conf . c_extra_libs . search_paths {
0 commit comments