pythonscons

How to call SCons global function from a helper-script called by a SConscript?


I have some non-trivial logic necessary to compute the paths to certain source & header file directories and since it applies to multiple SConscripts I put it in a separate .py file, imported from each SConscript that needs it. Now I need to be able to call a SCons global function (in this case, the Glob function) from within the helper-script. Previously that function was callable directly from within the SConscripts, but now that I need to call it from the separate helper-script I can't figure out how to call it. I suppose this is probably trivial but I'm really not very familiar with Python.

UPDATE:
It seems the ability to call Glob() as a "global function" has something to do with some trickery that SCons is playing. Here's an excerpt from the main entry file (SConscript.py, which is not the same as the SConscripts that we pepper all over our source tree):

_DefaultEnvironmentProxy = None

def get_DefaultEnvironmentProxy():
    global _DefaultEnvironmentProxy
    if not _DefaultEnvironmentProxy:
        default_env = SCons.Defaults.DefaultEnvironment()
        _DefaultEnvironmentProxy = SCons.Environment.NoSubstitutionProxy(default_env)
    return _DefaultEnvironmentProxy

class DefaultEnvironmentCall(object):
    """A class that implements "global function" calls of
    Environment methods by fetching the specified method from the
    DefaultEnvironment's class.  Note that this uses an intermediate
    proxy class instead of calling the DefaultEnvironment method
    directly so that the proxy can override the subst() method and
    thereby prevent expansion of construction variables (since from
    the user's point of view this was called as a global function,
    with no associated construction environment)."""
    def __init__(self, method_name, subst=0):
        self.method_name = method_name
        if subst:
            self.factory = SCons.Defaults.DefaultEnvironment
        else:
            self.factory = get_DefaultEnvironmentProxy
    def __call__(self, *args, **kw):
        env = self.factory()
        method = getattr(env, self.method_name)
        return method(*args, **kw)


def BuildDefaultGlobals():
    """
    Create a dictionary containing all the default globals for
    SConstruct and SConscript files.
    """

    global GlobalDict
    if GlobalDict is None:
        GlobalDict = {}

        import SCons.Script #     <-------This is referring to a directory with a file named __init__.py, which I've learned is something special in Python
        d = SCons.Script.__dict__
        def not_a_module(m, d=d, mtype=type(SCons.Script)):
             return not isinstance(d[m], mtype)
        for m in filter(not_a_module, dir(SCons.Script)):
             GlobalDict[m] = d[m]

    return GlobalDict.copy()

So I thought perhaps I need to import SCons.Script in my helper-script:

import SCons.Script

Unfortunately I still get this:

NameError: name 'Glob' is not defined:
  File "D:\Git\......\SConstruct", line 412:
    SConscript(theSconscript, duplicate=0)
  File "c:\python37\lib\site-packages\scons\SCons\Script\SConscript.py", line 671:
    return method(*args, **kw)
  File "c:\python37\lib\site-packages\scons\SCons\Script\SConscript.py", line 608:
    return _SConscript(self.fs, *files, **subst_kw)
  .
  .
  .
  File "D:\Git\........\SConscript", line 433:
  .
  .
  .
  File "D:\Git\............\PathSelector.py", line 78:
    src_files.extend(Glob((os.path.join(src_path_a, '*.c')), strings=1))

Solution

  • From the manpage:

    Global functions may be called from custom Python modules that you import into an SConscript file by adding the following import to the Python module:

    from SCons.Script import *