From 275136aeac316bd56eecc175df146826f3b52e00 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Mon, 11 Jan 2021 14:36:30 +0100 Subject: [PATCH] Add scanner for Cython dependencies (#19722) * add scanner for cython dependencies * cleanup and comments * comment about relative imports --- site_scons/site_tools/cython.py | 44 +++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/site_scons/site_tools/cython.py b/site_scons/site_tools/cython.py index 45ba797c4..c29147553 100644 --- a/site_scons/site_tools/cython.py +++ b/site_scons/site_tools/cython.py @@ -1,18 +1,52 @@ +import re import SCons from SCons.Action import Action +from SCons.Scanner import Scanner +pyx_from_import_re = re.compile(r'^from\s+(\S+)\s+cimport', re.M) +pyx_import_re = re.compile(r'^cimport\s+(\S+)', re.M) +cdef_import_re = re.compile(r'^cdef extern from\s+.(\S+).:', re.M) + + +def pyx_scan(node, env, path, arg=None): + contents = node.get_text_contents() + + # from cimport ... + matches = pyx_from_import_re.findall(contents) + # cimport + matches += pyx_import_re.findall(contents) + + # Modules can be either .pxd or .pyx files + files = [m.replace('.', '/') + '.pxd' for m in matches] + files += [m.replace('.', '/') + '.pyx' for m in matches] + + # cdef extern from + files += cdef_import_re.findall(contents) + + # Handle relative imports + cur_dir = str(node.get_dir()) + files = [cur_dir + f if f.startswith('/') else f for f in files] + + # Filter out non-existing files (probably system imports) + files = [f for f in files if env.File(f).exists()] + return env.File(files) + + +pyxscanner = Scanner(function=pyx_scan, skeys=['.pyx', '.pxd'], recursive=True) cythonAction = Action("$CYTHONCOM") + def create_builder(env): try: cython = env['BUILDERS']['Cython'] except KeyError: cython = SCons.Builder.Builder( - action = cythonAction, - emitter = {}, - suffix = cython_suffix_emitter, - single_source = 1 - ) + action=cythonAction, + emitter={}, + suffix=cython_suffix_emitter, + single_source=1 + ) + env.Append(SCANNERS=pyxscanner) env['BUILDERS']['Cython'] = cython return cython