Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 1 | # |
| 2 | # Copyright OpenEmbedded Contributors |
| 3 | # |
| 4 | # SPDX-License-Identifier: MIT |
| 5 | # |
| 6 | |
| 7 | # |
| 8 | # Packaging process |
| 9 | # |
| 10 | # Executive summary: This class iterates over the functions listed in PACKAGEFUNCS |
| 11 | # Taking D and splitting it up into the packages listed in PACKAGES, placing the |
| 12 | # resulting output in PKGDEST. |
| 13 | # |
| 14 | # There are the following default steps but PACKAGEFUNCS can be extended: |
| 15 | # |
| 16 | # a) package_convert_pr_autoinc - convert AUTOINC in PKGV to ${PRSERV_PV_AUTOINC} |
| 17 | # |
| 18 | # b) perform_packagecopy - Copy D into PKGD |
| 19 | # |
| 20 | # c) package_do_split_locales - Split out the locale files, updates FILES and PACKAGES |
| 21 | # |
| 22 | # d) split_and_strip_files - split the files into runtime and debug and strip them. |
| 23 | # Debug files include debug info split, and associated sources that end up in -dbg packages |
| 24 | # |
| 25 | # e) fixup_perms - Fix up permissions in the package before we split it. |
| 26 | # |
| 27 | # f) populate_packages - Split the files in PKGD into separate packages in PKGDEST/<pkgname> |
| 28 | # Also triggers the binary stripping code to put files in -dbg packages. |
| 29 | # |
| 30 | # g) package_do_filedeps - Collect perfile run-time dependency metadata |
| 31 | # The data is stores in FILER{PROVIDES,DEPENDS}_file_pkg variables with |
| 32 | # a list of affected files in FILER{PROVIDES,DEPENDS}FLIST_pkg |
| 33 | # |
| 34 | # h) package_do_shlibs - Look at the shared libraries generated and autotmatically add any |
| 35 | # dependencies found. Also stores the package name so anyone else using this library |
| 36 | # knows which package to depend on. |
| 37 | # |
| 38 | # i) package_do_pkgconfig - Keep track of which packages need and provide which .pc files |
| 39 | # |
| 40 | # j) read_shlibdeps - Reads the stored shlibs information into the metadata |
| 41 | # |
| 42 | # k) package_depchains - Adds automatic dependencies to -dbg and -dev packages |
| 43 | # |
| 44 | # l) emit_pkgdata - saves the packaging data into PKGDATA_DIR for use in later |
| 45 | # packaging steps |
| 46 | |
| 47 | inherit packagedata |
| 48 | inherit chrpath |
| 49 | inherit package_pkgdata |
| 50 | inherit insane |
| 51 | |
| 52 | PKGD = "${WORKDIR}/package" |
| 53 | PKGDEST = "${WORKDIR}/packages-split" |
| 54 | |
| 55 | LOCALE_SECTION ?= '' |
| 56 | |
| 57 | ALL_MULTILIB_PACKAGE_ARCHS = "${@all_multilib_tune_values(d, 'PACKAGE_ARCHS')}" |
| 58 | |
| 59 | # rpm is used for the per-file dependency identification |
| 60 | # dwarfsrcfiles is used to determine the list of debug source files |
| 61 | PACKAGE_DEPENDS += "rpm-native dwarfsrcfiles-native" |
| 62 | |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 63 | # If your postinstall can execute at rootfs creation time rather than on |
| 64 | # target but depends on a native/cross tool in order to execute, you need to |
| 65 | # list that tool in PACKAGE_WRITE_DEPS. Target package dependencies belong |
| 66 | # in the package dependencies as normal, this is just for native/cross support |
| 67 | # tools at rootfs build time. |
| 68 | PACKAGE_WRITE_DEPS ??= "" |
| 69 | |
| 70 | def legitimize_package_name(s): |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 71 | return oe.package.legitimize_package_name(s) |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 72 | |
| 73 | def do_split_packages(d, root, file_regex, output_pattern, description, postinst=None, recursive=False, hook=None, extra_depends=None, aux_files_pattern=None, postrm=None, allow_dirs=False, prepend=False, match_path=False, aux_files_pattern_verbatim=None, allow_links=False, summary=None): |
| 74 | """ |
| 75 | Used in .bb files to split up dynamically generated subpackages of a |
| 76 | given package, usually plugins or modules. |
| 77 | |
| 78 | Arguments: |
| 79 | root -- the path in which to search |
| 80 | file_regex -- regular expression to match searched files. Use |
| 81 | parentheses () to mark the part of this expression |
| 82 | that should be used to derive the module name (to be |
| 83 | substituted where %s is used in other function |
| 84 | arguments as noted below) |
| 85 | output_pattern -- pattern to use for the package names. Must include %s. |
| 86 | description -- description to set for each package. Must include %s. |
| 87 | postinst -- postinstall script to use for all packages (as a |
| 88 | string) |
| 89 | recursive -- True to perform a recursive search - default False |
| 90 | hook -- a hook function to be called for every match. The |
| 91 | function will be called with the following arguments |
| 92 | (in the order listed): |
| 93 | f: full path to the file/directory match |
| 94 | pkg: the package name |
| 95 | file_regex: as above |
| 96 | output_pattern: as above |
| 97 | modulename: the module name derived using file_regex |
| 98 | extra_depends -- extra runtime dependencies (RDEPENDS) to be set for |
| 99 | all packages. The default value of None causes a |
| 100 | dependency on the main package (${PN}) - if you do |
| 101 | not want this, pass '' for this parameter. |
| 102 | aux_files_pattern -- extra item(s) to be added to FILES for each |
| 103 | package. Can be a single string item or a list of |
| 104 | strings for multiple items. Must include %s. |
| 105 | postrm -- postrm script to use for all packages (as a string) |
| 106 | allow_dirs -- True allow directories to be matched - default False |
| 107 | prepend -- if True, prepend created packages to PACKAGES instead |
| 108 | of the default False which appends them |
| 109 | match_path -- match file_regex on the whole relative path to the |
| 110 | root rather than just the file name |
| 111 | aux_files_pattern_verbatim -- extra item(s) to be added to FILES for |
| 112 | each package, using the actual derived module name |
| 113 | rather than converting it to something legal for a |
| 114 | package name. Can be a single string item or a list |
| 115 | of strings for multiple items. Must include %s. |
| 116 | allow_links -- True to allow symlinks to be matched - default False |
| 117 | summary -- Summary to set for each package. Must include %s; |
| 118 | defaults to description if not set. |
| 119 | |
| 120 | """ |
| 121 | |
| 122 | dvar = d.getVar('PKGD') |
| 123 | root = d.expand(root) |
| 124 | output_pattern = d.expand(output_pattern) |
| 125 | extra_depends = d.expand(extra_depends) |
| 126 | |
| 127 | # If the root directory doesn't exist, don't error out later but silently do |
| 128 | # no splitting. |
| 129 | if not os.path.exists(dvar + root): |
| 130 | return [] |
| 131 | |
| 132 | ml = d.getVar("MLPREFIX") |
| 133 | if ml: |
| 134 | if not output_pattern.startswith(ml): |
| 135 | output_pattern = ml + output_pattern |
| 136 | |
| 137 | newdeps = [] |
| 138 | for dep in (extra_depends or "").split(): |
| 139 | if dep.startswith(ml): |
| 140 | newdeps.append(dep) |
| 141 | else: |
| 142 | newdeps.append(ml + dep) |
| 143 | if newdeps: |
| 144 | extra_depends = " ".join(newdeps) |
| 145 | |
| 146 | |
| 147 | packages = d.getVar('PACKAGES').split() |
| 148 | split_packages = set() |
| 149 | |
| 150 | if postinst: |
| 151 | postinst = '#!/bin/sh\n' + postinst + '\n' |
| 152 | if postrm: |
| 153 | postrm = '#!/bin/sh\n' + postrm + '\n' |
| 154 | if not recursive: |
| 155 | objs = os.listdir(dvar + root) |
| 156 | else: |
| 157 | objs = [] |
| 158 | for walkroot, dirs, files in os.walk(dvar + root): |
| 159 | for file in files: |
| 160 | relpath = os.path.join(walkroot, file).replace(dvar + root + '/', '', 1) |
| 161 | if relpath: |
| 162 | objs.append(relpath) |
| 163 | |
| 164 | if extra_depends == None: |
| 165 | extra_depends = d.getVar("PN") |
| 166 | |
| 167 | if not summary: |
| 168 | summary = description |
| 169 | |
| 170 | for o in sorted(objs): |
| 171 | import re, stat |
| 172 | if match_path: |
| 173 | m = re.match(file_regex, o) |
| 174 | else: |
| 175 | m = re.match(file_regex, os.path.basename(o)) |
| 176 | |
| 177 | if not m: |
| 178 | continue |
| 179 | f = os.path.join(dvar + root, o) |
| 180 | mode = os.lstat(f).st_mode |
| 181 | if not (stat.S_ISREG(mode) or (allow_links and stat.S_ISLNK(mode)) or (allow_dirs and stat.S_ISDIR(mode))): |
| 182 | continue |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 183 | on = oe.package.legitimize_package_name(m.group(1)) |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 184 | pkg = output_pattern % on |
| 185 | split_packages.add(pkg) |
| 186 | if not pkg in packages: |
| 187 | if prepend: |
| 188 | packages = [pkg] + packages |
| 189 | else: |
| 190 | packages.append(pkg) |
| 191 | oldfiles = d.getVar('FILES:' + pkg) |
| 192 | newfile = os.path.join(root, o) |
| 193 | # These names will be passed through glob() so if the filename actually |
| 194 | # contains * or ? (rare, but possible) we need to handle that specially |
| 195 | newfile = newfile.replace('*', '[*]') |
| 196 | newfile = newfile.replace('?', '[?]') |
| 197 | if not oldfiles: |
| 198 | the_files = [newfile] |
| 199 | if aux_files_pattern: |
| 200 | if type(aux_files_pattern) is list: |
| 201 | for fp in aux_files_pattern: |
| 202 | the_files.append(fp % on) |
| 203 | else: |
| 204 | the_files.append(aux_files_pattern % on) |
| 205 | if aux_files_pattern_verbatim: |
| 206 | if type(aux_files_pattern_verbatim) is list: |
| 207 | for fp in aux_files_pattern_verbatim: |
| 208 | the_files.append(fp % m.group(1)) |
| 209 | else: |
| 210 | the_files.append(aux_files_pattern_verbatim % m.group(1)) |
| 211 | d.setVar('FILES:' + pkg, " ".join(the_files)) |
| 212 | else: |
| 213 | d.setVar('FILES:' + pkg, oldfiles + " " + newfile) |
| 214 | if extra_depends != '': |
| 215 | d.appendVar('RDEPENDS:' + pkg, ' ' + extra_depends) |
| 216 | if not d.getVar('DESCRIPTION:' + pkg): |
| 217 | d.setVar('DESCRIPTION:' + pkg, description % on) |
| 218 | if not d.getVar('SUMMARY:' + pkg): |
| 219 | d.setVar('SUMMARY:' + pkg, summary % on) |
| 220 | if postinst: |
| 221 | d.setVar('pkg_postinst:' + pkg, postinst) |
| 222 | if postrm: |
| 223 | d.setVar('pkg_postrm:' + pkg, postrm) |
| 224 | if callable(hook): |
| 225 | hook(f, pkg, file_regex, output_pattern, m.group(1)) |
| 226 | |
| 227 | d.setVar('PACKAGES', ' '.join(packages)) |
| 228 | return list(split_packages) |
| 229 | |
| 230 | PACKAGE_DEPENDS += "file-native" |
| 231 | |
| 232 | python () { |
| 233 | if d.getVar('PACKAGES') != '': |
| 234 | deps = "" |
| 235 | for dep in (d.getVar('PACKAGE_DEPENDS') or "").split(): |
| 236 | deps += " %s:do_populate_sysroot" % dep |
Patrick Williams | 169d7bc | 2024-01-05 11:33:25 -0600 | [diff] [blame] | 237 | if bb.utils.contains('DISTRO_FEATURES', 'minidebuginfo', True, False, d): |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 238 | deps += ' xz-native:do_populate_sysroot' |
| 239 | d.appendVarFlag('do_package', 'depends', deps) |
| 240 | |
| 241 | # shlibs requires any DEPENDS to have already packaged for the *.list files |
| 242 | d.appendVarFlag('do_package', 'deptask', " do_packagedata") |
| 243 | } |
| 244 | |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 245 | |
| 246 | PRSERV_ACTIVE = "${@bool(d.getVar("PRSERV_HOST"))}" |
| 247 | PRSERV_ACTIVE[vardepvalue] = "${PRSERV_ACTIVE}" |
| 248 | package_get_auto_pr[vardepsexclude] = "BB_TASKDEPDATA" |
| 249 | package_get_auto_pr[vardeps] += "PRSERV_ACTIVE" |
| 250 | python package_get_auto_pr() { |
| 251 | import oe.prservice |
| 252 | |
| 253 | def get_do_package_hash(pn): |
| 254 | if d.getVar("BB_RUNTASK") != "do_package": |
| 255 | taskdepdata = d.getVar("BB_TASKDEPDATA", False) |
| 256 | for dep in taskdepdata: |
| 257 | if taskdepdata[dep][1] == "do_package" and taskdepdata[dep][0] == pn: |
| 258 | return taskdepdata[dep][6] |
| 259 | return None |
| 260 | |
| 261 | # Support per recipe PRSERV_HOST |
| 262 | pn = d.getVar('PN') |
| 263 | host = d.getVar("PRSERV_HOST_" + pn) |
| 264 | if not (host is None): |
| 265 | d.setVar("PRSERV_HOST", host) |
| 266 | |
| 267 | pkgv = d.getVar("PKGV") |
| 268 | |
| 269 | # PR Server not active, handle AUTOINC |
| 270 | if not d.getVar('PRSERV_HOST'): |
| 271 | d.setVar("PRSERV_PV_AUTOINC", "0") |
| 272 | return |
| 273 | |
| 274 | auto_pr = None |
| 275 | pv = d.getVar("PV") |
| 276 | version = d.getVar("PRAUTOINX") |
| 277 | pkgarch = d.getVar("PACKAGE_ARCH") |
| 278 | checksum = get_do_package_hash(pn) |
| 279 | |
| 280 | # If do_package isn't in the dependencies, we can't get the checksum... |
| 281 | if not checksum: |
| 282 | bb.warn('Task %s requested do_package unihash, but it was not available.' % d.getVar('BB_RUNTASK')) |
| 283 | #taskdepdata = d.getVar("BB_TASKDEPDATA", False) |
| 284 | #for dep in taskdepdata: |
| 285 | # bb.warn('%s:%s = %s' % (taskdepdata[dep][0], taskdepdata[dep][1], taskdepdata[dep][6])) |
| 286 | return |
| 287 | |
| 288 | if d.getVar('PRSERV_LOCKDOWN'): |
| 289 | auto_pr = d.getVar('PRAUTO_' + version + '_' + pkgarch) or d.getVar('PRAUTO_' + version) or None |
| 290 | if auto_pr is None: |
| 291 | bb.fatal("Can NOT get PRAUTO from lockdown exported file") |
| 292 | d.setVar('PRAUTO',str(auto_pr)) |
| 293 | return |
| 294 | |
| 295 | try: |
| 296 | conn = oe.prservice.prserv_make_conn(d) |
| 297 | if conn is not None: |
| 298 | if "AUTOINC" in pkgv: |
| 299 | srcpv = bb.fetch2.get_srcrev(d) |
| 300 | base_ver = "AUTOINC-%s" % version[:version.find(srcpv)] |
| 301 | value = conn.getPR(base_ver, pkgarch, srcpv) |
| 302 | d.setVar("PRSERV_PV_AUTOINC", str(value)) |
| 303 | |
| 304 | auto_pr = conn.getPR(version, pkgarch, checksum) |
| 305 | conn.close() |
| 306 | except Exception as e: |
| 307 | bb.fatal("Can NOT get PRAUTO, exception %s" % str(e)) |
| 308 | if auto_pr is None: |
| 309 | bb.fatal("Can NOT get PRAUTO from remote PR service") |
| 310 | d.setVar('PRAUTO',str(auto_pr)) |
| 311 | } |
| 312 | |
| 313 | # |
| 314 | # Package functions suitable for inclusion in PACKAGEFUNCS |
| 315 | # |
| 316 | |
Andrew Geissler | 5082cc7 | 2023-09-11 08:41:39 -0400 | [diff] [blame] | 317 | python package_setup_pkgv() { |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 318 | pkgv = d.getVar("PKGV") |
Andrew Geissler | 5082cc7 | 2023-09-11 08:41:39 -0400 | [diff] [blame] | 319 | # Expand SRCPV into PKGV if not present |
| 320 | srcpv = bb.fetch.get_pkgv_string(d) |
| 321 | if srcpv and "+" in pkgv: |
| 322 | d.appendVar("PKGV", srcpv) |
| 323 | pkgv = d.getVar("PKGV") |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 324 | |
| 325 | # Adjust pkgv as necessary... |
| 326 | if 'AUTOINC' in pkgv: |
| 327 | d.setVar("PKGV", pkgv.replace("AUTOINC", "${PRSERV_PV_AUTOINC}")) |
Andrew Geissler | 5082cc7 | 2023-09-11 08:41:39 -0400 | [diff] [blame] | 328 | } |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 329 | |
Andrew Geissler | 5082cc7 | 2023-09-11 08:41:39 -0400 | [diff] [blame] | 330 | |
| 331 | python package_convert_pr_autoinc() { |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 332 | # Change PRSERV_PV_AUTOINC and EXTENDPRAUTO usage to special values |
| 333 | d.setVar('PRSERV_PV_AUTOINC', '@PRSERV_PV_AUTOINC@') |
| 334 | d.setVar('EXTENDPRAUTO', '@EXTENDPRAUTO@') |
| 335 | } |
| 336 | |
| 337 | LOCALEBASEPN ??= "${PN}" |
| 338 | |
| 339 | python package_do_split_locales() { |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 340 | oe.package.split_locales(d) |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 341 | } |
| 342 | |
| 343 | python perform_packagecopy () { |
| 344 | import subprocess |
| 345 | import shutil |
| 346 | |
| 347 | dest = d.getVar('D') |
| 348 | dvar = d.getVar('PKGD') |
| 349 | |
| 350 | # Start by package population by taking a copy of the installed |
| 351 | # files to operate on |
| 352 | # Preserve sparse files and hard links |
| 353 | cmd = 'tar --exclude=./sysroot-only -cf - -C %s -p -S . | tar -xf - -C %s' % (dest, dvar) |
| 354 | subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT) |
| 355 | |
| 356 | # replace RPATHs for the nativesdk binaries, to make them relocatable |
| 357 | if bb.data.inherits_class('nativesdk', d) or bb.data.inherits_class('cross-canadian', d): |
| 358 | rpath_replace (dvar, d) |
| 359 | } |
| 360 | perform_packagecopy[cleandirs] = "${PKGD}" |
| 361 | perform_packagecopy[dirs] = "${PKGD}" |
| 362 | |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 363 | python populate_packages () { |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 364 | oe.package.populate_packages(d) |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 365 | } |
| 366 | populate_packages[dirs] = "${D}" |
| 367 | |
| 368 | python package_fixsymlinks () { |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 369 | oe.package.process_fixsymlinks(pkgfiles, d) |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 370 | } |
| 371 | |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 372 | python package_package_name_hook() { |
| 373 | """ |
| 374 | A package_name_hook function can be used to rewrite the package names by |
| 375 | changing PKG. For an example, see debian.bbclass. |
| 376 | """ |
| 377 | pass |
| 378 | } |
| 379 | |
| 380 | EXPORT_FUNCTIONS package_name_hook |
| 381 | |
| 382 | |
| 383 | PKGDESTWORK = "${WORKDIR}/pkgdata" |
| 384 | |
| 385 | 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" |
| 386 | |
| 387 | python emit_pkgdata() { |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 388 | import oe.packagedata |
| 389 | oe.packagedata.emit_pkgdata(pkgfiles, d) |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 390 | } |
| 391 | emit_pkgdata[dirs] = "${PKGDESTWORK}/runtime ${PKGDESTWORK}/runtime-reverse ${PKGDESTWORK}/runtime-rprovides ${PKGDESTWORK}/extended" |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 392 | |
| 393 | ldconfig_postinst_fragment() { |
| 394 | if [ x"$D" = "x" ]; then |
| 395 | if [ -x /sbin/ldconfig ]; then /sbin/ldconfig ; fi |
| 396 | fi |
| 397 | } |
| 398 | |
| 399 | RPMDEPS = "${STAGING_LIBDIR_NATIVE}/rpm/rpmdeps --alldeps --define '__font_provides %{nil}'" |
| 400 | |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 401 | python package_do_filedeps() { |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 402 | oe.package.process_filedeps(pkgfiles, d) |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 403 | } |
| 404 | |
| 405 | SHLIBSDIRS = "${WORKDIR_PKGDATA}/${MLPREFIX}shlibs2" |
| 406 | SHLIBSWORKDIR = "${PKGDESTWORK}/${MLPREFIX}shlibs2" |
| 407 | |
| 408 | python package_do_shlibs() { |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 409 | oe.package.process_shlibs(pkgfiles, d) |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 410 | } |
| 411 | |
| 412 | python package_do_pkgconfig () { |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 413 | oe.package.process_pkgconfig(pkgfiles, d) |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 414 | } |
| 415 | |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 416 | python read_shlibdeps () { |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 417 | pkglibdeps = oe.package.read_libdep_files(d) |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 418 | |
| 419 | packages = d.getVar('PACKAGES').split() |
| 420 | for pkg in packages: |
| 421 | rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS:' + pkg) or "") |
| 422 | for dep in sorted(pkglibdeps[pkg]): |
| 423 | # Add the dep if it's not already there, or if no comparison is set |
| 424 | if dep not in rdepends: |
| 425 | rdepends[dep] = [] |
| 426 | for v in pkglibdeps[pkg][dep]: |
| 427 | if v not in rdepends[dep]: |
| 428 | rdepends[dep].append(v) |
| 429 | d.setVar('RDEPENDS:' + pkg, bb.utils.join_deps(rdepends, commasep=False)) |
| 430 | } |
| 431 | |
| 432 | python package_depchains() { |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 433 | oe.package.process_depchains(pkgfiles, d) |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 434 | } |
| 435 | |
| 436 | # Since bitbake can't determine which variables are accessed during package |
| 437 | # iteration, we need to list them here: |
| 438 | 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" |
| 439 | |
| 440 | def gen_packagevar(d, pkgvars="PACKAGEVARS"): |
| 441 | ret = [] |
| 442 | pkgs = (d.getVar("PACKAGES") or "").split() |
| 443 | vars = (d.getVar(pkgvars) or "").split() |
| 444 | for v in vars: |
| 445 | ret.append(v) |
| 446 | for p in pkgs: |
| 447 | for v in vars: |
| 448 | ret.append(v + ":" + p) |
| 449 | |
| 450 | # Ensure that changes to INCOMPATIBLE_LICENSE re-run do_package for |
| 451 | # affected recipes. |
| 452 | ret.append('_exclude_incompatible-%s' % p) |
| 453 | return " ".join(ret) |
| 454 | |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 455 | |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 456 | # Functions for setting up PKGD |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 457 | PACKAGE_PREPROCESS_FUNCS ?= "" |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 458 | # Functions which split PKGD up into separate packages |
| 459 | PACKAGESPLITFUNCS ?= " \ |
| 460 | package_do_split_locales \ |
| 461 | populate_packages" |
| 462 | # Functions which process metadata based on split packages |
| 463 | PACKAGEFUNCS += " \ |
| 464 | package_fixsymlinks \ |
| 465 | package_name_hook \ |
| 466 | package_do_filedeps \ |
| 467 | package_do_shlibs \ |
| 468 | package_do_pkgconfig \ |
| 469 | read_shlibdeps \ |
| 470 | package_depchains \ |
| 471 | emit_pkgdata" |
| 472 | |
| 473 | python do_package () { |
| 474 | # Change the following version to cause sstate to invalidate the package |
| 475 | # cache. This is useful if an item this class depends on changes in a |
| 476 | # way that the output of this class changes. rpmdeps is a good example |
| 477 | # as any change to rpmdeps requires this to be rerun. |
Andrew Geissler | fc113ea | 2023-03-31 09:59:46 -0500 | [diff] [blame] | 478 | # PACKAGE_BBCLASS_VERSION = "5" |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 479 | |
| 480 | # Init cachedpath |
| 481 | global cpath |
| 482 | cpath = oe.cachedpath.CachedPath() |
| 483 | |
| 484 | ########################################################################### |
| 485 | # Sanity test the setup |
| 486 | ########################################################################### |
| 487 | |
| 488 | packages = (d.getVar('PACKAGES') or "").split() |
| 489 | if len(packages) < 1: |
| 490 | bb.debug(1, "No packages to build, skipping do_package") |
| 491 | return |
| 492 | |
| 493 | workdir = d.getVar('WORKDIR') |
| 494 | outdir = d.getVar('DEPLOY_DIR') |
| 495 | dest = d.getVar('D') |
| 496 | dvar = d.getVar('PKGD') |
| 497 | pn = d.getVar('PN') |
| 498 | |
| 499 | if not workdir or not outdir or not dest or not dvar or not pn: |
| 500 | msg = "WORKDIR, DEPLOY_DIR, D, PN and PKGD all must be defined, unable to package" |
| 501 | oe.qa.handle_error("var-undefined", msg, d) |
| 502 | return |
| 503 | |
Andrew Geissler | 5082cc7 | 2023-09-11 08:41:39 -0400 | [diff] [blame] | 504 | bb.build.exec_func("package_setup_pkgv", d) |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 505 | bb.build.exec_func("package_convert_pr_autoinc", d) |
| 506 | |
Andrew Geissler | fc113ea | 2023-03-31 09:59:46 -0500 | [diff] [blame] | 507 | # Check for conflict between renamed packages and existing ones |
| 508 | # for each package in PACKAGES, check if it will be renamed to an existing one |
| 509 | for p in packages: |
Andrew Geissler | 2013739 | 2023-10-12 04:59:14 -0600 | [diff] [blame] | 510 | rename = d.getVar('PKG:%s' % p) |
| 511 | if rename and rename in packages: |
| 512 | bb.fatal('package "%s" is renamed to "%s" using PKG:%s, but package name already exists' % (p, rename, p)) |
Andrew Geissler | fc113ea | 2023-03-31 09:59:46 -0500 | [diff] [blame] | 513 | |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 514 | ########################################################################### |
| 515 | # Optimisations |
| 516 | ########################################################################### |
| 517 | |
| 518 | # Continually expanding complex expressions is inefficient, particularly |
| 519 | # when we write to the datastore and invalidate the expansion cache. This |
| 520 | # code pre-expands some frequently used variables |
| 521 | |
| 522 | def expandVar(x, d): |
| 523 | d.setVar(x, d.getVar(x)) |
| 524 | |
| 525 | for x in 'PN', 'PV', 'BPN', 'TARGET_SYS', 'EXTENDPRAUTO': |
| 526 | expandVar(x, d) |
| 527 | |
| 528 | ########################################################################### |
| 529 | # Setup PKGD (from D) |
| 530 | ########################################################################### |
| 531 | |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 532 | bb.build.exec_func("package_prepare_pkgdata", d) |
| 533 | bb.build.exec_func("perform_packagecopy", d) |
| 534 | for f in (d.getVar('PACKAGE_PREPROCESS_FUNCS') or '').split(): |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 535 | bb.build.exec_func(f, d) |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 536 | oe.package.process_split_and_strip_files(d) |
| 537 | oe.package.fixup_perms(d) |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 538 | |
| 539 | ########################################################################### |
| 540 | # Split up PKGD into PKGDEST |
| 541 | ########################################################################### |
| 542 | |
| 543 | cpath = oe.cachedpath.CachedPath() |
| 544 | |
| 545 | for f in (d.getVar('PACKAGESPLITFUNCS') or '').split(): |
| 546 | bb.build.exec_func(f, d) |
| 547 | |
| 548 | ########################################################################### |
| 549 | # Process PKGDEST |
| 550 | ########################################################################### |
| 551 | |
| 552 | # Build global list of files in each split package |
| 553 | global pkgfiles |
| 554 | pkgfiles = {} |
| 555 | packages = d.getVar('PACKAGES').split() |
| 556 | pkgdest = d.getVar('PKGDEST') |
| 557 | for pkg in packages: |
| 558 | pkgfiles[pkg] = [] |
| 559 | for walkroot, dirs, files in cpath.walk(pkgdest + "/" + pkg): |
| 560 | for file in files: |
| 561 | pkgfiles[pkg].append(walkroot + os.sep + file) |
| 562 | |
| 563 | for f in (d.getVar('PACKAGEFUNCS') or '').split(): |
| 564 | bb.build.exec_func(f, d) |
| 565 | |
| 566 | oe.qa.exit_if_errors(d) |
| 567 | } |
| 568 | |
| 569 | do_package[dirs] = "${SHLIBSWORKDIR} ${D}" |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 570 | do_package[vardeps] += "${PACKAGE_PREPROCESS_FUNCS} ${PACKAGESPLITFUNCS} ${PACKAGEFUNCS} ${@gen_packagevar(d)}" |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 571 | addtask package after do_install |
| 572 | |
| 573 | SSTATETASKS += "do_package" |
| 574 | do_package[cleandirs] = "${PKGDEST} ${PKGDESTWORK}" |
| 575 | do_package[sstate-plaindirs] = "${PKGD} ${PKGDEST} ${PKGDESTWORK}" |
| 576 | do_package_setscene[dirs] = "${STAGING_DIR}" |
| 577 | |
| 578 | python do_package_setscene () { |
| 579 | sstate_setscene(d) |
| 580 | } |
| 581 | addtask do_package_setscene |
| 582 | |
| 583 | # Copy from PKGDESTWORK to tempdirectory as tempdirectory can be cleaned at both |
| 584 | # do_package_setscene and do_packagedata_setscene leading to races |
| 585 | python do_packagedata () { |
Andrew Geissler | 5082cc7 | 2023-09-11 08:41:39 -0400 | [diff] [blame] | 586 | bb.build.exec_func("package_setup_pkgv", d) |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 587 | bb.build.exec_func("package_get_auto_pr", d) |
| 588 | |
| 589 | src = d.expand("${PKGDESTWORK}") |
| 590 | dest = d.expand("${WORKDIR}/pkgdata-pdata-input") |
| 591 | oe.path.copyhardlinktree(src, dest) |
| 592 | |
| 593 | bb.build.exec_func("packagedata_translate_pr_autoinc", d) |
| 594 | } |
| 595 | do_packagedata[cleandirs] += "${WORKDIR}/pkgdata-pdata-input" |
| 596 | |
| 597 | # Translate the EXTENDPRAUTO and AUTOINC to the final values |
| 598 | packagedata_translate_pr_autoinc() { |
| 599 | find ${WORKDIR}/pkgdata-pdata-input -type f | xargs --no-run-if-empty \ |
| 600 | sed -e 's,@PRSERV_PV_AUTOINC@,${PRSERV_PV_AUTOINC},g' \ |
| 601 | -e 's,@EXTENDPRAUTO@,${EXTENDPRAUTO},g' -i |
| 602 | } |
| 603 | |
| 604 | addtask packagedata before do_build after do_package |
| 605 | |
| 606 | SSTATETASKS += "do_packagedata" |
| 607 | do_packagedata[sstate-inputdirs] = "${WORKDIR}/pkgdata-pdata-input" |
| 608 | do_packagedata[sstate-outputdirs] = "${PKGDATA_DIR}" |
| 609 | do_packagedata[stamp-extra-info] = "${MACHINE_ARCH}" |
| 610 | |
| 611 | python do_packagedata_setscene () { |
| 612 | sstate_setscene(d) |
| 613 | } |
| 614 | addtask do_packagedata_setscene |
| 615 | |