VS2017编译OpenBLAS后链接项目出现LNK2019错误求助
解决OpenBLAS自编译后VS2017链接LNK2019未解析外部符号问题
这问题我之前帮人排查过好几次,核心原因是Fortran函数的符号命名规则不匹配——你自己编译的OpenBLAS和预编译版本的符号导出格式不一样,导致VS的C/C++代码找不到对应的函数。结合你的场景,给你一步步的解决方案:
1. 先确认编译OpenBLAS的核心配置是否正确
- 首先保证架构一致:你的项目是32位还是64位?编译OpenBLAS时一定要用对应的CMake选项(比如64位要加
BUILD_WIN64=ON),预编译版本如果是64位,你自己编译成32位肯定会出符号找不到的问题。 - 检查是否开启了LAPACK模块:你报错的这些函数(
spotrf_、dsyevd_等)都是LAPACK里的,编译OpenBLAS时要确保CMake配置里BUILD_LAPACK=ON(OpenBLAS默认是开启的,但最好重新确认)。 - 确认生成的是MSVC兼容的导入库:你提到替换了
libopenblas.dll.a为openblas.lib,要注意这个openblas.lib必须是CMake编译时生成的MSVC格式导入库,不是手动改文件名的MinGW格式文件——MinGW的.dll.a和MSVC的.lib格式完全不同,强行替换肯定链接失败。
2. 用VS工具验证库中的符号是否存在
打开VS2017的开发者命令提示符,进入你编译的OpenBLAS的lib目录,执行以下命令检查目标符号:
dumpbin /symbols openblas.lib | findstr "spotrf_"
如果返回结果里找不到spotrf_这类符号,说明编译OpenBLAS时根本没生成这些函数,需要重新配置CMake:
- 删掉之前的build目录,重新运行CMake-GUI,选择VS2017的编译器;
- 勾选
BUILD_LAPACK、BUILD_SHARED_LIBS(如果你用动态库); - 点击
Configure和Generate后,重新编译OpenBLAS。
3. 调整VS项目的链接设置
- 打开项目属性,进入链接器->常规,确保附加库目录指向你自己编译的OpenBLAS的lib目录,而不是预编译版本的路径;
- 进入链接器->输入,附加依赖项里只留
openblas.lib,不要混着加其他OpenBLAS相关的库; - 如果是动态库,还要把编译生成的
openblas.dll放到项目的输出目录里,运行时才能找到。
4. 确保C/C++代码的函数声明正确
如果你是手动声明Fortran函数,一定要用extern "C"包裹,并且匹配符号的命名规则(小写加下划线后缀):
extern "C" { // 示例:spotrf_的声明,注意参数都是指针 void spotrf_(char* uplo, int* n, float* a, int* lda, int* info); void dpotrf_(char* uplo, int* n, double* a, int* lda, int* info); // 其他报错的函数同理补充 }
更推荐的方式是直接包含OpenBLAS编译生成的cblas.h或lapacke.h头文件,这些头文件已经帮你做好了正确的函数声明,避免手动写错。
5. 编译器兼容性排查
如果用的是GFortran编译OpenBLAS,要注意它和MSVC的符号兼容性:
- 在CMake配置时,可以尝试添加Fortran编译选项
-fno-second-underscore,避免生成双下划线的符号; - 或者换成Intel Fortran Compiler(集成在VS2017里)来编译OpenBLAS,这样生成的库和MSVC的C/C++代码兼容性更好,符号命名规则也更匹配。
内容的提问来源于stack exchange,提问作者Emile D.
相关产品推荐
相关产品推荐

