Skip to content

Commit a88c321

Browse files
authored
Try using Conda-Forge's IPOPT Windows build. (#78)
- Appveyor CI now uses the official 3.13.3 binaries. - Appveyor CI now uses Conda Forge's ipopt for Python 3 builds - IPOPTWINDIR="USECONDAFORGEIPOPT" environment variable required to build against the Conda Forge ipopt binaries.
1 parent ada3198 commit a88c321

File tree

5 files changed

+120
-18
lines changed

5 files changed

+120
-18
lines changed

.travis.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ before_install:
1919
- conda config --add channels conda-forge
2020
- conda update -q conda
2121
install:
22-
- conda create -q -n test-env python=$TRAVIS_PYTHON_VERSION lapack numpy cython ipopt future six setuptools sphinx numpydoc pkg-config
22+
# NOTE : conda-forge removed the .pc files for blas, cblas, lapack, and
23+
# lapacke inadvertently. Setting lapack < 3.9.0 ensures the .pc files are
24+
# available. See this issue:
25+
# https://github.com/conda-forge/blas-feedstock/issues/58
26+
- conda create -q -n test-env python=$TRAVIS_PYTHON_VERSION "lapack<3.9.0" numpy cython ipopt future six setuptools sphinx numpydoc pkg-config
2327
- conda activate test-env
2428
before_script:
2529
- conda info

CHANGELOG

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
0.3.0dev0
22
=========
3+
4+
- Added support for Conda Forge Windows Ipopt >=3.13 binaries using the
5+
IPOPTWINDIR="USECONDAFORGEIPOPT" environment variable value.
6+
(https://github.com/matthias-k/cyipopt/pull/78)
37
- Added support for Ipopt >=3.13 on Windows.
48
(https://github.com/matthias-k/cyipopt/pull/63)
59

README.rst

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,16 +124,28 @@ https://github.com/matthias-k/cyipopt/issues/52).
124124

125125
Download and extract the cyipopt source code from Github or PyPi.
126126

127+
Obtain IPOPT one of two ways:
128+
129+
1. Using official IPOPTs binaries:
130+
127131
Download the latest precompiled version of Ipopt that includes the DLL files from
128132
https://github.com/coin-or/Ipopt/releases. Note that the current setup only
129-
supports Ipopt >= 3.13.0. The build 3.13.2 of Ipopt has been confirmed to work and
130-
can be downloaded from `Ipopt-3.13.2-win64-msvs2019-md.zip
131-
<https://github.com/coin-or/Ipopt/releases/download/releases%2F3.13.2/Ipopt-3.13.2-win64-msvs2019-md.zip>`_
133+
supports Ipopt >= 3.13.0. The build 3.13.3 of Ipopt has been confirmed to work and
134+
can be downloaded from `Ipopt-3.13.3-win64-msvs2019-md.zip
135+
<https://github.com/coin-or/Ipopt/releases/download/releases%2F3.13.3/Ipopt-3.13.3-win64-msvs2019-md.zip>`_
132136
. After Ipopt is extracted, the ``bin``, ``lib`` and ``include`` folders should
133137
be in the root cyipopt directory, i.e. adjacent to the ``setup.py`` file.
134138
Alternatively, you can set the environment variable ``IPOPTWINDIR`` to point to
135139
the Ipopt directory that contains the ``bin``, ``lib`` and ``include`` directories.
136140

141+
2. Using Conda Forge's IPOPT binary:
142+
143+
If using conda, you can install an IPOPT binary from Conda Forge::
144+
145+
conda.exe install -c conda-forge ipopt
146+
147+
The environment variable ``IPOPTWINDIR`` should then be set to ``USECONDAFORGEIPOPT``.
148+
137149
Finally, execute::
138150

139151
python setup.py install

appveyor.yml

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,45 @@
11
environment:
22

3-
global:
4-
IPOPTWINDIR: "C:\\projects\\cyipopt\\Ipopt-3.13.2-win64-msvs2019-md"
5-
3+
# NOTE : There is no conda-forge ipopt build for Python 2.7, so we use the
4+
# official IPOPT binaries. Python 3 is tested with conda-forge's ipopt, but
5+
# we also test at least the latest Python with the official ipopt binaries
6+
# too.
67
matrix:
78
- PYTHON: "C:\\Miniconda-x64"
89
PYTHON_VERSION: "2.7"
910
PYTHON_ARCH: "64"
1011
CONDA_PY: "27"
12+
IPOPT: ""
13+
IPOPTWINDIR: "C:\\projects\\cyipopt\\Ipopt-3.13.3-win64-msvs2019-md"
1114

1215
- PYTHON: "C:\\Miniconda36-x64"
1316
PYTHON_VERSION: "3.6"
1417
PYTHON_ARCH: "64"
1518
CONDA_PY: "36"
19+
IPOPT: "ipopt "
20+
IPOPTWINDIR: "USECONDAFORGEIPOPT"
1621

1722
- PYTHON: "C:\\Miniconda37-x64"
1823
PYTHON_VERSION: "3.7"
1924
PYTHON_ARCH: "64"
2025
CONDA_PY: "37"
26+
IPOPT: "ipopt "
27+
IPOPTWINDIR: "USECONDAFORGEIPOPT"
2128

2229
# There is not Miniconda38 on appveyor yet.
2330
- PYTHON: "C:\\Miniconda37-x64"
2431
PYTHON_VERSION: "3.8"
2532
PYTHON_ARCH: "64"
2633
CONDA_PY: "38"
34+
IPOPT: "ipopt "
35+
IPOPTWINDIR: "USECONDAFORGEIPOPT"
36+
37+
- PYTHON: "C:\\Miniconda37-x64"
38+
PYTHON_VERSION: "3.8"
39+
PYTHON_ARCH: "64"
40+
CONDA_PY: "38"
41+
IPOPT: ""
42+
IPOPTWINDIR: "C:\\projects\\cyipopt\\Ipopt-3.13.3-win64-msvs2019-md"
2743

2844
install:
2945
- ECHO "Filesystem root:"
@@ -38,15 +54,18 @@ install:
3854
- "%PYTHON%\\Scripts\\conda.exe update --yes conda"
3955
- "%PYTHON%\\Scripts\\conda.exe update --yes --all"
4056
- "%PYTHON%\\Scripts\\conda.exe config --prepend channels conda-forge"
41-
- "%PYTHON%\\Scripts\\conda.exe install --yes python=%PYTHON_VERSION% numpy cython future six setuptools sphinx numpydoc"
57+
- "%PYTHON%\\Scripts\\conda.exe install --yes python=%PYTHON_VERSION% numpy cython %IPOPT%future six setuptools sphinx numpydoc"
4258
- "%PYTHON%\\Scripts\\conda.exe update -y --all"
4359
- "%PYTHON%\\Scripts\\conda.exe info"
4460
- "%PYTHON%\\Scripts\\conda.exe list"
4561

4662
# This downloads and extracts a precomplied IPOPT for Windows.
47-
- ps: Start-FileDownload 'https://github.com/coin-or/Ipopt/releases/download/releases%2F3.13.2/Ipopt-3.13.2-win64-msvs2019-md.zip'
48-
- 7z x Ipopt-3.13.2-win64-msvs2019-md.zip
49-
- ps: "ls"
63+
- ps: >-
64+
if(!($env:IPOPT -eq "ipopt ")){
65+
Start-FileDownload 'https://github.com/coin-or/Ipopt/releases/download/releases%2F3.13.3/Ipopt-3.13.3-win64-msvs2019-md.zip'
66+
7z x Ipopt-3.13.3-win64-msvs2019-md.zip
67+
ls
68+
}
5069
5170
# Prepend newly installed Python to the PATH of this build (this cannot be
5271
# done from inside the powershell script as it would require to restart the

setup.py

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,47 @@
4545

4646

4747
def pkgconfig(*packages, **kw):
48-
"""Based on http://code.activestate.com/recipes/502261-python-distutils-pkg-config/#c2"""
49-
48+
"""Returns a dictionary containing the include and library flags to pass to
49+
a Python extension that depends on the provided packages.
50+
51+
Parameters
52+
==========
53+
*packages : one or more strings
54+
These are the names of ``.pc`` files that pkg-config can locate, for
55+
example ``ipopt`` for the ``ipopt.pc`` file.
56+
**kw : list of strings
57+
Any values that should be preset in the returned dictionary. These can
58+
include lists of items for: ``include_dirs``, ``library_dirs``,
59+
``libraries``, ``extra_compile_args``.
60+
61+
Returns
62+
=======
63+
kw : dictionary
64+
Dictionary containing the keys: ``include_dirs``, ``library_dirs``,
65+
``libraries``, ``extra_compile_args`` that are mapped to lists of
66+
strings.
67+
68+
Notes
69+
=====
70+
71+
This function is based on:
72+
73+
http://code.activestate.com/recipes/502261-python-distutils-pkg-config/#c2
74+
75+
"""
5076
flag_map = {'-I': 'include_dirs', '-L': 'library_dirs', '-l': 'libraries'}
5177
output = sp.Popen(["pkg-config", "--libs", "--cflags"] + list(packages),
5278
stdout=sp.PIPE).communicate()[0]
5379

54-
if not output: # output will be an empty string if pkg-config finds nothing
80+
if not output: # output will be empty string if pkg-config finds nothing
5581
msg = ('pkg-config was not able to find any of the requested packages '
5682
'{} on your system. Make sure pkg-config can discover the .pc '
5783
'files associated with the installed packages.')
5884
raise OSError(msg.format(list(packages)))
5985

6086
if six.PY3:
6187
output = output.decode('utf8')
88+
6289
for token in output.split():
6390
if token[:2] in flag_map:
6491
kw.setdefault(flag_map.get(token[:2]), []).append(token[2:])
@@ -72,16 +99,52 @@ def pkgconfig(*packages, **kw):
7299

73100
if __name__ == '__main__':
74101

75-
if sys.platform == 'win32':
102+
ipoptdir = os.environ.get('IPOPTWINDIR', '')
103+
104+
# conda forge hosts a windows version of ipopt for ipopt versions >= 3.13.
105+
# The location of the headers and binaries are in $CONDA_PREFIX/Library/
106+
# and the library binary is named "libipopt.lib". If the IPOPTWINDIR
107+
# environment variable is set to USECONDAFORGEIPOPT then this setup will be
108+
# run.
109+
if sys.platform == 'win32' and ipoptdir == "USECONDAFORGEIPOPT":
76110

77-
ipoptdir = os.environ.get('IPOPTWINDIR', '')
111+
conda_prefix = os.path.split(sys.executable)[0]
112+
113+
IPOPT_INCLUDE_DIRS = [os.path.join(conda_prefix, 'Library', 'include',
114+
'coin-or'), np.get_include()]
115+
IPOPT_LIBS = ['libipopt']
116+
IPOPT_LIB_DIRS = [os.path.join(conda_prefix, 'Library', 'lib')]
117+
118+
EXT_MODULES = [
119+
Extension(
120+
"cyipopt", ['src/cyipopt.pyx'],
121+
include_dirs=IPOPT_INCLUDE_DIRS,
122+
libraries=IPOPT_LIBS,
123+
library_dirs=IPOPT_LIB_DIRS
124+
)
125+
]
126+
DATA_FILES = None
127+
include_package_data = True
128+
129+
elif sys.platform == 'win32' and ipoptdir:
78130

79131
IPOPT_INCLUDE_DIRS = [os.path.join(ipoptdir, 'include', 'coin-or'),
80132
np.get_include()]
133+
134+
# These are the specific binaries in the IPOPT 3.13.2 binary download:
135+
# https://github.com/coin-or/Ipopt/releases/download/releases%2F3.13.2/Ipopt-3.13.2-win64-msvs2019-md.zip
81136
IPOPT_LIBS = ['ipopt.dll', 'ipoptamplinterface.dll']
82137
IPOPT_LIB_DIRS = [os.path.join(ipoptdir, 'lib')]
83-
IPOPT_DLL = ['ipopt-3.dll', 'ipoptamplinterface-3.dll', 'libifcoremd.dll',
84-
'libmmd.dll', 'msvcp140.dll', 'svml_dispmd.dll', 'vcruntime140.dll']
138+
139+
IPOPT_DLL = [
140+
'ipopt-3.dll',
141+
'ipoptamplinterface-3.dll',
142+
'libifcoremd.dll',
143+
'libmmd.dll',
144+
'msvcp140.dll',
145+
'svml_dispmd.dll',
146+
'vcruntime140.dll',
147+
]
85148
IPOPT_DLL_DIRS = [os.path.join(ipoptdir, 'bin')]
86149

87150
EXT_MODULES = [

0 commit comments

Comments
 (0)