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
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))
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')
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')
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')
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
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)
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]
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)
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'])
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')
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 )
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()
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)
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)
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