1# Debian package renaming only occurs when a package is built 2# We therefore have to make sure we build all runtime packages 3# before building the current package to make the packages runtime 4# depends are correct 5# 6# Custom library package names can be defined setting 7# DEBIANNAME: + pkgname to the desired name. 8# 9# Better expressed as ensure all RDEPENDS package before we package 10# This means we can't have circular RDEPENDS/RRECOMMENDS 11 12AUTO_LIBNAME_PKGS = "${PACKAGES}" 13 14inherit package 15 16DEBIANRDEP = "do_packagedata" 17do_package_write_ipk[deptask] = "${DEBIANRDEP}" 18do_package_write_deb[deptask] = "${DEBIANRDEP}" 19do_package_write_tar[deptask] = "${DEBIANRDEP}" 20do_package_write_rpm[deptask] = "${DEBIANRDEP}" 21do_package_write_ipk[rdeptask] = "${DEBIANRDEP}" 22do_package_write_deb[rdeptask] = "${DEBIANRDEP}" 23do_package_write_tar[rdeptask] = "${DEBIANRDEP}" 24do_package_write_rpm[rdeptask] = "${DEBIANRDEP}" 25 26python () { 27 if not d.getVar("PACKAGES"): 28 d.setVar("DEBIANRDEP", "") 29} 30 31python debian_package_name_hook () { 32 import glob, copy, stat, errno, re, pathlib, subprocess 33 34 pkgdest = d.getVar("PKGDEST") 35 packages = d.getVar('PACKAGES') 36 so_re = re.compile(r"lib.*\.so") 37 38 def socrunch(s): 39 s = s.lower().replace('_', '-') 40 m = re.match(r"^(.*)(.)\.so\.(.*)$", s) 41 if m is None: 42 return None 43 if m.group(2) in '0123456789': 44 bin = '%s%s-%s' % (m.group(1), m.group(2), m.group(3)) 45 else: 46 bin = m.group(1) + m.group(2) + m.group(3) 47 dev = m.group(1) + m.group(2) 48 return (bin, dev) 49 50 def isexec(path): 51 try: 52 s = os.stat(path) 53 except (os.error, AttributeError): 54 return 0 55 return (s[stat.ST_MODE] & stat.S_IEXEC) 56 57 def add_rprovides(pkg, d): 58 newpkg = d.getVar('PKG:' + pkg) 59 if newpkg and newpkg != pkg: 60 provs = (d.getVar('RPROVIDES:' + pkg) or "").split() 61 if pkg not in provs: 62 d.appendVar('RPROVIDES:' + pkg, " " + pkg + " (=" + d.getVar("PKGV") + ")") 63 64 def auto_libname(packages, orig_pkg): 65 p = lambda var: pathlib.PurePath(d.getVar(var)) 66 libdirs = (p("base_libdir"), p("libdir")) 67 bindirs = (p("base_bindir"), p("base_sbindir"), p("bindir"), p("sbindir")) 68 69 sonames = [] 70 has_bins = 0 71 has_libs = 0 72 for f in pkgfiles[orig_pkg]: 73 # This is .../packages-split/orig_pkg/ 74 pkgpath = pathlib.PurePath(pkgdest, orig_pkg) 75 # Strip pkgpath off the full path to a file in the package, re-root 76 # so it is absolute, and then get the parent directory of the file. 77 path = pathlib.PurePath("/") / (pathlib.PurePath(f).relative_to(pkgpath).parent) 78 if path in bindirs: 79 has_bins = 1 80 if path in libdirs: 81 has_libs = 1 82 if so_re.match(os.path.basename(f)): 83 try: 84 cmd = [d.expand("${TARGET_PREFIX}objdump"), "-p", f] 85 output = subprocess.check_output(cmd).decode("utf-8") 86 for m in re.finditer(r"\s+SONAME\s+([^\s]+)", output): 87 if m.group(1) not in sonames: 88 sonames.append(m.group(1)) 89 except subprocess.CalledProcessError: 90 pass 91 bb.debug(1, 'LIBNAMES: pkg %s libs %d bins %d sonames %s' % (orig_pkg, has_libs, has_bins, sonames)) 92 soname = None 93 if len(sonames) == 1: 94 soname = sonames[0] 95 elif len(sonames) > 1: 96 lead = d.getVar('LEAD_SONAME') 97 if lead: 98 r = re.compile(lead) 99 filtered = [] 100 for s in sonames: 101 if r.match(s): 102 filtered.append(s) 103 if len(filtered) == 1: 104 soname = filtered[0] 105 elif len(filtered) > 1: 106 bb.note("Multiple matches (%s) for LEAD_SONAME '%s'" % (", ".join(filtered), lead)) 107 else: 108 bb.note("Multiple libraries (%s) found, but LEAD_SONAME '%s' doesn't match any of them" % (", ".join(sonames), lead)) 109 else: 110 bb.note("Multiple libraries (%s) found and LEAD_SONAME not defined" % ", ".join(sonames)) 111 112 if has_libs and not has_bins and soname: 113 soname_result = socrunch(soname) 114 if soname_result: 115 (pkgname, devname) = soname_result 116 for pkg in packages.split(): 117 if (d.getVar('PKG:' + pkg, False) or d.getVar('DEBIAN_NOAUTONAME:' + pkg, False)): 118 add_rprovides(pkg, d) 119 continue 120 debian_pn = d.getVar('DEBIANNAME:' + pkg, False) 121 if debian_pn: 122 newpkg = debian_pn 123 elif pkg == orig_pkg: 124 newpkg = pkgname 125 else: 126 newpkg = pkg.replace(orig_pkg, devname, 1) 127 mlpre=d.getVar('MLPREFIX') 128 if mlpre: 129 if not newpkg.find(mlpre) == 0: 130 newpkg = mlpre + newpkg 131 if newpkg != pkg: 132 bb.note("debian: renaming %s to %s" % (pkg, newpkg)) 133 d.setVar('PKG:' + pkg, newpkg) 134 add_rprovides(pkg, d) 135 else: 136 add_rprovides(orig_pkg, d) 137 138 # reversed sort is needed when some package is substring of another 139 # ie in ncurses we get without reverse sort: 140 # DEBUG: LIBNAMES: pkgname libtic5 devname libtic pkg ncurses-libtic orig_pkg ncurses-libtic debian_pn None newpkg libtic5 141 # and later 142 # DEBUG: LIBNAMES: pkgname libtic5 devname libtic pkg ncurses-libticw orig_pkg ncurses-libtic debian_pn None newpkg libticw 143 # so we need to handle ncurses-libticw->libticw5 before ncurses-libtic->libtic5 144 for pkg in sorted((d.getVar('AUTO_LIBNAME_PKGS') or "").split(), reverse=True): 145 auto_libname(packages, pkg) 146} 147 148EXPORT_FUNCTIONS package_name_hook 149 150DEBIAN_NAMES = "1" 151