Skip to content

Commit

Permalink
Static modules use constructor functions to register with Python on l…
Browse files Browse the repository at this point in the history
…oad.
  • Loading branch information
renpytom committed Aug 1, 2020
1 parent 75c0c20 commit f60bc1d
Showing 1 changed file with 35 additions and 6 deletions.
41 changes: 35 additions & 6 deletions setuplib.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,16 +255,45 @@ def cython(name, source=[], libs=[], compile_if=True, define_macros=[]):
c_fn])

# Fix-up source for static loading
if static and len(split_name) > 1:
if static:

parent_module = '.'.join(split_name[:-1])
parent_module_identifier = parent_module.replace('.', '_')

with open(c_fn, 'r') as f:
ccode = f.read()
ccode = re.sub('Py_InitModule4\("([^"]+)"', 'Py_InitModule4("'+parent_module+'.\\1"', ccode) # Py2
ccode = re.sub('(__pyx_moduledef.*?"){}"'.format(re.escape(split_name[-1])), '\\1'+'.'.join(split_name)+'"', ccode, flags=re.DOTALL) # Py3
ccode = re.sub('^__Pyx_PyMODINIT_FUNC init', '__Pyx_PyMODINIT_FUNC init'+parent_module_identifier+'_', ccode, 0, re.MULTILINE) # Py2 Cython 0.28+
ccode = re.sub('^__Pyx_PyMODINIT_FUNC PyInit_', '__Pyx_PyMODINIT_FUNC PyInit_'+parent_module_identifier+'_', ccode, 0, re.MULTILINE) # Py3 Cython 0.28+
ccode = re.sub('^PyMODINIT_FUNC init', 'PyMODINIT_FUNC init'+parent_module_identifier+'_', ccode, 0, re.MULTILINE) # Py2 Cython 0.25.2

with open(c_fn + ".dynamic", 'w') as f:
f.write(ccode)

if len(split_name) > 1:

ccode = re.sub('Py_InitModule4\("([^"]+)"', 'Py_InitModule4("' + parent_module + '.\\1"', ccode) # Py2
ccode = re.sub('(__pyx_moduledef.*?"){}"'.format(re.escape(split_name[-1])), '\\1' + '.'.join(split_name) + '"', ccode, count=1, flags=re.DOTALL) # Py3
ccode = re.sub('^__Pyx_PyMODINIT_FUNC init', '__Pyx_PyMODINIT_FUNC init' + parent_module_identifier + '_', ccode, 0, re.MULTILINE) # Py2 Cython 0.28+
ccode = re.sub('^__Pyx_PyMODINIT_FUNC PyInit_', '__Pyx_PyMODINIT_FUNC PyInit_' + parent_module_identifier + '_', ccode, 0, re.MULTILINE) # Py3 Cython 0.28+
ccode = re.sub('^PyMODINIT_FUNC init', 'PyMODINIT_FUNC init' + parent_module_identifier + '_', ccode, 0, re.MULTILINE) # Py2 Cython 0.25.2

cname = "_".join(split_name)

ccode += """
static struct _inittab CNAME_inittab[] = {
#if PY_MAJOR_VERSION < 3
{ "PYNAME", initCNAME },
#else
{ "PYNAME", PyInit_CNAME },
#endif
{ NULL, NULL },
};
static void CNAME_constructor(void) __attribute__((constructor));
static void CNAME_constructor(void) {
PyImport_ExtendInittab(CNAME_inittab);
}
""".replace("PYNAME", name).replace("CNAME", cname)

with open(c_fn, 'w') as f:
f.write(ccode)

Expand Down

0 comments on commit f60bc1d

Please sign in to comment.