def extract_autotools_deps(outlines, srctree, extravalues=None, acfile=None): import shlex # Find all plugins that want to register handlers logger.debug('Loading autotools handlers') handlers = [] for plugin in plugins: if hasattr(plugin, 'register_autotools_handlers'): plugin.register_autotools_handlers(handlers) values = {} inherits = [] # Hardcoded map, we also use a dynamic one based on what's in the sysroot progmap = { 'flex': 'flex-native', 'bison': 'bison-native', 'm4': 'm4-native', 'tar': 'tar-native', 'ar': 'binutils-native', 'ranlib': 'binutils-native', 'ld': 'binutils-native', 'strip': 'binutils-native', 'libtool': '', 'autoconf': '', 'autoheader': '', 'automake': '', 'uname': '', 'rm': '', 'cp': '', 'mv': '', 'find': '', 'awk': '', 'sed': '', } progclassmap = { 'gconftool-2': 'gconf', 'pkg-config': 'pkgconfig', 'python': 'pythonnative', 'python3': 'python3native', 'perl': 'perlnative', 'makeinfo': 'texinfo', } pkg_re = re.compile( 'PKG_CHECK_MODULES\(\s*\[?[a-zA-Z0-9_]*\]?,\s*\[?([^,\]]*)\]?[),].*' ) pkgce_re = re.compile('PKG_CHECK_EXISTS\(\s*\[?([^,\]]*)\]?[),].*') lib_re = re.compile('AC_CHECK_LIB\(\s*\[?([^,\]]*)\]?,.*') libx_re = re.compile( 'AX_CHECK_LIBRARY\(\s*\[?[^,\]]*\]?,\s*\[?([^,\]]*)\]?,\s*\[?([a-zA-Z0-9-]*)\]?,.*' ) progs_re = re.compile( '_PROGS?\(\s*\[?[a-zA-Z0-9_]*\]?,\s*\[?([^,\]]*)\]?[),].*') dep_re = re.compile('([^ ><=]+)( [<>=]+ [^ ><=]+)?') ac_init_re = re.compile('AC_INIT\(\s*([^,]+),\s*([^,]+)[,)].*') am_init_re = re.compile( 'AM_INIT_AUTOMAKE\(\s*([^,]+),\s*([^,]+)[,)].*') define_re = re.compile('\s*(m4_)?define\(\s*([^,]+),\s*([^,]+)\)') version_re = re.compile('([0-9.]+)') defines = {} def subst_defines(value): newvalue = value for define, defval in defines.items(): newvalue = newvalue.replace(define, defval) if newvalue != value: return subst_defines(newvalue) return value def process_value(value): value = value.replace('[', '').replace(']', '') if value.startswith('m4_esyscmd(') or value.startswith( 'm4_esyscmd_s('): cmd = subst_defines(value[value.index('(') + 1:-1]) try: if '|' in cmd: cmd = 'set -o pipefail; ' + cmd stdout, _ = bb.process.run(cmd, cwd=srctree, shell=True) ret = stdout.rstrip() except bb.process.ExecutionError as e: ret = '' elif value.startswith('m4_'): return None ret = subst_defines(value) if ret: ret = ret.strip('"\'') return ret # Since a configure.ac file is essentially a program, this is only ever going to be # a hack unfortunately; but it ought to be enough of an approximation if acfile: srcfiles = [acfile] else: srcfiles = RecipeHandler.checkfiles( srctree, ['acinclude.m4', 'configure.ac', 'configure.in']) pcdeps = [] libdeps = [] deps = [] unmapped = [] RecipeHandler.load_binmap(tinfoil.config_data) def process_macro(keyword, value): for handler in handlers: if handler.process_macro(srctree, keyword, value, process_value, libdeps, pcdeps, deps, outlines, inherits, values): return logger.debug('Found keyword %s with value "%s"' % (keyword, value)) if keyword == 'PKG_CHECK_MODULES': res = pkg_re.search(value) if res: res = dep_re.findall(res.group(1)) if res: pcdeps.extend([x[0] for x in res]) inherits.append('pkgconfig') elif keyword == 'PKG_CHECK_EXISTS': res = pkgce_re.search(value) if res: res = dep_re.findall(res.group(1)) if res: pcdeps.extend([x[0] for x in res]) inherits.append('pkgconfig') elif keyword in ('AM_GNU_GETTEXT', 'AM_GLIB_GNU_GETTEXT', 'GETTEXT_PACKAGE'): inherits.append('gettext') elif keyword in ('AC_PROG_INTLTOOL', 'IT_PROG_INTLTOOL'): deps.append('intltool-native') elif keyword == 'AM_PATH_GLIB_2_0': deps.append('glib-2.0') elif keyword in ('AC_CHECK_PROG', 'AC_PATH_PROG', 'AX_WITH_PROG'): res = progs_re.search(value) if res: for prog in shlex.split(res.group(1)): prog = prog.split()[0] for handler in handlers: if handler.process_prog(srctree, keyword, value, prog, deps, outlines, inherits, values): return progclass = progclassmap.get(prog, None) if progclass: inherits.append(progclass) else: progdep = RecipeHandler.recipebinmap.get( prog, None) if not progdep: progdep = progmap.get(prog, None) if progdep: deps.append(progdep) elif progdep is None: if not prog.startswith('$'): unmapped.append(prog) elif keyword == 'AC_CHECK_LIB': res = lib_re.search(value) if res: lib = res.group(1) if not lib.startswith('$'): libdeps.append(lib) elif keyword == 'AX_CHECK_LIBRARY': res = libx_re.search(value) if res: lib = res.group(2) if not lib.startswith('$'): header = res.group(1) libdeps.append((lib, header)) elif keyword == 'AC_PATH_X': deps.append('libx11') elif keyword in ('AX_BOOST', 'BOOST_REQUIRE'): deps.append('boost') elif keyword in ('AC_PROG_LEX', 'AM_PROG_LEX', 'AX_PROG_FLEX'): deps.append('flex-native') elif keyword in ('AC_PROG_YACC', 'AX_PROG_BISON'): deps.append('bison-native') elif keyword == 'AX_CHECK_ZLIB': deps.append('zlib') elif keyword in ('AX_CHECK_OPENSSL', 'AX_LIB_CRYPTO'): deps.append('openssl') elif keyword == 'AX_LIB_CURL': deps.append('curl') elif keyword == 'AX_LIB_BEECRYPT': deps.append('beecrypt') elif keyword == 'AX_LIB_EXPAT': deps.append('expat') elif keyword == 'AX_LIB_GCRYPT': deps.append('libgcrypt') elif keyword == 'AX_LIB_NETTLE': deps.append('nettle') elif keyword == 'AX_LIB_READLINE': deps.append('readline') elif keyword == 'AX_LIB_SQLITE3': deps.append('sqlite3') elif keyword == 'AX_LIB_TAGLIB': deps.append('taglib') elif keyword in ['AX_PKG_SWIG', 'AC_PROG_SWIG']: deps.append('swig-native') elif keyword == 'AX_PROG_XSLTPROC': deps.append('libxslt-native') elif keyword in [ 'AC_PYTHON_DEVEL', 'AX_PYTHON_DEVEL', 'AM_PATH_PYTHON' ]: pythonclass = 'pythonnative' res = version_re.search(value) if res: if res.group(1).startswith('3'): pythonclass = 'python3native' # Avoid replacing python3native with pythonnative if not pythonclass in inherits and not 'python3native' in inherits: if 'pythonnative' in inherits: inherits.remove('pythonnative') inherits.append(pythonclass) elif keyword == 'AX_WITH_CURSES': deps.append('ncurses') elif keyword == 'AX_PATH_BDB': deps.append('db') elif keyword == 'AX_PATH_LIB_PCRE': deps.append('libpcre') elif keyword == 'AC_INIT': if extravalues is not None: res = ac_init_re.match(value) if res: extravalues['PN'] = process_value(res.group(1)) pv = process_value(res.group(2)) if validate_pv(pv): extravalues['PV'] = pv elif keyword == 'AM_INIT_AUTOMAKE': if extravalues is not None: if 'PN' not in extravalues: res = am_init_re.match(value) if res: if res.group(1) != 'AC_PACKAGE_NAME': extravalues['PN'] = process_value(res.group(1)) pv = process_value(res.group(2)) if validate_pv(pv): extravalues['PV'] = pv elif keyword == 'define(': res = define_re.match(value) if res: key = res.group(2).strip('[]') value = process_value(res.group(3)) if value is not None: defines[key] = value keywords = [ 'PKG_CHECK_MODULES', 'PKG_CHECK_EXISTS', 'AM_GNU_GETTEXT', 'AM_GLIB_GNU_GETTEXT', 'GETTEXT_PACKAGE', 'AC_PROG_INTLTOOL', 'IT_PROG_INTLTOOL', 'AM_PATH_GLIB_2_0', 'AC_CHECK_PROG', 'AC_PATH_PROG', 'AX_WITH_PROG', 'AC_CHECK_LIB', 'AX_CHECK_LIBRARY', 'AC_PATH_X', 'AX_BOOST', 'BOOST_REQUIRE', 'AC_PROG_LEX', 'AM_PROG_LEX', 'AX_PROG_FLEX', 'AC_PROG_YACC', 'AX_PROG_BISON', 'AX_CHECK_ZLIB', 'AX_CHECK_OPENSSL', 'AX_LIB_CRYPTO', 'AX_LIB_CURL', 'AX_LIB_BEECRYPT', 'AX_LIB_EXPAT', 'AX_LIB_GCRYPT', 'AX_LIB_NETTLE', 'AX_LIB_READLINE' 'AX_LIB_SQLITE3', 'AX_LIB_TAGLIB', 'AX_PKG_SWIG', 'AC_PROG_SWIG', 'AX_PROG_XSLTPROC', 'AC_PYTHON_DEVEL', 'AX_PYTHON_DEVEL', 'AM_PATH_PYTHON', 'AX_WITH_CURSES', 'AX_PATH_BDB', 'AX_PATH_LIB_PCRE', 'AC_INIT', 'AM_INIT_AUTOMAKE', 'define(', ] for handler in handlers: handler.extend_keywords(keywords) for srcfile in srcfiles: nesting = 0 in_keyword = '' partial = '' with open(srcfile, 'r', errors='surrogateescape') as f: for line in f: if in_keyword: partial += ' ' + line.strip() if partial.endswith('\\'): partial = partial[:-1] nesting = nesting + line.count('(') - line.count(')') if nesting == 0: process_macro(in_keyword, partial) partial = '' in_keyword = '' else: for keyword in keywords: if keyword in line: nesting = line.count('(') - line.count(')') if nesting > 0: partial = line.strip() if partial.endswith('\\'): partial = partial[:-1] in_keyword = keyword else: process_macro(keyword, line.strip()) break if in_keyword: process_macro(in_keyword, partial) if extravalues: for k, v in list(extravalues.items()): if v: if v.startswith('$') or v.startswith('@') or v.startswith( '%'): del extravalues[k] else: extravalues[k] = v.strip('"\'').rstrip('()') if unmapped: outlines.append( '# NOTE: the following prog dependencies are unknown, ignoring: %s' % ' '.join(list(set(unmapped)))) RecipeHandler.handle_depends(libdeps, pcdeps, deps, outlines, values, tinfoil.config_data) for handler in handlers: handler.post_process(srctree, libdeps, pcdeps, deps, outlines, inherits, values) if inherits: values['inherit'] = ' '.join(list(set(inherits))) return values
def extract_autotools_deps(outlines, srctree, extravalues=None, acfile=None): import shlex # Find all plugins that want to register handlers logger.debug('Loading autotools handlers') handlers = [] for plugin in plugins: if hasattr(plugin, 'register_autotools_handlers'): plugin.register_autotools_handlers(handlers) values = {} inherits = [] # Hardcoded map, we also use a dynamic one based on what's in the sysroot progmap = {'flex': 'flex-native', 'bison': 'bison-native', 'm4': 'm4-native', 'tar': 'tar-native', 'ar': 'binutils-native', 'ranlib': 'binutils-native', 'ld': 'binutils-native', 'strip': 'binutils-native', 'libtool': '', 'autoconf': '', 'autoheader': '', 'automake': '', 'uname': '', 'rm': '', 'cp': '', 'mv': '', 'find': '', 'awk': '', 'sed': '', } progclassmap = {'gconftool-2': 'gconf', 'pkg-config': 'pkgconfig', 'python': 'pythonnative', 'python3': 'python3native', 'perl': 'perlnative', 'makeinfo': 'texinfo', } pkg_re = re.compile('PKG_CHECK_MODULES\(\s*\[?[a-zA-Z0-9_]*\]?,\s*\[?([^,\]]*)\]?[),].*') pkgce_re = re.compile('PKG_CHECK_EXISTS\(\s*\[?([^,\]]*)\]?[),].*') lib_re = re.compile('AC_CHECK_LIB\(\s*\[?([^,\]]*)\]?,.*') libx_re = re.compile('AX_CHECK_LIBRARY\(\s*\[?[^,\]]*\]?,\s*\[?([^,\]]*)\]?,\s*\[?([a-zA-Z0-9-]*)\]?,.*') progs_re = re.compile('_PROGS?\(\s*\[?[a-zA-Z0-9_]*\]?,\s*\[?([^,\]]*)\]?[),].*') dep_re = re.compile('([^ ><=]+)( [<>=]+ [^ ><=]+)?') ac_init_re = re.compile('AC_INIT\(\s*([^,]+),\s*([^,]+)[,)].*') am_init_re = re.compile('AM_INIT_AUTOMAKE\(\s*([^,]+),\s*([^,]+)[,)].*') define_re = re.compile('\s*(m4_)?define\(\s*([^,]+),\s*([^,]+)\)') defines = {} def subst_defines(value): newvalue = value for define, defval in defines.items(): newvalue = newvalue.replace(define, defval) if newvalue != value: return subst_defines(newvalue) return value def process_value(value): value = value.replace('[', '').replace(']', '') if value.startswith('m4_esyscmd(') or value.startswith('m4_esyscmd_s('): cmd = subst_defines(value[value.index('(')+1:-1]) try: if '|' in cmd: cmd = 'set -o pipefail; ' + cmd stdout, _ = bb.process.run(cmd, cwd=srctree, shell=True) ret = stdout.rstrip() except bb.process.ExecutionError as e: ret = '' elif value.startswith('m4_'): return None ret = subst_defines(value) if ret: ret = ret.strip('"\'') return ret # Since a configure.ac file is essentially a program, this is only ever going to be # a hack unfortunately; but it ought to be enough of an approximation if acfile: srcfiles = [acfile] else: srcfiles = RecipeHandler.checkfiles(srctree, ['acinclude.m4', 'configure.ac', 'configure.in']) pcdeps = [] libdeps = [] deps = [] unmapped = [] RecipeHandler.load_binmap(tinfoil.config_data) def process_macro(keyword, value): for handler in handlers: if handler.process_macro(srctree, keyword, value, process_value, libdeps, pcdeps, deps, outlines, inherits, values): return if keyword == 'PKG_CHECK_MODULES': res = pkg_re.search(value) if res: res = dep_re.findall(res.group(1)) if res: pcdeps.extend([x[0] for x in res]) inherits.append('pkgconfig') elif keyword == 'PKG_CHECK_EXISTS': res = pkgce_re.search(value) if res: res = dep_re.findall(res.group(1)) if res: pcdeps.extend([x[0] for x in res]) inherits.append('pkgconfig') elif keyword in ('AM_GNU_GETTEXT', 'AM_GLIB_GNU_GETTEXT', 'GETTEXT_PACKAGE'): inherits.append('gettext') elif keyword in ('AC_PROG_INTLTOOL', 'IT_PROG_INTLTOOL'): deps.append('intltool-native') elif keyword == 'AM_PATH_GLIB_2_0': deps.append('glib-2.0') elif keyword in ('AC_CHECK_PROG', 'AC_PATH_PROG', 'AX_WITH_PROG'): res = progs_re.search(value) if res: for prog in shlex.split(res.group(1)): prog = prog.split()[0] for handler in handlers: if handler.process_prog(srctree, keyword, value, prog, deps, outlines, inherits, values): return progclass = progclassmap.get(prog, None) if progclass: inherits.append(progclass) else: progdep = RecipeHandler.recipebinmap.get(prog, None) if not progdep: progdep = progmap.get(prog, None) if progdep: deps.append(progdep) elif progdep is None: if not prog.startswith('$'): unmapped.append(prog) elif keyword == 'AC_CHECK_LIB': res = lib_re.search(value) if res: lib = res.group(1) if not lib.startswith('$'): libdeps.append(lib) elif keyword == 'AX_CHECK_LIBRARY': res = libx_re.search(value) if res: lib = res.group(2) if not lib.startswith('$'): header = res.group(1) libdeps.append((lib, header)) elif keyword == 'AC_PATH_X': deps.append('libx11') elif keyword in ('AX_BOOST', 'BOOST_REQUIRE'): deps.append('boost') elif keyword in ('AC_PROG_LEX', 'AM_PROG_LEX', 'AX_PROG_FLEX'): deps.append('flex-native') elif keyword in ('AC_PROG_YACC', 'AX_PROG_BISON'): deps.append('bison-native') elif keyword == 'AX_CHECK_ZLIB': deps.append('zlib') elif keyword in ('AX_CHECK_OPENSSL', 'AX_LIB_CRYPTO'): deps.append('openssl') elif keyword == 'AX_LIB_CURL': deps.append('curl') elif keyword == 'AX_LIB_BEECRYPT': deps.append('beecrypt') elif keyword == 'AX_LIB_EXPAT': deps.append('expat') elif keyword == 'AX_LIB_GCRYPT': deps.append('libgcrypt') elif keyword == 'AX_LIB_NETTLE': deps.append('nettle') elif keyword == 'AX_LIB_READLINE': deps.append('readline') elif keyword == 'AX_LIB_SQLITE3': deps.append('sqlite3') elif keyword == 'AX_LIB_TAGLIB': deps.append('taglib') elif keyword == 'AX_PKG_SWIG': deps.append('swig-native') elif keyword == 'AX_PROG_XSLTPROC': deps.append('libxslt-native') elif keyword == 'AX_WITH_CURSES': deps.append('ncurses') elif keyword == 'AX_PATH_BDB': deps.append('db') elif keyword == 'AX_PATH_LIB_PCRE': deps.append('libpcre') elif keyword == 'AC_INIT': if extravalues is not None: res = ac_init_re.match(value) if res: extravalues['PN'] = process_value(res.group(1)) pv = process_value(res.group(2)) if validate_pv(pv): extravalues['PV'] = pv elif keyword == 'AM_INIT_AUTOMAKE': if extravalues is not None: if 'PN' not in extravalues: res = am_init_re.match(value) if res: if res.group(1) != 'AC_PACKAGE_NAME': extravalues['PN'] = process_value(res.group(1)) pv = process_value(res.group(2)) if validate_pv(pv): extravalues['PV'] = pv elif keyword == 'define(': res = define_re.match(value) if res: key = res.group(2).strip('[]') value = process_value(res.group(3)) if value is not None: defines[key] = value keywords = ['PKG_CHECK_MODULES', 'PKG_CHECK_EXISTS', 'AM_GNU_GETTEXT', 'AM_GLIB_GNU_GETTEXT', 'GETTEXT_PACKAGE', 'AC_PROG_INTLTOOL', 'IT_PROG_INTLTOOL', 'AM_PATH_GLIB_2_0', 'AC_CHECK_PROG', 'AC_PATH_PROG', 'AX_WITH_PROG', 'AC_CHECK_LIB', 'AX_CHECK_LIBRARY', 'AC_PATH_X', 'AX_BOOST', 'BOOST_REQUIRE', 'AC_PROG_LEX', 'AM_PROG_LEX', 'AX_PROG_FLEX', 'AC_PROG_YACC', 'AX_PROG_BISON', 'AX_CHECK_ZLIB', 'AX_CHECK_OPENSSL', 'AX_LIB_CRYPTO', 'AX_LIB_CURL', 'AX_LIB_BEECRYPT', 'AX_LIB_EXPAT', 'AX_LIB_GCRYPT', 'AX_LIB_NETTLE', 'AX_LIB_READLINE' 'AX_LIB_SQLITE3', 'AX_LIB_TAGLIB', 'AX_PKG_SWIG', 'AX_PROG_XSLTPROC', 'AX_WITH_CURSES', 'AX_PATH_BDB', 'AX_PATH_LIB_PCRE', 'AC_INIT', 'AM_INIT_AUTOMAKE', 'define(', ] for handler in handlers: handler.extend_keywords(keywords) for srcfile in srcfiles: nesting = 0 in_keyword = '' partial = '' with open(srcfile, 'r', errors='surrogateescape') as f: for line in f: if in_keyword: partial += ' ' + line.strip() if partial.endswith('\\'): partial = partial[:-1] nesting = nesting + line.count('(') - line.count(')') if nesting == 0: process_macro(in_keyword, partial) partial = '' in_keyword = '' else: for keyword in keywords: if keyword in line: nesting = line.count('(') - line.count(')') if nesting > 0: partial = line.strip() if partial.endswith('\\'): partial = partial[:-1] in_keyword = keyword else: process_macro(keyword, line.strip()) break if in_keyword: process_macro(in_keyword, partial) if extravalues: for k,v in list(extravalues.items()): if v: if v.startswith('$') or v.startswith('@') or v.startswith('%'): del extravalues[k] else: extravalues[k] = v.strip('"\'').rstrip('()') if unmapped: outlines.append('# NOTE: the following prog dependencies are unknown, ignoring: %s' % ' '.join(list(set(unmapped)))) RecipeHandler.handle_depends(libdeps, pcdeps, deps, outlines, values, tinfoil.config_data) for handler in handlers: handler.post_process(srctree, libdeps, pcdeps, deps, outlines, inherits, values) if inherits: values['inherit'] = ' '.join(list(set(inherits))) return values
def extract_autotools_deps(outlines, srctree, extravalues=None, acfile=None): import shlex # Find all plugins that want to register handlers logger.debug("Loading autotools handlers") handlers = [] for plugin in plugins: if hasattr(plugin, "register_autotools_handlers"): plugin.register_autotools_handlers(handlers) values = {} inherits = [] # Hardcoded map, we also use a dynamic one based on what's in the sysroot progmap = { "flex": "flex-native", "bison": "bison-native", "m4": "m4-native", "tar": "tar-native", "ar": "binutils-native", "ranlib": "binutils-native", "ld": "binutils-native", "strip": "binutils-native", "libtool": "", "autoconf": "", "autoheader": "", "automake": "", "uname": "", "rm": "", "cp": "", "mv": "", "find": "", "awk": "", "sed": "", } progclassmap = { "gconftool-2": "gconf", "pkg-config": "pkgconfig", "python": "pythonnative", "python3": "python3native", "perl": "perlnative", "makeinfo": "texinfo", } pkg_re = re.compile("PKG_CHECK_MODULES\(\s*\[?[a-zA-Z0-9_]*\]?,\s*\[?([^,\]]*)\]?[),].*") pkgce_re = re.compile("PKG_CHECK_EXISTS\(\s*\[?([^,\]]*)\]?[),].*") lib_re = re.compile("AC_CHECK_LIB\(\s*\[?([^,\]]*)\]?,.*") libx_re = re.compile("AX_CHECK_LIBRARY\(\s*\[?[^,\]]*\]?,\s*\[?([^,\]]*)\]?,\s*\[?([a-zA-Z0-9-]*)\]?,.*") progs_re = re.compile("_PROGS?\(\s*\[?[a-zA-Z0-9_]*\]?,\s*\[?([^,\]]*)\]?[),].*") dep_re = re.compile("([^ ><=]+)( [<>=]+ [^ ><=]+)?") ac_init_re = re.compile("AC_INIT\(\s*([^,]+),\s*([^,]+)[,)].*") am_init_re = re.compile("AM_INIT_AUTOMAKE\(\s*([^,]+),\s*([^,]+)[,)].*") define_re = re.compile("\s*(m4_)?define\(\s*([^,]+),\s*([^,]+)\)") defines = {} def subst_defines(value): newvalue = value for define, defval in defines.iteritems(): newvalue = newvalue.replace(define, defval) if newvalue != value: return subst_defines(newvalue) return value def process_value(value): value = value.replace("[", "").replace("]", "") if value.startswith("m4_esyscmd(") or value.startswith("m4_esyscmd_s("): cmd = subst_defines(value[value.index("(") + 1 : -1]) try: if "|" in cmd: cmd = "set -o pipefail; " + cmd stdout, _ = bb.process.run(cmd, cwd=srctree, shell=True) ret = stdout.rstrip() except bb.process.ExecutionError as e: ret = "" elif value.startswith("m4_"): return None ret = subst_defines(value) if ret: ret = ret.strip("\"'") return ret # Since a configure.ac file is essentially a program, this is only ever going to be # a hack unfortunately; but it ought to be enough of an approximation if acfile: srcfiles = [acfile] else: srcfiles = RecipeHandler.checkfiles(srctree, ["acinclude.m4", "configure.ac", "configure.in"]) pcdeps = [] libdeps = [] deps = [] unmapped = [] RecipeHandler.load_binmap(tinfoil.config_data) def process_macro(keyword, value): for handler in handlers: if handler.process_macro( srctree, keyword, value, process_value, libdeps, pcdeps, deps, outlines, inherits, values ): return if keyword == "PKG_CHECK_MODULES": res = pkg_re.search(value) if res: res = dep_re.findall(res.group(1)) if res: pcdeps.extend([x[0] for x in res]) inherits.append("pkgconfig") elif keyword == "PKG_CHECK_EXISTS": res = pkgce_re.search(value) if res: res = dep_re.findall(res.group(1)) if res: pcdeps.extend([x[0] for x in res]) inherits.append("pkgconfig") elif keyword in ("AM_GNU_GETTEXT", "AM_GLIB_GNU_GETTEXT", "GETTEXT_PACKAGE"): inherits.append("gettext") elif keyword in ("AC_PROG_INTLTOOL", "IT_PROG_INTLTOOL"): deps.append("intltool-native") elif keyword == "AM_PATH_GLIB_2_0": deps.append("glib-2.0") elif keyword in ("AC_CHECK_PROG", "AC_PATH_PROG", "AX_WITH_PROG"): res = progs_re.search(value) if res: for prog in shlex.split(res.group(1)): prog = prog.split()[0] for handler in handlers: if handler.process_prog(srctree, keyword, value, prog, deps, outlines, inherits, values): return progclass = progclassmap.get(prog, None) if progclass: inherits.append(progclass) else: progdep = RecipeHandler.recipebinmap.get(prog, None) if not progdep: progdep = progmap.get(prog, None) if progdep: deps.append(progdep) elif progdep is None: if not prog.startswith("$"): unmapped.append(prog) elif keyword == "AC_CHECK_LIB": res = lib_re.search(value) if res: lib = res.group(1) if not lib.startswith("$"): libdeps.append(lib) elif keyword == "AX_CHECK_LIBRARY": res = libx_re.search(value) if res: lib = res.group(2) if not lib.startswith("$"): header = res.group(1) libdeps.append((lib, header)) elif keyword == "AC_PATH_X": deps.append("libx11") elif keyword in ("AX_BOOST", "BOOST_REQUIRE"): deps.append("boost") elif keyword in ("AC_PROG_LEX", "AM_PROG_LEX", "AX_PROG_FLEX"): deps.append("flex-native") elif keyword in ("AC_PROG_YACC", "AX_PROG_BISON"): deps.append("bison-native") elif keyword == "AX_CHECK_ZLIB": deps.append("zlib") elif keyword in ("AX_CHECK_OPENSSL", "AX_LIB_CRYPTO"): deps.append("openssl") elif keyword == "AX_LIB_CURL": deps.append("curl") elif keyword == "AX_LIB_BEECRYPT": deps.append("beecrypt") elif keyword == "AX_LIB_EXPAT": deps.append("expat") elif keyword == "AX_LIB_GCRYPT": deps.append("libgcrypt") elif keyword == "AX_LIB_NETTLE": deps.append("nettle") elif keyword == "AX_LIB_READLINE": deps.append("readline") elif keyword == "AX_LIB_SQLITE3": deps.append("sqlite3") elif keyword == "AX_LIB_TAGLIB": deps.append("taglib") elif keyword == "AX_PKG_SWIG": deps.append("swig") elif keyword == "AX_PROG_XSLTPROC": deps.append("libxslt-native") elif keyword == "AX_WITH_CURSES": deps.append("ncurses") elif keyword == "AX_PATH_BDB": deps.append("db") elif keyword == "AX_PATH_LIB_PCRE": deps.append("libpcre") elif keyword == "AC_INIT": if extravalues is not None: res = ac_init_re.match(value) if res: extravalues["PN"] = process_value(res.group(1)) pv = process_value(res.group(2)) if validate_pv(pv): extravalues["PV"] = pv elif keyword == "AM_INIT_AUTOMAKE": if extravalues is not None: if "PN" not in extravalues: res = am_init_re.match(value) if res: if res.group(1) != "AC_PACKAGE_NAME": extravalues["PN"] = process_value(res.group(1)) pv = process_value(res.group(2)) if validate_pv(pv): extravalues["PV"] = pv elif keyword == "define(": res = define_re.match(value) if res: key = res.group(2).strip("[]") value = process_value(res.group(3)) if value is not None: defines[key] = value keywords = [ "PKG_CHECK_MODULES", "PKG_CHECK_EXISTS", "AM_GNU_GETTEXT", "AM_GLIB_GNU_GETTEXT", "GETTEXT_PACKAGE", "AC_PROG_INTLTOOL", "IT_PROG_INTLTOOL", "AM_PATH_GLIB_2_0", "AC_CHECK_PROG", "AC_PATH_PROG", "AX_WITH_PROG", "AC_CHECK_LIB", "AX_CHECK_LIBRARY", "AC_PATH_X", "AX_BOOST", "BOOST_REQUIRE", "AC_PROG_LEX", "AM_PROG_LEX", "AX_PROG_FLEX", "AC_PROG_YACC", "AX_PROG_BISON", "AX_CHECK_ZLIB", "AX_CHECK_OPENSSL", "AX_LIB_CRYPTO", "AX_LIB_CURL", "AX_LIB_BEECRYPT", "AX_LIB_EXPAT", "AX_LIB_GCRYPT", "AX_LIB_NETTLE", "AX_LIB_READLINE" "AX_LIB_SQLITE3", "AX_LIB_TAGLIB", "AX_PKG_SWIG", "AX_PROG_XSLTPROC", "AX_WITH_CURSES", "AX_PATH_BDB", "AX_PATH_LIB_PCRE", "AC_INIT", "AM_INIT_AUTOMAKE", "define(", ] for handler in handlers: handler.extend_keywords(keywords) for srcfile in srcfiles: nesting = 0 in_keyword = "" partial = "" with open(srcfile, "r") as f: for line in f: if in_keyword: partial += " " + line.strip() if partial.endswith("\\"): partial = partial[:-1] nesting = nesting + line.count("(") - line.count(")") if nesting == 0: process_macro(in_keyword, partial) partial = "" in_keyword = "" else: for keyword in keywords: if keyword in line: nesting = line.count("(") - line.count(")") if nesting > 0: partial = line.strip() if partial.endswith("\\"): partial = partial[:-1] in_keyword = keyword else: process_macro(keyword, line.strip()) break if in_keyword: process_macro(in_keyword, partial) if extravalues: for k, v in extravalues.items(): if v: if v.startswith("$") or v.startswith("@") or v.startswith("%"): del extravalues[k] else: extravalues[k] = v.strip("\"'").rstrip("()") if unmapped: outlines.append( "# NOTE: the following prog dependencies are unknown, ignoring: %s" % " ".join(list(set(unmapped))) ) RecipeHandler.handle_depends(libdeps, pcdeps, deps, outlines, values, tinfoil.config_data) for handler in handlers: handler.post_process(srctree, libdeps, pcdeps, deps, outlines, inherits, values) if inherits: values["inherit"] = " ".join(list(set(inherits))) return values