scons是如何处理 -C和 --site-dir

/usr/bin/scons –debug=pdb -j4 -C /your/project/dir –site-
dir=/yours/scons/site_scons

1. -j4 表示同时可以并行4个job

2. -C scons在做任何事情之前,先转到-
C指定的目录,这会使得scons首先会在/your/project/dir目录下面找SConstruct文件去执行

3. –site-dir
会使得scons在执行自己的SConstruct文件之前,先执行/yours/scons/site_scons目录下的site_init.py

SCons/Script/Main.py 使得你自己的site被加载到上下文中,并且将site追加到PYTHONPATH中:

def _load_site_scons_dir(topdir, site_dir_name=None):
    """Load the site_scons dir under topdir.
    Adds site_scons to sys.path, imports site_scons/site_init.py,
    and adds site_scons/site_tools to default toolpath."""
    if site_dir_name:
        err_if_not_found = True       # user specified: err if missing
    else:
        site_dir_name = "site_scons"
        err_if_not_found = False

    site_dir = os.path.join(topdir.path, site_dir_name)
    if not os.path.exists(site_dir):
        if err_if_not_found:
            raise SCons.Errors.UserError("site dir %s not found."%site_dir)
        return

    site_init_filename = "site_init.py"
    site_init_modname = "site_init"
    site_tools_dirname = "site_tools"
    sys.path = [os.path.abspath(site_dir)] + sys.path
    site_init_file = os.path.join(site_dir, site_init_filename)
    site_tools_dir = os.path.join(site_dir, site_tools_dirname)
    if os.path.exists(site_init_file):
        **import imp**
        # TODO(2.4): turn this into try:-except:-finally:
        try:
            try:
                fp, pathname, description = imp.find_module(site_init_modname,
                                                            [site_dir])
                # Load the file into SCons.Script namespace.  This is
                # opaque and clever; m is the module object for the
                # SCons.Script module, and the exec ... in call executes a
                # file (or string containing code) in the context of the
                # module's dictionary, so anything that code defines ends
                # up adding to that module.  This is really short, but all
                # the error checking makes it longer.
                try:
                    m = sys.modules['SCons.Script']
                except Exception, e:
                    fmt = 'cannot import site_init.py: missing SCons.Script module %s'
                    raise SCons.Errors.InternalError(fmt % repr(e))
                try:
                    # This is the magic.
                    **exec fp in m.__dict__**
                except KeyboardInterrupt:
                    raise
                except Exception, e:
                    fmt = '*** Error loading site_init file %s:\n'
                    sys.stderr.write(fmt % repr(site_init_file))
                    raise
            except KeyboardInterrupt:
                raise
            except ImportError, e:
                fmt = '*** cannot import site init file %s:\n'
                sys.stderr.write(fmt % repr(site_init_file))
                raise
        finally:
            if fp:
                fp.close()
    if os.path.exists(site_tools_dir):
        SCons.Tool.DefaultToolpath.append(os.path.abspath(site_tools_dir))

SCons/Script/SConsript.py使得SConstruct文件在当前上下文中被执行:

# Append the SConscript directory to the beginning
# of sys.path so Python modules in the SConscript
# directory can be easily imported.
sys.path = [ f.dir.get_abspath() ] + sys.path

# This is the magic line that actually reads up
# and executes the stuff in the SConscript file.
# The locals for this frame contain the special
# bottom-of-the-stack marker so that any
# exceptions that occur when processing this
# SConscript can base the printed frames at this
# level and not show SCons internals as well.
call_stack[-1].globals.update({stack_bottom:1})
old_file = call_stack[-1].globals.get('__file__')
try:
    del call_stack[-1].globals['__file__']
except KeyError:
    pass
try:
    try:
        **exec _file_ in call_stack[-1].globals**
    except SConscriptReturn:
        pass
finally:
    if old_file is not None:
        call_stack[-1].globals.update({__file__:old_file})