【发布时间】:2016-11-26 20:49:12
【问题描述】:
我正在努力让a repository 收集我可以在互联网上找到的所有示例、教程和说明,用于 C 数学和代数库(BLAS、CBLAS、LAPACK、CLAPACK、LAPACKE、ATLAS、openblas、GSL.. .)。但似乎我无法让编译后的 BLAS .a 文件在 mac OS X 上运行。
到目前为止,我已经能够编译 BLAS 并在 ubuntu 上使用它:
- 从 netlib 网站下载并编译 BLAS 源代码(将 blas_LINUX.a 重命名为 libblas.a)
-
然后我可以在 ubuntu 上使用以下命令编译 C 文件:
gcc foo.c path/to/libblas.a
在我的 mac OS X (EL Capitan) 上,我可以编译 BLAS(将 make.inc 中的 LINUX 更改为 DARWIN),但是当我尝试使用上面的命令编译 C 代码时,出现如下错误:
Undefined symbols for architecture x86_64:
"_ddot_", referenced from:
_main in foo-3a35db.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
("ddot" 部分因功能不同而不同)
可能性:
- 也许我没有在 mac 上正确编译库,并且存在一些我不知道的差异
- mac OS X 的内置 Accelerate 框架搞乱了编译过程
附:我知道 BLAS/LAPACK 已经内置在 mac OS X Accelerate 框架中,我可以使用命令 gcc foo.c -lblas 或 gcc foo.c -framework Accelerate 轻松编译,但我想使用来自 netlib 的已编译 .a。我想知道为什么它在 ubuntu 上可以正常工作,但在 mac OS X 上不行?
附注 2。请注意,我可以在 mac OS X 上成功编译源代码而没有任何错误。我可以使用它!
示例代码:source
#include <stdio.h>
#include <stdlib.h>
double ddot_(const int *N, const double *a, const int *inca, const double *b, const int *incb);
int main(int argc, char **argv) {
double *a = (double *)malloc(3 * sizeof(double));
a[0] = 1.0;
a[1] = 2.0;
a[2] = 3.0;
// on the stack
double b[3] = {4.0, 5.0, 6.0};
int N = 3, one = 1; // one really doesn't look good in C
double dot_product = ddot_(&N, a, &one, b, &one);
printf(" The dot product is: %f \n", dot_product);
return 0;
}
(edit1)解决方案:
- 打开 make.inc
- 将
OPTS = -O3行更改为OPTS = -O3 -pipe -c并制作。
(edit2):更好的解决方案:
自从我问了这个问题后,我意识到我做错了一切。 Netlib BLAS 实际上是 fortran 例程/子例程/函数的集合。源代码中的 Makefile 只为我们提供了一个静态库 libblas.a,它是使用 gfortran 编译的所有 .o 目标文件的集合。当我们想要编译一个想要调用其中一个例程的 C 代码时,我们还需要链接到 gfortran 库 libgfortran.* 所以如果你安装了 gcc(brew install gcc)。查找 libgfrotran* (sudo find / -name "libgfortrn.*"),然后也将您的 gcc 链接到此文件夹。为了方便起见,我在这里放了一个 Makefile:
all:
gcc -c foo.c
gcc -o bar.out foo.o -L path/to/libgfortran.*/ -lgfortran -L path/to/libblas.a -lblas
或者直接使用 gfortran 编译代码:
all:
gcc -c foo.c
gfortran -o bar.out foo.o -L path/to/libblas.a -lblas
或简单地编译:
gcc foo.c bar.out -L path/to/libblas.a -lblas -L path/to/libgfortran.*/ -lgfortran
奇怪的是前一个解决方案是如何/为什么实际起作用的,以及为什么在 ubuntu 上您不必链接到 -lgfortran!
【问题讨论】: