VS新版本编译levmar库遇LNK2019错误,求简化构建方案
我来帮你梳理下遇到的问题和可行的解决思路:
首先得明确核心原因:哪怕只调用dlevmar_der,也绕不开LAPACK/BLAS依赖——Levmar的非线性最小二乘算法(包括带导数的dlevmar_der)底层依赖QR分解、线性方程组求解等数值计算操作,这些都是通过LAPACK/BLAS实现的。但我们完全可以用更简便的方式处理这些依赖,不用手动折腾旧版Makefile和复杂的路径配置。
问题1:有没有更简便的Levmar库构建与代码运行方式?
当然有,推荐几种适配VS新版本的方案:
1. 使用vcpkg包管理器(最省心)
vcpkg已经预编译了适配不同VS版本的Levmar库,并且会自动处理所有依赖(包括LAPACK/BLAS):
- 先安装vcpkg,然后在命令行执行:
vcpkg install levmar:x64-windows # 按需换成x86-windows对应32位环境 - 执行
vcpkg integrate install把vcpkg集成到VS中,之后新建或打开你的C++工程,直接包含Levmar的头文件levmar.h调用dlevmar_der即可——头文件路径、库文件链接都会自动配置,完全不用手动处理LAPACK等依赖。
2. 用CMake生成VS工程(灵活可控)
Levmar源码自带CMakeLists.txt,可以用CMake直接生成适配VS2019的工程:
- 下载Levmar源码,打开CMake-GUI,指定源码目录和构建输出目录;
- 选择VS2019作为生成器(比如
Visual Studio 16 2019),点击Configure; - CMake会自动查找系统中的LAPACK/BLAS库,如果找不到,也可以通过配置选项指定预编译的库路径,或者让CMake自动下载依赖;
- 配置完成后点击Generate,生成VS工程,打开工程编译即可得到适配VS2019的Levmar库,之后在你的项目里链接这个库就行。
3. 抽取核心代码(轻量化可选)
如果你的需求真的只用到dlevmar_der的核心逻辑,可以尝试从Levmar源码中抽取dlevmar_der及其直接依赖的模块(比如相关的优化迭代代码、线性求解模块),自己编译成一个小型库。不过这个方法需要你对Levmar的源码结构有一定了解,适合追求极小体积的场景,一般不推荐。
问题2:是否必须使用MakeFile并配置所有依赖库的路径?
完全不需要。旧的Makefile.vc是针对VS2012这类旧版本设计的,和新版本VS的工具链兼容性不好,这也是你出现LNK2019错误的核心原因。你可以选择这些替代方式:
- 用上面提到的vcpkg或CMake,完全不用手动写Makefile,依赖配置全自动化;
- 手动在VS工程中配置:把Levmar的源文件添加到你的VS项目中,然后在项目属性里:
- 把LAPACK/BLAS的头文件路径添加到
C/C++ -> 常规 -> 附加包含目录; - 把LAPACK/BLAS的库文件路径添加到
链接器 -> 常规 -> 附加库目录; - 在
链接器 -> 输入 -> 附加依赖项中添加需要的.lib文件(比如clapack.lib、blas.lib等);
这样直接用VS的编译系统就能构建,不用依赖Makefile。
- 把LAPACK/BLAS的头文件路径添加到
另外补充下VS版本兼容的细节:VS2012到VS2019的编译器ABI、标准库实现都有变化,旧Makefile编译的库用的是旧编译器选项,和新版本VS生成的代码链接时就会出现LNK2019这类未解析符号错误,所以用适配新版本的构建方式(vcpkg/CMake)才能从根本上解决这个问题。
内容的提问来源于stack exchange,提问作者Matteo Paggiaro

