У меня есть этот фрагмент кода:
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 */
}
Здесь используется привязка Lapack. Чего я не понимаю, так это того, что если я закомментирую два внешних оператора, я получу ошибку компоновщика, где dsteqr
не найден. Я хотел бы понять, почему это происходит.
Компилятор не будет связывать зависимость, если считает, что она не используется.
В книге Rusc о параметре --extern (именно так Cargo предоставляет зависимости):
Указание
--extern
имеет одно отличие в поведении отextern crate
:--extern
просто делает ящик кандидатом на привязку; на самом деле он не связывает его, если он не используется активно. В редких случаях вам может потребоваться обеспечить связь с крейтом, даже если вы не используете его активно из своего кода: например, если он меняет глобальный распределитель или содержит символы#[no_mangle]
для использования другими языками программирования. В таких случаях вам нужно использоватьextern crate
.
Таким образом, добавление extern crate openblas_src;
гарантирует, что он будет связан с системной библиотекой openblas
.
Однако обычно это не проблема, о которой вам стоит беспокоиться. Если вы добавляете зависимость груза и просто не используете ее, вероятно, лучше, чтобы она не требовала этой связи во время выполнения. И даже если вы не используете крейт -sys
напрямую, использование крейта, который сам зависит от него и использует его, будет считаться «использованным» и автоматически связываться.
Встреча с этой ошибкой довольно уникальна для blas/lapack, поскольку существуют конкурирующие системные библиотеки (accelerate, blis, intel-mkl, netlib, openblas), которые обеспечивают функциональность, на которую полагаются библиотеки более высокого уровня. Крейты blas
/lapack
опираются на свои аналоги -sys
, но это всего лишь объявления функций и в них отсутствуют ссылки= на конкретную системную библиотеку. Таким образом, они просто полагаются на глобальные символы, чтобы связать их во время компоновки, что, как указано выше, не будет гарантировано, если extern crate
не будет добавлен конечным пользователем для одного из -src
ящиков реализации. Немного дополнительной информации на их blas-lapack-rs вики.
@eggyal очень признателен! Я включил это в ответ
пожалуйста, включите зависимости Cargo.toml и покажите ошибку компоновщика