Windows下Ipopt优化库安装
1. 类UNIX环境 MSYS2 / MINGW 安装
注意!!!
以下编译 HSL 时出现的问题都是由于运行的是 msys2.exe
这个终端,包括找不到 gcc
编译器等原因。实际应该使用 mingw64.exe
终端!
- 安装其他软件包:
pacman --disable-download-timeout -S binutils diffutils git grep make patch pkg-config
Note: 这里在安装时可能有些包提示签名未授权,类似这样的提示
error: gcc-libs: signature from “David Macek [email protected]” is unknown trust
这里需要更新一下 Key 就行:
pacman-key --keyserver keyserver.ubuntu.com --refresh-keys
- 使用 GNU 编译器
pacman --disable-download-timeout -S mingw-w64-x86_64-gcc mingw-w64-x86_64-gcc-fortran
- 使用 MINGW 时,可以安装对应的 Lapack
pacman -S mingw-w64-x86_64-lapack
2. 安装 Ipopt 的依赖库
- OpenBLAS 直接从 github 的网站上下载二进制文件包即可。 对于linux,直接使用apt-get安装。
sudo apt-get install libopenblas-dev
-
LAPACK 已经在前面安装 MinGW 时安装了。
-
HSL 这里使用的是个人免费版本,然后需要在 Msys 中使用源码编译。 需要注意的点包括:
- Windows 下的路径表示与 Unix 下的表示不同,因此需要进行转换,官方提供了转换工具
cygpath
,使用示例:
$ cygpath - u "D:\ipoptProject\ThirdParty-HSL" - u /d/ipoptProject/ThirdParty-HSL $ cd /d/ipoptProject/ThirdParty-HSL
- 若编译时提示找不到 gcc 编译器,但是在 mingw64/bin 中存在编译器,则检查路径是否包括编译器:
$ $PATH #若不包括路径,则添加上去 $ PATH=$PATH:/mingw64/bin
- Windows 下的路径表示与 Unix 下的表示不同,因此需要进行转换,官方提供了转换工具
3. 编译测试文件
这是 example/examples/hs071_cpp 中 makefile 的编译顺序,在终端中按照如此方式进行可正常编译。这里使用的是包管理器 pkg-config
去处理需要添加的库路径与库文件。
1. g++ -O2 -DNDEBUG `PKG_CONFIG_PATH=/mingw64/lib/pkgconfig:/mingw64/lib/pkgconfig:/mingw64/share/pkgconfig pkg-config --cflags ipopt` -c -o hs071_main.o hs071_main.cpp
2. g++ -O2 -DNDEBUG `PKG_CONFIG_PATH=/mingw64/lib/pkgconfig:/mingw64/lib/pkgconfig:/mingw64/share/pkgconfig pkg-config --cflags ipopt` -c -o hs071_nlp.o hs071_nlp.cpp
3. g++ -O2 -DNDEBUG -o hs071_cpp.exe hs071_main.o hs071_nlp.o `PKG_CONFIG_PATH=/mingw64/lib/pkgconfig:/mingw64/lib/pkgconfig:/mingw64/share/pkgconfig pkg-config --libs ipopt`
其中 pkg-config --cflags --libs ipopt
命令实际是找到 ipopt
库中头文件,库文件所在目录,以及要链接的必要库名称:
$ PKG_CONFIG_PATH=/mingw64/lib/pkgconfig:/mingw64/lib/pkgconfig:/mingw64/share/pkgconfig pkg-config --cflags --libs ipopt
-I/mingw64/include/coin-or -I/mingw64/include/coin-or/hsl -I/mingw64/include/coin-or/mumps -L/mingw64/lib -lipopt -lcoinhsl -lcoinmumps -llapack -lblas
但是我想直接使用 -o
命令生成可执行文件,不需要产生中间文件,于是做了以下尝试:
g++ hs071_nlp.cpp hs071_main.cpp -o main.exe -I. 'PKG_CONFIG_PATH=/mingw64/lib/pkgconfig:/mingw64/lib/pkgconfig:/mingw64/share/pkgconfig pkg-config --cflags --libs ipopt'
却会报错如下:
In file included from hs071_nlp.cpp:7:
hs071_nlp.hpp:10:10: fatal error: IpTNLP.hpp: No such file or directory
10 | #include "IpTNLP.hpp"
| ^~~~~~~~~~~~
compilation terminated.
hs071_main.cpp:8:10: fatal error: IpIpoptApplication.hpp: No such file or directory
8 | #include "IpIpoptApplication.hpp"
| ^~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
然后就折腾了一整天,按理来说应该是没有问题的,直到我写这个文档时,才发现了这个问题,原来 PKG_CONFIG_PATH=…ipopt 这段配置语句是用 ` ` 括起来的,而不是单引号 ’ ’ 。所以正确的语句应该是
g++ hs071_nlp.cpp hs071_main.cpp -o main.exe -I. `PKG_CONFIG_PATH=/mingw64/lib/pkgconfig:/mingw64/lib/pkgconfig:/mingw64/share/pkgconfig pkg-config --cflags --libs ipopt`