Skip to content

Commit f60bc1d

Browse files
committed
Static modules use constructor functions to register with Python on load.
1 parent 75c0c20 commit f60bc1d

File tree

1 file changed

+35
-6
lines changed

1 file changed

+35
-6
lines changed

setuplib.py

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -255,16 +255,45 @@ def cython(name, source=[], libs=[], compile_if=True, define_macros=[]):
255255
c_fn])
256256

257257
# Fix-up source for static loading
258-
if static and len(split_name) > 1:
258+
if static:
259+
259260
parent_module = '.'.join(split_name[:-1])
260261
parent_module_identifier = parent_module.replace('.', '_')
262+
261263
with open(c_fn, 'r') as f:
262264
ccode = f.read()
263-
ccode = re.sub('Py_InitModule4\("([^"]+)"', 'Py_InitModule4("'+parent_module+'.\\1"', ccode) # Py2
264-
ccode = re.sub('(__pyx_moduledef.*?"){}"'.format(re.escape(split_name[-1])), '\\1'+'.'.join(split_name)+'"', ccode, flags=re.DOTALL) # Py3
265-
ccode = re.sub('^__Pyx_PyMODINIT_FUNC init', '__Pyx_PyMODINIT_FUNC init'+parent_module_identifier+'_', ccode, 0, re.MULTILINE) # Py2 Cython 0.28+
266-
ccode = re.sub('^__Pyx_PyMODINIT_FUNC PyInit_', '__Pyx_PyMODINIT_FUNC PyInit_'+parent_module_identifier+'_', ccode, 0, re.MULTILINE) # Py3 Cython 0.28+
267-
ccode = re.sub('^PyMODINIT_FUNC init', 'PyMODINIT_FUNC init'+parent_module_identifier+'_', ccode, 0, re.MULTILINE) # Py2 Cython 0.25.2
265+
266+
with open(c_fn + ".dynamic", 'w') as f:
267+
f.write(ccode)
268+
269+
if len(split_name) > 1:
270+
271+
ccode = re.sub('Py_InitModule4\("([^"]+)"', 'Py_InitModule4("' + parent_module + '.\\1"', ccode) # Py2
272+
ccode = re.sub('(__pyx_moduledef.*?"){}"'.format(re.escape(split_name[-1])), '\\1' + '.'.join(split_name) + '"', ccode, count=1, flags=re.DOTALL) # Py3
273+
ccode = re.sub('^__Pyx_PyMODINIT_FUNC init', '__Pyx_PyMODINIT_FUNC init' + parent_module_identifier + '_', ccode, 0, re.MULTILINE) # Py2 Cython 0.28+
274+
ccode = re.sub('^__Pyx_PyMODINIT_FUNC PyInit_', '__Pyx_PyMODINIT_FUNC PyInit_' + parent_module_identifier + '_', ccode, 0, re.MULTILINE) # Py3 Cython 0.28+
275+
ccode = re.sub('^PyMODINIT_FUNC init', 'PyMODINIT_FUNC init' + parent_module_identifier + '_', ccode, 0, re.MULTILINE) # Py2 Cython 0.25.2
276+
277+
cname = "_".join(split_name)
278+
279+
ccode += """
280+
281+
static struct _inittab CNAME_inittab[] = {
282+
#if PY_MAJOR_VERSION < 3
283+
{ "PYNAME", initCNAME },
284+
#else
285+
{ "PYNAME", PyInit_CNAME },
286+
#endif
287+
{ NULL, NULL },
288+
};
289+
290+
static void CNAME_constructor(void) __attribute__((constructor));
291+
292+
static void CNAME_constructor(void) {
293+
PyImport_ExtendInittab(CNAME_inittab);
294+
}
295+
""".replace("PYNAME", name).replace("CNAME", cname)
296+
268297
with open(c_fn, 'w') as f:
269298
f.write(ccode)
270299

0 commit comments

Comments
 (0)