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 的依赖库

ipopt官网

  • OpenBLAS 直接从 github 的网站上下载二进制文件包即可。 对于linux,直接使用apt-get安装。
sudo apt-get install libopenblas-dev
  • LAPACK 已经在前面安装 MinGW 时安装了。

  • HSL 这里使用的是个人免费版本,然后需要在 Msys 中使用源码编译。 需要注意的点包括:

    1. Windows 下的路径表示与 Unix 下的表示不同,因此需要进行转换,官方提供了转换工具 cygpath ,使用示例:
      $ cygpath - u "D:\ipoptProject\ThirdParty-HSL"
      -
      u
      /d/ipoptProject/ThirdParty-HSL
      $ cd /d/ipoptProject/ThirdParty-HSL
    
    1. 若编译时提示找不到 gcc 编译器,但是在 mingw64/bin 中存在编译器,则检查路径是否包括编译器:
    $ $PATH #若不包括路径,则添加上去
    $ PATH=$PATH:/mingw64/bin
    

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`