1
1
import os
2
- import sys
3
2
from pathlib import Path
4
- from typing import Any , Dict , List
3
+ from typing import Any , List , Tuple
5
4
6
- import setuptools
7
- from setuptools import Extension , find_packages , setup
8
- from setuptools .command .build_ext import build_ext
5
+ from pybind11 .setup_helpers import Pybind11Extension , build_ext
6
+ from setuptools import find_packages , setup
9
7
10
8
SETUP_DIRECTORY = Path (__file__ ).resolve ().parent
11
9
25
23
],
26
24
)
27
25
28
- setup_requires = ["pybind11>=2.4" , "requests" , "setuptools_scm" ]
29
- IRSPACK_TESTING = os .environ .get ("IRSPACK_TESTING" , None ) is not None
30
-
31
26
32
27
class get_eigen_include (object ):
33
28
EIGEN3_URL = "https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.zip"
@@ -59,141 +54,18 @@ def __str__(self) -> str:
59
54
return target_dir .name
60
55
61
56
62
- class get_pybind_include (object ):
63
- """Helper class to determine the pybind11 include path
64
- The purpose of this class is to postpone importing pybind11
65
- until it is actually installed, so that the ``get_include()``
66
- method can be invoked."""
67
-
68
- def __init__ (self , user : Any = False ):
69
- self .user = user
70
-
71
- def __str__ (self ) -> Any :
72
- import pybind11
73
-
74
- return pybind11 .get_include (self .user )
75
-
76
-
57
+ module_name_and_sources : List [Tuple [str , List [str ]]] = [
58
+ ("irspack.evaluator._core" , ["cpp_source/evaluator.cpp" ]),
59
+ ("irspack.recommenders._ials" , ["cpp_source/als/wrapper.cpp" ]),
60
+ ("irspack.recommenders._knn" , ["cpp_source/knn/wrapper.cpp" ]),
61
+ ("irspack.utils._util_cpp" , ["cpp_source/util.cpp" ]),
62
+ ]
77
63
ext_modules = [
78
- Extension (
79
- "irspack.evaluator._core" ,
80
- ["cpp_source/evaluator.cpp" ],
81
- include_dirs = [
82
- get_pybind_include (),
83
- get_pybind_include (user = True ),
84
- get_eigen_include (),
85
- ],
86
- language = "c++" ,
87
- ),
88
- Extension (
89
- "irspack.recommenders._ials" ,
90
- ["cpp_source/als/wrapper.cpp" ],
91
- include_dirs = [
92
- # Path to pybind11 headers
93
- get_pybind_include (),
94
- get_pybind_include (user = True ),
95
- get_eigen_include (),
96
- ],
97
- language = "c++" ,
98
- ),
99
- Extension (
100
- "irspack.recommenders._knn" ,
101
- ["cpp_source/knn/wrapper.cpp" ],
102
- include_dirs = [
103
- # Path to pybind11 headers
104
- get_pybind_include (),
105
- get_pybind_include (user = True ),
106
- get_eigen_include (),
107
- ],
108
- language = "c++" ,
109
- ),
110
- Extension (
111
- "irspack.utils._util_cpp" ,
112
- ["cpp_source/util.cpp" ],
113
- include_dirs = [
114
- get_pybind_include (),
115
- get_pybind_include (user = True ),
116
- get_eigen_include (),
117
- ],
118
- language = "c++" ,
119
- ),
64
+ Pybind11Extension (module_name , sources , include_dirs = [get_eigen_include ()])
65
+ for module_name , sources in module_name_and_sources
120
66
]
121
67
122
68
123
- # As of Python 3.6, CCompiler has a `has_flag` method.
124
- # cf http://bugs.python.org/issue26689
125
- def has_flag (compiler : Any , flagname : Any ) -> bool :
126
- """Return a boolean indicating whether a flag name is supported on
127
- the specified compiler.
128
- """
129
- import tempfile
130
-
131
- with tempfile .NamedTemporaryFile ("w" , suffix = ".cpp" ) as f :
132
- f .write ("int main (int argc, char **argv) { return 0; }" )
133
- try :
134
- compiler .compile ([f .name ], extra_postargs = [flagname ])
135
- except setuptools .distutils .errors .CompileError :
136
- return False
137
- return True
138
-
139
-
140
- def cpp_flag (compiler : Any ) -> str :
141
- """Return the -std=c++[11/14/17] compiler flag.
142
- The newer version is prefered over c++11 (when it is available).
143
- """
144
- flags = ["-std=c++11" ]
145
-
146
- for flag in flags :
147
- if has_flag (compiler , flag ):
148
- return flag
149
-
150
- raise RuntimeError ("Unsupported compiler -- at least C++11 support " "is needed!" )
151
-
152
-
153
- class BuildExt (build_ext ):
154
- """A custom build extension for adding compiler-specific options."""
155
-
156
- if IRSPACK_TESTING :
157
- c_opts : Dict [str , List [str ]] = {
158
- "msvc" : ["/EHsc" ],
159
- "unix" : ["-O0" , "-coverage" , "-g" ],
160
- }
161
- l_opts : Dict [str , List [str ]] = {
162
- "msvc" : [],
163
- "unix" : ["-coverage" ],
164
- }
165
- else :
166
- c_opts = {
167
- "msvc" : ["/EHsc" ],
168
- "unix" : [],
169
- }
170
- l_opts = {
171
- "msvc" : [],
172
- "unix" : [],
173
- }
174
-
175
- if sys .platform == "darwin" :
176
- darwin_opts = ["-stdlib=libc++" , "-mmacosx-version-min=10.7" ]
177
- c_opts ["unix" ] += darwin_opts
178
- l_opts ["unix" ] += darwin_opts
179
-
180
- def build_extensions (self ) -> None :
181
- ct = self .compiler .compiler_type
182
- opts = self .c_opts .get (ct , [])
183
- link_opts = self .l_opts .get (ct , [])
184
- if ct == "unix" :
185
- opts .append ('-DVERSION_INFO="%s"' % self .distribution .get_version ())
186
- opts .append (cpp_flag (self .compiler ))
187
- if has_flag (self .compiler , "-fvisibility=hidden" ):
188
- opts .append ("-fvisibility=hidden" )
189
- elif ct == "msvc" :
190
- opts .append ('/DVERSION_INFO=\\ "%s\\ "' % self .distribution .get_version ())
191
- for ext in self .extensions :
192
- ext .extra_compile_args = opts
193
- ext .extra_link_args = link_opts
194
- build_ext .build_extensions (self )
195
-
196
-
197
69
def local_scheme (version : Any ) -> str :
198
70
return ""
199
71
@@ -213,8 +85,7 @@ def local_scheme(version: Any) -> str:
213
85
ext_modules = ext_modules ,
214
86
install_requires = install_requires ,
215
87
include_package_data = True ,
216
- setup_requires = setup_requires ,
217
- cmdclass = {"build_ext" : BuildExt },
88
+ cmdclass = {"build_ext" : build_ext },
218
89
packages = find_packages (),
219
90
python_requires = ">=3.6" ,
220
91
)
0 commit comments