我正在尝试让a repository收集我在互联网上找到的C数学和代数库(BLAS,CBLAS,LAPACK,CLAPACK,LAPACKE,ATLAS,openblas,GSL)的所有示例,教程和说明。 ...)。但似乎我无法获得在mac OS X上运行的已编译的BLAS .a文件。
到目前为止,我已经能够编译BLAS并在ubuntu上使用它:
然后我可以使用以下命令在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 ”部分因不同功能而异)
可能性:
P.S。我知道BLAS / LAPACK已经内置到mac OS X Accelerate框架中,我可以使用命令gcc foo.c -lblas
或gcc foo.c -framework Accelerate
轻松编译,但我想使用netlib编译的.a。我想知道为什么它在ubuntu上运行正常而不是mac OS X?
P.S.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)解决方案:
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!
答案 0 :(得分:0)
似乎你用Netlib编译了BLAS库,编译器选项改变了Fortran例程的修改方案。
默认情况下,Netlib的make.inc
使用gfortran
来编译BLAS:
$ grep FORTRAN make.inc
# Modify the FORTRAN and OPTS definitions to refer to the
FORTRAN = gfortran
它是在没有任何标志的情况下编译的:
gfortran -O3 -pipe -c ddot.f -o ddot.o
你得到了ddot()
例程:
$ grep -i ddot ddot.o libblas.a
Binary file ddot.o matches
Binary file libblas.a matches
您可以使用命令行工具找到它:
$ nm ddot.o libblas.a | grep -i ddot
ddot.o:
0000000000000000 T _ddot_
libblas.a(ddot.o):
0000000000000000 T _ddot_
您的示例使用库进行编译:
cc ex.c libblas.a
或使用ddot.o
文件:
cc -pipe ex.c ddot.o
我无法重现你的问题。您应该使用nm
和grep
命令来查明ddot()
例程名称的变化。
PS。在;
的定义结束后,您的代码会有额外的分号main()
。