Example #1
0
def run_ctags(target, source, env):
    """ action function invoked by the TagsFile() Builder to run `ctags` command """

    getList = base.BindCallArguments(base.getList, target, source, env, False)
    getPathList = base.BindCallArguments(base.getPathList, target, source, env,
                                         False)
    getFile = base.BindCallArguments(base.getString, target, source, env,
                                     lambda x: x)
    getBool = base.BindCallArguments(base.getBool, target, source, env, None)

    local_dir = target[0].cwd.srcnode()
    variant_dir = target[0].cwd
    ctags_dir = variant_dir.Dir(getFile('CTAGSDIRECTORY'))

    command = env.Split(
        env.subst('$CTAGSCOM', True, target, source, lambda x: x))

    ctags_process = \
        subprocess.Popen(command, stdin = subprocess.PIPE, cwd = str(ctags_dir), env = env['ENV'])

    # source.sort()
    for file in source:
        # print("Generating tags for source file " + str(file))
        file_str = base.translate_relative_path(str(file), '.', str(ctags_dir))
        ctags_process.stdin.write(file_str + "\n")

    ctags_process.stdin.close()

    if ctags_process.wait():
        sys.stderr.write("ctags command exited with code: " +
                         str(ctags_process.returncode) + '\n')
        return ctags_process.returncode
Example #2
0
def reload_dependency_file(target, source, env):
    getString = base.BindCallArguments(base.getString, target, source, env,
                                       None)
    getList = base.BindCallArguments(base.getList, target, source, env, False)

    ext = os.path.splitext(str(source[0]))[1]
    is_cc = ext in getList('GCCDEP_CSUFFIXES')
    is_cxx = ext in getList('GCCDEP_CXXSUFFIXES')

    if is_cc or is_cxx:
        is_static_obj = base.match_ixes(target[0],
                                        getString('GCCDEP_OBJPREFIX'),
                                        getString('GCCDEP_OBJSUFFIX'))
        is_shared_obj = base.match_ixes(target[0],
                                        getString('GCCDEP_SHOBJPREFIX'),
                                        getString('GCCDEP_SHOBJSUFFIX'))

        if is_static_obj or is_shared_obj:
            if is_cc:
                if 'GCCDEP_MAKEDEP_CFLAGS' in env and env[
                        'GCCDEP_MAKEDEP_CFLAGS']:
                    env.XRefParseDepends(
                        env.subst('$GCCDEP_FILENAME', 0, target, source))
            else:
                if 'GCCDEP_MAKEDEP_CXXFLAGS' in env and env[
                        'GCCDEP_MAKEDEP_CXXFLAGS']:
                    env.XRefParseDepends(
                        env.subst('$GCCDEP_FILENAME', 0, target, source))
Example #3
0
def collect_source_dependencies(target, source, env):
    """ emitter function for TagsFile() builder, for listing sources of any target node included in the tags file """

    ext = os.path.splitext(str(env.File(
        target[0]).path)) if len(target) else ''

    if ext[1] == '.4f9807f6-fcb3-47ff-ac8e-e3a0e2e2c478':
        if len(source) and ext[0] == os.path.splitext(
                str(env.File(source[0]).path))[0]:
            target = []
        else:
            target[0] = ext[0]  # remove automatically added extension

    getBool = base.BindCallArguments(base.getBool, target, source, env, None)

    if not len(target):
        getString = base.BindCallArguments(base.getString, target, source, env,
                                           None)
        target.append(getString('CTAGSFILE'))

    if 'CTAGSCONFIG' in env:
        for tgt in target:
            for config in env.Split(env['CTAGSCONFIG']):
                if os.path.exists(config):
                    env.Depends(tgt, config)

    keepVariantDir = getBool('CTAGSKEEPVARIANTDIR')
    return base.collect_source_dependencies(keepVariantDir, target, source,
                                            env, 'CTAGSSUFFIXES')
Example #4
0
def collect_source_dependencies(target, source, env):
    """ emitter function for GTAGS() builder for listing sources of any target node included in the tags file """

    ext = os.path.splitext(str(env.Dir(target[0]).path)) if len(target) else ''

    if ext[1] == '.b7900ba9-4778-4214-82df-bb4e13689250':
        if len(source) and ext[0] == os.path.splitext(
                str(env.File(source[0]).path))[0]:
            target = []
        else:
            target[0] = ext[0]  # remove automatically added extension

    getBool = base.BindCallArguments(base.getBool, target, source, env, None)

    if not len(target):
        target.append(env['GTAGSDBPATH'])

    target = [
        env.Dir(target[0]).File(tagfile) for tagfile in env['GTAGSOUTPUTS']
    ]

    if 'GTAGSCONFIGLIST' in env and 'GTAGSCONFIG' not in env:
        for tgt in target:
            for config in env.Split(env['GTAGSCONFIGLIST']):
                if os.path.exists(config):
                    env.Depends(tgt, config)

    keepVariantDir = getBool('GTAGSKEEPVARIANTDIR')

    return base.collect_source_dependencies(keepVariantDir, target, source,
                                            env, 'GTAGSSUFFIXES')
Example #5
0
def collect_source_dependencies(target, source, env):
    """ emitter function for CFlowTree() builder, for listing sources of any target node included in the tags file """

    ext = os.path.splitext(str(target[0]))

    getBool = base.BindCallArguments(base.getBool, target, source, env, None)

    keys_list = env['CFLOWFORMAT'].keys()

    del target[0]

    keys_list.sort()
    keys_list.reverse()
    for k in keys_list:
        target.insert(0, ''.join([ext[0], k, ext[1]]))

    if 'CFLOWCONFIG' in env:
        for tgt in target:
            for config in env.Split(env['CFLOWCONFIG']):
                if os.path.exists(config):
                    env.Depends(tgt, config)

    keepVariantDir = getBool('CFLOWKEEPVARIANTDIR')

    return base.collect_source_dependencies(keepVariantDir, target, source,
                                            env, 'CFLOWSUFFIXES')
Example #6
0
def collect_source_directories(target, source, env):
    """ emitter function for CScopeDirXRef() builder, for listing source directories for xref file """

    ext = os.path.splitext(str(env.File(
        target[0]).path)) if len(target) else ''

    if ext[1] == '.8ebd1f37-538d-4d1b-a9f7-7fefa88581e4':
        if len(source) and ext[0] == os.path.splitext(
                str(env.File(source[0]).path))[0]:
            target = []
        else:
            target[0] = ext[0]  # remove automatically added extension

    getList = base.BindCallArguments(base.getList, target, source, env, False)
    getString = base.BindCallArguments(base.getString, target, source, env,
                                       None)
    getBool = base.BindCallArguments(base.getBool, target, source, env, None)

    if not target:
        target.append(getString('CSCOPEFILE'))

    for flag in getList('CSCOPEQUICKFLAG'):
        if flag in getList('CSCOPEFLAGS'):
            target += [str(target[0]) + '.in', str(target[0]) + '.po']
            break

    default_namefile = getString('CSCOPEDEFAULTNAMEFILE')

    if default_namefile:
        env.SideEffect(
            default_namefile + '.8ebd1f37-538d-4d1b-a9f7-7fefa88581e4', target)

    # if env.Dir('.').srcnode() not in source:
    #     source = [ env.Dir('.').srcnode() ] + source

    target = env.AlwaysBuild(target)
    source = source if getBool('CSCOPEKEEPVARIANTDIR') else [
        src.srcnode() for src in source
    ]

    return target, source
Example #7
0
def collect_source_dependencies(target, source, env):
    """ emitter function for CScopeXRef() builder, for listing sources of any target node included in the xref file """

    ext = os.path.splitext(str(env.File(
        target[0]).path)) if len(target) else ''

    if ext[1] == '.9afe1b0b-baf3-4dde-8c8f-338b120bc882':
        if len(source) and ext[0] == os.path.splitext(
                str(env.File(source[0]).path))[0]:
            target = []
        else:
            target[0] = ext[0]  # remove automatically added extension

    getString = base.BindCallArguments(base.getString, target, source, env,
                                       None)
    getPath = base.BindCallArguments(base.getPath, target, source, env, None)
    getList = base.BindCallArguments(base.getList, target, source, env, False)
    getBool = base.BindCallArguments(base.getBool, target, source, env, None)

    if not len(target):
        target.append(getString('CSCOPEFILE'))

    for flag in getList('CSCOPEQUICKFLAG'):
        if flag in getList('CSCOPEFLAGS'):
            target += [str(target[0]) + '.in', str(target[0]) + '.po']
            break

    if getString('CSCOPENAMEFILE'):
        target.append(getString('CSCOPENAMEFILE'))

        default_namefile = getString('CSCOPEDEFAULTNAMEFILE')

        if getString('CSCOPENAMEFILE') == default_namefile:
            env.SideEffect(default_namefile +
                           '.8ebd1f37-538d-4d1b-a9f7-7fefa88581e4'.target)

    keepVariantDir = getBool('CSCOPEKEEPVARIANTDIR')

    return base.collect_source_dependencies(keepVariantDir, target, source,
                                            env, 'CSCOPESUFFIXES', True)
Example #8
0
def build_suffix_map(target, source, env):
    """
        fills two maps with names of variables to be expanded by file name extension (suffix), using
        the list in the construction environment.
    """
    getList = base.BindCallArguments(base.getList, target, source, env, False)

    obj_suffix_map = {
        k: v
        for suffix in getList('CCCOM_COMMANDVAR') for (k, v) in suffix.items()
    }
    shobj_suffix_map = {
        k: v
        for suffix in getList('CCCOM_SHCOMMANDVAR')
        for (k, v) in suffix.items()
    }

    return [obj_suffix_map, shobj_suffix_map]
Example #9
0
def JSONCompilationDatabase(env, *args, **kw):
    """
        pseudo-builder (environement method) to translate source and target arguments as needed for the
        CompileCommandsBuilder(), and call that with the right arguments.
    """

    getString = base.BindCallArguments(base.getString, None, None, env, None)

    if len(args) == 0:
        target, source = [getString('CCCOM_DATABASE_FILE')], ['.']
    else:
        if len(args) == 1:
            target, source = [getString('CCCOM_DATABASE_FILE')
                              ], env.Flatten(args)
        else:
            target, source = env.Flatten(args[0]), env.Flatten(args[1:])

    return CompileCommandsBuilder(env, target, source, **kw)
Example #10
0
def run_cflow(target, source, env):
    """ action function invoked by the CFlowTree() Builder to run `cflow` command """

    getFile = base.BindCallArguments(base.getString, target, source, env,
                                     lambda x: x)
    getBool = base.BindCallArguments(base.getBool, target, source, env, None)

    variant_dir = target[0].cwd
    cflow_dir = variant_dir.Dir(getFile('CFLOWDIRECTORY'))

    command = env.Split(env['CFLOW']) + env.Split(env['CFLOWFLAGS']) + (
        env.subst(env.Split(env['CFLOWCPP'])) if 'CFLOWCPP' in env else [])
    command[0] = base.translate_path_executable(command[0], str(variant_dir),
                                                str(cflow_dir), env)

    if len(env.Split(env['CFLOWCPP'])):
        for definition in env.Split(env['CFLOWSDEF']):
            command += env.Split(env['CFLOWSDEFFLAG']) + [definition]

        inc_path = \
            base.translate_include_path\
                (
                    env,
                    env.Split(env['CFLOWPATH']),
                    variant_dir,
                    cflow_dir,
                    getBool('CFLOWINCLUDEVARIANTDIR')
                )

        for inc in inc_path:
            command += env.Split(env['CFLOWPATHFLAG']) + [inc]

    for sym in env.Split(env['CFLOWSYM']):
        command += env.Split(env['CFLOWSYMFLAG']) + [sym]

    keys_list = env['CFLOWFORMAT'].keys()
    keys_list.sort()

    target_index = 0

    for nested_ext in keys_list:
        format_command = command[:]
        format_command += env.Split(env['CFLOWFORMAT'][nested_ext]) + env.Split(env['CFLOWOUTPUTFLAG']) + \
                [ base.translate_relative_path(str(target[target_index]), '.', str(cflow_dir)) ]
        format_command += [
            base.translate_relative_path(str(src), '.', str(cflow_dir))
            for src in source
        ]

        target_index = target_index + 1

        print\
            (
                '(cd ' + ' '.join(base.shell_escape([ str(cflow_dir) ]))
                        + ' && ' +
                ' '.join(base.shell_escape(format_command))
            )

        cflow_process = subprocess.check_output(format_command,
                                                cwd=str(cflow_dir),
                                                env=env['ENV'])
Example #11
0
def write_compile_commands(target, source, env):
    """
        generator function to write the compilation database file (default 'compile_commands.json') for
        the given list of source binaries (executables, libraries)
    """
    getString = base.BindCallArguments(base.getString, target, source, env,
                                       None)
    getList = base.BindCallArguments(base.getList, target, source, env, False)
    getBool = base.BindCallArguments(base.getBool, target, source, env,
                                     lambda x: x)

    obj_ixes = \
        map(getString, [ 'CCCOM_OBJPREFIX',  'CCCOM_OBJSUFFIX', 'CCCOM_SHOBJPREFIX', 'CCCOM_SHOBJSUFFIX' ])

    cc_suffixes = \
        getList('CCCOM_SUFFIXES')

    source = env.Flatten(source)
    suffix_map = build_suffix_map(target, source, env)
    has_previous_unit = False
    keep_variant_dir = getBool('CCCOM_KEEP_VARIANT_DIR')

    db_file = ['[']

    for src in source:
        nodeWalker = SCons.Node.Walker(src)
        child = nodeWalker.get_next()

        while child:
            if base.is_object_file(child, obj_ixes):
                for child_src in child.sources:
                    if is_cc_source(child_src, cc_suffixes):
                        build_env = clone_build_env(child.get_build_env())

                        build_targets = [child] + child.alter_targets()[0]

                        if keep_variant_dir:
                            build_sources = child.sources
                        else:
                            build_sources = [
                                obj_src.srcnode() for obj_src in child.sources
                            ]

                        append_flags = getList('CCCOM_APPEND_FLAGS')
                        filter_flags = getList('CCCOM_REMOVE_FLAGS')
                        abs_file_path = getBool('CCCOM_ABSOLUTE_FILE')

                        if not keep_variant_dir or append_flags or filter_flags or 'CCCOM_FILTER_FUNC' in env:
                            for filter_set in filter_flags:
                                for var_name in filter_set:
                                    if var_name in build_env:
                                        for val in env.Split(
                                                filter_set[var_name]):
                                            if val in build_env[var_name]:
                                                if val in build_env[var_name]:
                                                    if isinstance(
                                                            build_env[
                                                                var_name],
                                                            str):
                                                        build_env[
                                                            var_name] = re.sub(
                                                                r'(^|\s+)' +
                                                                re.escape(val)
                                                                + r'(\s+|$)',
                                                                ' ', build_env[
                                                                    var_name])
                                                    else:
                                                        while val in build_env[
                                                                var_name]:
                                                            build_env[
                                                                var_name].remove(
                                                                    val)

                            for flag_set in append_flags:
                                build_env.Append(**flag_set)

                            if 'CCCOM_FILTER_FUNC' in env:
                                build_env['CCCOM_FILTER_FUNC'] = env[
                                    'CCCOM_FILTER_FUNC']
                                build_env['CCCOM_ENV'] = env
                                val = base.getBool(build_targets,
                                                   build_sources, build_env,
                                                   lambda x: x,
                                                   'CCCOM_FILTER_FUNC')
                                if not val:
                                    continue

                        if has_previous_unit:
                            db_file.append('    },')

                        has_previous_unit = True

                        db_file.extend\
                            ([
                        '    {',
                        '        "directory": ' + json_escape_string(build_env.fs.getcwd().get_abspath()) + ','
                            ])

                        if keep_variant_dir:
                            src_file = child_src
                        else:
                            src_file = child_src.srcnode()

                        if abs_file_path:
                            src_file = src_file.get_abspath()
                        else:
                            src_file = src_file.get_path()

                        db_file.extend\
                            ([
                        '        "file":      ' + json_escape_string(src_file) + ',',
                        '        "command":   '
                        +
                        json_escape_string\
                    (
                        build_env.subst\
                        (
                            get_build_command(obj_ixes, suffix_map, child, child_src, build_env),
                            False,
                            build_targets,
                            build_sources,
                            None
                        )
                        ) + ',',
                        '        "output":    '
                        +
                        json_escape_string(env.subst('$TARGET', False, build_targets, build_sources))
                            ])
            child = nodeWalker.get_next()

    if has_previous_unit:
        db_file.append('    }')

    db_file.append(']')

    with open(str(target[0]), 'w') as output_file:
        for line in db_file:
            output_file.write(line + '\n')
Example #12
0
def generate(env, **kw):
    """
        Populate environment with variables for the TagsFile() builder:
            $CTAGS, $CTAGSFILE, $CTAGSFLAGS, $CTAGSDEF, $CTAGSDEFPREFIX,
            $CTAGSCONFIG, $CTAGSSUFFIXES, $CTAGSSTDINFLAGS, $CTAGSOUTPUTFLAG

        Attach the TagsFile() builder to the environment.
    """

    env.SetDefault\
        (
            CTAGS           = ctags_bin,
            CTAGS_UNIVERSAL = base.BindCallArguments(check_has_universal_ctags, sys.modules[__package__]),
            CTAGS_VERSION_FLAG = [ '--version' ],
            CTAGSDIRECTORY  = env.Dir('.').srcnode(),
            CTAGSFLAGS      =
                [
                    '-h', '+.tcc.',
                    '--c-kinds=+px',
                    '--c++-kinds=+px',
                    '${__env__.subst("$CTAGS_UNIVERSAL", 0, TARGETS, SOURCES, lambda x: x) and "--extras=+q" or "--extra=+q"}',
                    '--langmap=c++:+.tcc.',
                    '--fields=+iaSt',
                    '--totals=yes'
                ],
            CTAGSDEFPREFIX  = '-I',
            CTAGSSTDINFLAGS = [ '-L', '-' ],
            CTAGSOUTPUTFLAG = [ '-o' ],
            CTAGSDEF        =
                [
                    '_GLIBCXX_NOEXCEPT',
                    '_GLIBCXX_VISIBILITY+',
                    '_GLIBCXX_VISIBILITY(x)'
                ],
            CTAGSFILE       = lambda target, source, env, for_signature: env.Dir('.').srcnode().File('tags'),
            CTAGSCONFIG     = [ '/etc/ctags.conf', '/usr/local/etc/ctags.conf', os.path.join(os.environ['HOME'], '.ctags'), '#.ctags' ],
            CTAGSSUFFIXES   =
                [
                    '',
                    '.build.xml',
                    '.asm', '.ASM', '.s', '.S', '.A51', '.29k', '.29K', # *.[68][68][kKsSxX] *.[xX][68][68]
                    '.asp', '.asa',
                    '.awk', '.gawk', '.mawk',
                    '.bas', '.bi', '.bb', '.pb',
                    '.bet',
                    '.c',
                    '.c++', '.cc', '.cp', '.cpp', '.cxx',
                    '.h', '.h++', '.hh', '.hp', '.hpp', '.hxx', '.C', '.H', '.tcc',
                    '.cs',
                    '.cbl', '.cob', '.CBL', '.COB',
                    '.bat', '.cmd',
                    '.e',
                    '.erl', '.ERL', '.hrl', '.HRL',
                    '.as', '.mxml',
                    '.f', '.for', '.ftn', '.f77', '.f90', '.f95', '.F', '.FOR', '.FTN', '.F77', '.F90', '.F95',
                    '.go',
                    '.htm', '.html',
                    '.java',
                    '.js',
                    '.cl', '.clisp', '.el', '.l', '.lisp', '.lsp',
                    '.lua',
                    '.mak', '.mk', # [Mm]akefile GNUmakefile',
                    '.m',
                    '.m', '.h',
                    '.ml', '.mli',
                    '.p', '.pas',
                    '.pl', '.pm', '.plx', '.perl',
                    '.php', '.php3', '.phtml',
                    '.py', '.pyx', '.pxd', '.pxi', '.scons',
                    '.cmd', '.rexx', '.rx',
                    '.rb', '.ruby',
                    '.SCM', '.SM', '.sch', '.scheme', '.scm', '.sm',
                    '.sh', '.SH', '.bsh', '.bash', '.ksh', '.zsh',
                    '.sl',
                    '.sml', '.sig',
                    '.sql',
                    '.tcl', '.tk', '.wish', '.itcl',
                    '.tex',
                    '.vr', '.vri', '.vrh',
                    '.v',
                    '.vhdl', '.vhd',
                    '.vim',
                    '.y'
                ],
            CTAGSKEEPVARIANTDIR = False,
            CTAGS_TRANSLATED_CMD =
                lambda target, source, env, for_signature:
                    [
                        base.translate_path_executable
                            (
                                str(env.Split(env.subst("$CTAGS", True, target, source, lambda x: x))[0]),
                                str(target[0].cwd),
                                str(target[0].cwd.Dir(env.subst('$CTAGSDIRECTORY', True, target, source, lambda x: x))),
                                env
                            )
                    ] \
                        + \
                    env.Split(env.subst("$CTAGS", True, target, source, lambda x: x))[1:],

            CTAGS_TRANSLATED_TARGET =
                lambda target, source, env, for_signature:
                    base.translate_relative_path\
                        (
                            str(target[0]),
                            '.',
                            str(target[0].cwd.Dir(env.subst('$CTAGSDIRECTORY', True, target, source, lambda x: x)))
                        ),

            CTAGS_DEF_ARGS =
                lambda target, source, env, for_signature:
                    [
                        arg
                            for ctags_def in env.Split(env.subst('$CTAGSDEF', True, target, source, lambda x: x))
                                for arg in env.Split(env.subst('$CTAGSDEFPREFIX', True, target, source, lambda x: x))
                                                + [ ctags_def ]
                    ],

            CTAGSCOM =
                lambda target, source, env, for_signature:
                    env.Split(env.subst('$CTAGS_TRANSLATED_CMD',    True, target, source, lambda x: x))
                            +
                    env.Split(env.subst('$CTAGSFLAGS',              True, target, source, lambda x: x))
                            +
                    env.Split(env.subst('$CTAGSSTDINFLAGS',         True, target, source, lambda x: x))
                            +
                    env.Split(env.subst('$CTAGSOUTPUTFLAG',         True, target, source, lambda x: x))
                            +
                    [ (env.subst('$CTAGS_TRANSLATED_TARGET',        True, target, source, lambda x: x)) ]
                            +
                    env.Split(env.subst('$CTAGS_DEF_ARGS',          True, target, source, lambda x: x)),

            CTAGSCOM_QUOTED =
                lambda target, source, env, for_signature:
                    base.env_shell_escape(env, env.Split(env.subst('$CTAGSCOM', True, target, source, lambda x: x))),

            CTAGSCOMSTR = "(cd $CTAGSDIRECTORY && $CTAGSCOM_QUOTED)"
        )

    env['BUILDERS']['TagsFile'] = env.Builder\
            (
                emitter = collect_source_dependencies,
                action  = SCons.Script.Action(run_ctags, '$CTAGSCOMSTR'),
                multi   = True,
                name    = 'TagsFile',
                suffix  = '4f9807f6-fcb3-47ff-ac8e-e3a0e2e2c478',
                # source_scanner = SCons.Script.CScan
            )
Example #13
0
def run_cscope(target, source, env):
    """ action function invoked by the CScopeXRef() Builder to run `cscope` command """

    getList = base.BindCallArguments(base.getList, target, source, env, False)
    getPathList = base.BindCallArguments(base.getPathList, target, source, env,
                                         False)
    getFile = base.BindCallArguments(base.getString, target, source, env,
                                     lambda x: x)
    getBool = base.BindCallArguments(base.getBool, target, source, env, None)

    variant_dir = target[0].cwd
    cscope_dir = variant_dir.Dir(getFile('CSCOPEDIRECTORY'))

    namefile = None

    if 'CSCOPENAMEFILE' in env:
        namefile = open(str(variant_dir.File(getFile('CSCOPENAMEFILE'))), 'w')

        nameFileFlags = getList('CSCOPENAMEFILEFLAGS')

        for arg in env.Split(
                env.subst("$CSCOPEFLAGS", True, target, source, lambda x: x)):
            if arg in nameFileFlags:
                namefile.write(arg)
                namefile.write('\n')

    cscope_env = env['ENV']

    env_var_list = getList('CSCOPESOURCEDIRSENV')
    inc_var_list = getList('CSCOPEINCLUDEDIRSENV')

    for env_var in env_var_list:
        if env_var and env_var in cscope_env and cscope_env[env_var]:
            source_dirs = str(cscope_env[env_var]).split(os.pathsep)

            source_dirs = \
                base.translate_include_path\
                    (
                        env, source_dirs, '.', cscope_dir, getBool('CSCOPEKEEPVARIANTDIR')
                    )
            cscope_env[env_var] = os.pathsep.join(source_dirs)

    for inc_var in inc_var_list:
        if inc_var and inc_var in cscope_env and cscope_env[inc_var]:
            inc_dirs = str(cscope_env[inc_var]).split(os.pathsep)

            inc_dirs = \
                base.translate_include_path\
                    (
                        env, inc_dirs, '.', cscope_dir, getBool('CSCOPEINCLUDEVARIANTDIR')
                    )
            cscope_env[inc_var] = os.pathsep.join(inc_dirs)

    inc_path = env.Split(
        env.subst("$CSCOPE_TRANSLATED_PATH", True, target, source,
                  lambda x: x))

    if namefile is not None:
        for inc_var in inc_var_list:
            if inc_var and inc_var in cscope_env and cscope_env[inc_var]:
                for incdir in cscope_env[inc_var].split(os.pathsep):
                    if incdir not in inc_path:
                        inc_path.append(incdir)

        for incdir in inc_path:
            for arg in getList('CSCOPEINCFLAG'):
                namefile.write(arg)
                namefile.write(' ')

            if re.search('[\s"]', incdir) is not None:
                incdir = '"' + incdir.replace('\\', '\\\\').replace(
                    '"', '\\"') + '"'

            namefile.write(incdir)
            namefile.write('\n')

    try:
        command = env.Split(
            env.subst("$CSCOPECOM", True, target, source, lambda x: x))

        cscope_process = \
            subprocess.Popen(command, stdin = subprocess.PIPE, env = cscope_env, cwd = str(cscope_dir))

        source.sort()
        for file in source:
            file_str = base.translate_relative_path(str(file), '.',
                                                    str(cscope_dir))

            if re.search('[\s"]', file_str) is not None:
                file_str = '"' + file_str.replace('\\', '\\\\').replace(
                    '"', '\\"') + '"'

            # print("Generating xrefs for source file " + file_str)
            if namefile is not None:
                namefile.write(file_str + '\n')

            cscope_process.stdin.write(file_str + '\n')

        cscope_process.stdin.close()

        if cscope_process.wait():
            sys.stderr.write("cscope command exited with code: " +
                             str(cscope_process.returncode) + '\n')
            return cscope_process.returncode
    finally:
        if namefile is not None:
            namefile.close()
Example #14
0
def run_cscope_on_dirs(target, source, env):
    """ action function invoked by the CScopeDirXRef() Builder to run `cscope` command """

    getList = base.BindCallArguments(base.getList, target, source, env, False)
    getPathList = base.BindCallArguments(base.getPathList, target, source, env,
                                         False)
    getString = base.BindCallArguments(base.getString, target, source, env,
                                       None)
    getFile = base.BindCallArguments(base.getString, target, source, env,
                                     lambda x: x)
    getBool = base.BindCallArguments(base.getBool, target, source, env, None)

    variant_dir = target[0].cwd
    cscope_dir = variant_dir.Dir(getFile('CSCOPEDIRECTORY'))

    command = getList('CSCOPE') + getList('CSCOPEFLAGS')

    command[0] = base.translate_path_executable(command[0], str(variant_dir),
                                                str(cscope_dir), env)

    command += \
            getList('CSCOPEOUTPUTFLAG') \
                + \
            [ base.translate_relative_path(str(target[0]), '.', str(cscope_dir)) ]

    inc_path = \
        base.translate_include_path\
            (
                env,
                getPathList('CSCOPEPATH') + getPathList('CSCOPESYSPATH'),
                variant_dir,
                cscope_dir,
                getBool('CSCOPEINCLUDEVARIANTDIR')
            )

    for incdir in inc_path:
        command += getList('CSCOPEINCFLAG') + [incdir]

    for srcdir in source:
        command += \
                getList('CSCOPESOURCEDIRFLAG') \
                    + \
                [ base.translate_relative_path(str(srcdir), '.', str(cscope_dir)) ]

    cscope_env = env['ENV']

    env_var_list = getList('CSCOPESOURCEDIRSENV')
    inc_var_list = getList('CSCOPEINCLUDEDIRSENV')

    for env_var in env_var_list:
        if env_var and env_var in cscope_env and cscope_env[env_var]:
            source_dirs = str(cscope_env[env_var]).split(os.pathsep)

            source_dirs = \
                base.translate_include_path\
                    (
                        env, source_dirs, '.', cscope_dir, getBool('CSCOPEKEEPVARIANTDIR')
                    )
            cscope_env[env_var] = os.pathsep.join(source_dirs)

    for inc_var in inc_var_list:
        if inc_var and inc_var in cscope_env and cscope_env[inc_var]:
            inc_dirs = str(cscope_env[inc_var]).split(os.pathsep)

            inc_dirs = \
                base.translate_include_path\
                    (
                        env, inc_dirs, '.', cscope_dir, getBool('CSCOPEINCLUDEVARIANTDIR')
                    )
            cscope_env[inc_var] = os.pathsep.join(inc_dirs)

    default_namefile = str(cscope_dir.File(getFile('CSCOPEDEFAULTNAMEFILE')))

    if os.path.exists(default_namefile):
        os.rename(default_namefile,
                  default_namefile + '.8ebd1f37-538d-4d1b-a9f7-7fefa88581e4')

    try:
        print\
            (
                '(cd ' + ' '.join(base.shell_escape([ str(cscope_dir) ]))
                       +  ' && ' + \
                ' '.join(base.shell_escape(command)) + ')'
            )

        return subprocess.Popen(command, env=cscope_env,
                                cwd=str(cscope_dir)).wait()
    finally:
        if os.path.exists(default_namefile +
                          '.8ebd1f37-538d-4d1b-a9f7-7fefa88581e4'):
            os.rename(
                default_namefile + '.8ebd1f37-538d-4d1b-a9f7-7fefa88581e4',
                default_namefile)
Example #15
0
def generate(env, **kw):
    """
        Populate the given environment with the information to run the tool
        Also inject the tool emitter for gcc dependency generation and parsing
        into existing Object / SharedObject builders in the environment
    """

    geBool = base.BindCallArguments(base.getList, None, None, env, lambda x: x)
    getList = base.BindCallArguments(base.getList, None, None, env, False)

    env.SetDefault\
        (
            GCCDEP_SUFFIX   = '.d',
            GCCDEP_CSUFFIXES = [ '.c' ] + ([ ] if SCons.Util.case_sensitive_suffixes('.c', 'C') else [ '.C' ] ),
            GCCDEP_CXXSUFFIXES  =
                [ '.cc', '.cpp', '.cxx', '.c++', '.C++' ]
                    +
                ([ '.C' ] if SCons.Util.case_sensitive_suffixes('.c', '.C') else [ ]),
            GCCDEP_FILENAME =
                lambda target, source, env, for_signature:
                    env.File(target[0]).Dir('depend').Dir\
                        (
                            re.sub
                                (
                                    '((?<=^)|(?<=/))\.\.(?=(/|$))',
                                    '__',
                                    str(env.Dir('#').rel_path(source[0].srcnode().dir))
                                )
                        )
                            .File(str(target[0].name) + env.subst('$GCCDEP_SUFFIX', False, source, target)),
            GCCDEP_CFLAGS_VAR        = 'CFLAGS',
            GCCDEP_CXXFLAGS_VAR      = 'CXXFLAGS',
            GCCDEP_MAKEDEP_CFLAGS    = [ ],
            GCCDEP_MAKEDEP_CXXFLAGS  = [ ],
            GCCDEP_OBJPREFIX         = '$OBJPREFIX',
            GCCDEP_OBJSUFFIX         = '$OBJSUFFIX',
            GCCDEP_SHOBJPREFIX       = '$SHOBJPREFIX',
            GCCDEP_SHOBJSUFFIX       = '$SHOBJSUFFIX',
            GCCDEP_CFLAGS            = [ '-MD', '-MF', '$GCCDEP_FILENAME' ],
            GCCDEP_CXXFLAGS          = [ '-MD', '-MF', '$GCCDEP_FILENAME' ],
            GCCDEP_CC                = '$CC',
            GCCDEP_GCC_BASENAME      = 'gcc',
            GCCDEP_SHCC              = '$SHCC',
            GCCDEP_GCC_SH_BASENAME   = 'gcc',
            GCCDEP_CXX               = '$CXX',
            GCCDEP_GXX_BASENAME      = 'g++',
            GCCDEP_SHCXX             = '$SHCXX',
            GCCDEP_GXX_SH_BASENAME   = 'g++',
            GCCDEP_CHECK_USING_GCC   =
                lambda target, source, env, for_signature:
                    not not re.match
                        (
                            r'^(.*\b)?' + re.escape(env.subst('$GCCDEP_GCC_BASENAME', 1, source, target)) + r'(-[0-9\.]+)?(\b|\s|$)',
                            find_tool_basename(env, env.subst('$GCCDEP_CC', 0, source, target))
                        ),
            GCCDEP_CHECK_USING_SH_GCC   =
                lambda target, source, env, for_signature:
                    not not re.match
                        (
                            r'^(.*\b)?' + re.escape(env.subst('$GCCDEP_GCC_SH_BASENAME', 1, source, target)) + r'(-[0-9\.]+)?(\b|\s|$)',
                            find_tool_basename(env, env.subst('$GCCDEP_SHCC', 0, source, target))
                        ),
            GCCDEP_CHECK_USING_GXX   =
                lambda target, source, env, for_signature:
                    not not re.match
                        (
                            r'^(.*\b)?' + re.escape(env.subst('$GCCDEP_GXX_BASENAME', 1, source, target)) + r'(-[0-9\.]+)?(\b|\s|$)',
                            find_tool_basename(env, env.subst('$GCCDEP_CXX', 0, source, target))
                        ),
            GCCDEP_CHECK_USING_SH_GXX   =
                lambda target, source, env, for_signature:
                    not not re.match
                        (
                            r'^(.*\b)?' + re.escape(env.subst('$GCCDEP_GXX_SH_BASENAME', 1, source, target)) + r'(-[0-9\.]+)?(\b|\s|$)',
                            find_tool_basename(env, env.subst('$GCCDEP_SHCXX', 0, source, target))
                        ),
            GCCDEP_INJECTED = False
        )

    env.Append\
        (
            **
            {
                env['GCCDEP_CFLAGS_VAR']:   [ '$GCCDEP_MAKEDEP_CFLAGS' ],
                env['GCCDEP_CXXFLAGS_VAR']: [ '$GCCDEP_MAKEDEP_CXXFLAGS' ]
            }
        )

    builders = [
        env['BUILDERS'][name] for name in ['StaticObject', 'SharedObject']
        if name in env['BUILDERS']
    ]

    if 'Object' in env['BUILDERS']:
        objectBuilder = env['BUILDERS']['Object']
        if objectBuilder not in builders:
            builders.append(objectBuilder)

    # print("Selected builders: " + str(builders))

    for builder in builders:
        # inject gcc_dep_emitter in the current builder
        if isinstance(builder.emitter, DictEmitter):
            for ext in getList('GCCDEP_CSUFFIXES') + getList(
                    'GCCDEP_CXXSUFFIXES'):
                if ext in builder.emitter:
                    if isinstance(builder.emitter[ext], ListEmitter):
                        if gcc_dep_emitter not in builder.emitter[ext]:
                            builder.emitter[ext].append(gcc_dep_emitter)
                            # print('\033[92m' "Emitter injected in Builder list in dict" '\033[0m')
                    else:
                        builder.emitter[ext] = ListEmitter(
                            [builder.emitter[ext], gcc_dep_emitter])
                        # print('\033[92m' "Emitter injected in Builder dict in a new list" '\033[0m')
                else:
                    build.emitter[ext] = gcc_dep_emitter
                    # print('\033[92m' "Emitter injected in Builder dict" '\033[0m')
        else:
            if isinstance(builder.emitter, ListEmitter):
                if gcc_dep_emitter not in builder.emitter:
                    builder.emitter.append(gcc_dep_emitter)
                    # print('\033[92m' "Emitter injected in Builder list" '\033[0m')
            else:
                old_emitter = builder.emitter[ext]
                builder.emitter[ext] = ListEmitter(
                    [old_emitter, gcc_dep_emitter])

        if isinstance(builder, CompositeBuilder):
            for ext in getList('GCCDEP_CSUFFIXES') + getList(
                    'GCCDEP_CXXSUFFIXES'):
                try:
                    if ext in builder.cmdgen:
                        builder.add_action\
                                (
                                    ext,
                                    ListAction
                                        (
                                            [
                                                builder.cmdgen[ext],
                                                env.Action(reload_dependency_file, lambda target, source, env: None)
                                            ]
                                        )
                                )
                except AttributeError:
                    pass

        env['GCCDEP_INJECTED'] = True
        env.AddMethod(XRefParseDepends)
Example #16
0
def gcc_dep_emitter(target, source, env):
    """
        emitter function for SCons Builders, injected into the existing Object / SharedObject
        builders in the environment, to include and load the new dependency file with the
        object
    """
    getBool = base.BindCallArguments(base.getBool, target, source, env,
                                     lambda x: x)
    getString = base.BindCallArguments(base.getString, target, source, env,
                                       None)
    getList = base.BindCallArguments(base.getList, target, source, env, False)

    if len(target):
        ext = os.path.splitext(str(source[0]))[1]

        is_cc = ext in getList('GCCDEP_CSUFFIXES')
        is_cxx = ext in getList('GCCDEP_CXXSUFFIXES')

        is_static_obj = base.match_ixes(target[0],
                                        getString('GCCDEP_OBJPREFIX'),
                                        getString('GCCDEP_OBJSUFFIX'))
        is_shared_obj = base.match_ixes(target[0],
                                        getString('GCCDEP_SHOBJPREFIX'),
                                        getString('GCCDEP_SHOBJSUFFIX'))

        if (is_cc or is_cxx) and (is_static_obj or is_shared_obj):
            if is_cc:
                is_gnu_compiler = getBool(
                    'GCCDEP_CHECK_USING_GCC'
                    if is_static_obj else 'GCCDEP_CHECK_USING_SH_GCC')
                has_makedep_flags = ('GCCDEP_MAKEDEP_CFLAGS' in env
                                     and env['GCCDEP_MAKEDEP_CFLAGS'])
            else:
                is_gnu_compiler = getBool(
                    'GCCDEP_CHECK_USING_GXX'
                    if is_static_obj else 'GCCDEP_CHECK_USING_SH_GXX')
                has_makedep_flags = ('GCCDEP_MAKEDEP_CXXFLAGS' in env
                                     and env['GCCDEP_MAKEDEP_CXXFLAGS'])

            if is_gnu_compiler:
                if not has_makedep_flags:
                    if is_cc:
                        env['GCCDEP_MAKEDEP_CFLAGS'] = env['GCCDEP_CFLAGS']
                    else:
                        env['GCCDEP_MAKEDEP_CXXFLAGS'] = env['GCCDEP_CXXFLAGS']

                if callable(env['GCCDEP_FILENAME']):
                    # make explicit call, to work around the "relative path outside" issue
                    dep_file = env.File(env['GCCDEP_FILENAME'](target, source,
                                                               env, False))
                else:
                    dep_file = env.File(
                        env.subst('$GCCDEP_FILENAME', 0, source, target))

                env.SideEffect(dep_file, target[0])

                script_dir = env.fs.getcwd()
                env.fs.chdir(env.Dir('#'))

                try:
                    # env.ParseDepends(dep_file.get_abspath())
                    env.XRefParseDepends(dep_file.get_abspath(),
                                         existing_only=True)
                finally:
                    env.fs.chdir(script_dir)

                env.Clean(target[0], dep_file)
            else:
                if has_makedep_flags:
                    if is_cc:
                        env['GCCDEP_MAKEDEP_CFLAGS'] = []
                    else:
                        env['GCCDEP_MAKEDEP_CXXFLAGS'] = []

    return target, source