omdev 0.0.0.dev7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. omdev/__about__.py +35 -0
  2. omdev/__init__.py +0 -0
  3. omdev/amalg/__init__.py +0 -0
  4. omdev/amalg/__main__.py +4 -0
  5. omdev/amalg/amalg.py +513 -0
  6. omdev/classdot.py +61 -0
  7. omdev/cmake.py +164 -0
  8. omdev/exts/__init__.py +0 -0
  9. omdev/exts/_distutils/__init__.py +10 -0
  10. omdev/exts/_distutils/build_ext.py +367 -0
  11. omdev/exts/_distutils/compilers/__init__.py +3 -0
  12. omdev/exts/_distutils/compilers/ccompiler.py +1032 -0
  13. omdev/exts/_distutils/compilers/options.py +80 -0
  14. omdev/exts/_distutils/compilers/unixccompiler.py +385 -0
  15. omdev/exts/_distutils/dir_util.py +76 -0
  16. omdev/exts/_distutils/errors.py +62 -0
  17. omdev/exts/_distutils/extension.py +107 -0
  18. omdev/exts/_distutils/file_util.py +216 -0
  19. omdev/exts/_distutils/modified.py +47 -0
  20. omdev/exts/_distutils/spawn.py +103 -0
  21. omdev/exts/_distutils/sysconfig.py +349 -0
  22. omdev/exts/_distutils/util.py +201 -0
  23. omdev/exts/_distutils/version.py +308 -0
  24. omdev/exts/build.py +43 -0
  25. omdev/exts/cmake.py +195 -0
  26. omdev/exts/importhook.py +88 -0
  27. omdev/exts/scan.py +74 -0
  28. omdev/interp/__init__.py +1 -0
  29. omdev/interp/__main__.py +4 -0
  30. omdev/interp/cli.py +63 -0
  31. omdev/interp/inspect.py +105 -0
  32. omdev/interp/providers.py +67 -0
  33. omdev/interp/pyenv.py +353 -0
  34. omdev/interp/resolvers.py +76 -0
  35. omdev/interp/standalone.py +187 -0
  36. omdev/interp/system.py +125 -0
  37. omdev/interp/types.py +92 -0
  38. omdev/mypy/__init__.py +0 -0
  39. omdev/mypy/debug.py +86 -0
  40. omdev/pyproject/__init__.py +1 -0
  41. omdev/pyproject/__main__.py +4 -0
  42. omdev/pyproject/cli.py +319 -0
  43. omdev/pyproject/configs.py +97 -0
  44. omdev/pyproject/ext.py +107 -0
  45. omdev/pyproject/pkg.py +196 -0
  46. omdev/scripts/__init__.py +0 -0
  47. omdev/scripts/execrss.py +19 -0
  48. omdev/scripts/findimports.py +62 -0
  49. omdev/scripts/findmagic.py +70 -0
  50. omdev/scripts/interp.py +2118 -0
  51. omdev/scripts/pyproject.py +3584 -0
  52. omdev/scripts/traceimport.py +502 -0
  53. omdev/tokens.py +42 -0
  54. omdev/toml/__init__.py +1 -0
  55. omdev/toml/parser.py +823 -0
  56. omdev/toml/writer.py +104 -0
  57. omdev/tools/__init__.py +0 -0
  58. omdev/tools/dockertools.py +81 -0
  59. omdev/tools/sqlrepl.py +193 -0
  60. omdev/versioning/__init__.py +1 -0
  61. omdev/versioning/specifiers.py +531 -0
  62. omdev/versioning/versions.py +416 -0
  63. omdev-0.0.0.dev7.dist-info/LICENSE +21 -0
  64. omdev-0.0.0.dev7.dist-info/METADATA +24 -0
  65. omdev-0.0.0.dev7.dist-info/RECORD +67 -0
  66. omdev-0.0.0.dev7.dist-info/WHEEL +5 -0
  67. omdev-0.0.0.dev7.dist-info/top_level.txt +1 -0
omdev/cmake.py ADDED
@@ -0,0 +1,164 @@
1
+ import abc
2
+ import io
3
+ import typing as ta
4
+
5
+ from omlish import dataclasses as dc
6
+
7
+
8
+ @dc.dataclass(frozen=True)
9
+ class Command:
10
+ name: str
11
+ args: str | ta.Sequence[str]
12
+ lines: ta.Sequence[str] | None = None
13
+
14
+
15
+ @dc.dataclass(frozen=True)
16
+ class Var:
17
+ name: str
18
+ value: str | ta.Sequence[str]
19
+
20
+
21
+ @dc.dataclass(frozen=True)
22
+ class Target(abc.ABC):
23
+ name: str
24
+ src_files: ta.Sequence[str]
25
+
26
+ include_dirs: ta.Sequence[str] | None = None
27
+ compile_opts: ta.Sequence[str] | None = None
28
+ link_dirs: ta.Sequence[str] | None = None
29
+ link_opts: ta.Sequence[str] | None = None
30
+
31
+ compile_flags_by_source_file: ta.Mapping[str, ta.Sequence[str]] | None = None
32
+
33
+ link_libs: ta.Sequence[str] | None = None
34
+
35
+ extra_cmds: ta.Sequence[Command] | None = None
36
+
37
+ @property
38
+ @abc.abstractmethod
39
+ def command_name(self) -> str:
40
+ raise NotImplementedError
41
+
42
+ @property
43
+ def command_extra(self) -> ta.Sequence[str]:
44
+ return []
45
+
46
+
47
+ @dc.dataclass(frozen=True)
48
+ class Library(Target):
49
+
50
+ @property
51
+ def command_name(self) -> str:
52
+ return 'add_library'
53
+
54
+
55
+ @dc.dataclass(frozen=True)
56
+ class StaticLibrary(Library):
57
+
58
+ @property
59
+ def command_extra(self) -> ta.Sequence[str]:
60
+ return ['STATIC']
61
+
62
+
63
+ @dc.dataclass(frozen=True)
64
+ class ModuleLibrary(Library):
65
+
66
+ @property
67
+ def command_extra(self) -> ta.Sequence[str]:
68
+ return ['MODULE']
69
+
70
+
71
+ @dc.dataclass(frozen=True)
72
+ class Executable(Target):
73
+
74
+ @property
75
+ def command_name(self) -> str:
76
+ return 'add_executable'
77
+
78
+
79
+ class CmakeGen:
80
+
81
+ def __init__(
82
+ self,
83
+ out: io.TextIOBase,
84
+ *,
85
+ indent: int = 4,
86
+ ) -> None:
87
+ super().__init__()
88
+
89
+ self._out = out
90
+ self._indent = indent
91
+
92
+ def write(
93
+ self,
94
+ obj: str | ta.Sequence[str] = '',
95
+ *,
96
+ spacing: int | str = 0,
97
+ indent: int | str | None = None,
98
+ ) -> None:
99
+ if isinstance(obj, str):
100
+ obj = [obj]
101
+ if isinstance(spacing, int):
102
+ spacing = '\n' * spacing
103
+ if isinstance(indent, int):
104
+ indent = ' ' * indent
105
+ for line in obj:
106
+ if indent is not None:
107
+ line = indent + line
108
+ self._out.write(line)
109
+ self._out.write('\n')
110
+ if spacing is not None:
111
+ self._out.write(spacing)
112
+
113
+ def write_section(self, label: str) -> None:
114
+ self.write(['', f'### {label}', ''])
115
+
116
+ def write_cmd(self, cmd: Command) -> None:
117
+ args = cmd.args
118
+ if not isinstance(args, str):
119
+ args = ' '.join(args)
120
+ if not cmd.lines:
121
+ self.write(f'{cmd.name}({args})')
122
+ else:
123
+ if isinstance(cmd.lines, str):
124
+ raise TypeError(cmd.lines)
125
+ self.write(f'{cmd.name}({args}')
126
+ self.write(cmd.lines, indent=self._indent)
127
+ self.write(')')
128
+ self.write()
129
+
130
+ def write_var(self, var: Var) -> None:
131
+ return self.write_cmd(Command('set', var.name, [var.value] if isinstance(var.value, str) else var.value))
132
+
133
+ def write_target(self, target: Target) -> None:
134
+ self.write_section(target.name)
135
+
136
+ self.write_cmd(Command(target.command_name, [target.name, *target.command_extra], target.src_files))
137
+
138
+ if target.include_dirs:
139
+ self.write_cmd(Command('target_include_directories', [target.name, 'PRIVATE'], target.include_dirs))
140
+ if target.compile_opts:
141
+ self.write_cmd(Command('target_compile_options', [target.name, 'PRIVATE'], target.compile_opts))
142
+
143
+ if target.link_dirs:
144
+ self.write_cmd(Command('target_link_directories', [target.name, 'PRIVATE'], target.link_dirs))
145
+ if target.link_opts:
146
+ self.write_cmd(Command('target_link_options', [target.name, 'PRIVATE'], target.link_opts))
147
+
148
+ if target.compile_flags_by_source_file:
149
+ for sf, cf in target.compile_flags_by_source_file.items():
150
+ cf = ['"' + f.replace('"', '\\"') + '"' for f in cf]
151
+ self.write_cmd(Command('set_source_files_properties', [sf, 'PROPERTIES', 'COMPILE_FLAGS'], cf))
152
+
153
+ if target.link_libs:
154
+ self.write_cmd(Command('target_link_libraries', [target.name, 'PRIVATE'], target.link_libs))
155
+
156
+ for cmd in (target.extra_cmds or ()):
157
+ self.write_cmd(cmd)
158
+
159
+ @property
160
+ def preamble(self) -> ta.Sequence[str]:
161
+ return [
162
+ 'cmake_minimum_required(VERSION 3.1...3.16)',
163
+ 'set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR})',
164
+ ]
omdev/exts/__init__.py ADDED
File without changes
@@ -0,0 +1,10 @@
1
+ from . import build_ext # noqa
2
+ from . import compilers # noqa
3
+ from . import errors # noqa
4
+ from . import extension # noqa
5
+ from . import modified # noqa
6
+ from . import sysconfig # noqa
7
+ from . import util # noqa
8
+
9
+ from .build_ext import BuildExt # noqa
10
+ from .extension import Extension # noqa
@@ -0,0 +1,367 @@
1
+ """
2
+ PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
3
+ --------------------------------------------
4
+
5
+ 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization
6
+ ("Licensee") accessing and otherwise using this software ("Python") in source or binary form and its associated
7
+ documentation.
8
+
9
+ 2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive,
10
+ royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works,
11
+ distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement
12
+ and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
13
+ 2012, 2013, 2014, 2015, 2016, 2017 Python Software Foundation; All Rights Reserved" are retained in Python alone or in
14
+ any derivative version prepared by Licensee.
15
+
16
+ 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and
17
+ wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any
18
+ such work a brief summary of the changes made to Python.
19
+
20
+ 4. PSF is making Python available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS
21
+ OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF
22
+ MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT INFRINGE ANY THIRD PARTY
23
+ RIGHTS.
24
+
25
+ 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL
26
+ DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, OR ANY DERIVATIVE THEREOF, EVEN IF
27
+ ADVISED OF THE POSSIBILITY THEREOF.
28
+
29
+ 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions.
30
+
31
+ 7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture
32
+ between PSF and Licensee. This License Agreement does not grant permission to use PSF trademarks or trade name in a
33
+ trademark sense to endorse or promote products or services of Licensee, or any third party.
34
+
35
+ 8. By copying, installing or otherwise using Python, Licensee agrees to be bound by the terms and conditions of this
36
+ License Agreement.
37
+ """
38
+ import contextlib
39
+ import dataclasses as dc
40
+ import logging
41
+ import os
42
+ import site
43
+ import sys
44
+ import typing as ta
45
+
46
+ from omlish import cached
47
+ from omlish import check
48
+ from omlish import lang
49
+
50
+ from . import compilers
51
+ from . import errors
52
+ from . import extension
53
+ from . import modified
54
+ from . import sysconfig
55
+ from . import util
56
+
57
+
58
+ log = logging.getLogger(__name__)
59
+
60
+
61
+ def _get_str_config_var(name: str) -> str:
62
+ return check.isinstance(sysconfig.get_config_var(name), str)
63
+
64
+
65
+ class BuildExt:
66
+
67
+ @dc.dataclass(frozen=True)
68
+ class Options:
69
+ build_base: str | None = None
70
+ build_lib: str | None = None # directory for compiled extension modules
71
+ build_temp: str | None = None # directory for temporary files (build by-products)
72
+
73
+ plat_name: str | None = None # platform name to cross-compile for, if supported
74
+
75
+ include_dirs: ta.Sequence[str] | None = None # list of directories to search for header files (pathsep)
76
+ define: ta.Mapping[str, str] | None = None # C preprocessor macros to define
77
+ undef: ta.Sequence[str] | None = None # C preprocessor macros to undefine
78
+
79
+ libraries: ta.Sequence[str] | None = None # external C libraries to link with
80
+ library_dirs: ta.Sequence[str] | None = None # directories to search for external C libraries (pathsep)
81
+ rpath: ta.Sequence[str] | None = None # directories to search for shared C libraries at runtime
82
+ link_objects: ta.Sequence[str] | None = None # extra explicit link objects to include in the link
83
+
84
+ inplace: bool = False # ignore build-lib and put compiled extensions into the source directory
85
+ debug: bool = False # compile/link with debugging information
86
+ force: bool = False # forcibly build everything (ignore file timestamps)
87
+ compiler: str | None = None # specify the compiler type
88
+ parallel: int | None = None # number of parallel build jobs
89
+ user: bool = False # add user include, library and rpath
90
+
91
+ dry_run: bool = False
92
+ verbose: bool = False
93
+
94
+ package: str | None = None
95
+ package_dir: ta.Mapping[str, str] | None = None
96
+
97
+ def __init__(self, opts: Options = Options()) -> None:
98
+ super().__init__()
99
+
100
+ self._opts = check.isinstance(opts, BuildExt.Options)
101
+
102
+ @property
103
+ def options(self) -> Options:
104
+ return self._opts
105
+
106
+ @cached.property
107
+ def build_base(self) -> str:
108
+ return self._opts.build_base or 'build'
109
+
110
+ @cached.property
111
+ def plat_name(self) -> str:
112
+ return self._opts.plat_name or util.get_host_platform()
113
+
114
+ @cached.property
115
+ def plat_specifier(self) -> str:
116
+ ps = '.{}-{:d}.{:d}'.format(self.plat_name, *sys.version_info[:2])
117
+ if hasattr(sys, 'gettotalrefcount'):
118
+ ps += '-pydebug'
119
+ return ps
120
+
121
+ @cached.property
122
+ def build_lib(self) -> str:
123
+ return self._opts.build_lib or os.path.join(self.build_base, 'lib' + self.plat_specifier)
124
+
125
+ @cached.property
126
+ def build_temp(self) -> str:
127
+ if self._opts.build_temp:
128
+ return self._opts.build_temp
129
+ bt = os.path.join(self.build_base, 'temp' + self.plat_specifier)
130
+ return bt
131
+
132
+ @dc.dataclass(frozen=True)
133
+ class CDirs:
134
+ include: ta.Sequence[str]
135
+ library: ta.Sequence[str]
136
+ runtime: ta.Sequence[str]
137
+
138
+ @cached.property
139
+ def cdirs(self) -> CDirs:
140
+ include_dirs = list(self._opts.include_dirs or [])
141
+ library_dirs = list(self._opts.library_dirs or [])
142
+ rpath = list(self._opts.rpath or [])
143
+
144
+ plat_py_include = sysconfig.get_python_inc(plat_specific=1)
145
+
146
+ if sys.exec_prefix != sys.base_exec_prefix:
147
+ include_dirs.append(os.path.join(sys.exec_prefix, 'include'))
148
+
149
+ py_include = sysconfig.get_python_inc()
150
+ include_dirs.extend(py_include.split(os.path.pathsep))
151
+ if plat_py_include != py_include:
152
+ include_dirs.extend(plat_py_include.split(os.path.pathsep))
153
+
154
+ if (sysconfig.get_config_var('Py_ENABLE_SHARED')):
155
+ if not sysconfig.python_build: # noqa
156
+ library_dirs.append(_get_str_config_var('LIBDIR'))
157
+ else:
158
+ library_dirs.append('.')
159
+
160
+ if self._opts.user:
161
+ user_include = os.path.join(check.isinstance(site.USER_BASE, str), 'include')
162
+ if os.path.isdir(user_include):
163
+ include_dirs.append(user_include)
164
+
165
+ user_lib = os.path.join(check.isinstance(site.USER_BASE, str), 'lib')
166
+ if os.path.isdir(user_lib):
167
+ library_dirs.append(user_lib)
168
+ rpath.append(user_lib)
169
+
170
+ return BuildExt.CDirs(
171
+ include=include_dirs,
172
+ library=library_dirs,
173
+ runtime=rpath,
174
+ )
175
+
176
+ @lang.cached_function
177
+ def get_compiler(self) -> compilers.ccompiler.CCompiler:
178
+ cc = compilers.ccompiler.new_compiler(
179
+ compiler=self._opts.compiler,
180
+ verbose=int(self._opts.verbose),
181
+ dry_run=int(self._opts.dry_run),
182
+ force=int(self._opts.force),
183
+ )
184
+
185
+ sysconfig.customize_compiler(cc)
186
+
187
+ cc.set_include_dirs(list(self.cdirs.include))
188
+
189
+ if self._opts.define:
190
+ for (name, value) in self._opts.define.items():
191
+ cc.define_macro(name, value)
192
+
193
+ if self._opts.undef is not None:
194
+ for macro in self._opts.undef:
195
+ cc.undefine_macro(macro)
196
+
197
+ if self._opts.libraries:
198
+ cc.set_libraries(list(self._opts.libraries))
199
+
200
+ cc.set_library_dirs(list(self.cdirs.library))
201
+
202
+ cc.set_runtime_library_dirs(list(self.cdirs.runtime))
203
+
204
+ if self._opts.link_objects:
205
+ cc.set_link_objects(list(self._opts.link_objects))
206
+
207
+ return cc
208
+
209
+ def get_ext_fullpath(self, ext_name: str) -> str:
210
+ fullname = self.get_ext_fullname(ext_name)
211
+ modpath = fullname.split('.')
212
+ filename = self.get_ext_filename(modpath[-1])
213
+
214
+ if not self._opts.inplace:
215
+ filename = os.path.join(*modpath[:-1] + [filename])
216
+ return os.path.join(self.build_lib, filename) # noqa
217
+
218
+ package = '.'.join(modpath[0:-1])
219
+ package_dir = os.path.abspath(self.get_package_dir(package))
220
+
221
+ return os.path.join(package_dir, filename)
222
+
223
+ def get_package_dir(self, package: str) -> str:
224
+ path = package.split('.')
225
+
226
+ package_dir = self._opts.package_dir
227
+ if package_dir is None:
228
+ if path:
229
+ return os.path.join(*path) # noqa
230
+ else:
231
+ return ''
232
+
233
+ tail: list[str] = []
234
+ while path:
235
+ try:
236
+ pdir = package_dir['.'.join(path)]
237
+ except KeyError:
238
+ tail.insert(0, path[-1])
239
+ del path[-1]
240
+ else:
241
+ tail.insert(0, pdir)
242
+ return os.path.join(*tail) # noqa
243
+
244
+ pdir = package_dir.get('') # type: ignore
245
+ if pdir is not None:
246
+ tail.insert(0, pdir)
247
+
248
+ if tail:
249
+ return os.path.join(*tail) # noqa
250
+ else:
251
+ return ''
252
+
253
+ def get_ext_fullname(self, ext_name: str) -> str:
254
+ if self._opts.package is None:
255
+ return ext_name
256
+ else:
257
+ return self._opts.package + '.' + ext_name
258
+
259
+ def get_ext_filename(self, ext_name: str) -> str:
260
+ ext_path = ext_name.split('.')
261
+ ext_suffix = _get_str_config_var('EXT_SUFFIX')
262
+ return os.path.join(*ext_path) + ext_suffix # noqa
263
+
264
+ def get_export_symbols(self, ext: extension.Extension) -> ta.Sequence[str]:
265
+ suffix = '_' + ext.name.split('.')[-1]
266
+ try:
267
+ # Unicode module name support as defined in PEP-489
268
+ # https://www.python.org/dev/peps/pep-0489/#export-hook-name
269
+ suffix.encode('ascii')
270
+ except UnicodeEncodeError:
271
+ suffix = 'U' + suffix.encode('punycode').replace(b'-', b'_').decode('ascii')
272
+
273
+ initfunc_name = 'PyInit' + suffix
274
+ if initfunc_name not in ext.export_symbols:
275
+ ext.export_symbols.append(initfunc_name)
276
+ return ext.export_symbols
277
+
278
+ def get_libraries(self, ext: extension.Extension) -> ta.Sequence[str]:
279
+ if sys.platform == 'win32':
280
+ from distutils._msvccompiler import MSVCCompiler # noqa
281
+
282
+ if not isinstance(self.get_compiler(), MSVCCompiler):
283
+ template = 'python%d%d'
284
+ if self._opts.debug:
285
+ template = template + '_d'
286
+ pythonlib = (template % (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
287
+ return [*ext.libraries, pythonlib]
288
+
289
+ else:
290
+ link_libpython = False
291
+ if sysconfig.get_config_var('Py_ENABLE_SHARED'):
292
+ if hasattr(sys, 'getandroidapilevel') or sys.platform == 'cygwin':
293
+ link_libpython = True
294
+
295
+ if link_libpython:
296
+ ldversion = _get_str_config_var('LDVERSION')
297
+ return [*ext.libraries, 'python' + ldversion]
298
+
299
+ return ext.libraries
300
+
301
+ def build_extension(self, ext: extension.Extension) -> ta.Sequence[str]:
302
+ with self._filter_build_errors(ext):
303
+ return self._build_extension(ext)
304
+
305
+ @contextlib.contextmanager
306
+ def _filter_build_errors(self, ext: extension.Extension) -> ta.Iterator[None]:
307
+ try:
308
+ yield
309
+ except (
310
+ errors.CCompilerError,
311
+ errors.CompileError,
312
+ errors.DistutilsError,
313
+ ) as e:
314
+ if not ext.optional:
315
+ raise
316
+ log.warning('building extension "%s" failed: %s', ext.name, e)
317
+
318
+ def _build_extension(self, ext: extension.Extension) -> ta.Sequence[str]:
319
+ sources = ext.sources
320
+ sources = sorted(sources)
321
+
322
+ ext_path = self.get_ext_fullpath(ext.name)
323
+ depends = sources + ext.depends
324
+ if not (self._opts.force or modified.newer_group(depends, ext_path, 'newer')):
325
+ log.debug('skipping "%s" extension (up-to-date)', ext.name)
326
+ return []
327
+ else:
328
+ log.info('building "%s" extension', ext.name)
329
+
330
+ extra_args = ext.extra_compile_args or []
331
+
332
+ macros = ext.define_macros[:]
333
+ for undef in ext.undef_macros:
334
+ macros.append((undef,)) # type: ignore # noqa
335
+
336
+ cc = self.get_compiler()
337
+
338
+ objects = cc.compile(
339
+ sources,
340
+ output_dir=self.build_temp,
341
+ macros=macros, # noqa
342
+ include_dirs=ext.include_dirs,
343
+ debug=int(self._opts.debug), # noqa
344
+ extra_postargs=extra_args,
345
+ depends=ext.depends,
346
+ )
347
+
348
+ if ext.extra_objects:
349
+ objects.extend(ext.extra_objects)
350
+ extra_args = ext.extra_link_args or []
351
+
352
+ language = ext.language or cc.detect_language(sources)
353
+
354
+ cc.link_shared_object(
355
+ objects,
356
+ ext_path,
357
+ libraries=list(self.get_libraries(ext)),
358
+ library_dirs=ext.library_dirs,
359
+ runtime_library_dirs=ext.runtime_library_dirs,
360
+ extra_postargs=extra_args,
361
+ export_symbols=list(self.get_export_symbols(ext)),
362
+ debug=int(self._opts.debug), # noqa
363
+ build_temp=self.build_temp,
364
+ target_lang=language,
365
+ )
366
+
367
+ return objects
@@ -0,0 +1,3 @@
1
+ from . import ccompiler # noqa
2
+
3
+ from . import unixccompiler # noqa