diff options
Diffstat (limited to 'meta/classes/package.bbclass')
-rw-r--r-- | meta/classes/package.bbclass | 568 |
1 files changed, 400 insertions, 168 deletions
diff --git a/meta/classes/package.bbclass b/meta/classes/package.bbclass index aa8451ffe8..3a78e48da4 100644 --- a/meta/classes/package.bbclass +++ b/meta/classes/package.bbclass @@ -7,7 +7,7 @@ # # There are the following default steps but PACKAGEFUNCS can be extended: # -# a) package_get_auto_pr - get PRAUTO from remote PR service +# a) package_convert_pr_autoinc - convert AUTOINC in PKGV to ${PRSERV_PV_AUTOINC} # # b) perform_packagecopy - Copy D into PKGD # @@ -199,7 +199,7 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst packages = [pkg] + packages else: packages.append(pkg) - oldfiles = d.getVar('FILES_' + 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 @@ -219,19 +219,19 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst 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)) + d.setVar('FILES:' + pkg, " ".join(the_files)) else: - d.setVar('FILES_' + pkg, oldfiles + " " + newfile) + 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) + 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) + d.setVar('pkg_postinst:' + pkg, postinst) if postrm: - d.setVar('pkg_postrm_' + pkg, postrm) + d.setVar('pkg_postrm:' + pkg, postrm) if callable(hook): hook(f, pkg, file_regex, output_pattern, m.group(1)) @@ -245,6 +245,8 @@ python () { deps = "" for dep in (d.getVar('PACKAGE_DEPENDS') or "").split(): deps += " %s:do_populate_sysroot" % dep + if d.getVar('PACKAGE_MINIDEBUGINFO') == '1': + deps += ' xz-native:do_populate_sysroot' d.appendVarFlag('do_package', 'depends', deps) # shlibs requires any DEPENDS to have already packaged for the *.list files @@ -301,7 +303,7 @@ def get_conffiles(pkg, d): cwd = os.getcwd() os.chdir(root) - conffiles = d.getVar('CONFFILES_%s' % pkg); + conffiles = d.getVar('CONFFILES:%s' % pkg); if conffiles == None: conffiles = d.getVar('CONFFILES') if conffiles == None: @@ -416,6 +418,126 @@ def splitdebuginfo(file, dvar, debugdir, debuglibdir, debugappend, debugsrcdir, return (file, sources) +def splitstaticdebuginfo(file, dvar, debugstaticdir, debugstaticlibdir, debugstaticappend, debugsrcdir, d): + # Unlike the function above, there is no way to split a static library + # two components. So to get similar results we will copy the unmodified + # static library (containing the debug symbols) into a new directory. + # We will then strip (preserving symbols) the static library in the + # typical location. + # + # return a mapping of files:debugsources + + import stat + import shutil + + src = file[len(dvar):] + dest = debugstaticlibdir + os.path.dirname(src) + debugstaticdir + "/" + os.path.basename(src) + debugstaticappend + debugfile = dvar + dest + sources = [] + + # Copy the file... + bb.utils.mkdirhier(os.path.dirname(debugfile)) + #bb.note("Copy %s -> %s" % (file, debugfile)) + + dvar = d.getVar('PKGD') + + 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) + + # We need to extract the debug src information here... + if debugsrcdir: + sources = source_info(file, d) + + bb.utils.mkdirhier(os.path.dirname(debugfile)) + + # Copy the unmodified item to the debug directory + shutil.copy2(file, debugfile) + + if newmode: + os.chmod(file, origmode) + + return (file, sources) + +def inject_minidebuginfo(file, dvar, debugdir, debuglibdir, debugappend, debugsrcdir, d): + # Extract just the symbols from debuginfo into minidebuginfo, + # compress it with xz and inject it back into the binary in a .gnu_debugdata section. + # https://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html + + import subprocess + + readelf = d.getVar('READELF') + nm = d.getVar('NM') + objcopy = d.getVar('OBJCOPY') + + minidebuginfodir = d.expand('${WORKDIR}/minidebuginfo') + + src = file[len(dvar):] + dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend + debugfile = dvar + dest + minidebugfile = minidebuginfodir + src + '.minidebug' + bb.utils.mkdirhier(os.path.dirname(minidebugfile)) + + # If we didn't produce debuginfo for any reason, we can't produce minidebuginfo either + # so skip it. + if not os.path.exists(debugfile): + bb.debug(1, 'ELF file {} has no debuginfo, skipping minidebuginfo injection'.format(file)) + return + + # Find non-allocated PROGBITS, NOTE, and NOBITS sections in the debuginfo. + # We will exclude all of these from minidebuginfo to save space. + remove_section_names = [] + for line in subprocess.check_output([readelf, '-W', '-S', debugfile], universal_newlines=True).splitlines(): + fields = line.split() + if len(fields) < 8: + continue + name = fields[0] + type = fields[1] + flags = fields[7] + # .debug_ sections will be removed by objcopy -S so no need to explicitly remove them + if name.startswith('.debug_'): + continue + if 'A' not in flags and type in ['PROGBITS', 'NOTE', 'NOBITS']: + remove_section_names.append(name) + + # List dynamic symbols in the binary. We can exclude these from minidebuginfo + # because they are always present in the binary. + dynsyms = set() + for line in subprocess.check_output([nm, '-D', file, '--format=posix', '--defined-only'], universal_newlines=True).splitlines(): + dynsyms.add(line.split()[0]) + + # Find all function symbols from debuginfo which aren't in the dynamic symbols table. + # These are the ones we want to keep in minidebuginfo. + keep_symbols_file = minidebugfile + '.symlist' + found_any_symbols = False + with open(keep_symbols_file, 'w') as f: + for line in subprocess.check_output([nm, debugfile, '--format=sysv', '--defined-only'], universal_newlines=True).splitlines(): + fields = line.split('|') + if len(fields) < 7: + continue + name = fields[0].strip() + type = fields[3].strip() + if type == 'FUNC' and name not in dynsyms: + f.write('{}\n'.format(name)) + found_any_symbols = True + + if not found_any_symbols: + bb.debug(1, 'ELF file {} contains no symbols, skipping minidebuginfo injection'.format(file)) + return + + bb.utils.remove(minidebugfile) + bb.utils.remove(minidebugfile + '.xz') + + subprocess.check_call([objcopy, '-S'] + + ['--remove-section={}'.format(s) for s in remove_section_names] + + ['--keep-symbols={}'.format(keep_symbols_file), debugfile, minidebugfile]) + + subprocess.check_call(['xz', '--keep', minidebugfile]) + + subprocess.check_call([objcopy, '--add-section', '.gnu_debugdata={}.xz'.format(minidebugfile), file]) + def copydebugsources(debugsrcdir, sources, d): # The debug src information written out to sourcefile is further processed # and copied to the destination here. @@ -492,17 +614,25 @@ def copydebugsources(debugsrcdir, sources, d): # Package data handling routines # -def get_package_mapping (pkg, basepkg, d): +def get_package_mapping (pkg, basepkg, d, depversions=None): import oe.packagedata data = oe.packagedata.read_subpkgdata(pkg, d) - key = "PKG_%s" % pkg + 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 not d.getVar('MULTILIB_VARIANTS') \ and data[key] == basepkg: return pkg + if depversions == []: + # Avoid returning a mapping if the renamed package rprovides its original name + rprovkey = "RPROVIDES:%s" % pkg + if rprovkey in data: + if pkg in bb.utils.explode_dep_versions2(data[rprovkey]): + bb.note("%s rprovides %s, not replacing the latter" % (data[key], pkg)) + return pkg + # Do map to rewritten package name return data[key] return pkg @@ -523,8 +653,10 @@ def runtime_mapping_rename (varname, pkg, d): new_depends = {} deps = bb.utils.explode_dep_versions2(d.getVar(varname) or "") - for depend in deps: - new_depend = get_package_mapping(depend, pkg, d) + for depend, depversions in deps.items(): + new_depend = get_package_mapping(depend, pkg, d, depversions) + if depend != new_depend: + bb.note("package name mapping done: %s -> %s" % (depend, new_depend)) new_depends[new_depend] = deps[depend] d.setVar(varname, bb.utils.join_deps(new_depends, commasep=False)) @@ -532,12 +664,20 @@ def runtime_mapping_rename (varname, pkg, d): #bb.note("%s after: %s" % (varname, d.getVar(varname))) # -# Package functions suitable for inclusion in PACKAGEFUNCS +# Used by do_packagedata (and possibly other routines post do_package) # +package_get_auto_pr[vardepsexclude] = "BB_TASKDEPDATA" python package_get_auto_pr() { import oe.prservice - import re + + def get_do_package_hash(pn): + if d.getVar("BB_RUNTASK") != "do_package": + taskdepdata = d.getVar("BB_TASKDEPDATA", False) + for dep in taskdepdata: + if taskdepdata[dep][1] == "do_package" and taskdepdata[dep][0] == pn: + return taskdepdata[dep][6] + return None # Support per recipe PRSERV_HOST pn = d.getVar('PN') @@ -549,15 +689,22 @@ python package_get_auto_pr() { # PR Server not active, handle AUTOINC if not d.getVar('PRSERV_HOST'): - if 'AUTOINC' in pkgv: - d.setVar("PKGV", pkgv.replace("AUTOINC", "0")) + d.setVar("PRSERV_PV_AUTOINC", "0") return auto_pr = None pv = d.getVar("PV") version = d.getVar("PRAUTOINX") pkgarch = d.getVar("PACKAGE_ARCH") - checksum = d.getVar("BB_TASKHASH") + checksum = get_do_package_hash(pn) + + # If do_package isn't in the dependencies, we can't get the checksum... + if not checksum: + bb.warn('Task %s requested do_package unihash, but it was not available.' % d.getVar('BB_RUNTASK')) + #taskdepdata = d.getVar("BB_TASKDEPDATA", False) + #for dep in taskdepdata: + # bb.warn('%s:%s = %s' % (taskdepdata[dep][0], taskdepdata[dep][1], taskdepdata[dep][6])) + return if d.getVar('PRSERV_LOCKDOWN'): auto_pr = d.getVar('PRAUTO_' + version + '_' + pkgarch) or d.getVar('PRAUTO_' + version) or None @@ -567,17 +714,16 @@ python package_get_auto_pr() { return try: - conn = d.getVar("__PRSERV_CONN") - if conn is None: - conn = oe.prservice.prserv_make_conn(d) + 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))) + d.setVar("PRSERV_PV_AUTOINC", str(value)) auto_pr = conn.getPR(version, pkgarch, checksum) + conn.close() except Exception as e: bb.fatal("Can NOT get PRAUTO, exception %s" % str(e)) if auto_pr is None: @@ -585,6 +731,22 @@ python package_get_auto_pr() { d.setVar('PRAUTO',str(auto_pr)) } +# +# Package functions suitable for inclusion in PACKAGEFUNCS +# + +python package_convert_pr_autoinc() { + pkgv = d.getVar("PKGV") + + # Adjust pkgv as necessary... + if 'AUTOINC' in pkgv: + d.setVar("PKGV", pkgv.replace("AUTOINC", "${PRSERV_PV_AUTOINC}")) + + # Change PRSERV_PV_AUTOINC and EXTENDPRAUTO usage to special values + d.setVar('PRSERV_PV_AUTOINC', '@PRSERV_PV_AUTOINC@') + d.setVar('EXTENDPRAUTO', '@EXTENDPRAUTO@') +} + LOCALEBASEPN ??= "${PN}" python package_do_split_locales() { @@ -621,13 +783,13 @@ python package_do_split_locales() { ln = legitimize_package_name(l) pkg = pn + '-locale-' + ln packages.append(pkg) - d.setVar('FILES_' + pkg, os.path.join(datadir, 'locale', l)) - 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)) + d.setVar('FILES:' + pkg, os.path.join(datadir, 'locale', l)) + 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)) if locale_section: - d.setVar('SECTION_' + pkg, locale_section) + d.setVar('SECTION:' + pkg, locale_section) d.setVar('PACKAGES', ' '.join(packages)) @@ -637,17 +799,23 @@ 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) or "").split() + #rdep = (d.getVar('RDEPENDS:%s' % pn) or "").split() #rdep.append('%s-locale*' % pn) - #d.setVar('RDEPENDS_%s' % pn, ' '.join(rdep)) + #d.setVar('RDEPENDS:%s' % pn, ' '.join(rdep)) } python perform_packagecopy () { import subprocess + import shutil dest = d.getVar('D') dvar = d.getVar('PKGD') + # Remove ${D}/sysroot-only if present + sysroot_only = os.path.join(dest, 'sysroot-only') + if cpath.exists(sysroot_only) and cpath.isdir(sysroot_only): + shutil.rmtree(sysroot_only) + # Start by package population by taking a copy of the installed # files to operate on # Preserve sparse files and hard links @@ -826,8 +994,9 @@ python fixup_perms () { # Now we actually load from the configuration files for conf in get_fs_perms_list(d).split(): - if os.path.exists(conf): - f = open(conf) + if not os.path.exists(conf): + continue + with open(conf) as f: for line in f: if line.startswith('#'): continue @@ -848,7 +1017,6 @@ python fixup_perms () { 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: @@ -880,7 +1048,7 @@ python fixup_perms () { # Create path to move directory to, move it, and then setup the symlink bb.utils.mkdirhier(os.path.dirname(target)) #bb.note("Fixup Perms: Rename %s -> %s" % (dir, ptarget)) - os.rename(origin, target) + bb.utils.rename(origin, target) #bb.note("Fixup Perms: Link %s -> %s" % (dir, link)) os.symlink(link, origin) @@ -907,7 +1075,7 @@ python split_and_strip_files () { dvar = d.getVar('PKGD') pn = d.getVar('PN') - targetos = d.getVar('TARGET_OS') + hostos = d.getVar('HOST_OS') oldcwd = os.getcwd() os.chdir(dvar) @@ -916,25 +1084,37 @@ python split_and_strip_files () { if d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-file-directory': # Single debug-file-directory style debug info debugappend = ".debug" + debugstaticappend = "" debugdir = "" + debugstaticdir = "" debuglibdir = "/usr/lib/debug" + debugstaticlibdir = "/usr/lib/debug-static" debugsrcdir = "/usr/src/debug" 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 = "" + debugstaticappend = "" debugdir = "/.debug" + debugstaticdir = "/.debug-static" debuglibdir = "" + debugstaticlibdir = "" debugsrcdir = "" elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg': debugappend = "" + debugstaticappend = "" debugdir = "/.debug" + debugstaticdir = "/.debug-static" debuglibdir = "" + debugstaticlibdir = "" debugsrcdir = "/usr/src/debug" else: # Original OE-core, a.k.a. ".debug", style debug info debugappend = "" + debugstaticappend = "" debugdir = "/.debug" + debugstaticdir = "/.debug-static" debuglibdir = "" + debugstaticlibdir = "" debugsrcdir = "/usr/src/debug" # @@ -955,12 +1135,6 @@ python split_and_strip_files () { for root, dirs, files in cpath.walk(dvar): for f in files: file = os.path.join(root, f) - if file.endswith(".ko") and file.find("/lib/modules/") != -1: - kernmods.append(file) - continue - if oe.package.is_static_lib(file): - staticlibs.append(file) - continue # Skip debug files if debugappend and file.endswith(debugappend): @@ -971,6 +1145,13 @@ python split_and_strip_files () { if file in skipfiles: continue + if file.endswith(".ko") and file.find("/lib/modules/") != -1: + kernmods.append(file) + continue + if oe.package.is_static_lib(file): + staticlibs.append(file) + continue + try: ltarget = cpath.realpath(file, dvar, False) s = cpath.lstat(ltarget) @@ -1017,7 +1198,7 @@ python split_and_strip_files () { # ...but is it ELF, and is it already stripped? if elf_file & 1: if elf_file & 2: - if 'already-stripped' in (d.getVar('INSANE_SKIP_' + pn) 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) @@ -1043,15 +1224,28 @@ python split_and_strip_files () { # Modified the file so clear the cache cpath.updatecache(file) + def strip_pkgd_prefix(f): + nonlocal dvar + + if f.startswith(dvar): + return f[len(dvar):] + + return f + # # First lets process debug splitting # if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'): results = oe.utils.multiprocess_launch(splitdebuginfo, list(elffiles), d, extraargs=(dvar, debugdir, debuglibdir, debugappend, debugsrcdir, d)) - if debugsrcdir and not targetos.startswith("mingw"): - for file in staticlibs: - results.extend(source_info(file, d, fatal=False)) + if debugsrcdir and not hostos.startswith("mingw"): + if (d.getVar('PACKAGE_DEBUG_STATIC_SPLIT') == '1'): + results = oe.utils.multiprocess_launch(splitstaticdebuginfo, staticlibs, d, extraargs=(dvar, debugstaticdir, debugstaticlibdir, debugstaticappend, debugsrcdir, d)) + else: + for file in staticlibs: + results.append( (file,source_info(file, d)) ) + + d.setVar("PKGDEBUGSOURCES", {strip_pkgd_prefix(f): sorted(s) for f, s in results}) sources = set() for r in results: @@ -1120,9 +1314,17 @@ python split_and_strip_files () { sfiles.append((file, elf_file, strip)) for f in kernmods: sfiles.append((f, 16, strip)) + if (d.getVar('PACKAGE_STRIP_STATIC') == '1' or d.getVar('PACKAGE_DEBUG_STATIC_SPLIT') == '1'): + for f in staticlibs: + sfiles.append((f, 16, strip)) oe.utils.multiprocess_launch(oe.package.runstrip, sfiles, d) + # Build "minidebuginfo" and reinject it back into the stripped binaries + if d.getVar('PACKAGE_MINIDEBUGINFO') == '1': + oe.utils.multiprocess_launch(inject_minidebuginfo, list(elffiles), d, + extraargs=(dvar, debugdir, debuglibdir, debugappend, debugsrcdir, d)) + # # End of strip # @@ -1151,7 +1353,7 @@ python populate_packages () { src_package_name = ('%s-src' % d.getVar('PN')) if not src_package_name in packages: packages.append(src_package_name) - d.setVar('FILES_%s' % src_package_name, '/usr/src/debug') + d.setVar('FILES:%s' % src_package_name, '/usr/src/debug') # Sanity check PACKAGES for duplicates # Sanity should be moved to sanity.bbclass once we have the infrastructure @@ -1187,14 +1389,14 @@ python populate_packages () { dir = os.sep for f in (files + dirs): path = "." + os.path.join(dir, f) - if "/.debug/" in path or path.endswith("/.debug"): + if "/.debug/" in path or "/.debug-static/" in path or path.endswith("/.debug"): debug.append(path) for pkg in packages: root = os.path.join(pkgdest, pkg) bb.utils.mkdirhier(root) - filesvar = d.getVar('FILES_%s' % pkg) 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) @@ -1263,8 +1465,9 @@ python populate_packages () { # Handle LICENSE_EXCLUSION package_list = [] for pkg in packages: - if d.getVar('LICENSE_EXCLUSION-' + pkg): - msg = "%s has an incompatible license. Excluding from packaging." % pkg + licenses = d.getVar('LICENSE_EXCLUSION-' + pkg) + if licenses: + msg = "Excluding %s from packaging as it has incompatible license(s): %s" % (pkg, licenses) package_qa_handle_error("incompatible-license", msg, d) else: package_list.append(pkg) @@ -1282,7 +1485,7 @@ python populate_packages () { if unshipped != []: msg = pn + ": Files/directories were installed but not shipped in any package:" - if "installed-vs-shipped" in (d.getVar('INSANE_SKIP_' + pn) or "").split(): + 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: @@ -1330,11 +1533,11 @@ 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) or "") + rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS:' + pkg) or "") for p in newrdepends[pkg]: if p not in rdepends: rdepends[p] = [] - d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False)) + d.setVar('RDEPENDS:' + pkg, bb.utils.join_deps(rdepends, commasep=False)) } @@ -1351,14 +1554,15 @@ EXPORT_FUNCTIONS package_name_hook PKGDESTWORK = "${WORKDIR}/pkgdata" -PKGDATA_VARS = "PN PE PV PR PKGE PKGV PKGR LICENSE DESCRIPTION SUMMARY RDEPENDS RPROVIDES RRECOMMENDS RSUGGESTS RREPLACES RCONFLICTS SECTION PKG ALLOW_EMPTY FILES CONFFILES FILES_INFO pkg_postinst pkg_postrm pkg_preinst pkg_prerm" +PKGDATA_VARS = "PN PE PV PR PKGE PKGV PKGR LICENSE DESCRIPTION SUMMARY RDEPENDS RPROVIDES RRECOMMENDS RSUGGESTS RREPLACES RCONFLICTS SECTION PKG ALLOW_EMPTY FILES CONFFILES FILES_INFO PACKAGE_ADD_METADATA pkg_postinst pkg_postrm pkg_preinst pkg_prerm" python emit_pkgdata() { from glob import glob import json + import bb.compress.zstd def process_postinst_on_target(pkg, mlprefix): - pkgval = d.getVar('PKG_%s' % pkg) + pkgval = d.getVar('PKG:%s' % pkg) if pkgval is None: pkgval = pkg @@ -1369,8 +1573,8 @@ if [ -n "$D" ]; then fi """ % (pkgval, mlprefix) - postinst = d.getVar('pkg_postinst_%s' % pkg) - postinst_ontarget = d.getVar('pkg_postinst_ontarget_%s' % pkg) + postinst = d.getVar('pkg_postinst:%s' % pkg) + postinst_ontarget = d.getVar('pkg_postinst_ontarget:%s' % pkg) if postinst_ontarget: bb.debug(1, 'adding deferred pkg_postinst_ontarget() to pkg_postinst() for %s' % pkg) @@ -1378,18 +1582,18 @@ fi postinst = '#!/bin/sh\n' postinst += defer_fragment postinst += postinst_ontarget - d.setVar('pkg_postinst_%s' % pkg, postinst) + d.setVar('pkg_postinst:%s' % pkg, postinst) def add_set_e_to_scriptlets(pkg): for scriptlet_name in ('pkg_preinst', 'pkg_postinst', 'pkg_prerm', 'pkg_postrm'): - scriptlet = d.getVar('%s_%s' % (scriptlet_name, pkg)) + scriptlet = d.getVar('%s:%s' % (scriptlet_name, pkg)) if scriptlet: scriptlet_split = scriptlet.split('\n') if scriptlet_split[0].startswith("#!"): scriptlet = scriptlet_split[0] + "\nset -e\n" + "\n".join(scriptlet_split[1:]) else: scriptlet = "set -e\n" + "\n".join(scriptlet_split[0:]) - d.setVar('%s_%s' % (scriptlet_name, pkg), scriptlet) + d.setVar('%s:%s' % (scriptlet_name, pkg), scriptlet) def write_if_exists(f, pkg, var): def encode(str): @@ -1397,9 +1601,9 @@ fi c = codecs.getencoder("unicode_escape") return c(str)[0].decode("latin1") - val = d.getVar('%s_%s' % (var, pkg)) + val = d.getVar('%s:%s' % (var, pkg)) if val: - f.write('%s_%s: %s\n' % (var, pkg, encode(val))) + f.write('%s:%s: %s\n' % (var, pkg, encode(val))) return val val = d.getVar('%s' % (var)) if val: @@ -1418,16 +1622,17 @@ fi ml_pkg = "%s-%s" % (variant, pkg) subdata_file = "%s/runtime/%s" % (pkgdatadir, ml_pkg) with open(subdata_file, 'w') as fd: - fd.write("PKG_%s: %s" % (ml_pkg, pkg)) + fd.write("PKG:%s: %s" % (ml_pkg, pkg)) packages = d.getVar('PACKAGES') pkgdest = d.getVar('PKGDEST') pkgdatadir = d.getVar('PKGDESTWORK') - data_file = pkgdatadir + d.expand("/${PN}" ) - f = open(data_file, 'w') - f.write("PACKAGES: %s\n" % packages) - f.close() + data_file = pkgdatadir + d.expand("/${PN}") + with open(data_file, 'w') as fd: + fd.write("PACKAGES: %s\n" % packages) + + pkgdebugsource = d.getVar("PKGDEBUGSOURCES") or [] pn = d.getVar('PN') global_variants = (d.getVar('MULTILIB_GLOBAL_VARIANTS') or "").split() @@ -1443,23 +1648,38 @@ fi workdir = d.getVar('WORKDIR') for pkg in packages.split(): - pkgval = d.getVar('PKG_%s' % pkg) + pkgval = d.getVar('PKG:%s' % pkg) if pkgval is None: pkgval = pkg - d.setVar('PKG_%s' % pkg, pkg) + d.setVar('PKG:%s' % pkg, pkg) + + extended_data = { + "files_info": {} + } pkgdestpkg = os.path.join(pkgdest, pkg) files = {} + files_extra = {} total_size = 0 seen = set() for f in pkgfiles[pkg]: - relpth = os.path.relpath(f, pkgdestpkg) + fpath = os.sep + os.path.relpath(f, pkgdestpkg) + fstat = os.lstat(f) - files[os.sep + relpth] = fstat.st_size + files[fpath] = fstat.st_size + + extended_data["files_info"].setdefault(fpath, {}) + extended_data["files_info"][fpath]['size'] = 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, sort_keys=True)) + + if fpath in pkgdebugsource: + extended_data["files_info"][fpath]['debugsrc'] = pkgdebugsource[fpath] + del pkgdebugsource[fpath] + + d.setVar('FILES_INFO:' + pkg , json.dumps(files, sort_keys=True)) process_postinst_on_target(pkg, d.getVar("MLPREFIX")) add_set_e_to_scriptlets(pkg) @@ -1470,24 +1690,29 @@ fi val = write_if_exists(sf, pkg, var) write_if_exists(sf, pkg, 'FILERPROVIDESFLIST') - for dfile in (d.getVar('FILERPROVIDESFLIST_' + pkg) or "").split(): - write_if_exists(sf, pkg, 'FILERPROVIDES_' + dfile) + 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) or "").split(): - write_if_exists(sf, pkg, 'FILERDEPENDS_' + dfile) + 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)) - sf.write('%s_%s: %d\n' % ('PKGSIZE', pkg, total_size)) + subdata_extended_file = pkgdatadir + "/extended/%s.json.zstd" % pkg + num_threads = int(d.getVar("BB_NUMBER_THREADS")) + with bb.compress.zstd.open(subdata_extended_file, "wt", encoding="utf-8", num_threads=num_threads) as f: + json.dump(extended_data, f, sort_keys=True, separators=(",", ":")) # Symlinks needed for rprovides lookup - rprov = d.getVar('RPROVIDES_%s' % pkg) or d.getVar('RPROVIDES') + rprov = d.getVar('RPROVIDES:%s' % pkg) or d.getVar('RPROVIDES') if rprov: - for p in rprov.strip().split(): + for p in bb.utils.explode_deps(rprov): subdata_sym = pkgdatadir + "/runtime-rprovides/%s/%s" % (p, pkg) 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) + allow_empty = d.getVar('ALLOW_EMPTY:%s' % pkg) if not allow_empty: allow_empty = d.getVar('ALLOW_EMPTY') root = "%s/%s" % (pkgdest, pkg) @@ -1509,7 +1734,8 @@ fi write_extra_runtime_pkgs(global_variants, packages, pkgdatadir) } -emit_pkgdata[dirs] = "${PKGDESTWORK}/runtime ${PKGDESTWORK}/runtime-reverse ${PKGDESTWORK}/runtime-rprovides" +emit_pkgdata[dirs] = "${PKGDESTWORK}/runtime ${PKGDESTWORK}/runtime-reverse ${PKGDESTWORK}/runtime-rprovides ${PKGDESTWORK}/extended" +emit_pkgdata[vardepsexclude] = "BB_NUMBER_THREADS" ldconfig_postinst_fragment() { if [ x"$D" = "x" ]; then @@ -1517,15 +1743,15 @@ if [ x"$D" = "x" ]; then fi } -RPMDEPS = "${STAGING_LIBDIR_NATIVE}/rpm/rpmdeps --alldeps" +RPMDEPS = "${STAGING_LIBDIR_NATIVE}/rpm/rpmdeps --alldeps --define '__font_provides %{nil}'" # Collect perfile run-time dependency metadata # Output: -# FILERPROVIDESFLIST_pkg - list of all files w/ deps -# FILERPROVIDES_filepath_pkg - per file dep +# FILERPROVIDESFLIST:pkg - list of all files w/ deps +# FILERPROVIDES:filepath:pkg - per file dep # -# FILERDEPENDSFLIST_pkg - list of all files w/ deps -# FILERDEPENDS_filepath_pkg - per file dep +# FILERDEPENDSFLIST:pkg - list of all files w/ deps +# FILERDEPENDS:filepath:pkg - per file dep python package_do_filedeps() { if d.getVar('SKIP_FILEDEPS') == '1': @@ -1540,7 +1766,7 @@ python package_do_filedeps() { pkglist = [] for pkg in packages.split(): - if d.getVar('SKIP_FILEDEPS_' + pkg) == '1': + if d.getVar('SKIP_FILEDEPS:' + pkg) == '1': continue if pkg.endswith('-dbg') or pkg.endswith('-doc') or pkg.find('-locale-') != -1 or pkg.find('-localedata-') != -1 or pkg.find('-gconv-') != -1 or pkg.find('-charmap-') != -1 or pkg.startswith('kernel-module-') or pkg.endswith('-src'): continue @@ -1562,24 +1788,25 @@ python package_do_filedeps() { for file in sorted(provides): provides_files[pkg].append(file) - key = "FILERPROVIDES_" + file + "_" + pkg + key = "FILERPROVIDES:" + file + ":" + pkg d.appendVar(key, " " + " ".join(provides[file])) for file in sorted(requires): requires_files[pkg].append(file) - key = "FILERDEPENDS_" + file + "_" + pkg + key = "FILERDEPENDS:" + file + ":" + pkg d.appendVar(key, " " + " ".join(requires[file])) for pkg in requires_files: - d.setVar("FILERDEPENDSFLIST_" + pkg, " ".join(requires_files[pkg])) + d.setVar("FILERDEPENDSFLIST:" + pkg, " ".join(requires_files[pkg])) for pkg in provides_files: - d.setVar("FILERPROVIDESFLIST_" + pkg, " ".join(provides_files[pkg])) + d.setVar("FILERPROVIDESFLIST:" + pkg, " ".join(provides_files[pkg])) } SHLIBSDIRS = "${WORKDIR_PKGDATA}/${MLPREFIX}shlibs2" SHLIBSWORKDIR = "${PKGDESTWORK}/${MLPREFIX}shlibs2" python package_do_shlibs() { + import itertools import re, pipes import subprocess @@ -1604,7 +1831,7 @@ python package_do_shlibs() { else: shlib_pkgs = packages.split() - targetos = d.getVar('TARGET_OS') + hostos = d.getVar('HOST_OS') workdir = d.getVar('WORKDIR') @@ -1731,19 +1958,17 @@ python package_do_shlibs() { else: snap_symlinks = False - use_ldconfig = bb.utils.contains('DISTRO_FEATURES', 'ldconfig', True, False, d) - needed = {} shlib_provider = oe.package.read_shlib_providers(d) for pkg in shlib_pkgs: - private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or "" + private_libs = d.getVar('PRIVATE_LIBS:' + pkg) or d.getVar('PRIVATE_LIBS') or "" private_libs = private_libs.split() needs_ldconfig = False bb.debug(2, "calculating shlib provides for %s" % pkg) - pkgver = d.getVar('PKGV_' + pkg) + pkgver = d.getVar('PKGV:' + pkg) if not pkgver: pkgver = d.getVar('PV_' + pkg) if not pkgver: @@ -1757,9 +1982,9 @@ python package_do_shlibs() { soname = None if cpath.islink(file): continue - if targetos == "darwin" or targetos == "darwin8": + if hostos == "darwin" or hostos == "darwin8": darwin_so(file, needed, sonames, renames, pkgver) - elif targetos.startswith("mingw"): + elif hostos.startswith("mingw"): mingw_dll(file, needed, sonames, renames, pkgver) elif os.access(file, os.X_OK) or lib_re.match(file): linuxlist.append(file) @@ -1775,30 +2000,29 @@ python package_do_shlibs() { for (old, new) in renames: bb.note("Renaming %s to %s" % (old, new)) - os.rename(old, new) + bb.utils.rename(old, new) pkgfiles[pkg].remove(old) - + shlibs_file = os.path.join(shlibswork_dir, pkg + ".list") if len(sonames): - fd = open(shlibs_file, 'w') - for s in sonames: - if s[0] in shlib_provider and s[1] in shlib_provider[s[0]]: - (old_pkg, old_pkgver) = shlib_provider[s[0]][s[1]] - if old_pkg != pkg: - bb.warn('%s-%s was registered as shlib provider for %s, changing it to %s-%s because it was built later' % (old_pkg, old_pkgver, s[0], pkg, pkgver)) - bb.debug(1, 'registering %s-%s as shlib provider for %s' % (pkg, pkgver, s[0])) - fd.write(s[0] + ':' + s[1] + ':' + s[2] + '\n') - if s[0] not in shlib_provider: - shlib_provider[s[0]] = {} - shlib_provider[s[0]][s[1]] = (pkg, pkgver) - fd.close() - if needs_ldconfig and use_ldconfig: + with open(shlibs_file, 'w') as fd: + for s in sorted(sonames): + if s[0] in shlib_provider and s[1] in shlib_provider[s[0]]: + (old_pkg, old_pkgver) = shlib_provider[s[0]][s[1]] + if old_pkg != pkg: + bb.warn('%s-%s was registered as shlib provider for %s, changing it to %s-%s because it was built later' % (old_pkg, old_pkgver, s[0], pkg, pkgver)) + bb.debug(1, 'registering %s-%s as shlib provider for %s' % (pkg, pkgver, s[0])) + fd.write(s[0] + ':' + s[1] + ':' + s[2] + '\n') + if s[0] not in shlib_provider: + shlib_provider[s[0]] = {} + shlib_provider[s[0]][s[1]] = (pkg, pkgver) + if needs_ldconfig: bb.debug(1, 'adding ldconfig call to postinst for %s' % pkg) - postinst = d.getVar('pkg_postinst_%s' % pkg) + postinst = d.getVar('pkg_postinst:%s' % pkg) if not postinst: postinst = '#!/bin/sh\n' postinst += d.getVar('ldconfig_postinst_fragment') - d.setVar('pkg_postinst_%s' % pkg, postinst) + d.setVar('pkg_postinst:%s' % pkg, postinst) bb.debug(1, 'LIBNAMES: pkg %s sonames %s' % (pkg, sonames)) assumed_libs = d.getVar('ASSUME_SHLIBS') @@ -1820,7 +2044,7 @@ python package_do_shlibs() { for pkg in shlib_pkgs: bb.debug(2, "calculating shlib requirements for %s" % pkg) - private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or "" + private_libs = d.getVar('PRIVATE_LIBS:' + pkg) or d.getVar('PRIVATE_LIBS') or "" private_libs = private_libs.split() deps = list() @@ -1835,16 +2059,16 @@ python package_do_shlibs() { bb.debug(2, '%s: Dependency %s covered by PRIVATE_LIBS' % (pkg, n[0])) continue if n[0] in shlib_provider.keys(): - shlib_provider_path = [] - for k in shlib_provider[n[0]].keys(): - shlib_provider_path.append(k) - match = None - for p in list(n[2]) + shlib_provider_path + libsearchpath: - if p in shlib_provider[n[0]]: - match = p - break - if match: - (dep_pkg, ver_needed) = shlib_provider[n[0]][match] + shlib_provider_map = shlib_provider[n[0]] + matches = set() + for p in itertools.chain(list(n[2]), sorted(shlib_provider_map.keys()), libsearchpath): + if p in shlib_provider_map: + matches.add(p) + if len(matches) > 1: + matchpkgs = ', '.join([shlib_provider_map[match][0] for match in matches]) + bb.error("%s: Multiple shlib providers for %s: %s (used by files: %s)" % (pkg, n[0], matchpkgs, n[1])) + elif len(matches) == 1: + (dep_pkg, ver_needed) = shlib_provider_map[matches.pop()] bb.debug(2, '%s: Dependency %s requires package %s (used by files: %s)' % (pkg, n[0], dep_pkg, n[1])) @@ -1863,11 +2087,10 @@ python package_do_shlibs() { deps_file = os.path.join(pkgdest, pkg + ".shlibdeps") if os.path.exists(deps_file): os.remove(deps_file) - if len(deps): - fd = open(deps_file, 'w') - for dep in sorted(deps): - fd.write(dep + '\n') - fd.close() + if deps: + with open(deps_file, 'w') as fd: + for dep in sorted(deps): + fd.write(dep + '\n') } python package_do_pkgconfig () { @@ -1897,9 +2120,8 @@ python package_do_pkgconfig () { pkgconfig_provided[pkg].append(name) if not os.access(file, os.R_OK): continue - f = open(file, 'r') - lines = f.readlines() - f.close() + with open(file, 'r') as f: + lines = f.readlines() for l in lines: m = var_re.match(l) if m: @@ -1917,10 +2139,9 @@ python package_do_pkgconfig () { for pkg in packages.split(): pkgs_file = os.path.join(shlibswork_dir, pkg + ".pclist") if pkgconfig_provided[pkg] != []: - f = open(pkgs_file, 'w') - for p in pkgconfig_provided[pkg]: - f.write('%s\n' % p) - f.close() + with open(pkgs_file, 'w') as f: + for p in pkgconfig_provided[pkg]: + f.write('%s\n' % p) # Go from least to most specific since the last one found wins for dir in reversed(shlibs_dirs): @@ -1930,9 +2151,8 @@ python package_do_pkgconfig () { m = re.match(r'^(.*)\.pclist$', file) if m: pkg = m.group(1) - fd = open(os.path.join(dir, file)) - lines = fd.readlines() - fd.close() + with open(os.path.join(dir, file)) as fd: + lines = fd.readlines() pkgconfig_provided[pkg] = [] for l in lines: pkgconfig_provided[pkg].append(l.rstrip()) @@ -1950,10 +2170,9 @@ python package_do_pkgconfig () { bb.note("couldn't find pkgconfig module '%s' in any package" % n) deps_file = os.path.join(pkgdest, pkg + ".pcdeps") if len(deps): - fd = open(deps_file, 'w') - for dep in deps: - fd.write(dep + '\n') - fd.close() + with open(deps_file, 'w') as fd: + for dep in deps: + fd.write(dep + '\n') } def read_libdep_files(d): @@ -1964,9 +2183,8 @@ def read_libdep_files(d): for extension in ".shlibdeps", ".pcdeps", ".clilibdeps": depsfile = d.expand("${PKGDEST}/" + pkg + extension) if os.access(depsfile, os.R_OK): - fd = open(depsfile) - lines = fd.readlines() - fd.close() + with open(depsfile) as fd: + lines = fd.readlines() for l in lines: l.rstrip() deps = bb.utils.explode_dep_versions2(l) @@ -1980,7 +2198,7 @@ python read_shlibdeps () { packages = d.getVar('PACKAGES').split() for pkg in packages: - rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg) or "") + rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS:' + pkg) or "") for dep in sorted(pkglibdeps[pkg]): # Add the dep if it's not already there, or if no comparison is set if dep not in rdepends: @@ -1988,7 +2206,7 @@ python read_shlibdeps () { for v in pkglibdeps[pkg][dep]: if v not in rdepends[dep]: rdepends[dep].append(v) - d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False)) + d.setVar('RDEPENDS:' + pkg, bb.utils.join_deps(rdepends, commasep=False)) } python package_depchains() { @@ -2012,7 +2230,7 @@ python package_depchains() { def pkg_adddeprrecs(pkg, base, suffix, getname, depends, d): #bb.note('depends for %s is %s' % (base, depends)) - rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "") + rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS:' + pkg) or "") for depend in sorted(depends): if depend.find('-native') != -1 or depend.find('-cross') != -1 or depend.startswith('virtual/'): @@ -2027,13 +2245,13 @@ python package_depchains() { if pkgname not in rreclist and pkgname != pkg: rreclist[pkgname] = [] - #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist))) - d.setVar('RRECOMMENDS_%s' % pkg, bb.utils.join_deps(rreclist, commasep=False)) + #bb.note('setting: RRECOMMENDS:%s=%s' % (pkg, ' '.join(rreclist))) + d.setVar('RRECOMMENDS:%s' % pkg, bb.utils.join_deps(rreclist, commasep=False)) def pkg_addrrecs(pkg, base, suffix, getname, rdepends, d): #bb.note('rdepends for %s is %s' % (base, rdepends)) - rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "") + rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS:' + pkg) or "") for depend in sorted(rdepends): if depend.find('virtual-locale-') != -1: @@ -2048,8 +2266,8 @@ python package_depchains() { if pkgname not in rreclist and pkgname != pkg: rreclist[pkgname] = [] - #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist))) - d.setVar('RRECOMMENDS_%s' % pkg, bb.utils.join_deps(rreclist, commasep=False)) + #bb.note('setting: RRECOMMENDS:%s=%s' % (pkg, ' '.join(rreclist))) + d.setVar('RRECOMMENDS:%s' % pkg, bb.utils.join_deps(rreclist, commasep=False)) def add_dep(list, dep): if dep not in list: @@ -2061,7 +2279,7 @@ python package_depchains() { rdepends = [] for pkg in packages.split(): - for dep in bb.utils.explode_deps(d.getVar('RDEPENDS_' + pkg) or ""): + for dep in bb.utils.explode_deps(d.getVar('RDEPENDS:' + pkg) or ""): add_dep(rdepends, dep) #bb.note('rdepends is %s' % rdepends) @@ -2095,7 +2313,7 @@ python package_depchains() { for suffix in pkgs: for pkg in pkgs[suffix]: - if d.getVarFlag('RRECOMMENDS_' + pkg, 'nodeprrecs'): + if d.getVarFlag('RRECOMMENDS:' + pkg, 'nodeprrecs'): continue (base, func) = pkgs[suffix][pkg] if suffix == "-dev": @@ -2108,22 +2326,24 @@ python package_depchains() { pkg_addrrecs(pkg, base, suffix, func, rdepends, d) else: rdeps = [] - for dep in bb.utils.explode_deps(d.getVar('RDEPENDS_' + base) or ""): + for dep in bb.utils.explode_deps(d.getVar('RDEPENDS:' + base) or ""): add_dep(rdeps, dep) pkg_addrrecs(pkg, base, suffix, func, rdeps, d) } # Since bitbake can't determine which variables are accessed during package # iteration, we need to list them here: -PACKAGEVARS = "FILES RDEPENDS RRECOMMENDS SUMMARY DESCRIPTION RSUGGESTS RPROVIDES RCONFLICTS PKG ALLOW_EMPTY pkg_postinst pkg_postrm pkg_postinst_ontarget INITSCRIPT_NAME INITSCRIPT_PARAMS DEBIAN_NOAUTONAME ALTERNATIVE PKGE PKGV PKGR USERADD_PARAM GROUPADD_PARAM CONFFILES SYSTEMD_SERVICE LICENSE SECTION pkg_preinst pkg_prerm RREPLACES GROUPMEMS_PARAM SYSTEMD_AUTO_ENABLE SKIP_FILEDEPS PRIVATE_LIBS" +PACKAGEVARS = "FILES RDEPENDS RRECOMMENDS SUMMARY DESCRIPTION RSUGGESTS RPROVIDES RCONFLICTS PKG ALLOW_EMPTY pkg_postinst pkg_postrm pkg_postinst_ontarget INITSCRIPT_NAME INITSCRIPT_PARAMS DEBIAN_NOAUTONAME ALTERNATIVE PKGE PKGV PKGR USERADD_PARAM GROUPADD_PARAM CONFFILES SYSTEMD_SERVICE LICENSE SECTION pkg_preinst pkg_prerm RREPLACES GROUPMEMS_PARAM SYSTEMD_AUTO_ENABLE SKIP_FILEDEPS PRIVATE_LIBS PACKAGE_ADD_METADATA" -def gen_packagevar(d): +def gen_packagevar(d, pkgvars="PACKAGEVARS"): ret = [] pkgs = (d.getVar("PACKAGES") or "").split() - vars = (d.getVar("PACKAGEVARS") or "").split() + vars = (d.getVar(pkgvars) or "").split() + for v in vars: + ret.append(v) for p in pkgs: for v in vars: - ret.append(v + "_" + p) + ret.append(v + ":" + p) # Ensure that changes to INCOMPATIBLE_LICENSE re-run do_package for # affected recipes. @@ -2159,7 +2379,7 @@ python do_package () { # cache. This is useful if an item this class depends on changes in a # way that the output of this class changes. rpmdeps is a good example # as any change to rpmdeps requires this to be rerun. - # PACKAGE_BBCLASS_VERSION = "2" + # PACKAGE_BBCLASS_VERSION = "4" # Init cachedpath global cpath @@ -2185,7 +2405,7 @@ python do_package () { package_qa_handle_error("var-undefined", msg, d) return - bb.build.exec_func("package_get_auto_pr", d) + bb.build.exec_func("package_convert_pr_autoinc", d) ########################################################################### # Optimisations @@ -2257,9 +2477,21 @@ addtask do_package_setscene # Copy from PKGDESTWORK to tempdirectory as tempdirectory can be cleaned at both # do_package_setscene and do_packagedata_setscene leading to races python do_packagedata () { + bb.build.exec_func("package_get_auto_pr", d) + src = d.expand("${PKGDESTWORK}") dest = d.expand("${WORKDIR}/pkgdata-pdata-input") oe.path.copyhardlinktree(src, dest) + + bb.build.exec_func("packagedata_translate_pr_autoinc", d) +} +do_packagedata[cleandirs] += "${WORKDIR}/pkgdata-pdata-input" + +# Translate the EXTENDPRAUTO and AUTOINC to the final values +packagedata_translate_pr_autoinc() { + find ${WORKDIR}/pkgdata-pdata-input -type f | xargs --no-run-if-empty \ + sed -e 's,@PRSERV_PV_AUTOINC@,${PRSERV_PV_AUTOINC},g' \ + -e 's,@EXTENDPRAUTO@,${EXTENDPRAUTO},g' -i } addtask packagedata before do_build after do_package |