blob: 6f8a599ccb6b4bc8ded7670e84f4725520fe7990 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001# 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[rdeptask] = "${DEBIANRDEP}"
18do_package_write_deb[rdeptask] = "${DEBIANRDEP}"
19do_package_write_tar[rdeptask] = "${DEBIANRDEP}"
20do_package_write_rpm[rdeptask] = "${DEBIANRDEP}"
21
22python () {
Brad Bishop6e60e8b2018-02-01 10:27:11 -050023 if not d.getVar("PACKAGES"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050024 d.setVar("DEBIANRDEP", "")
25}
26
27python debian_package_name_hook () {
Brad Bishop316dfdd2018-06-25 12:45:53 -040028 import glob, copy, stat, errno, re, pathlib, subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -050029
Brad Bishop316dfdd2018-06-25 12:45:53 -040030 pkgdest = d.getVar("PKGDEST")
Brad Bishop6e60e8b2018-02-01 10:27:11 -050031 packages = d.getVar('PACKAGES')
Brad Bishop19323692019-04-05 15:28:33 -040032 so_re = re.compile(r"lib.*\.so")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050033
34 def socrunch(s):
35 s = s.lower().replace('_', '-')
Brad Bishop19323692019-04-05 15:28:33 -040036 m = re.match(r"^(.*)(.)\.so\.(.*)$", s)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050037 if m is None:
38 return None
39 if m.group(2) in '0123456789':
40 bin = '%s%s-%s' % (m.group(1), m.group(2), m.group(3))
41 else:
42 bin = m.group(1) + m.group(2) + m.group(3)
43 dev = m.group(1) + m.group(2)
44 return (bin, dev)
45
46 def isexec(path):
47 try:
48 s = os.stat(path)
49 except (os.error, AttributeError):
50 return 0
51 return (s[stat.ST_MODE] & stat.S_IEXEC)
52
53 def add_rprovides(pkg, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050054 newpkg = d.getVar('PKG_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050055 if newpkg and newpkg != pkg:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050056 provs = (d.getVar('RPROVIDES_' + pkg) or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -050057 if pkg not in provs:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050058 d.appendVar('RPROVIDES_' + pkg, " " + pkg + " (=" + d.getVar("PKGV") + ")")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050059
60 def auto_libname(packages, orig_pkg):
Brad Bishop316dfdd2018-06-25 12:45:53 -040061 p = lambda var: pathlib.PurePath(d.getVar(var))
62 libdirs = (p("base_libdir"), p("libdir"))
63 bindirs = (p("base_bindir"), p("base_sbindir"), p("bindir"), p("sbindir"))
64
Patrick Williamsc124f4f2015-09-15 14:41:29 -050065 sonames = []
66 has_bins = 0
67 has_libs = 0
Brad Bishop316dfdd2018-06-25 12:45:53 -040068 for f in pkgfiles[orig_pkg]:
69 # This is .../packages-split/orig_pkg/
70 pkgpath = pathlib.PurePath(pkgdest, orig_pkg)
71 # Strip pkgpath off the full path to a file in the package, re-root
72 # so it is absolute, and then get the parent directory of the file.
73 path = pathlib.PurePath("/") / (pathlib.PurePath(f).relative_to(pkgpath).parent)
74 if path in bindirs:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050075 has_bins = 1
Brad Bishop316dfdd2018-06-25 12:45:53 -040076 if path in libdirs:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050077 has_libs = 1
Brad Bishop316dfdd2018-06-25 12:45:53 -040078 if so_re.match(os.path.basename(f)):
79 try:
80 cmd = [d.expand("${TARGET_PREFIX}objdump"), "-p", f]
81 output = subprocess.check_output(cmd).decode("utf-8")
Brad Bishop19323692019-04-05 15:28:33 -040082 for m in re.finditer(r"\s+SONAME\s+([^\s]+)", output):
Brad Bishop316dfdd2018-06-25 12:45:53 -040083 if m.group(1) not in sonames:
84 sonames.append(m.group(1))
85 except subprocess.CalledProcessError:
86 pass
Patrick Williamsc124f4f2015-09-15 14:41:29 -050087 bb.debug(1, 'LIBNAMES: pkg %s libs %d bins %d sonames %s' % (orig_pkg, has_libs, has_bins, sonames))
88 soname = None
89 if len(sonames) == 1:
90 soname = sonames[0]
91 elif len(sonames) > 1:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050092 lead = d.getVar('LEAD_SONAME')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050093 if lead:
94 r = re.compile(lead)
95 filtered = []
96 for s in sonames:
97 if r.match(s):
98 filtered.append(s)
99 if len(filtered) == 1:
100 soname = filtered[0]
101 elif len(filtered) > 1:
102 bb.note("Multiple matches (%s) for LEAD_SONAME '%s'" % (", ".join(filtered), lead))
103 else:
104 bb.note("Multiple libraries (%s) found, but LEAD_SONAME '%s' doesn't match any of them" % (", ".join(sonames), lead))
105 else:
106 bb.note("Multiple libraries (%s) found and LEAD_SONAME not defined" % ", ".join(sonames))
107
108 if has_libs and not has_bins and soname:
109 soname_result = socrunch(soname)
110 if soname_result:
111 (pkgname, devname) = soname_result
112 for pkg in packages.split():
113 if (d.getVar('PKG_' + pkg, False) or d.getVar('DEBIAN_NOAUTONAME_' + pkg, False)):
114 add_rprovides(pkg, d)
115 continue
116 debian_pn = d.getVar('DEBIANNAME_' + pkg, False)
117 if debian_pn:
118 newpkg = debian_pn
119 elif pkg == orig_pkg:
120 newpkg = pkgname
121 else:
122 newpkg = pkg.replace(orig_pkg, devname, 1)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500123 mlpre=d.getVar('MLPREFIX')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500124 if mlpre:
125 if not newpkg.find(mlpre) == 0:
126 newpkg = mlpre + newpkg
127 if newpkg != pkg:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400128 bb.note("debian: renaming %s to %s" % (pkg, newpkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500129 d.setVar('PKG_' + pkg, newpkg)
130 add_rprovides(pkg, d)
131 else:
132 add_rprovides(orig_pkg, d)
133
134 # reversed sort is needed when some package is substring of another
135 # ie in ncurses we get without reverse sort:
136 # DEBUG: LIBNAMES: pkgname libtic5 devname libtic pkg ncurses-libtic orig_pkg ncurses-libtic debian_pn None newpkg libtic5
137 # and later
138 # DEBUG: LIBNAMES: pkgname libtic5 devname libtic pkg ncurses-libticw orig_pkg ncurses-libtic debian_pn None newpkg libticw
139 # so we need to handle ncurses-libticw->libticw5 before ncurses-libtic->libtic5
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500140 for pkg in sorted((d.getVar('AUTO_LIBNAME_PKGS') or "").split(), reverse=True):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500141 auto_libname(packages, pkg)
142}
143
144EXPORT_FUNCTIONS package_name_hook
145
146DEBIAN_NAMES = "1"