def util_linux_libpackages(d): do_split_packages(d, root=d.getVar('UTIL_LINUX_LIBDIR'), file_regex=r'^lib(.*)\.so\..*$', output_pattern='${PN}-lib%s', description='${PN} lib%s', extra_depends='', prepend=True, allow_links=True) util_linux_libpackages(d) def do_split_packages(d, root, file_regex, output_pattern, description, postinst=None, recursive=False, hook=None, extra_depends=None, aux_files_pattern=None, postrm=None, allow_dirs=False, prepend=False, match_path=False, aux_files_pattern_verbatim=None, allow_links=False, summary=None): """ Used in .bb files to split up dynamically generated subpackages of a given package, usually plugins or modules. Arguments: root -- the path in which to search file_regex -- regular expression to match searched files. Use parentheses () to mark the part of this expression that should be used to derive the module name (to be substituted where %s is used in other function arguments as noted below) output_pattern -- pattern to use for the package names. Must include %s. description -- description to set for each package. Must include %s. postinst -- postinstall script to use for all packages (as a string) recursive -- True to perform a recursive search - default False hook -- a hook function to be called for every match. The function will be called with the following arguments (in the order listed): f: full path to the file/directory match pkg: the package name file_regex: as above output_pattern: as above modulename: the module name derived using file_regex extra_depends -- extra runtime dependencies (RDEPENDS) to be set for all packages. The default value of None causes a dependency on the main package (${PN}) - if you do not want this, pass '' for this parameter. aux_files_pattern -- extra item(s) to be added to FILES for each package. Can be a single string item or a list of strings for multiple items. Must include %s. postrm -- postrm script to use for all packages (as a string) allow_dirs -- True allow directories to be matched - default False prepend -- if True, prepend created packages to PACKAGES instead of the default False which appends them match_path -- match file_regex on the whole relative path to the root rather than just the file name aux_files_pattern_verbatim -- extra item(s) to be added to FILES for each package, using the actual derived module name rather than converting it to something legal for a package name. Can be a single string item or a list of strings for multiple items. Must include %s. allow_links -- True to allow symlinks to be matched - default False summary -- Summary to set for each package. Must include %s; defaults to description if not set. """ dvar = d.getVar('PKGD') root = d.expand(root) output_pattern = d.expand(output_pattern) extra_depends = d.expand(extra_depends) # If the root directory doesn't exist, don't error out later but silently do # no splitting. if not os.path.exists(dvar + root): return [] ml = d.getVar("MLPREFIX") if ml: if not output_pattern.startswith(ml): output_pattern = ml + output_pattern newdeps = [] for dep in (extra_depends or "").split(): if dep.startswith(ml): newdeps.append(dep) else: newdeps.append(ml + dep) if newdeps: extra_depends = " ".join(newdeps) packages = d.getVar('PACKAGES').split() split_packages = set() if postinst: postinst = '#!/bin/sh\n' + postinst + '\n' if postrm: postrm = '#!/bin/sh\n' + postrm + '\n' if not recursive: objs = os.listdir(dvar + root) else: objs = [] for walkroot, dirs, files in os.walk(dvar + root): for file in files: relpath = os.path.join(walkroot, file).replace(dvar + root + '/', '', 1) if relpath: objs.append(relpath) if extra_depends == None: extra_depends = d.getVar("PN") if not summary: summary = description for o in sorted(objs): import re, stat if match_path: m = re.match(file_regex, o) else: m = re.match(file_regex, os.path.basename(o)) if not m: continue f = os.path.join(dvar + root, o) mode = os.lstat(f).st_mode if not (stat.S_ISREG(mode) or (allow_links and stat.S_ISLNK(mode)) or (allow_dirs and stat.S_ISDIR(mode))): continue on = legitimize_package_name(m.group(1)) pkg = output_pattern % on split_packages.add(pkg) if not pkg in packages: if prepend: packages = [pkg] + packages else: packages.append(pkg) oldfiles = d.getVar('FILES_' + pkg) newfile = os.path.join(root, o) # These names will be passed through glob() so if the filename actually # contains * or ? (rare, but possible) we need to handle that specially newfile = newfile.replace('*', '[*]') newfile = newfile.replace('?', '[?]') if not oldfiles: the_files = [newfile] if aux_files_pattern: if type(aux_files_pattern) is list: for fp in aux_files_pattern: the_files.append(fp % on) else: the_files.append(aux_files_pattern % on) if aux_files_pattern_verbatim: if type(aux_files_pattern_verbatim) is list: for fp in aux_files_pattern_verbatim: the_files.append(fp % m.group(1)) else: the_files.append(aux_files_pattern_verbatim % m.group(1)) d.setVar('FILES_' + pkg, " ".join(the_files)) else: d.setVar('FILES_' + pkg, oldfiles + " " + newfile) if extra_depends != '': d.appendVar('RDEPENDS_' + pkg, ' ' + extra_depends) if not d.getVar('DESCRIPTION_' + pkg): d.setVar('DESCRIPTION_' + pkg, description % on) if not d.getVar('SUMMARY_' + pkg): d.setVar('SUMMARY_' + pkg, summary % on) if postinst: d.setVar('pkg_postinst_' + pkg, postinst) if postrm: d.setVar('pkg_postrm_' + pkg, postrm) if callable(hook): hook(f, pkg, file_regex, output_pattern, m.group(1)) d.setVar('PACKAGES', ' '.join(packages)) return list(split_packages) def legitimize_package_name(s): """ Make sure package names are legitimate strings """ import re def fixutf(m): cp = m.group(1) if cp: return ('\\u%s' % cp).encode('latin-1').decode('unicode_escape') # Handle unicode codepoints encoded as , as in glibc locale files. s = re.sub(r'', fixutf, s) # Remaining package name validity fixes return s.lower().replace('_', '-').replace('@', '+').replace(',', '+').replace('/', '-')