一个问题可能是该-L
选项后面需要一个“目录”名称,因此gcc
(或由 调用的链接器gcc
)被-lgoto2.a
视为目录。编译器不会抱怨不存在的目录;它只是忽略了它们。您希望在哪个目录中找到该库?(为了这个答案的目的,我假设它在/usr/local/lib
.)
另一个问题可能是该库不称为 libgoto2.aa 或 libgoto2.a.so 或类似名称。您通常不会指定.a
后缀。(出于此答案的目的,我假设该库是 libgoto2.a 或 libgoto2.so。)
看来您不需要指定标头的位置;这意味着它们位于一个足够常规的位置,编译器无论如何都会在那里查找。如果这是正确的,那么库也可能位于一个非常传统的位置,并且该-L
选项可能是不必要的。
因此,您也许可以使用:
gcc -Wall -o outputprog main.c -lgoto2
或者您可能需要使用:
gcc -Wall -o outputprog main.c -L/usr/local/lib -lgoto2
在评论中进行了一些广泛的讨论之后,以及库在当前目录中并命名libgoto2.a
并且符号dgemm
仍然丢失的信息之后,我下载了 GotoBLAS2 版本 1.13并尝试在半支持的平台上编译它(MacOS X,可能假装是 Linux,具有 x86_64 架构)。构建并不完全成功 - 一些汇编代码中的问题。但是,在标题中四处寻找,似乎可以解决您的问题:
cblas.h
在此,在许多其他函数定义中,我们发现:
void cblas_dgemm(enum CBLAS_ORDER Order, enum CBLAS_TRANSPOSE TransA,
enum CBLAS_TRANSPOSE TransB, blasint M, blasint N, blasint K,
double alpha, double *A, blasint lda, double *B, blasint ldb,
double beta, double *C, blasint ldc);
标头中的所有函数符号都以 . 为前缀cblas_
。您的代码应该使用:
#include "cblas.h"
您应该使用带有前缀的 Fortran 名称(小写)调用函数cblas_
:
cblas_dgemm(...);
并且要使用的正确链接线是上面列出的第一个选项:
gcc -Wall -o outputprog main.c -lgoto2
在紧要关头,您可以定义宏以将常规(无前缀)名称映射到正确的 C 函数名称,但我不相信这是值得的:
#define DGEMM cblas_dgemm
或(更安全,因为它检查参数列表的长度,但更详细):
#define DGEMM(a,b,c,d,e,f,g,h,i,j,k,l,m,n) cblas_dgemm(a,b,c,d,e,f,g,h,i,j,k,l,m,n)
然后你可以写:
DGEMM(a, ..., n);
并且将调用正确的函数。
对上述部分成功构建的 GotoBLAS2 的实验表明:
cblas.h
不是独立的(与良好的编码标准相反)。
common.h
必须包含在它之前。
common.h
包括许多其他标题:
- 配置文件
- common_x86_64.h
- 参数.h
- common_param.h
- common_interface.h
- common_macro.h
- common_s.h
- common_d.h
- common_q.h
- common_c.h
- common_z.h
- common_x.h
- common_level1.h
- common_level2.h
- common_level3.h
- common_lapack.h
以下代码有可能与完整的库链接:
#include "common.h"
#include "cblas.h"
void check_dgemm(void)
{
double A[33] = { 0.0 };
double B[33] = { 0.0 };
double C[33] = { 0.0 };
cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,
3, 3, 3, 2.0, A, 3, B, 3, 3.0, C, 3);
}
int main(void)
{
check_dgemm();
return 0;
}
(在我公认的损坏的库构建中,投诉从“cblas_dgemm()
找不到”到缺少许多其他功能。这是一个巨大的改进!)