-
Notifications
You must be signed in to change notification settings - Fork 2
/
setup.py
202 lines (179 loc) · 6.16 KB
/
setup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
import os
import sys
import platform
import shutil
import json
from pathlib import Path
from setuptools import setup, find_packages
from setuptools.command.build_ext import build_ext
from distutils.extension import Extension
from distutils.sysconfig import get_python_inc
from distutils.errors import CCompilerError
from distutils.util import get_platform
USE_CYTHON = True#'--use-cython' in sys.argv
if USE_CYTHON:
# sys.argv.remove('--use-cython')
from Cython.Build import cythonize
from Cython.Compiler import Options
try:
from annotate_index import AnnotateIndex
except (ImportError, SyntaxError):
AnnotateIndex = False
Options.fast_fail = True
USE_PROFILE = '--use-profile' in sys.argv
if USE_PROFILE:
sys.argv.remove('--use-profile')
ANNOTATE = '--annotate' in sys.argv
if ANNOTATE:
sys.argv.remove('--annotate')
else:
USE_PROFILE = False
PROJECT_PATH = Path(__file__).parent
WIN32 = sys.platform == 'win32'
MACOS = sys.platform == 'darwin'
IS_BUILD = True
LIB_DIRS = []
RUNTIME_LIB_DIRS = []
NDI_INCLUDE = PROJECT_PATH / 'src' / 'cyndilib' / 'wrapper' / 'include'
INCLUDE_PATH = [str(NDI_INCLUDE), get_python_inc()]
PACKAGE_DATA = {
'*':[
'LICENSE', 'README*', 'libndi_licenses.txt',
'*.pxd', '*.pyx', '*.c', '*.cpp',
],
'cyndilib.wrapper.include':['*.h'],
'cyndilib.wrapper.bin':['*.txt'],
'cyndilib.wrapper.lib':[],
}
def get_ndi_libdir():
lib_pkg_data = []
bin_pkg_data = []
if WIN32:
p = Path(os.environ.get('PROGRAMFILES'))
sdk_dir = p / 'NDI' / 'NDI 5 SDK'
lib_sys = sdk_dir / 'Lib' / 'x64'
dll_sys = sdk_dir / 'Bin' / 'x64'
lib_dir = PROJECT_PATH / 'src' / 'cyndilib' / 'wrapper' / 'lib'
dll_dir = lib_dir.parent / 'bin'
if not len(list(lib_dir.glob('*.lib'))):
assert lib_sys.exists()
lib_sys = sdk_dir / 'Lib' / 'x64'
dll_sys = sdk_dir / 'Bin' / 'x64'
for src_p, dst_p in zip([lib_sys, dll_sys], [lib_dir, dll_dir]):
for fn in src_p.iterdir():
if not fn.is_file():
continue
dest_fn = dst_p / fn.name
if dest_fn.exists():
continue
shutil.copy2(fn, dest_fn)
LIB_DIRS.extend([str(dll_dir.resolve()), str(lib_dir.resolve())])
bin_pkg_data.append('*.dll')
lib_pkg_data.append('*.lib')
else:
lib_dir = PROJECT_PATH / 'src' / 'cyndilib' / 'wrapper' / 'bin'
if MACOS:
bin_pkg_data.append('*.dylib')
else:
platform_str = get_platform()
if not platform_str.startswith('linux-'):
raise Exception(f'Unknown platform: "{platform_str}"')
if 'i686' in platform_str:
arch = 'i686-linux-gnu'
elif 'x86_64' in platform_str:
arch = 'x86_64-linux-gnu'
elif 'aarch64' in platform_str:
arch = 'aarch64-rpi4-linux-gnueabi'
else:
raise Exception(f'Unsupported platform: "{platform_str}"')
lib_dir = lib_dir / arch
bin_pkg_data.append(f'{arch}/*.so')
lib_dir = lib_dir.resolve()
LIB_DIRS.append(str(lib_dir))
RUNTIME_LIB_DIRS.append(str(lib_dir))
PACKAGE_DATA['cyndilib.wrapper.bin'].extend(bin_pkg_data)
PACKAGE_DATA['cyndilib.wrapper.lib'].extend(lib_pkg_data)
def get_ndi_libname():
if WIN32:
return 'Processing.NDI.Lib.x64'
return 'ndi'
if IS_BUILD:
get_ndi_libdir()
try:
import numpy
except ImportError:
numpy = None
if numpy is not None:
INCLUDE_PATH.append(numpy.get_include())
class CyBuildError(CCompilerError):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return '{} (try building with "--use-cython")'.format(self.msg)
compiler_directives = {'embedsignature':True, 'embedsignature.format':'python'}
if USE_PROFILE:
ext_macros = [('CYTHON_TRACE', 1), ('CYTHON_TRACE_NOGIL', 1)]
compiler_directives.update({'profile':True, 'linetrace':True})
else:
ext_macros = None
extra_compile_args = []
if WIN32:
extra_compile_args.append('/Zc:strictStrings')
else:
extra_compile_args.append('-fpermissive')
if not len(LIB_DIRS):
LIB_DIRS = None
if not len(RUNTIME_LIB_DIRS):
RUNTIME_LIB_DIRS = None
ext_modules = [
Extension(
'*', ['src/**/*.pyx'],
include_dirs=INCLUDE_PATH,
extra_compile_args=extra_compile_args,
libraries=[get_ndi_libname()],
library_dirs=LIB_DIRS,
runtime_library_dirs=RUNTIME_LIB_DIRS,
define_macros=ext_macros,
# define_macros=[('CYTHON_TRACE', 1), ('CYTHON_TRACE_NOGIL', 1)]
),
]
ext_modules = cythonize(
ext_modules,
annotate=ANNOTATE,
compiler_directives=compiler_directives,
)
# From https://github.com/scikit-learn/scikit-learn/blob/3ee60a720aab3598668af3a3d7eb01d6958859be/setup.py#L106-L117
class build_ext_subclass(build_ext):
def finalize_options(self):
build_ext.finalize_options(self)
if self.parallel is None:
# Do not override self.parallel if already defined by
# command-line flag (--parallel or -j)
if os.environ.get('READTHEDOCS', '').lower() == 'true':
parallel = 'auto'
else:
parallel = os.environ.get("CYNDILIB_BUILD_PARALLEL")
if parallel == 'auto':
self.parallel = os.cpu_count()
elif parallel:
self.parallel = int(parallel)
if self.parallel:
print("setting parallel=%d " % self.parallel)
def build_annotate_index(extensions):
root = AnnotateIndex('', root_dir=PROJECT_PATH / 'src')
for ext in extensions:
pkg_dir = Path(ext.sources[0]).parent
pkg = root.add_module(ext.name)
for c in root.walk():
print('{} -> {}'.format(c, c.to_path('index.html')))
c.write_html()
if ANNOTATE and AnnotateIndex is not None:
build_annotate_index(ext_modules)
setup(
cmdclass={
'build_ext':build_ext_subclass,
},
ext_modules=ext_modules,
include_package_data=True,
package_data=PACKAGE_DATA,
)