summaryrefslogtreecommitdiff
path: root/meta/classes/package.bbclass
diff options
context:
space:
mode:
Diffstat (limited to 'meta/classes/package.bbclass')
-rw-r--r--meta/classes/package.bbclass1437
1 files changed, 837 insertions, 600 deletions
diff --git a/meta/classes/package.bbclass b/meta/classes/package.bbclass
index 4be2fc2dc5..d731757f14 100644
--- a/meta/classes/package.bbclass
+++ b/meta/classes/package.bbclass
@@ -42,6 +42,9 @@ inherit packagedata
inherit prserv
inherit chrpath
+# Need the package_qa_handle_error() in insane.bbclass
+inherit insane
+
PKGD = "${WORKDIR}/package"
PKGDEST = "${WORKDIR}/packages-split"
@@ -69,12 +72,62 @@ def legitimize_package_name(s):
# Remaining package name validity fixes
return s.lower().replace('_', '-').replace('@', '+').replace(',', '+').replace('/', '-')
-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):
+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', True)
+
+ # 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", True)
if ml:
if not output_pattern.startswith(ml):
@@ -89,9 +142,9 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst
if newdeps:
extra_depends = " ".join(newdeps)
- dvar = d.getVar('PKGD', True)
packages = d.getVar('PACKAGES', True).split()
+ split_packages = []
if postinst:
postinst = '#!/bin/sh\n' + postinst + '\n'
@@ -110,6 +163,9 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst
if extra_depends == None:
extra_depends = d.getVar("PN", True)
+ if not summary:
+ summary = description
+
for o in sorted(objs):
import re, stat
if match_path:
@@ -125,14 +181,20 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst
continue
on = legitimize_package_name(m.group(1))
pkg = output_pattern % on
+ split_packages.append(pkg)
if not pkg in packages:
if prepend:
packages = [pkg] + packages
else:
packages.append(pkg)
oldfiles = d.getVar('FILES_' + pkg, True)
+ 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 = [os.path.join(root, o)]
+ the_files = [newfile]
if aux_files_pattern:
if type(aux_files_pattern) is list:
for fp in aux_files_pattern:
@@ -146,19 +208,23 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst
else:
the_files.append(aux_files_pattern_verbatim % m.group(1))
d.setVar('FILES_' + pkg, " ".join(the_files))
- if extra_depends != '':
- d.appendVar('RDEPENDS_' + pkg, ' ' + extra_depends)
- d.setVar('DESCRIPTION_' + pkg, description % on)
- if postinst:
- d.setVar('pkg_postinst_' + pkg, postinst)
- if postrm:
- d.setVar('pkg_postrm_' + pkg, postrm)
else:
- d.setVar('FILES_' + pkg, oldfiles + " " + os.path.join(root, o))
+ d.setVar('FILES_' + pkg, oldfiles + " " + newfile)
+ if extra_depends != '':
+ d.appendVar('RDEPENDS_' + pkg, ' ' + extra_depends)
+ if not d.getVar('DESCRIPTION_' + pkg, True):
+ d.setVar('DESCRIPTION_' + pkg, description % on)
+ if not d.getVar('SUMMARY_' + pkg, True):
+ 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 split_packages
PACKAGE_DEPENDS += "file-native"
@@ -170,29 +236,83 @@ python () {
d.appendVarFlag('do_package', 'depends', deps)
# shlibs requires any DEPENDS to have already packaged for the *.list files
- d.appendVarFlag('do_package', 'deptask', " do_package")
-
- elif not bb.data.inherits_class('image', d):
- d.setVar("PACKAGERDEPTASK", "")
+ d.appendVarFlag('do_package', 'deptask', " do_packagedata")
}
-def splitfile(file, debugfile, debugsrcdir, d):
- # Function to split a single file, called from split_and_strip_files below
- # A working 'file' (one which works on the target architecture)
- # is split and the split off portions go to debugfile.
+# Get a list of files from file vars by searching files under current working directory
+# The list contains symlinks, directories and normal files.
+def files_from_filevars(filevars):
+ import os,glob
+ cpath = oe.cachedpath.CachedPath()
+ files = []
+ for f in filevars:
+ if os.path.isabs(f):
+ f = '.' + f
+ if not f.startswith("./"):
+ f = './' + f
+ globbed = glob.glob(f)
+ if globbed:
+ if [ f ] != globbed:
+ files += globbed
+ continue
+ files.append(f)
+
+ for f in files:
+ if not cpath.islink(f):
+ if cpath.isdir(f):
+ newfiles = [ os.path.join(f,x) for x in os.listdir(f) ]
+ if newfiles:
+ files += newfiles
+
+ return files
+
+# Called in package_<rpm,ipk,deb>.bbclass to get the correct list of configuration files
+def get_conffiles(pkg, d):
+ pkgdest = d.getVar('PKGDEST', True)
+ root = os.path.join(pkgdest, pkg)
+ cwd = os.getcwd()
+ os.chdir(root)
+
+ conffiles = d.getVar('CONFFILES_%s' % pkg, True);
+ if conffiles == None:
+ conffiles = d.getVar('CONFFILES', True)
+ if conffiles == None:
+ conffiles = ""
+ conffiles = conffiles.split()
+ conf_orig_list = files_from_filevars(conffiles)
+
+ # Remove links and directories from conf_orig_list to get conf_list which only contains normal files
+ conf_list = []
+ for f in conf_orig_list:
+ if os.path.isdir(f):
+ continue
+ if os.path.islink(f):
+ continue
+ if not os.path.exists(f):
+ continue
+ conf_list.append(f)
+
+ # Remove the leading './'
+ for i in range(0, len(conf_list)):
+ conf_list[i] = conf_list[i][1:]
+
+ os.chdir(cwd)
+ return conf_list
+
+def splitdebuginfo(file, debugfile, debugsrcdir, sourcefile, d):
+ # Function to split a single file into two components, one is the stripped
+ # target system binary, the other contains any debugging information. The
+ # two files are linked to reference each other.
#
- # The debug information is then processed for src references. These
- # references are copied to debugsrcdir, if defined.
+ # sourcefile is also generated containing a list of debugsources
- import commands, stat, subprocess
+ import stat
dvar = d.getVar('PKGD', True)
- pathprefix = "export PATH=%s; " % d.getVar('PATH', True)
objcopy = d.getVar("OBJCOPY", True)
debugedit = d.expand("${STAGING_LIBDIR_NATIVE}/rpm/bin/debugedit")
workdir = d.getVar("WORKDIR", True)
- workparentdir = d.getVar("DEBUGSRC_OVERRIDE_PATH", True) or os.path.dirname(workdir)
- sourcefile = d.expand("${WORKDIR}/debugsources.list")
+ workparentdir = d.getVar("DEBUGSRC_OVERRIDE_PATH", True) or os.path.dirname(os.path.dirname(workdir))
# We ignore kernel modules, we don't generate debug info files.
if file.find("/lib/modules/") != -1 and file.endswith(".ko"):
@@ -206,145 +326,126 @@ def splitfile(file, debugfile, debugsrcdir, d):
# We need to extract the debug src information here...
if debugsrcdir:
- subprocess.call("%s'%s' -b '%s' -d '%s' -i -l '%s' '%s'" % (pathprefix, debugedit, workparentdir, debugsrcdir, sourcefile, file), shell=True)
+ cmd = "'%s' -b '%s' -d '%s' -i -l '%s' '%s'" % (debugedit, workparentdir, debugsrcdir, sourcefile, file)
+ (retval, output) = oe.utils.getstatusoutput(cmd)
+ if retval:
+ bb.fatal("debugedit failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else ""))
- bb.mkdirhier(os.path.dirname(debugfile))
+ bb.utils.mkdirhier(os.path.dirname(debugfile))
- subprocess.call("%s'%s' --only-keep-debug '%s' '%s'" % (pathprefix, objcopy, file, debugfile), shell=True)
+ cmd = "'%s' --only-keep-debug '%s' '%s'" % (objcopy, file, debugfile)
+ (retval, output) = oe.utils.getstatusoutput(cmd)
+ if retval:
+ bb.fatal("objcopy failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else ""))
# Set the debuglink to have the view of the file path on the target
- subprocess.call("%s'%s' --add-gnu-debuglink='%s' '%s'" % (pathprefix, objcopy, debugfile, file), shell=True)
+ cmd = "'%s' --add-gnu-debuglink='%s' '%s'" % (objcopy, debugfile, file)
+ (retval, output) = oe.utils.getstatusoutput(cmd)
+ if retval:
+ bb.fatal("objcopy failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else ""))
if newmode:
os.chmod(file, origmode)
return 0
-def splitfile2(debugsrcdir, d):
- # Function to split a single file, called from split_and_strip_files below
- #
- # The debug src information processed in the splitfile2 is further procecessed
+def copydebugsources(debugsrcdir, d):
+ # The debug src information written out to sourcefile is further procecessed
# and copied to the destination here.
- import commands, stat, subprocess
+ import stat
sourcefile = d.expand("${WORKDIR}/debugsources.list")
if debugsrcdir and os.path.isfile(sourcefile):
- dvar = d.getVar('PKGD', True)
- pathprefix = "export PATH=%s; " % d.getVar('PATH', True)
- strip = d.getVar("STRIP", True)
- objcopy = d.getVar("OBJCOPY", True)
- debugedit = d.expand("${STAGING_LIBDIR_NATIVE}/rpm/bin/debugedit")
- workdir = d.getVar("WORKDIR", True)
- workparentdir = os.path.dirname(workdir)
- workbasedir = os.path.basename(workdir)
-
- nosuchdir = []
- basepath = dvar
- for p in debugsrcdir.split("/"):
- basepath = basepath + "/" + p
- if not os.path.exists(basepath):
- nosuchdir.append(basepath)
- bb.mkdirhier(basepath)
-
- processdebugsrc = "LC_ALL=C ; sort -z -u '%s' | egrep -v -z '(<internal>|<built-in>)$' | "
- # We need to ignore files that are not actually ours
- # we do this by only paying attention to items from this package
- processdebugsrc += "fgrep -z '%s' | "
- processdebugsrc += "(cd '%s' ; cpio -pd0mL --no-preserve-owner '%s%s' 2>/dev/null)"
-
- subprocess.call(processdebugsrc % (sourcefile, workbasedir, workparentdir, dvar, debugsrcdir), shell=True)
-
- # The copy by cpio may have resulted in some empty directories! Remove these
- for root, dirs, files in os.walk("%s%s" % (dvar, debugsrcdir)):
- for d in dirs:
- dir = os.path.join(root, d)
- #bb.note("rmdir -p %s" % dir)
- subprocess.call("rmdir -p %s 2>/dev/null" % dir, shell=True)
-
- # Also remove debugsrcdir if its empty
- for p in nosuchdir[::-1]:
- if os.path.exists(p) and not os.listdir(p):
- os.rmdir(p)
-
-def runstrip(file, elftype, d):
- # Function to strip a single file, called from split_and_strip_files below
- # A working 'file' (one which works on the target architecture)
- #
- # The elftype is a bit pattern (explained in split_and_strip_files) to tell
- # us what type of file we're processing...
- # 4 - executable
- # 8 - shared library
-
- import commands, stat, subprocess
-
- pathprefix = "export PATH=%s; " % d.getVar('PATH', True)
- strip = d.getVar("STRIP", True)
-
- # Handle kernel modules specifically - .debug directories here are pointless
- if file.find("/lib/modules/") != -1 and file.endswith(".ko"):
- return subprocess.call("%s'%s' --strip-debug --remove-section=.comment --remove-section=.note --preserve-dates '%s'" % (pathprefix, strip, file), shell=True)
-
- newmode = None
- if not os.access(file, os.W_OK) or os.access(file, os.R_OK):
- origmode = os.stat(file)[stat.ST_MODE]
- newmode = origmode | stat.S_IWRITE | stat.S_IREAD
- os.chmod(file, newmode)
-
- extraflags = ""
-
- # split_and_strip_files is calling this with elf_type None, causing:
- # TypeError: unsupported operand type(s) for &: 'NoneType' and 'int'
- if elftype:
- # .so and shared library
- if ".so" in file and elftype & 8:
- extraflags = "--remove-section=.comment --remove-section=.note --strip-unneeded"
- # shared or executable:
- elif elftype & 8 or elftype & 4:
- extraflags = "--remove-section=.comment --remove-section=.note"
-
- stripcmd = "'%s' %s '%s'" % (strip, extraflags, file)
- bb.debug(1, "runstrip: %s" % stripcmd)
-
- ret = subprocess.call("%s%s" % (pathprefix, stripcmd), shell=True)
-
- if newmode:
- os.chmod(file, origmode)
-
- if ret:
- bb.error("runstrip: '%s' strip command failed" % stripcmd)
-
- return 0
+ dvar = d.getVar('PKGD', True)
+ strip = d.getVar("STRIP", True)
+ objcopy = d.getVar("OBJCOPY", True)
+ debugedit = d.expand("${STAGING_LIBDIR_NATIVE}/rpm/bin/debugedit")
+ workdir = d.getVar("WORKDIR", True)
+ workparentdir = os.path.dirname(os.path.dirname(workdir))
+ workbasedir = os.path.basename(os.path.dirname(workdir)) + "/" + os.path.basename(workdir)
+
+ nosuchdir = []
+ basepath = dvar
+ for p in debugsrcdir.split("/"):
+ basepath = basepath + "/" + p
+ if not cpath.exists(basepath):
+ nosuchdir.append(basepath)
+ bb.utils.mkdirhier(basepath)
+ cpath.updatecache(basepath)
+
+ processdebugsrc = "LC_ALL=C ; sort -z -u '%s' | egrep -v -z '(<internal>|<built-in>)$' | "
+ # We need to ignore files that are not actually ours
+ # we do this by only paying attention to items from this package
+ processdebugsrc += "fgrep -zw '%s' | "
+ processdebugsrc += "(cd '%s' ; cpio -pd0mlL --no-preserve-owner '%s%s' 2>/dev/null)"
+
+ cmd = processdebugsrc % (sourcefile, workbasedir, workparentdir, dvar, debugsrcdir)
+ (retval, output) = oe.utils.getstatusoutput(cmd)
+ # Can "fail" if internal headers/transient sources are attempted
+ #if retval:
+ # bb.fatal("debug source copy failed with exit code %s (cmd was %s)" % (retval, cmd))
+
+ # cpio seems to have a bug with -lL together and symbolic links are just copied, not dereferenced.
+ # Work around this by manually finding and copying any symbolic links that made it through.
+ cmd = "find %s%s -type l -print0 -delete | sed s#%s%s/##g | (cd '%s' ; cpio -pd0mL --no-preserve-owner '%s%s' 2>/dev/null)" % (dvar, debugsrcdir, dvar, debugsrcdir, workparentdir, dvar, debugsrcdir)
+ (retval, output) = oe.utils.getstatusoutput(cmd)
+ if retval:
+ bb.fatal("debugsrc symlink fixup failed with exit code %s (cmd was %s)" % (retval, cmd))
+
+ # The copy by cpio may have resulted in some empty directories! Remove these
+ cmd = "find %s%s -empty -type d -delete" % (dvar, debugsrcdir)
+ (retval, output) = oe.utils.getstatusoutput(cmd)
+ if retval:
+ bb.fatal("empty directory removal failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else ""))
+
+ # Also remove debugsrcdir if its empty
+ for p in nosuchdir[::-1]:
+ if os.path.exists(p) and not os.listdir(p):
+ os.rmdir(p)
#
# Package data handling routines
#
-def get_package_mapping (pkg, d):
+def get_package_mapping (pkg, basepkg, d):
import oe.packagedata
data = oe.packagedata.read_subpkgdata(pkg, d)
key = "PKG_%s" % pkg
if key in data:
+ # Have to avoid undoing the write_extra_pkgs(global_variants...)
+ if bb.data.inherits_class('allarch', d) and data[key] == basepkg:
+ return pkg
return data[key]
return pkg
-def runtime_mapping_rename (varname, d):
+def get_package_additional_metadata (pkg_type, d):
+ base_key = "PACKAGE_ADD_METADATA"
+ for key in ("%s_%s" % (base_key, pkg_type.upper()), base_key):
+ if d.getVar(key) is None:
+ continue
+ d.setVarFlag(key, "type", "list")
+ if d.getVarFlag(key, "separator") is None:
+ d.setVarFlag(key, "separator", "\\n")
+ metadata_fields = [field.strip() for field in oe.data.typed_value(key, d)]
+ return "\n".join(metadata_fields).strip()
+
+def runtime_mapping_rename (varname, pkg, d):
#bb.note("%s before: %s" % (varname, d.getVar(varname, True)))
- new_depends = []
- deps = bb.utils.explode_dep_versions(d.getVar(varname, True) or "")
+ if bb.data.inherits_class('packagegroup', d):
+ return
+
+ new_depends = {}
+ deps = bb.utils.explode_dep_versions2(d.getVar(varname, True) or "")
for depend in deps:
- # Have to be careful with any version component of the depend
- new_depend = get_package_mapping(depend, d)
- if deps[depend]:
- new_depends.append("%s (%s)" % (new_depend, deps[depend]))
- else:
- new_depends.append(new_depend)
+ new_depend = get_package_mapping(depend, pkg, d)
+ new_depends[new_depend] = deps[depend]
- d.setVar(varname, " ".join(new_depends) or None)
+ d.setVar(varname, bb.utils.join_deps(new_depends, commasep=False))
#bb.note("%s after: %s" % (varname, d.getVar(varname, True)))
@@ -353,27 +454,53 @@ def runtime_mapping_rename (varname, d):
#
python package_get_auto_pr() {
- # per recipe PRSERV_HOST PRSERV_PORT
+ import oe.prservice
+ import re
+
+ # Support per recipe PRSERV_HOST
pn = d.getVar('PN', True)
host = d.getVar("PRSERV_HOST_" + pn, True)
- port = d.getVar("PRSERV_PORT_" + pn, True)
if not (host is None):
d.setVar("PRSERV_HOST", host)
- if not (port is None):
- d.setVar("PRSERV_PORT", port)
- if d.getVar('USE_PR_SERV', True) != "0":
- try:
- auto_pr=prserv_get_pr_auto(d)
- except Exception as e:
- bb.fatal("Can NOT get PRAUTO, exception %s" % str(e))
- return
+
+ pkgv = d.getVar("PKGV", True)
+
+ # PR Server not active, handle AUTOINC
+ if not d.getVar('PRSERV_HOST', True):
+ if 'AUTOINC' in pkgv:
+ d.setVar("PKGV", pkgv.replace("AUTOINC", "0"))
+ return
+
+ auto_pr = None
+ pv = d.getVar("PV", True)
+ version = d.getVar("PRAUTOINX", True)
+ pkgarch = d.getVar("PACKAGE_ARCH", True)
+ checksum = d.getVar("BB_TASKHASH", True)
+
+ if d.getVar('PRSERV_LOCKDOWN', True):
+ auto_pr = d.getVar('PRAUTO_' + version + '_' + pkgarch, True) or d.getVar('PRAUTO_' + version, True) or None
if auto_pr is None:
- if d.getVar('PRSERV_LOCKDOWN', True):
- bb.fatal("Can NOT get PRAUTO from lockdown exported file")
- else:
- bb.fatal("Can NOT get PRAUTO from remote PR service")
- return
+ bb.fatal("Can NOT get PRAUTO from lockdown exported file")
d.setVar('PRAUTO',str(auto_pr))
+ return
+
+ try:
+ conn = d.getVar("__PRSERV_CONN", True)
+ if conn is None:
+ conn = oe.prservice.prserv_make_conn(d)
+ if conn is not None:
+ if "AUTOINC" in pkgv:
+ srcpv = bb.fetch2.get_srcrev(d)
+ base_ver = "AUTOINC-%s" % version[:version.find(srcpv)]
+ value = conn.getPR(base_ver, pkgarch, srcpv)
+ d.setVar("PKGV", pkgv.replace("AUTOINC", str(value)))
+
+ auto_pr = conn.getPR(version, pkgarch, checksum)
+ except Exception as e:
+ bb.fatal("Can NOT get PRAUTO, exception %s" % str(e))
+ if auto_pr is None:
+ bb.fatal("Can NOT get PRAUTO from remote PR service")
+ d.setVar('PRAUTO',str(auto_pr))
}
LOCALEBASEPN ??= "${PN}"
@@ -398,7 +525,7 @@ python package_do_split_locales() {
localedir = os.path.join(dvar + datadir, 'locale')
- if not os.path.isdir(localedir):
+ if not cpath.isdir(localedir):
bb.debug(1, "No locale files in this package")
return
@@ -413,7 +540,7 @@ python package_do_split_locales() {
pkg = pn + '-locale-' + ln
packages.append(pkg)
d.setVar('FILES_' + pkg, os.path.join(datadir, 'locale', l))
- d.setVar('RDEPENDS_' + pkg, '%s %svirtual-locale-%s' % (pn, mlprefix, ln))
+ d.setVar('RRECOMMENDS_' + pkg, '%svirtual-locale-%s' % (mlprefix, ln))
d.setVar('RPROVIDES_' + pkg, '%s-locale %s%s-translation' % (pn, mlprefix, ln))
d.setVar('SUMMARY_' + pkg, '%s - %s translations' % (summary, l))
d.setVar('DESCRIPTION_' + pkg, '%s This package contains language translation files for the %s locale.' % (description, l))
@@ -428,28 +555,29 @@ python package_do_split_locales() {
# glibc-localedata-translit* won't install as a dependency
# for some other package which breaks meta-toolchain
# Probably breaks since virtual-locale- isn't provided anywhere
- #rdep = (d.getVar('RDEPENDS_%s' % pn, True) or d.getVar('RDEPENDS', True) or "").split()
+ #rdep = (d.getVar('RDEPENDS_%s' % pn, True) or "").split()
#rdep.append('%s-locale*' % pn)
#d.setVar('RDEPENDS_%s' % pn, ' '.join(rdep))
}
python perform_packagecopy () {
- import subprocess
dest = d.getVar('D', True)
dvar = d.getVar('PKGD', True)
- bb.mkdirhier(dvar)
-
# Start by package population by taking a copy of the installed
# files to operate on
- subprocess.call('rm -rf %s/*' % (dvar), shell=True)
# Preserve sparse files and hard links
- subprocess.call('tar -cf - -C %s -ps . | tar -xf - -C %s' % (dest, dvar), shell=True)
+ cmd = 'tar -cf - -C %s -p . | tar -xf - -C %s' % (dest, dvar)
+ (retval, output) = oe.utils.getstatusoutput(cmd)
+ if retval:
+ bb.fatal("file copy failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else ""))
# replace RPATHs for the nativesdk binaries, to make them relocatable
- if bb.data.inherits_class('nativesdk', d):
+ if bb.data.inherits_class('nativesdk', d) or bb.data.inherits_class('cross-canadian', d):
rpath_replace (dvar, d)
}
+perform_packagecopy[cleandirs] = "${PKGD}"
+perform_packagecopy[dirs] = "${PKGD}"
# We generate a master list of directories to process, we start by
# seeding this list with reasonable defaults, then load from
@@ -486,7 +614,8 @@ python fixup_perms () {
elif len(lsplit) == 8:
self._setdir(lsplit[0], lsplit[1], lsplit[2], lsplit[3], lsplit[4], lsplit[5], lsplit[6], lsplit[7])
else:
- bb.error("Fixup Perms: invalid config line %s" % line)
+ msg = "Fixup Perms: invalid config line %s" % line
+ package_qa_handle_error("perm-config", msg, d)
self.path = None
self.link = None
@@ -567,11 +696,12 @@ python fixup_perms () {
# paths are resolved via BBPATH
def get_fs_perms_list(d):
str = ""
+ bbpath = d.getVar('BBPATH', True)
fs_perms_tables = d.getVar('FILESYSTEM_PERMS_TABLES', True)
if not fs_perms_tables:
fs_perms_tables = 'files/fs-perms.txt'
for conf_file in fs_perms_tables.split():
- str += " %s" % bb.which(d.getVar('BBPATH', True), conf_file)
+ str += " %s" % bb.utils.which(bbpath, conf_file)
return str
@@ -620,7 +750,8 @@ python fixup_perms () {
if len(lsplit) == 0:
continue
if len(lsplit) != 8 and not (len(lsplit) == 3 and lsplit[1].lower() == "link"):
- bb.error("Fixup perms: %s invalid line: %s" % (conf, line))
+ msg = "Fixup perms: %s invalid line: %s" % (conf, line)
+ package_qa_handle_error("perm-line", msg, d)
continue
entry = fs_perms_entry(d.expand(line))
if entry and entry.path:
@@ -638,7 +769,7 @@ python fixup_perms () {
continue
origin = dvar + dir
- if not (os.path.exists(origin) and os.path.isdir(origin) and not os.path.islink(origin)):
+ if not (cpath.exists(origin) and cpath.isdir(origin) and not cpath.islink(origin)):
continue
link = fs_perms_table[dir].link
@@ -649,11 +780,12 @@ python fixup_perms () {
target = os.path.join(os.path.dirname(origin), link)
ptarget = os.path.join(os.path.dirname(dir), link)
if os.path.exists(target):
- bb.error("Fixup Perms: Unable to correct directory link, target already exists: %s -> %s" % (dir, ptarget))
+ msg = "Fixup Perms: Unable to correct directory link, target already exists: %s -> %s" % (dir, ptarget)
+ package_qa_handle_error("perm-link", msg, d)
continue
# Create path to move directory to, move it, and then setup the symlink
- bb.mkdirhier(os.path.dirname(target))
+ bb.utils.mkdirhier(os.path.dirname(target))
#bb.note("Fixup Perms: Rename %s -> %s" % (dir, ptarget))
os.rename(origin, target)
#bb.note("Fixup Perms: Link %s -> %s" % (dir, link))
@@ -664,7 +796,7 @@ python fixup_perms () {
continue
origin = dvar + dir
- if not (os.path.exists(origin) and os.path.isdir(origin)):
+ if not (cpath.exists(origin) and cpath.isdir(origin)):
continue
fix_perms(origin, fs_perms_table[dir].mode, fs_perms_table[dir].uid, fs_perms_table[dir].gid, dir)
@@ -680,7 +812,7 @@ python fixup_perms () {
}
python split_and_strip_files () {
- import commands, stat, errno, subprocess
+ import stat, errno
dvar = d.getVar('PKGD', True)
pn = d.getVar('PN', True)
@@ -692,6 +824,12 @@ python split_and_strip_files () {
debugdir = ""
debuglibdir = "/usr/lib/debug"
debugsrcdir = "/usr/src/debug"
+ elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE', True) == 'debug-without-src':
+ # Original OE-core, a.k.a. ".debug", style debug info, but without sources in /usr/src/debug
+ debugappend = ""
+ debugdir = "/.debug"
+ debuglibdir = ""
+ debugsrcdir = ""
else:
# Original OE-core, a.k.a. ".debug", style debug info
debugappend = ""
@@ -699,6 +837,9 @@ python split_and_strip_files () {
debuglibdir = ""
debugsrcdir = "/usr/src/debug"
+ sourcefile = d.expand("${WORKDIR}/debugsources.list")
+ bb.utils.remove(sourcefile)
+
os.chdir(dvar)
# Return type (bits):
@@ -707,13 +848,14 @@ python split_and_strip_files () {
# 2 - stripped
# 4 - executable
# 8 - shared library
+ # 16 - kernel module
def isELF(path):
type = 0
- pathprefix = "export PATH=%s; " % d.getVar('PATH', True)
- ret, result = commands.getstatusoutput("%sfile '%s'" % (pathprefix, path))
+ ret, result = oe.utils.getstatusoutput("file \"%s\"" % path.replace("\"", "\\\""))
if ret:
- bb.error("split_and_strip_files: 'file %s' failed" % path)
+ msg = "split_and_strip_files: 'file %s' failed" % path
+ package_qa_handle_error("split-strip", msg, d)
return type
# Not stripped
@@ -731,130 +873,138 @@ python split_and_strip_files () {
#
# First lets figure out all of the files we may have to process ... do this only once!
#
- file_list = {}
- file_links = {}
- if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT', True) != '1') and \
- (d.getVar('INHIBIT_PACKAGE_STRIP', True) != '1'):
- for root, dirs, files in os.walk(dvar):
+ elffiles = {}
+ symlinks = {}
+ kernmods = []
+ inodes = {}
+ libdir = os.path.abspath(dvar + os.sep + d.getVar("libdir", True))
+ baselibdir = os.path.abspath(dvar + os.sep + d.getVar("base_libdir", True))
+ if (d.getVar('INHIBIT_PACKAGE_STRIP', True) != '1'):
+ for root, dirs, files in cpath.walk(dvar):
for f in files:
file = os.path.join(root, f)
- # Only process files (and symlinks)... Skip files that are obviously debug files
- if not (debugappend != "" and file.endswith(debugappend)) and \
- not (debugdir != "" and debugdir in os.path.dirname(file[len(dvar):])) and \
- os.path.isfile(file):
- try:
- s = os.stat(file)
- except OSError, (err, strerror):
- if err != errno.ENOENT:
- raise
- # Skip broken symlinks
+ if file.endswith(".ko") and file.find("/lib/modules/") != -1:
+ kernmods.append(file)
+ continue
+
+ # Skip debug files
+ if debugappend and file.endswith(debugappend):
+ continue
+ if debugdir and debugdir in os.path.dirname(file[len(dvar):]):
+ continue
+
+ try:
+ ltarget = cpath.realpath(file, dvar, False)
+ s = cpath.lstat(ltarget)
+ except OSError as e:
+ (err, strerror) = e.args
+ if err != errno.ENOENT:
+ raise
+ # Skip broken symlinks
+ continue
+ if not s:
+ continue
+ # Check its an excutable
+ if (s[stat.ST_MODE] & stat.S_IXUSR) or (s[stat.ST_MODE] & stat.S_IXGRP) or (s[stat.ST_MODE] & stat.S_IXOTH) \
+ or ((file.startswith(libdir) or file.startswith(baselibdir)) and ".so" in f):
+ # If it's a symlink, and points to an ELF file, we capture the readlink target
+ if cpath.islink(file):
+ target = os.readlink(file)
+ if isELF(ltarget):
+ #bb.note("Sym: %s (%d)" % (ltarget, isELF(ltarget)))
+ symlinks[file] = target
continue
- # Is the item excutable? Then we need to process it.
- if (s[stat.ST_MODE] & stat.S_IXUSR) or \
- (s[stat.ST_MODE] & stat.S_IXGRP) or \
- (s[stat.ST_MODE] & stat.S_IXOTH):
- # If it's a symlink, and points to an ELF file, we capture the readlink target
- if os.path.islink(file):
- target = os.readlink(file)
- if not os.path.isabs(target):
- ltarget = os.path.join(os.path.dirname(file), target)
- else:
- ltarget = target
- if isELF(ltarget):
- #bb.note("Sym: %s (%d)" % (ltarget, isELF(ltarget)))
- file_list[file] = "sym: " + target
+ # It's a file (or hardlink), not a link
+ # ...but is it ELF, and is it already stripped?
+ elf_file = isELF(file)
+ if elf_file & 1:
+ if elf_file & 2:
+ if 'already-stripped' in (d.getVar('INSANE_SKIP_' + pn, True) or "").split():
+ bb.note("Skipping file %s from %s for already-stripped QA test" % (file[len(dvar):], pn))
+ else:
+ msg = "File '%s' from %s was already stripped, this will prevent future debugging!" % (file[len(dvar):], pn)
+ package_qa_handle_error("already-stripped", msg, d)
continue
- # It's a file (or hardlink), not a link
- # ...but is it ELF, and is it already stripped?
- elf_file = isELF(file)
- if elf_file & 1:
- # Check if it's a hard link to something else
- if s.st_nlink > 1:
- file_reference = "%d_%d" % (s.st_dev, s.st_ino)
- # Hard link to something else
- file_list[file] = "hard: " + file_reference
- continue
-
- file_list[file] = "ELF: %d" % elf_file
+ # At this point we have an unstripped elf file. We need to:
+ # a) Make sure any file we strip is not hardlinked to anything else outside this tree
+ # b) Only strip any hardlinked file once (no races)
+ # c) Track any hardlinks between files so that we can reconstruct matching debug file hardlinks
+
+ # Use a reference of device ID and inode number to indentify files
+ file_reference = "%d_%d" % (s.st_dev, s.st_ino)
+ if file_reference in inodes:
+ os.unlink(file)
+ os.link(inodes[file_reference][0], file)
+ inodes[file_reference].append(file)
+ else:
+ inodes[file_reference] = [file]
+ # break hardlink
+ bb.utils.copyfile(file, file)
+ elffiles[file] = elf_file
+ # Modified the file so clear the cache
+ cpath.updatecache(file)
#
# First lets process debug splitting
#
if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT', True) != '1'):
- for file in file_list:
+ for file in elffiles:
src = file[len(dvar):]
dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
fpath = dvar + dest
- # Preserve symlinks in debug area...
- if file_list[file].startswith("sym: "):
- ltarget = file_list[file][5:]
- lpath = os.path.dirname(ltarget)
- lbase = os.path.basename(ltarget)
- ftarget = ""
- if lpath and lpath != ".":
- ftarget += lpath + debugdir + "/"
- ftarget += lbase + debugappend
- if lpath.startswith(".."):
- ftarget = os.path.join("..", ftarget)
- bb.mkdirhier(os.path.dirname(fpath))
- #bb.note("Symlink %s -> %s" % (fpath, ftarget))
- os.symlink(ftarget, fpath)
- continue
- # Preserve hard links in debug area...
- file_reference = ""
- if file_list[file].startswith("hard: "):
- file_reference = file_list[file][6:]
- if file_reference not in file_links:
- # If this is a new file, add it as a reference, and
- # update it's type, so we can fall through and split
- file_list[file] = "ELF: %d" % (isELF(file))
- else:
- target = file_links[file_reference][len(dvar):]
- ftarget = dvar + debuglibdir + os.path.dirname(target) + debugdir + "/" + os.path.basename(target) + debugappend
- bb.mkdirhier(os.path.dirname(fpath))
- #bb.note("Link %s -> %s" % (fpath, ftarget))
- os.link(ftarget, fpath)
-