在项目中使用clapack-3.2.1时遭遇未定义引用问题求助
我正尝试使用netlib.org提供的clapack-3.2.1-CMAKE作为某待构建库的依赖,该库明确依赖CLAPACK,但不清楚具体依赖细节。下载并解压压缩包,禁用测试构建后编译得到libf2c.a、libblas.a、liblapack.a。完成库安装和头文件部署后,成功编译了目标库及测试可执行文件,但运行测试程序时出现大量函数未定义引用错误:
cgemm_(char*, char*, long*, long*, long*, complex*, complex*, long*, complex*, long*, complex*, complex*, long*) cgesvd_(char*, char*, long*, long*, complex*, long*, float*, complex*, long*, complex*, long*, complex*, long*, float*, long*) cgesv_(long*, long*, complex*, long*, long*, complex*, long*, long*) cposv_(char*, long*, long*, complex*, long*, complex*, long*, long*) dgemm_(char*, char*, long*, long*, long*, double*, double*, long*, double*, long*, double*, double*, long*) dgesvd_(char*, char*, long*, long*, double*, long*, double*, double*, long*, double*, long*, double*, long*, long*) dgesv_(long*, long*, double*, long*, long*, double*, long*, long*) dposv_(char*, char*, long*, long*, double*, long*, double*, long*, long*) sgemm_(char*, char*, long*, long*, long*, float*, float*, long*, float*, long*, float*, float*, long*) sgesvd_(char*, char*, long*, long*, float*, long*, float*, float*, long*, float*, long*, float*, long*, long*) sgesv_(long*, long*, float*, long*, long*, float*, long*, long*) sposv_(char*, long*, long*, float*, float*, long*, float*, long*, long*) zgemm_(char*, char*, long*, long*, long*, doublecomplex*, doublecomplex*, long*, doublecomplex*, long*, doublecomplex*, doublecomplex*, long*) zgesvd_(char*, char*, long*, long*, doublecomplex*, long*, double*, doublecomplex*, long*, doublecomplex*, long*, doublecomplex*, long*, double*, long*) zgesv_(long*, long*, doublecomplex*, long*, long*, doublecomplex*, long*, long*) zposv_(char*, long*, long*, doublecomplex*, long*, doublecomplex*, long*, long*)
用nm工具检查编译得到的三个库后发现,这些原语对应的符号缺失(仅能找到少量如cgemm_、zposv_等符号)。
我的问题:这些缺失的符号应该从哪里获取?BLAS原语不是应该在libblas.a中实现吗?我虽接触过BLAS原语,但对netlib相关工具并不熟悉。
相关问题:未定义引用cblas_sgemm
解决思路与方案
1. 确认CLAPACK自带BLAS的局限性
你用的clapack-3.2.1-CMAKE默认附带的BLAS是参考级简化实现,仅包含最基础的核心接口,并非全量BLAS库。像sgemm_、dgemm_这类通用矩阵乘接口,以及cgesvd_、dgesv_这类LAPACK高阶接口,可能因为构建配置未启用全量编译而缺失。
2. 重新配置CLAPACK构建参数
重新运行CMake时,调整以下配置:
- 不要过度禁用默认组件,CLAPACK的部分BLAS/LAPACK接口与组件绑定编译
- 检查CMake配置项中是否有
BUILD_FULL_BLAS、BUILD_FULL_LAPACK这类开关,若存在则开启 - 编译时避免添加过度精简的参数,确保所有源文件都被编译
3. 替换为独立全量BLAS库(推荐)
如果CLAPACK自带的BLAS始终无法提供完整符号,可以用第三方优化BLAS库替代:
- 安装OpenBLAS、ATLAS或MKL这类全量BLAS/LAPACK库
- 重新配置CLAPACK的CMake,通过
BLAS_LIBRARIES和LAPACK_LIBRARIES指定外部BLAS库的路径,让CLAPACK链接外部实现而非自带简化版
4. 检查链接顺序
即使库文件完整,错误的链接顺序也会导致符号找不到。链接时遵循依赖逆序原则:
# 示例链接命令:目标库在前,依次是LAPACK、BLAS、f2c gcc test.o -ltarget_lib -llapack -lblas -lf2c -o test
5. 符号接口的区分
你遇到的是带下划线的Fortran风格符号(如sgemm_),而cblas_sgemm是C接口的BLAS符号,两者属于不同的接口规范。如果目标库调用的是Fortran接口的BLAS/LAPACK,必须确保链接的库提供这类带下划线的符号。
内容的提问来源于stack exchange,提问作者einpoklum

