I have this code snippet:
extern crate blas;
extern crate openblas_src;
pub fn eigen_decompose_symmetric_tri_diagonal(
main_diag: &Vec<f64>,
sub_diag: &Vec<f64>,
)
{
/* code */
lapack::dsteqr(/* args */);
/* code */
}
That uses a lapack binding. What I don't understand is, if I comment out the two extern statements I get a linker error where dsteqr
is not found. I would like to understand why this happens.
The compiler will not end up linking a dependency if it thinks it is unused.
In the rustc book on the --extern
parameter (which is how Cargo provides dependencies):
Specifying
--extern
has one behavior difference fromextern crate
:--extern
merely makes the crate a candidate for being linked; it does not actually link it unless it's actively used. In rare occasions you may wish to ensure a crate is linked even if you don't actively use it from your code: for example, if it changes the global allocator or if it contains#[no_mangle]
symbols for use by other programming languages. In such cases you'll need to useextern crate
.
So adding extern crate openblas_src;
ensures it will link to the openblas
system library.
This isn't normally a problem that you need to worry about though. If you add a cargo dependency and simply don't use it its probably best that it doesn't require that runtime linkage. And even if you don't directly use a -sys
crate, using a crate that itself depends on and uses it will consider it "used" and automatically be linked.
Encountering this error is fairly unique to blas/lapack because there are competing system libraries (accelerate, blis, intel-mkl, netlib, openblas) that provide the functionality that the higher-level libraries rely on. The blas
/lapack
crates rely on their -sys
counterparts, but those are only function declarations and are lacking links=
to a particular system library. Thus they simply rely on global symbols to tie them at link-time, which as indicated above, won't be guaranteed unless extern crate
is added by the end-user for one of the -src
implementation crates. A bit more info on their blas-lapack-rs wiki.