python 如何从SConscript调用的helper-script中调用SCons全局函数?

fjaof16o  于 2023-01-11  发布在  Python
关注(0)|答案(1)|浏览(177)

我有一些重要的逻辑来计算某些源文件和头文件目录的路径,由于它适用于多个SConscript,所以我将它放在一个单独的.py文件中,从需要它的每个SConscript导入。(在本例中为Glob函数)。以前该函数可直接从SConscripts中调用,但是现在我需要从单独的helper-script调用它,我不知道该怎么调用它,我想这可能很简单,但是我对Python真的不是很熟悉。
我将这个问题的“标签”扩展到包括[python],因为只有[scons]标签几乎没有命中,但我认为回答这个问题可能需要对SCons和SCons环境有一些熟悉。

更新日期:

我发现Glob函数实际上是SCons的FS.py类FS的成员函数:

def Glob(self, pathname, ondisk=True, source=True, strings=False, exclude=None, cwd=None):
    """
    Globs

    This is mainly a shim layer
    """
    if cwd is None:
        cwd = self.getcwd()
    return cwd.glob(pathname, ondisk, source, strings, exclude)

好吧,FS.Glob()只是一个shim,但是我想我需要调用这个shim。除了这个shim之外,还有我不理解的重要SCons逻辑。奇怪的是,调用它的原始SConscript代码没有使用对象:

#gather source files
src_files = []
if (...some logic...):
    src_files.extend(Glob((os.path.join(src_path_a, '*.c')), strings=1))
    src_files.extend(Glob((os.path.join(src_path_a, '*.s')), strings=1))
if (...some more logic...):
    src_files.extend(Glob((os.path.join(src_path_b, '*.c')), strings=1))
    src_files.extend(Glob((os.path.join(src_path_b, '*.s')), strings=1))
.
.
.

在使用原始代码的工作区中(在我将其移到公共helper-script之前),像上面这样调用Glob(...)不知何故会得到FS.Glob函数,即使没有对象来调用它。

> d:\git\........\sconscript(73)<module>()
-> Glob((os.path.join(tx_src_path, '*.c')), strings=1)
(Pdb) s
--Call--
> c:\python37\lib\ntpath.py(75)join()
-> def join(path, *paths):
(Pdb) r
--Return--
> c:\python37\lib\ntpath.py(113)join()->'ThirdParty\\...eadx\\tx\\*.c'
-> return result_drive + result_path
(Pdb) s
--Call--
> c:\python37\lib\site-packages\scons\scons\script\sconscript.py(668)__call__()
-> def __call__(self, *args, **kw):
(Pdb) s
> c:\python37\lib\site-packages\scons\scons\script\sconscript.py(669)__call__()
-> env = self.factory()
(Pdb) s
--Call--
> c:\python37\lib\site-packages\scons\scons\script\sconscript.py(646)get_DefaultEnvironmentProxy()
-> def get_DefaultEnvironmentProxy():
(Pdb) s
> c:\python37\lib\site-packages\scons\scons\script\sconscript.py(648)get_DefaultEnvironmentProxy()
-> if not _DefaultEnvironmentProxy:
(Pdb) s
> c:\python37\lib\site-packages\scons\scons\script\sconscript.py(651)get_DefaultEnvironmentProxy()
-> return _DefaultEnvironmentProxy
(Pdb) s
--Return--
> c:\python37\lib\site-packages\scons\scons\script\sconscript.py(651)get_DefaultEnvironmentProxy()-><SCons.Enviro...0022AAB8E3F08>
-> return _DefaultEnvironmentProxy
(Pdb) s
> c:\python37\lib\site-packages\scons\scons\script\sconscript.py(670)__call__()
-> method = getattr(env, self.method_name)
(Pdb) s
> c:\python37\lib\site-packages\scons\scons\script\sconscript.py(671)__call__()
-> return method(*args, **kw)
(Pdb) s
--Call--
> c:\python37\lib\site-packages\scons\scons\environment.py(2077)Glob()
-> def Glob(self, pattern, ondisk=True, source=False, strings=False, exclude=None):
(Pdb) s
> c:\python37\lib\site-packages\scons\scons\environment.py(2078)Glob()
-> return self.fs.Glob(self.subst(pattern), ondisk, source, strings, exclude)

我不知道所有关于“get_DefaultEnvironmentProxy()”的东西是什么......这是SCons的一部分,我希望有人能帮助我。

另一项更新:

Glob()作为“全局函数”调用的能力似乎与SCons的一些诡计有关,下面是主入口文件(SConscript.py,它与我们在源代码树中使用的SConscripts不同)的摘录:

_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()

所以我想也许我需要在我的帮助脚本import SCons.Script

import SCons.Script

不幸的是,我仍然得到这个:

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 "c:\python37\lib\site-packages\scons\SCons\Script\SConscript.py", line 287:
    exec(compile(scriptdata, scriptname, 'exec'), call_stack[-1].globals)
  File "D:\Git\............\SConscript", line 43:
    packageBuilder.appendComponents(binaryBuildingBlocks)
  File "D:\Git\.........\Build\packageBuilder.py", line 222:
    self.env.SConscript(os.path.join(component, SCONSCRIPT_FILE))
  File "c:\python37\lib\site-packages\scons\SCons\Script\SConscript.py", line 608:
    return _SConscript(self.fs, *files, **subst_kw)
  File "c:\python37\lib\site-packages\scons\SCons\Script\SConscript.py", line 287:
    exec(compile(scriptdata, scriptname, 'exec'), call_stack[-1].globals)
  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))
wpx232ag

wpx232ag1#

从联机帮助页:
通过将以下导入添加到Python模块,可以从导入SConscript文件的自定义Python模块调用全局函数:

from SCons.Script import *

相关问题