4545
4646
4747def 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
73100if __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