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.bbclass559
1 files changed, 333 insertions, 226 deletions
diff --git a/meta/classes/package.bbclass b/meta/classes/package.bbclass
index 5558d0d100..cc466bd1b2 100644
--- a/meta/classes/package.bbclass
+++ b/meta/classes/package.bbclass
@@ -39,7 +39,6 @@
# packaging steps
inherit packagedata
-inherit prserv
inherit chrpath
# Need the package_qa_handle_error() in insane.bbclass
@@ -55,6 +54,14 @@ ALL_MULTILIB_PACKAGE_ARCHS = "${@all_multilib_tune_values(d, 'PACKAGE_ARCHS')}"
# rpm is used for the per-file dependency identification
PACKAGE_DEPENDS += "rpm-native"
+
+# If your postinstall can execute at rootfs creation time rather than on
+# target but depends on a native/cross tool in order to execute, you need to
+# list that tool in PACKAGE_WRITE_DEPENDS. Target package dependencies belong
+# in the package dependencies as normal, this is just for native/cross support
+# tools at rootfs build time.
+PACKAGE_WRITE_DEPS ??= ""
+
def legitimize_package_name(s):
"""
Make sure package names are legitimate strings
@@ -64,7 +71,7 @@ def legitimize_package_name(s):
def fixutf(m):
cp = m.group(1)
if cp:
- return ('\u%s' % cp).decode('unicode_escape').encode('utf-8')
+ return ('\\u%s' % cp).encode('latin-1').decode('unicode_escape')
# Handle unicode codepoints encoded as <U0123>, as in glibc locale files.
s = re.sub('<U([0-9A-Fa-f]{1,4})>', fixutf, s)
@@ -121,14 +128,17 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst
"""
- dvar = d.getVar('PKGD', True)
+ 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", True)
+ ml = d.getVar("MLPREFIX")
if ml:
if not output_pattern.startswith(ml):
output_pattern = ml + output_pattern
@@ -143,8 +153,8 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst
extra_depends = " ".join(newdeps)
- packages = d.getVar('PACKAGES', True).split()
- split_packages = []
+ packages = d.getVar('PACKAGES').split()
+ split_packages = set()
if postinst:
postinst = '#!/bin/sh\n' + postinst + '\n'
@@ -161,7 +171,7 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst
objs.append(relpath)
if extra_depends == None:
- extra_depends = d.getVar("PN", True)
+ extra_depends = d.getVar("PN")
if not summary:
summary = description
@@ -181,13 +191,13 @@ 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)
+ split_packages.add(pkg)
if not pkg in packages:
if prepend:
packages = [pkg] + packages
else:
packages.append(pkg)
- oldfiles = d.getVar('FILES_' + pkg, True)
+ 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
@@ -212,9 +222,9 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst
d.setVar('FILES_' + pkg, oldfiles + " " + newfile)
if extra_depends != '':
d.appendVar('RDEPENDS_' + pkg, ' ' + extra_depends)
- if not d.getVar('DESCRIPTION_' + pkg, True):
+ if not d.getVar('DESCRIPTION_' + pkg):
d.setVar('DESCRIPTION_' + pkg, description % on)
- if not d.getVar('SUMMARY_' + pkg, True):
+ if not d.getVar('SUMMARY_' + pkg):
d.setVar('SUMMARY_' + pkg, summary % on)
if postinst:
d.setVar('pkg_postinst_' + pkg, postinst)
@@ -224,14 +234,14 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst
hook(f, pkg, file_regex, output_pattern, m.group(1))
d.setVar('PACKAGES', ' '.join(packages))
- return split_packages
+ return list(split_packages)
PACKAGE_DEPENDS += "file-native"
python () {
- if d.getVar('PACKAGES', True) != '':
+ if d.getVar('PACKAGES') != '':
deps = ""
- for dep in (d.getVar('PACKAGE_DEPENDS', True) or "").split():
+ for dep in (d.getVar('PACKAGE_DEPENDS') or "").split():
deps += " %s:do_populate_sysroot" % dep
d.appendVarFlag('do_package', 'depends', deps)
@@ -257,29 +267,45 @@ def files_from_filevars(filevars):
continue
files.append(f)
- for f in files:
+ symlink_paths = []
+ for ind, f in enumerate(files):
+ # Handle directory symlinks. Truncate path to the lowest level symlink
+ parent = ''
+ for dirname in f.split('/')[:-1]:
+ parent = os.path.join(parent, dirname)
+ if dirname == '.':
+ continue
+ if cpath.islink(parent):
+ bb.warn("FILES contains file '%s' which resides under a "
+ "directory symlink. Please fix the recipe and use the "
+ "real path for the file." % f[1:])
+ symlink_paths.append(f)
+ files[ind] = parent
+ f = parent
+ break
+
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
+ return files, symlink_paths
# 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)
+ pkgdest = d.getVar('PKGDEST')
root = os.path.join(pkgdest, pkg)
cwd = os.getcwd()
os.chdir(root)
- conffiles = d.getVar('CONFFILES_%s' % pkg, True);
+ conffiles = d.getVar('CONFFILES_%s' % pkg);
if conffiles == None:
- conffiles = d.getVar('CONFFILES', True)
+ conffiles = d.getVar('CONFFILES')
if conffiles == None:
conffiles = ""
conffiles = conffiles.split()
- conf_orig_list = files_from_filevars(conffiles)
+ conf_orig_list = files_from_filevars(conffiles)[0]
# Remove links and directories from conf_orig_list to get conf_list which only contains normal files
conf_list = []
@@ -299,6 +325,15 @@ def get_conffiles(pkg, d):
os.chdir(cwd)
return conf_list
+def checkbuildpath(file, d):
+ tmpdir = d.getVar('TMPDIR')
+ with open(file) as f:
+ file_content = f.read()
+ if tmpdir in file_content:
+ return True
+
+ return False
+
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
@@ -308,11 +343,9 @@ def splitdebuginfo(file, debugfile, debugsrcdir, sourcefile, d):
import stat
- dvar = d.getVar('PKGD', 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(os.path.dirname(workdir))
+ dvar = d.getVar('PKGD')
+ objcopy = d.getVar("OBJCOPY")
+ debugedit = d.expand("${STAGING_LIBDIR_NATIVE}/rpm/debugedit")
# We ignore kernel modules, we don't generate debug info files.
if file.find("/lib/modules/") != -1 and file.endswith(".ko"):
@@ -326,7 +359,7 @@ def splitdebuginfo(file, debugfile, debugsrcdir, sourcefile, d):
# We need to extract the debug src information here...
if debugsrcdir:
- cmd = "'%s' -b '%s' -d '%s' -i -l '%s' '%s'" % (debugedit, workparentdir, debugsrcdir, sourcefile, file)
+ cmd = "'%s' -i -l '%s' '%s'" % (debugedit, 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 ""))
@@ -357,14 +390,21 @@ def copydebugsources(debugsrcdir, d):
sourcefile = d.expand("${WORKDIR}/debugsources.list")
if debugsrcdir and os.path.isfile(sourcefile):
- dvar = d.getVar('PKGD', True)
- strip = d.getVar("STRIP", True)
- objcopy = d.getVar("OBJCOPY", True)
+ dvar = d.getVar('PKGD')
+ strip = d.getVar("STRIP")
+ objcopy = d.getVar("OBJCOPY")
debugedit = d.expand("${STAGING_LIBDIR_NATIVE}/rpm/bin/debugedit")
- workdir = d.getVar("WORKDIR", True)
+ workdir = d.getVar("WORKDIR")
workparentdir = os.path.dirname(os.path.dirname(workdir))
workbasedir = os.path.basename(os.path.dirname(workdir)) + "/" + os.path.basename(workdir)
+ # If build path exists in sourcefile, it means toolchain did not use
+ # -fdebug-prefix-map to compile
+ if checkbuildpath(sourcefile, d):
+ localsrc_prefix = workparentdir + "/"
+ else:
+ localsrc_prefix = "/usr/src/debug/"
+
nosuchdir = []
basepath = dvar
for p in debugsrcdir.split("/"):
@@ -374,13 +414,16 @@ def copydebugsources(debugsrcdir, d):
bb.utils.mkdirhier(basepath)
cpath.updatecache(basepath)
- processdebugsrc = "LC_ALL=C ; sort -z -u '%s' | egrep -v -z '(<internal>|<built-in>)$' | "
+ # Ignore files from the recipe sysroots (target and native)
+ processdebugsrc = "LC_ALL=C ; sort -z -u '%s' | egrep -v -z '((<internal>|<built-in>)$|/.*recipe-sysroot.*/)' | "
# 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' | "
+ # Remove prefix in the source paths
+ processdebugsrc += "sed 's#%s##g' | "
processdebugsrc += "(cd '%s' ; cpio -pd0mlL --no-preserve-owner '%s%s' 2>/dev/null)"
- cmd = processdebugsrc % (sourcefile, workbasedir, workparentdir, dvar, debugsrcdir)
+ cmd = processdebugsrc % (sourcefile, workbasedir, localsrc_prefix, workparentdir, dvar, debugsrcdir)
(retval, output) = oe.utils.getstatusoutput(cmd)
# Can "fail" if internal headers/transient sources are attempted
#if retval:
@@ -425,7 +468,7 @@ def get_package_mapping (pkg, basepkg, 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:
+ if d.getVar(key, False) is None:
continue
d.setVarFlag(key, "type", "list")
if d.getVarFlag(key, "separator") is None:
@@ -434,20 +477,17 @@ def get_package_additional_metadata (pkg_type, d):
return "\n".join(metadata_fields).strip()
def runtime_mapping_rename (varname, pkg, d):
- #bb.note("%s before: %s" % (varname, d.getVar(varname, True)))
-
- if bb.data.inherits_class('packagegroup', d):
- return
+ #bb.note("%s before: %s" % (varname, d.getVar(varname)))
new_depends = {}
- deps = bb.utils.explode_dep_versions2(d.getVar(varname, True) or "")
+ deps = bb.utils.explode_dep_versions2(d.getVar(varname) or "")
for depend in deps:
new_depend = get_package_mapping(depend, pkg, d)
new_depends[new_depend] = deps[depend]
d.setVar(varname, bb.utils.join_deps(new_depends, commasep=False))
- #bb.note("%s after: %s" % (varname, d.getVar(varname, True)))
+ #bb.note("%s after: %s" % (varname, d.getVar(varname)))
#
# Package functions suitable for inclusion in PACKAGEFUNCS
@@ -458,34 +498,34 @@ python package_get_auto_pr() {
import re
# Support per recipe PRSERV_HOST
- pn = d.getVar('PN', True)
- host = d.getVar("PRSERV_HOST_" + pn, True)
+ pn = d.getVar('PN')
+ host = d.getVar("PRSERV_HOST_" + pn)
if not (host is None):
d.setVar("PRSERV_HOST", host)
- pkgv = d.getVar("PKGV", True)
+ pkgv = d.getVar("PKGV")
# PR Server not active, handle AUTOINC
- if not d.getVar('PRSERV_HOST', True):
+ if not d.getVar('PRSERV_HOST'):
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)
+ pv = d.getVar("PV")
+ version = d.getVar("PRAUTOINX")
+ pkgarch = d.getVar("PACKAGE_ARCH")
+ checksum = d.getVar("BB_TASKHASH")
- if d.getVar('PRSERV_LOCKDOWN', True):
- auto_pr = d.getVar('PRAUTO_' + version + '_' + pkgarch, True) or d.getVar('PRAUTO_' + version, True) or None
+ if d.getVar('PRSERV_LOCKDOWN'):
+ auto_pr = d.getVar('PRAUTO_' + version + '_' + pkgarch) or d.getVar('PRAUTO_' + version) or None
if auto_pr is None:
bb.fatal("Can NOT get PRAUTO from lockdown exported file")
d.setVar('PRAUTO',str(auto_pr))
return
try:
- conn = d.getVar("__PRSERV_CONN", True)
+ conn = d.getVar("__PRSERV_CONN")
if conn is None:
conn = oe.prservice.prserv_make_conn(d)
if conn is not None:
@@ -506,19 +546,19 @@ python package_get_auto_pr() {
LOCALEBASEPN ??= "${PN}"
python package_do_split_locales() {
- if (d.getVar('PACKAGE_NO_LOCALE', True) == '1'):
+ if (d.getVar('PACKAGE_NO_LOCALE') == '1'):
bb.debug(1, "package requested not splitting locales")
return
- packages = (d.getVar('PACKAGES', True) or "").split()
+ packages = (d.getVar('PACKAGES') or "").split()
- datadir = d.getVar('datadir', True)
+ datadir = d.getVar('datadir')
if not datadir:
bb.note("datadir not defined")
return
- dvar = d.getVar('PKGD', True)
- pn = d.getVar('LOCALEBASEPN', True)
+ dvar = d.getVar('PKGD')
+ pn = d.getVar('LOCALEBASEPN')
if pn + '-locale' in packages:
packages.remove(pn + '-locale')
@@ -531,10 +571,10 @@ python package_do_split_locales() {
locales = os.listdir(localedir)
- summary = d.getVar('SUMMARY', True) or pn
- description = d.getVar('DESCRIPTION', True) or ""
- locale_section = d.getVar('LOCALE_SECTION', True)
- mlprefix = d.getVar('MLPREFIX', True) or ""
+ summary = d.getVar('SUMMARY') or pn
+ description = d.getVar('DESCRIPTION') or ""
+ locale_section = d.getVar('LOCALE_SECTION')
+ mlprefix = d.getVar('MLPREFIX') or ""
for l in sorted(locales):
ln = legitimize_package_name(l)
pkg = pn + '-locale-' + ln
@@ -555,14 +595,14 @@ 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 "").split()
+ #rdep = (d.getVar('RDEPENDS_%s' % pn) or "").split()
#rdep.append('%s-locale*' % pn)
#d.setVar('RDEPENDS_%s' % pn, ' '.join(rdep))
}
python perform_packagecopy () {
- dest = d.getVar('D', True)
- dvar = d.getVar('PKGD', True)
+ dest = d.getVar('D')
+ dvar = d.getVar('PKGD')
# Start by package population by taking a copy of the installed
# files to operate on
@@ -696,8 +736,8 @@ 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)
+ bbpath = d.getVar('BBPATH')
+ fs_perms_tables = d.getVar('FILESYSTEM_PERMS_TABLES')
if not fs_perms_tables:
fs_perms_tables = 'files/fs-perms.txt'
for conf_file in fs_perms_tables.split():
@@ -706,9 +746,10 @@ python fixup_perms () {
- dvar = d.getVar('PKGD', True)
+ dvar = d.getVar('PKGD')
fs_perms_table = {}
+ fs_link_table = {}
# By default all of the standard directories specified in
# bitbake.conf will get 0755 root:root.
@@ -734,10 +775,10 @@ python fixup_perms () {
'oldincludedir' ]
for path in target_path_vars:
- dir = d.getVar(path, True) or ""
+ dir = d.getVar(path) or ""
if dir == "":
continue
- fs_perms_table[dir] = fs_perms_entry(bb.data.expand("%s 0755 root root false - - -" % (dir), d))
+ fs_perms_table[dir] = fs_perms_entry(d.expand("%s 0755 root root false - - -" % (dir)))
# Now we actually load from the configuration files
for conf in get_fs_perms_list(d).split():
@@ -755,24 +796,32 @@ python fixup_perms () {
continue
entry = fs_perms_entry(d.expand(line))
if entry and entry.path:
- fs_perms_table[entry.path] = entry
+ if entry.link:
+ fs_link_table[entry.path] = entry
+ if entry.path in fs_perms_table:
+ fs_perms_table.pop(entry.path)
+ else:
+ fs_perms_table[entry.path] = entry
+ if entry.path in fs_link_table:
+ fs_link_table.pop(entry.path)
f.close()
# Debug -- list out in-memory table
#for dir in fs_perms_table:
# bb.note("Fixup Perms: %s: %s" % (dir, str(fs_perms_table[dir])))
+ #for link in fs_link_table:
+ # bb.note("Fixup Perms: %s: %s" % (link, str(fs_link_table[link])))
# We process links first, so we can go back and fixup directory ownership
# for any newly created directories
- for dir in fs_perms_table:
- if not fs_perms_table[dir].link:
- continue
-
+ # Process in sorted order so /run gets created before /run/lock, etc.
+ for entry in sorted(fs_link_table.values(), key=lambda x: x.link):
+ link = entry.link
+ dir = entry.path
origin = dvar + dir
if not (cpath.exists(origin) and cpath.isdir(origin) and not cpath.islink(origin)):
continue
- link = fs_perms_table[dir].link
if link[0] == "/":
target = dvar + link
ptarget = link
@@ -792,9 +841,6 @@ python fixup_perms () {
os.symlink(link, origin)
for dir in fs_perms_table:
- if fs_perms_table[dir].link:
- continue
-
origin = dvar + dir
if not (cpath.exists(origin) and cpath.isdir(origin)):
continue
@@ -814,17 +860,20 @@ python fixup_perms () {
python split_and_strip_files () {
import stat, errno
- dvar = d.getVar('PKGD', True)
- pn = d.getVar('PN', True)
+ dvar = d.getVar('PKGD')
+ pn = d.getVar('PN')
+
+ oldcwd = os.getcwd()
+ os.chdir(dvar)
# We default to '.debug' style
- if d.getVar('PACKAGE_DEBUG_SPLIT_STYLE', True) == 'debug-file-directory':
+ if d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-file-directory':
# Single debug-file-directory style debug info
debugappend = ".debug"
debugdir = ""
debuglibdir = "/usr/lib/debug"
debugsrcdir = "/usr/src/debug"
- elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE', True) == 'debug-without-src':
+ elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-without-src':
# Original OE-core, a.k.a. ".debug", style debug info, but without sources in /usr/src/debug
debugappend = ""
debugdir = "/.debug"
@@ -840,8 +889,6 @@ python split_and_strip_files () {
sourcefile = d.expand("${WORKDIR}/debugsources.list")
bb.utils.remove(sourcefile)
- os.chdir(dvar)
-
# Return type (bits):
# 0 - not elf
# 1 - ELF
@@ -875,11 +922,12 @@ python split_and_strip_files () {
#
elffiles = {}
symlinks = {}
- hardlinks = {}
kernmods = []
- 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'):
+ inodes = {}
+ libdir = os.path.abspath(dvar + os.sep + d.getVar("libdir"))
+ baselibdir = os.path.abspath(dvar + os.sep + d.getVar("base_libdir"))
+ if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1' or \
+ d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
for root, dirs, files in cpath.walk(dvar):
for f in files:
file = os.path.join(root, f)
@@ -906,7 +954,7 @@ python split_and_strip_files () {
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):
+ or ((file.startswith(libdir) or file.startswith(baselibdir)) and (".so" in f or ".node" 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)
@@ -914,39 +962,42 @@ python split_and_strip_files () {
#bb.note("Sym: %s (%d)" % (ltarget, isELF(ltarget)))
symlinks[file] = target
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:
if elf_file & 2:
- if 'already-stripped' in (d.getVar('INSANE_SKIP_' + pn, True) or "").split():
+ if 'already-stripped' in (d.getVar('INSANE_SKIP_' + pn) 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
- # 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
- hardlinks[file] = file_reference
- continue
- elffiles[file] = 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'):
- hardlinkmap = {}
- # For hardlinks, process only one of the files
- for file in hardlinks:
- file_reference = hardlinks[file]
- if file_reference not in hardlinkmap:
- # If this is a new file, add it as a reference, and
- # update it's type, so we can fall through and split
- elffiles[file] = isELF(file)
- hardlinkmap[file_reference] = file
-
+ if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
for file in elffiles:
src = file[len(dvar):]
dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
@@ -959,13 +1010,14 @@ python split_and_strip_files () {
splitdebuginfo(file, fpath, debugsrcdir, sourcefile, d)
# Hardlink our debug symbols to the other hardlink copies
- for file in hardlinks:
- if file not in elffiles:
+ for ref in inodes:
+ if len(inodes[ref]) == 1:
+ continue
+ for file in inodes[ref][1:]:
src = file[len(dvar):]
dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
fpath = dvar + dest
- file_reference = hardlinks[file]
- target = hardlinkmap[file_reference][len(dvar):]
+ target = inodes[ref][0][len(dvar):]
ftarget = dvar + debuglibdir + os.path.dirname(target) + debugdir + "/" + os.path.basename(target) + debugappend
bb.utils.mkdirhier(os.path.dirname(fpath))
#bb.note("Link %s -> %s" % (fpath, ftarget))
@@ -1008,8 +1060,8 @@ python split_and_strip_files () {
#
# Now lets go back over things and strip them
#
- if (d.getVar('INHIBIT_PACKAGE_STRIP', True) != '1'):
- strip = d.getVar("STRIP", True)
+ if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1'):
+ strip = d.getVar("STRIP")
sfiles = []
for file in elffiles:
elf_file = int(elffiles[file])
@@ -1023,53 +1075,68 @@ python split_and_strip_files () {
#
# End of strip
#
+ os.chdir(oldcwd)
}
python populate_packages () {
import glob, re
- workdir = d.getVar('WORKDIR', True)
- outdir = d.getVar('DEPLOY_DIR', True)
- dvar = d.getVar('PKGD', True)
- packages = d.getVar('PACKAGES', True)
- pn = d.getVar('PN', True)
+ workdir = d.getVar('WORKDIR')
+ outdir = d.getVar('DEPLOY_DIR')
+ dvar = d.getVar('PKGD')
+ packages = d.getVar('PACKAGES')
+ pn = d.getVar('PN')
bb.utils.mkdirhier(outdir)
os.chdir(dvar)
+
+ autodebug = not (d.getVar("NOAUTOPACKAGEDEBUG") or False)
- # Sanity check PACKAGES for duplicates and for LICENSE_EXCLUSION
+ # Sanity check PACKAGES for duplicates
# Sanity should be moved to sanity.bbclass once we have the infrastucture
package_list = []
for pkg in packages.split():
- if d.getVar('LICENSE_EXCLUSION-' + pkg, True):
- msg = "%s has an incompatible license. Excluding from packaging." % pkg
- package_qa_handle_error("incompatible-license", msg, d)
if pkg in package_list:
msg = "%s is listed in PACKAGES multiple times, this leads to packaging errors." % pkg
package_qa_handle_error("packages-list", msg, d)
+ elif autodebug and pkg.endswith("-dbg"):
+ package_list.insert(0, pkg)
else:
package_list.append(pkg)
d.setVar('PACKAGES', ' '.join(package_list))
- pkgdest = d.getVar('PKGDEST', True)
+ pkgdest = d.getVar('PKGDEST')
seen = []
# os.mkdir masks the permissions with umask so we have to unset it first
oldumask = os.umask(0)
+ debug = []
+ for root, dirs, files in cpath.walk(dvar):
+ dir = root[len(dvar):]
+ if not dir:
+ dir = os.sep
+ for f in (files + dirs):
+ path = "." + os.path.join(dir, f)
+ if "/.debug/" in path or path.endswith("/.debug"):
+ debug.append(path)
+
for pkg in package_list:
root = os.path.join(pkgdest, pkg)
bb.utils.mkdirhier(root)
- filesvar = d.getVar('FILES_%s' % pkg, True) or ""
+ filesvar = d.getVar('FILES_%s' % pkg) or ""
if "//" in filesvar:
msg = "FILES variable for package %s contains '//' which is invalid. Attempting to fix this but you should correct the metadata.\n" % pkg
package_qa_handle_error("files-invalid", msg, d)
filesvar.replace("//", "/")
origfiles = filesvar.split()
- files = files_from_filevars(origfiles)
+ files, symlink_paths = files_from_filevars(origfiles)
+
+ if autodebug and pkg.endswith("-dbg"):
+ files.extend(debug)
for file in files:
if (not cpath.islink(file)) and (not cpath.exists(file)):
@@ -1078,9 +1145,6 @@ python populate_packages () {
continue
seen.append(file)
- if d.getVar('LICENSE_EXCLUSION-' + pkg, True):
- continue
-
def mkdir(src, dest, p):
src = os.path.join(src, p)
dest = os.path.join(dest, p)
@@ -1110,17 +1174,33 @@ python populate_packages () {
fpath = os.path.join(root,file)
if not cpath.islink(file):
os.link(file, fpath)
- fstat = cpath.stat(file)
- os.chmod(fpath, fstat.st_mode)
- os.chown(fpath, fstat.st_uid, fstat.st_gid)
continue
ret = bb.utils.copyfile(file, fpath)
if ret is False or ret == 0:
- raise bb.build.FuncFailed("File population failed")
+ bb.fatal("File population failed")
+
+ # Check if symlink paths exist
+ for file in symlink_paths:
+ if not os.path.exists(os.path.join(root,file)):
+ bb.fatal("File '%s' cannot be packaged into '%s' because its "
+ "parent directory structure does not exist. One of "
+ "its parent directories is a symlink whose target "
+ "directory is not included in the package." %
+ (file, pkg))
os.umask(oldumask)
os.chdir(workdir)
+ # Handle LICENSE_EXCLUSION
+ package_list = []
+ for pkg in packages.split():
+ if d.getVar('LICENSE_EXCLUSION-' + pkg):
+ msg = "%s has an incompatible license. Excluding from packaging." % pkg
+ package_qa_handle_error("incompatible-license", msg, d)
+ else:
+ package_list.append(pkg)
+ d.setVar('PACKAGES', ' '.join(package_list))
+
unshipped = []
for root, dirs, files in cpath.walk(dvar):
dir = root[len(dvar):]
@@ -1132,20 +1212,22 @@ python populate_packages () {
unshipped.append(path)
if unshipped != []:
- msg = pn + ": Files/directories were installed but not shipped"
- if "installed-vs-shipped" in (d.getVar('INSANE_SKIP_' + pn, True) or "").split():
+ msg = pn + ": Files/directories were installed but not shipped in any package:"
+ if "installed-vs-shipped" in (d.getVar('INSANE_SKIP_' + pn) or "").split():
bb.note("Package %s skipping QA tests: installed-vs-shipped" % pn)
else:
for f in unshipped:
msg = msg + "\n " + f
+ msg = msg + "\nPlease set FILES such that these items are packaged. Alternatively if they are unneeded, avoid installing them or delete them within do_install.\n"
+ msg = msg + "%s: %d installed and not shipped files." % (pn, len(unshipped))
package_qa_handle_error("installed-vs-shipped", msg, d)
}
populate_packages[dirs] = "${D}"
python package_fixsymlinks () {
import errno
- pkgdest = d.getVar('PKGDEST', True)
- packages = d.getVar("PACKAGES").split()
+ pkgdest = d.getVar('PKGDEST')
+ packages = d.getVar("PACKAGES", False).split()
dangling_links = {}
pkg_files = {}
@@ -1179,7 +1261,7 @@ python package_fixsymlinks () {
bb.note("%s contains dangling symlink to %s" % (pkg, l))
for pkg in newrdepends:
- rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg, True) or "")
+ rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg) or "")
for p in newrdepends[pkg]:
if p not in rdepends:
rdepends[p] = []
@@ -1207,14 +1289,14 @@ python emit_pkgdata() {
def write_if_exists(f, pkg, var):
def encode(str):
import codecs
- c = codecs.getencoder("string_escape")
- return c(str)[0]
+ c = codecs.getencoder("unicode_escape")
+ return c(str)[0].decode("latin1")
- val = d.getVar('%s_%s' % (var, pkg), True)
+ val = d.getVar('%s_%s' % (var, pkg))
if val:
f.write('%s_%s: %s\n' % (var, pkg, encode(val)))
return val
- val = d.getVar('%s' % (var), True)
+ val = d.getVar('%s' % (var))
if val:
f.write('%s: %s\n' % (var, encode(val)))
return val
@@ -1233,9 +1315,9 @@ python emit_pkgdata() {
with open(subdata_file, 'w') as fd:
fd.write("PKG_%s: %s" % (ml_pkg, pkg))
- packages = d.getVar('PACKAGES', True)
- pkgdest = d.getVar('PKGDEST', True)
- pkgdatadir = d.getVar('PKGDESTWORK', True)
+ packages = d.getVar('PACKAGES')
+ pkgdest = d.getVar('PKGDEST')
+ pkgdatadir = d.getVar('PKGDESTWORK')
# Take shared lock since we're only reading, not writing
lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"), True)
@@ -1245,9 +1327,9 @@ python emit_pkgdata() {
f.write("PACKAGES: %s\n" % packages)
f.close()
- pn = d.getVar('PN', True)
- global_variants = (d.getVar('MULTILIB_GLOBAL_VARIANTS', True) or "").split()
- variants = (d.getVar('MULTILIB_VARIANTS', True) or "").split()
+ pn = d.getVar('PN')
+ global_variants = (d.getVar('MULTILIB_GLOBAL_VARIANTS') or "").split()
+ variants = (d.getVar('MULTILIB_VARIANTS') or "").split()
if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
write_extra_pkgs(variants, pn, packages, pkgdatadir)
@@ -1255,10 +1337,10 @@ python emit_pkgdata() {
if (bb.data.inherits_class('allarch', d) and not bb.data.inherits_class('packagegroup', d)):
write_extra_pkgs(global_variants, pn, packages, pkgdatadir)
- workdir = d.getVar('WORKDIR', True)
+ workdir = d.getVar('WORKDIR')
for pkg in packages.split():
- pkgval = d.getVar('PKG_%s' % pkg, True)
+ pkgval = d.getVar('PKG_%s' % pkg)
if pkgval is None:
pkgval = pkg
d.setVar('PKG_%s' % pkg, pkg)
@@ -1266,11 +1348,14 @@ python emit_pkgdata() {
pkgdestpkg = os.path.join(pkgdest, pkg)
files = {}
total_size = 0
+ seen = set()
for f in pkgfiles[pkg]:
relpth = os.path.relpath(f, pkgdestpkg)
fstat = os.lstat(f)
- total_size += fstat.st_size
files[os.sep + relpth] = fstat.st_size
+ if fstat.st_ino not in seen:
+ seen.add(fstat.st_ino)
+ total_size += fstat.st_size
d.setVar('FILES_INFO', json.dumps(files))
subdata_file = pkgdatadir + "/runtime/%s" % pkg
@@ -1295,17 +1380,18 @@ python emit_pkgdata() {
write_if_exists(sf, pkg, 'PKG')
write_if_exists(sf, pkg, 'ALLOW_EMPTY')
write_if_exists(sf, pkg, 'FILES')
+ write_if_exists(sf, pkg, 'CONFFILES')
write_if_exists(sf, pkg, 'pkg_postinst')
write_if_exists(sf, pkg, 'pkg_postrm')
write_if_exists(sf, pkg, 'pkg_preinst')
write_if_exists(sf, pkg, 'pkg_prerm')
write_if_exists(sf, pkg, 'FILERPROVIDESFLIST')
write_if_exists(sf, pkg, 'FILES_INFO')
- for dfile in (d.getVar('FILERPROVIDESFLIST_' + pkg, True) or "").split():
+ for dfile in (d.getVar('FILERPROVIDESFLIST_' + pkg) or "").split():
write_if_exists(sf, pkg, 'FILERPROVIDES_' + dfile)
write_if_exists(sf, pkg, 'FILERDEPENDSFLIST')
- for dfile in (d.getVar('FILERDEPENDSFLIST_' + pkg, True) or "").split():
+ for dfile in (d.getVar('FILERDEPENDSFLIST_' + pkg) or "").split():
write_if_exists(sf, pkg, 'FILERDEPENDS_' + dfile)
sf.write('%s_%s: %d\n' % ('PKGSIZE', pkg, total_size))
@@ -1318,9 +1404,9 @@ python emit_pkgdata() {
bb.utils.mkdirhier(os.path.dirname(subdata_sym))
oe.path.symlink("../../runtime/%s" % pkg, subdata_sym, True)
- allow_empty = d.getVar('ALLOW_EMPTY_%s' % pkg, True)
+ allow_empty = d.getVar('ALLOW_EMPTY_%s' % pkg)
if not allow_empty:
- allow_empty = d.getVar('ALLOW_EMPTY', True)
+ allow_empty = d.getVar('ALLOW_EMPTY')
root = "%s/%s" % (pkgdest, pkg)
os.chdir(root)
g = glob('*')
@@ -1348,7 +1434,7 @@ if [ x"$D" = "x" ]; then
fi
}
-RPMDEPS = "${STAGING_LIBDIR_NATIVE}/rpm/bin/rpmdeps-oecore --macros ${STAGING_LIBDIR_NATIVE}/rpm/macros --define '_rpmfc_magic_path ${STAGING_DIR_NATIVE}${datadir_native}/misc/magic.mgc' --rpmpopt ${STAGING_LIBDIR_NATIVE}/rpm/rpmpopt"
+RPMDEPS = "${STAGING_LIBDIR_NATIVE}/rpm/rpmdeps --rcfile ${STAGING_LIBDIR_NATIVE}/rpm/rpmrc --macros ${STAGING_LIBDIR_NATIVE}/rpm/macros --define '_rpmconfigdir ${STAGING_LIBDIR_NATIVE}/rpm/'"
# Collect perfile run-time dependency metadata
# Output:
@@ -1359,24 +1445,25 @@ RPMDEPS = "${STAGING_LIBDIR_NATIVE}/rpm/bin/rpmdeps-oecore --macros ${STAGING_LI
# FILERDEPENDS_filepath_pkg - per file dep
python package_do_filedeps() {
- if d.getVar('SKIP_FILEDEPS', True) == '1':
+ if d.getVar('SKIP_FILEDEPS') == '1':
return
- pkgdest = d.getVar('PKGDEST', True)
- packages = d.getVar('PACKAGES', True)
- rpmdeps = d.getVar('RPMDEPS', True)
+ pkgdest = d.getVar('PKGDEST')
+ packages = d.getVar('PACKAGES')
+ rpmdeps = d.getVar('RPMDEPS')
+ magic = d.expand("${STAGING_DIR_NATIVE}${datadir_native}/misc/magic.mgc")
def chunks(files, n):
return [files[i:i+n] for i in range(0, len(files), n)]