From 1c7d6584a7811b7785ae5c1e378f14b5ba0971cf Mon Sep 17 00:00:00 2001 From: takeshi_hoshina Date: Mon, 2 Nov 2020 11:07:33 +0900 Subject: basesystem-jj recipes --- external/poky/meta/classes/package.bbclass | 420 ++++++++++++++++------------- 1 file changed, 235 insertions(+), 185 deletions(-) (limited to 'external/poky/meta/classes/package.bbclass') diff --git a/external/poky/meta/classes/package.bbclass b/external/poky/meta/classes/package.bbclass index 66e423e9..099d0459 100644 --- a/external/poky/meta/classes/package.bbclass +++ b/external/poky/meta/classes/package.bbclass @@ -40,6 +40,7 @@ inherit packagedata inherit chrpath +inherit package_pkgdata # Need the package_qa_handle_error() in insane.bbclass inherit insane @@ -75,7 +76,7 @@ def legitimize_package_name(s): return ('\\u%s' % cp).encode('latin-1').decode('unicode_escape') # Handle unicode codepoints encoded as , as in glibc locale files. - s = re.sub('', fixutf, s) + s = re.sub(r'', fixutf, s) # Remaining package name validity fixes return s.lower().replace('_', '-').replace('@', '+').replace(',', '+').replace('/', '-') @@ -344,7 +345,7 @@ def parse_debugsources_from_dwarfsrcfiles_output(dwarfsrcfiles_output): return debugfiles.keys() -def append_source_info(file, sourcefile, d, fatal=True): +def source_info(file, d, fatal=True): import subprocess cmd = ["dwarfsrcfiles", file] @@ -363,22 +364,15 @@ def append_source_info(file, sourcefile, d, fatal=True): bb.note(msg) debugsources = parse_debugsources_from_dwarfsrcfiles_output(output) - # filenames are null-separated - this is an artefact of the previous use - # of rpm's debugedit, which was writing them out that way, and the code elsewhere - # is still assuming that. - debuglistoutput = '\0'.join(debugsources) + '\0' - lf = bb.utils.lockfile(sourcefile + ".lock") - with open(sourcefile, 'a') as sf: - sf.write(debuglistoutput) - bb.utils.unlockfile(lf) + return list(debugsources) -def splitdebuginfo(file, dvar, debugdir, debuglibdir, debugappend, debugsrcdir, sourcefile, d): +def splitdebuginfo(file, dvar, debugdir, debuglibdir, debugappend, debugsrcdir, 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. # - # sourcefile is also generated containing a list of debugsources + # return a mapping of files:debugsources import stat import subprocess @@ -386,6 +380,7 @@ def splitdebuginfo(file, dvar, debugdir, debuglibdir, debugappend, debugsrcdir, src = file[len(dvar):] dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend debugfile = dvar + dest + sources = [] # Split the file... bb.utils.mkdirhier(os.path.dirname(debugfile)) @@ -397,7 +392,7 @@ def splitdebuginfo(file, dvar, debugdir, debuglibdir, debugappend, debugsrcdir, # We ignore kernel modules, we don't generate debug info files. if file.find("/lib/modules/") != -1 and file.endswith(".ko"): - return 1 + return (file, sources) newmode = None if not os.access(file, os.W_OK) or os.access(file, os.R_OK): @@ -407,7 +402,7 @@ def splitdebuginfo(file, dvar, debugdir, debuglibdir, debugappend, debugsrcdir, # We need to extract the debug src information here... if debugsrcdir: - append_source_info(file, sourcefile, d) + sources = source_info(file, d) bb.utils.mkdirhier(os.path.dirname(debugfile)) @@ -419,17 +414,69 @@ def splitdebuginfo(file, dvar, debugdir, debuglibdir, debugappend, debugsrcdir, if newmode: os.chmod(file, origmode) - return 0 + return (file, sources) -def copydebugsources(debugsrcdir, d): +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 copydebugsources(debugsrcdir, sources, d): # The debug src information written out to sourcefile is further processed # and copied to the destination here. import stat import subprocess - sourcefile = d.expand("${WORKDIR}/debugsources.list") - if debugsrcdir and os.path.isfile(sourcefile): + if debugsrcdir and sources: + sourcefile = d.expand("${WORKDIR}/debugsources.list") + bb.utils.remove(sourcefile) + + # filenames are null-separated - this is an artefact of the previous use + # of rpm's debugedit, which was writing them out that way, and the code elsewhere + # is still assuming that. + debuglistoutput = '\0'.join(sources) + '\0' + with open(sourcefile, 'a') as sf: + sf.write(debuglistoutput) + dvar = d.getVar('PKGD') strip = d.getVar("STRIP") objcopy = d.getVar("OBJCOPY") @@ -471,7 +518,8 @@ def copydebugsources(debugsrcdir, d): # 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) + cmd = "find %s%s -type l -print0 -delete | sed s#%s%s/##g | (cd '%s' ; cpio -pd0mL --no-preserve-owner '%s%s')" % \ + (dvar, debugsrcdir, dvar, debugsrcdir, workparentdir, dvar, debugsrcdir) subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT) # The copy by cpio may have resulted in some empty directories! Remove these @@ -821,8 +869,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 @@ -843,7 +892,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: @@ -902,7 +950,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) @@ -911,30 +959,39 @@ 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" - sourcefile = d.expand("${WORKDIR}/debugsources.list") - bb.utils.remove(sourcefile) - # # First lets figure out all of the files we may have to process ... do this only once! # @@ -953,12 +1010,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): @@ -969,6 +1020,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) @@ -1004,6 +1062,12 @@ python split_and_strip_files () { symlinks[file] = target results = oe.utils.multiprocess_launch(oe.package.is_elf, checkelf.keys(), d) + + # Sort results by file path. This ensures that the files are always + # processed in the same order, which is important to make sure builds + # are reproducible when dealing with hardlinks + results.sort(key=lambda x: x[0]) + for (file, elf_file) in results: # It's a file (or hardlink), not a link # ...but is it ELF, and is it already stripped? @@ -1039,11 +1103,18 @@ python split_and_strip_files () { # First lets process debug splitting # if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'): - oe.utils.multiprocess_launch(splitdebuginfo, list(elffiles), d, extraargs=(dvar, debugdir, debuglibdir, debugappend, debugsrcdir, sourcefile, d)) + results = oe.utils.multiprocess_launch(splitdebuginfo, list(elffiles), d, extraargs=(dvar, debugdir, debuglibdir, debugappend, debugsrcdir, d)) + + 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)) ) - if debugsrcdir and not targetos.startswith("mingw"): - for file in staticlibs: - append_source_info(file, sourcefile, d, fatal=False) + sources = set() + for r in results: + sources.update(r[1]) # Hardlink our debug symbols to the other hardlink copies for ref in inodes: @@ -1091,7 +1162,7 @@ python split_and_strip_files () { # Process the debugsrcdir if requested... # This copies and places the referenced sources for later debugging... - copydebugsources(debugsrcdir, d) + copydebugsources(debugsrcdir, sources, d) # # End of debug splitting # @@ -1108,6 +1179,9 @@ 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) @@ -1123,7 +1197,7 @@ python populate_packages () { workdir = d.getVar('WORKDIR') outdir = d.getVar('DEPLOY_DIR') dvar = d.getVar('PKGD') - packages = d.getVar('PACKAGES') + packages = d.getVar('PACKAGES').split() pn = d.getVar('PN') bb.utils.mkdirhier(outdir) @@ -1133,32 +1207,34 @@ python populate_packages () { split_source_package = (d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg') - # If debug-with-srcpkg mode is enabled then the src package is added - # into the package list and the source directory as its main content + # If debug-with-srcpkg mode is enabled then add the source package if it + # doesn't exist and add the source file contents to the source package. if split_source_package: src_package_name = ('%s-src' % d.getVar('PN')) - packages += (' ' + src_package_name) + if not src_package_name in packages: + packages.append(src_package_name) 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 package_dict = {} - for i, pkg in enumerate(packages.split()): + for i, pkg in enumerate(packages): if pkg in package_dict: msg = "%s is listed in PACKAGES multiple times, this leads to packaging errors." % pkg package_qa_handle_error("packages-list", msg, d) - # If debug-with-srcpkg mode is enabled then the src package will have - # priority over dbg package when assigning the files. - # This allows src package to include source files and remove them from dbg. - elif split_source_package and pkg.endswith("-src"): + # Ensure the source package gets the chance to pick up the source files + # before the debug package by ordering it first in PACKAGES. Whether it + # actually picks up any source files is controlled by + # PACKAGE_DEBUG_SPLIT_STYLE. + elif pkg.endswith("-src"): package_dict[pkg] = (10, i) elif autodebug and pkg.endswith("-dbg"): package_dict[pkg] = (30, i) else: package_dict[pkg] = (50, i) - package_list = sorted(package_dict.keys(), key=package_dict.get) - d.setVar('PACKAGES', ' '.join(package_list)) + packages = sorted(package_dict.keys(), key=package_dict.get) + d.setVar('PACKAGES', ' '.join(packages)) pkgdest = d.getVar('PKGDEST') seen = [] @@ -1173,10 +1249,10 @@ 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 package_list: + for pkg in packages: root = os.path.join(pkgdest, pkg) bb.utils.mkdirhier(root) @@ -1203,7 +1279,8 @@ python populate_packages () { src = os.path.join(src, p) dest = os.path.join(dest, p) fstat = cpath.stat(src) - os.mkdir(dest, fstat.st_mode) + os.mkdir(dest) + os.chmod(dest, fstat.st_mode) os.chown(dest, fstat.st_uid, fstat.st_gid) if p not in seen: seen.append(p) @@ -1247,9 +1324,10 @@ python populate_packages () { # 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 + for pkg in packages: + 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) @@ -1336,17 +1414,23 @@ 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" + python emit_pkgdata() { from glob import glob import json def process_postinst_on_target(pkg, mlprefix): + pkgval = d.getVar('PKG_%s' % pkg) + if pkgval is None: + pkgval = pkg + defer_fragment = """ if [ -n "$D" ]; then $INTERCEPT_DIR/postinst_intercept delay_to_first_boot %s mlprefix=%s exit 0 fi -""" % (pkg, mlprefix) +""" % (pkgval, mlprefix) postinst = d.getVar('pkg_postinst_%s' % pkg) postinst_ontarget = d.getVar('pkg_postinst_ontarget_%s' % pkg) @@ -1403,10 +1487,9 @@ fi 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) pn = d.getVar('PN') global_variants = (d.getVar('MULTILIB_GLOBAL_VARIANTS') or "").split() @@ -1438,50 +1521,28 @@ fi if fstat.st_ino not in seen: seen.add(fstat.st_ino) total_size += fstat.st_size - d.setVar('FILES_INFO', json.dumps(files)) + d.setVar('FILES_INFO', json.dumps(files, sort_keys=True)) - subdata_file = pkgdatadir + "/runtime/%s" % pkg - sf = open(subdata_file, 'w') - write_if_exists(sf, pkg, 'PN') - write_if_exists(sf, pkg, 'PE') - write_if_exists(sf, pkg, 'PV') - write_if_exists(sf, pkg, 'PR') - write_if_exists(sf, pkg, 'PKGE') - write_if_exists(sf, pkg, 'PKGV') - write_if_exists(sf, pkg, 'PKGR') - write_if_exists(sf, pkg, 'LICENSE') - write_if_exists(sf, pkg, 'DESCRIPTION') - write_if_exists(sf, pkg, 'SUMMARY') - write_if_exists(sf, pkg, 'RDEPENDS') - rprov = write_if_exists(sf, pkg, 'RPROVIDES') - write_if_exists(sf, pkg, 'RRECOMMENDS') - write_if_exists(sf, pkg, 'RSUGGESTS') - write_if_exists(sf, pkg, 'RREPLACES') - write_if_exists(sf, pkg, 'RCONFLICTS') - write_if_exists(sf, pkg, 'SECTION') - 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') process_postinst_on_target(pkg, d.getVar("MLPREFIX")) add_set_e_to_scriptlets(pkg) - 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) 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) - - sf.write('%s_%s: %d\n' % ('PKGSIZE', pkg, total_size)) - sf.close() + + subdata_file = pkgdatadir + "/runtime/%s" % pkg + with open(subdata_file, 'w') as sf: + for var in (d.getVar('PKGDATA_VARS') or "").split(): + 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) + + write_if_exists(sf, pkg, 'FILERDEPENDSFLIST') + 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)) # Symlinks needed for rprovides lookup + rprov = d.getVar('RPROVIDES_%s' % pkg) or d.getVar('RPROVIDES') if rprov: for p in rprov.strip().split(): subdata_sym = pkgdatadir + "/runtime-rprovides/%s/%s" % (p, pkg) @@ -1561,12 +1622,12 @@ python package_do_filedeps() { if pkg not in requires_files: requires_files[pkg] = [] - for file in provides: + for file in sorted(provides): provides_files[pkg].append(file) key = "FILERPROVIDES_" + file + "_" + pkg d.appendVar(key, " " + " ".join(provides[file])) - for file in requires: + for file in sorted(requires): requires_files[pkg].append(file) key = "FILERDEPENDS_" + file + "_" + pkg d.appendVar(key, " " + " ".join(requires[file])) @@ -1577,10 +1638,11 @@ python package_do_filedeps() { d.setVar("FILERPROVIDESFLIST_" + pkg, " ".join(provides_files[pkg])) } -SHLIBSDIRS = "${PKGDATA_DIR}/${MLPREFIX}shlibs2" +SHLIBSDIRS = "${WORKDIR_PKGDATA}/${MLPREFIX}shlibs2" SHLIBSWORKDIR = "${PKGDESTWORK}/${MLPREFIX}shlibs2" python package_do_shlibs() { + import itertools import re, pipes import subprocess @@ -1589,8 +1651,8 @@ python package_do_shlibs() { bb.note("not generating shlibs") return - lib_re = re.compile("^.*\.so") - libdir_re = re.compile(".*/%s$" % d.getVar('baselib')) + lib_re = re.compile(r"^.*\.so") + libdir_re = re.compile(r".*/%s$" % d.getVar('baselib')) packages = d.getVar('PACKAGES') @@ -1605,7 +1667,7 @@ python package_do_shlibs() { else: shlib_pkgs = packages.split() - targetos = d.getVar('TARGET_OS') + hostos = d.getVar('HOST_OS') workdir = d.getVar('WORKDIR') @@ -1631,23 +1693,24 @@ python package_do_shlibs() { fd.close() rpath = tuple() for l in lines: - m = re.match("\s+RPATH\s+([^\s]*)", l) + m = re.match(r"\s+RPATH\s+([^\s]*)", l) if m: rpaths = m.group(1).replace("$ORIGIN", ldir).split(":") rpath = tuple(map(os.path.normpath, rpaths)) for l in lines: - m = re.match("\s+NEEDED\s+([^\s]*)", l) + m = re.match(r"\s+NEEDED\s+([^\s]*)", l) if m: dep = m.group(1) if dep not in needed: needed.add((dep, file, rpath)) - m = re.match("\s+SONAME\s+([^\s]*)", l) + m = re.match(r"\s+SONAME\s+([^\s]*)", l) if m: this_soname = m.group(1) prov = (this_soname, ldir, pkgver) if not prov in sonames: # if library is private (only used by package) then do not build shlib for it - if not private_libs or this_soname not in private_libs: + import fnmatch + if not private_libs or len([i for i in private_libs if fnmatch.fnmatch(this_soname, i)]) == 0: sonames.add(prov) if libdir_re.match(os.path.dirname(file)): needs_ldconfig = True @@ -1721,7 +1784,7 @@ python package_do_shlibs() { out, err = p.communicate() # process the output, grabbing all .dll names if p.returncode == 0: - for m in re.finditer("DLL Name: (.*?\.dll)$", out.decode(), re.MULTILINE | re.IGNORECASE): + for m in re.finditer(r"DLL Name: (.*?\.dll)$", out.decode(), re.MULTILINE | re.IGNORECASE): dllname = m.group(1) if dllname: needed[pkg].add((dllname, file, tuple())) @@ -1731,14 +1794,9 @@ python package_do_shlibs() { else: snap_symlinks = False - use_ldconfig = bb.utils.contains('DISTRO_FEATURES', 'ldconfig', True, False, d) - needed = {} - # Take shared lock since we're only reading, not writing - lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"), True) shlib_provider = oe.package.read_shlib_providers(d) - bb.utils.unlockfile(lf) for pkg in shlib_pkgs: private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or "" @@ -1760,9 +1818,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) @@ -1780,22 +1838,21 @@ python package_do_shlibs() { bb.note("Renaming %s to %s" % (old, new)) os.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 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) if not postinst: @@ -1833,20 +1890,21 @@ python package_do_shlibs() { # /opt/abc/lib/libfoo.so.1 and contains /usr/bin/abc depending on system library libfoo.so.1 # but skipping it is still better alternative than providing own # version and then adding runtime dependency for the same system library - if private_libs and n[0] in private_libs: + import fnmatch + if private_libs and len([i for i in private_libs if fnmatch.fnmatch(n[0], i)]) > 0: 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])) @@ -1865,11 +1923,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 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 () { @@ -1882,9 +1939,9 @@ python package_do_pkgconfig () { shlibs_dirs = d.getVar('SHLIBSDIRS').split() shlibswork_dir = d.getVar('SHLIBSWORKDIR') - pc_re = re.compile('(.*)\.pc$') - var_re = re.compile('(.*)=(.*)') - field_re = re.compile('(.*): (.*)') + pc_re = re.compile(r'(.*)\.pc$') + var_re = re.compile(r'(.*)=(.*)') + field_re = re.compile(r'(.*): (.*)') pkgconfig_provided = {} pkgconfig_needed = {} @@ -1899,9 +1956,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: @@ -1919,31 +1975,24 @@ 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() - - # Take shared lock since we're only reading, not writing - lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"), True) + 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): if not os.path.exists(dir): continue - for file in os.listdir(dir): - m = re.match('^(.*)\.pclist$', file) + for file in sorted(os.listdir(dir)): + 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()) - bb.utils.unlockfile(lf) - for pkg in packages.split(): deps = [] for n in pkgconfig_needed[pkg]: @@ -1957,10 +2006,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): @@ -1971,9 +2019,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) @@ -1988,7 +2035,7 @@ python read_shlibdeps () { packages = d.getVar('PACKAGES').split() for pkg in packages: rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg) or "") - for dep in pkglibdeps[pkg]: + 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: rdepends[dep] = [] @@ -2021,7 +2068,7 @@ python package_depchains() { #bb.note('depends for %s is %s' % (base, depends)) rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "") - for depend in depends: + for depend in sorted(depends): if depend.find('-native') != -1 or depend.find('-cross') != -1 or depend.startswith('virtual/'): #bb.note("Skipping %s" % depend) continue @@ -2042,7 +2089,7 @@ python package_depchains() { #bb.note('rdepends for %s is %s' % (base, rdepends)) rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "") - for depend in rdepends: + for depend in sorted(rdepends): if depend.find('virtual-locale-') != -1: #bb.note("Skipping %s" % depend) continue @@ -2124,10 +2171,12 @@ python package_depchains() { # 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" -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) @@ -2140,6 +2189,7 @@ def gen_packagevar(d): PACKAGE_PREPROCESS_FUNCS ?= "" # Functions for setting up PKGD PACKAGEBUILDPKGD ?= " \ + package_prepare_pkgdata \ perform_packagecopy \ ${PACKAGE_PREPROCESS_FUNCS} \ split_and_strip_files \ @@ -2260,19 +2310,19 @@ python do_package_setscene () { } addtask do_package_setscene -do_packagedata () { - : +# 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 () { + src = d.expand("${PKGDESTWORK}") + dest = d.expand("${WORKDIR}/pkgdata-pdata-input") + oe.path.copyhardlinktree(src, dest) } addtask packagedata before do_build after do_package SSTATETASKS += "do_packagedata" -# PACKAGELOCK protects readers of PKGDATA_DIR against writes -# whilst code is reading in do_package -PACKAGELOCK = "${STAGING_DIR}/package-output.lock" -do_packagedata[sstate-inputdirs] = "${PKGDESTWORK}" +do_packagedata[sstate-inputdirs] = "${WORKDIR}/pkgdata-pdata-input" do_packagedata[sstate-outputdirs] = "${PKGDATA_DIR}" -do_packagedata[sstate-lockfile] = "${PACKAGELOCK}" do_packagedata[stamp-extra-info] = "${MACHINE_ARCH}" python do_packagedata_setscene () { -- cgit 1.2.3-korg