diff options
Diffstat (limited to 'meta/lib/oe/package_manager/__init__.py')
-rw-r--r-- | meta/lib/oe/package_manager/__init__.py | 109 |
1 files changed, 57 insertions, 52 deletions
diff --git a/meta/lib/oe/package_manager/__init__.py b/meta/lib/oe/package_manager/__init__.py index 8e7128b195..2100a97c12 100644 --- a/meta/lib/oe/package_manager/__init__.py +++ b/meta/lib/oe/package_manager/__init__.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: GPL-2.0-only | 4 | # SPDX-License-Identifier: GPL-2.0-only |
3 | # | 5 | # |
4 | 6 | ||
@@ -90,7 +92,7 @@ def opkg_query(cmd_output): | |||
90 | 92 | ||
91 | def failed_postinsts_abort(pkgs, log_path): | 93 | def failed_postinsts_abort(pkgs, log_path): |
92 | bb.fatal("""Postinstall scriptlets of %s have failed. If the intention is to defer them to first boot, | 94 | bb.fatal("""Postinstall scriptlets of %s have failed. If the intention is to defer them to first boot, |
93 | then please place them into pkg_postinst_ontarget_${PN} (). | 95 | then please place them into pkg_postinst_ontarget:${PN} (). |
94 | Deferring to first boot via 'exit 1' is no longer supported. | 96 | Deferring to first boot via 'exit 1' is no longer supported. |
95 | Details of the failure are in %s.""" %(pkgs, log_path)) | 97 | Details of the failure are in %s.""" %(pkgs, log_path)) |
96 | 98 | ||
@@ -120,7 +122,8 @@ def generate_locale_archive(d, rootfs, target_arch, localedir): | |||
120 | "riscv32": ["--uint32-align=4", "--little-endian"], | 122 | "riscv32": ["--uint32-align=4", "--little-endian"], |
121 | "i586": ["--uint32-align=4", "--little-endian"], | 123 | "i586": ["--uint32-align=4", "--little-endian"], |
122 | "i686": ["--uint32-align=4", "--little-endian"], | 124 | "i686": ["--uint32-align=4", "--little-endian"], |
123 | "x86_64": ["--uint32-align=4", "--little-endian"] | 125 | "x86_64": ["--uint32-align=4", "--little-endian"], |
126 | "loongarch64": ["--uint32-align=4", "--little-endian"] | ||
124 | } | 127 | } |
125 | if target_arch in locale_arch_options: | 128 | if target_arch in locale_arch_options: |
126 | arch_options = locale_arch_options[target_arch] | 129 | arch_options = locale_arch_options[target_arch] |
@@ -189,7 +192,7 @@ class PackageManager(object, metaclass=ABCMeta): | |||
189 | bb.utils.remove(self.intercepts_dir, True) | 192 | bb.utils.remove(self.intercepts_dir, True) |
190 | bb.utils.mkdirhier(self.intercepts_dir) | 193 | bb.utils.mkdirhier(self.intercepts_dir) |
191 | for intercept in postinst_intercepts: | 194 | for intercept in postinst_intercepts: |
192 | bb.utils.copyfile(intercept, os.path.join(self.intercepts_dir, os.path.basename(intercept))) | 195 | shutil.copy(intercept, os.path.join(self.intercepts_dir, os.path.basename(intercept))) |
193 | 196 | ||
194 | @abstractmethod | 197 | @abstractmethod |
195 | def _handle_intercept_failure(self, failed_script): | 198 | def _handle_intercept_failure(self, failed_script): |
@@ -266,7 +269,7 @@ class PackageManager(object, metaclass=ABCMeta): | |||
266 | pass | 269 | pass |
267 | 270 | ||
268 | @abstractmethod | 271 | @abstractmethod |
269 | def install(self, pkgs, attempt_only=False): | 272 | def install(self, pkgs, attempt_only=False, hard_depends_only=False): |
270 | """ | 273 | """ |
271 | Install a list of packages. 'pkgs' is a list object. If 'attempt_only' is | 274 | Install a list of packages. 'pkgs' is a list object. If 'attempt_only' is |
272 | True, installation failures are ignored. | 275 | True, installation failures are ignored. |
@@ -321,7 +324,7 @@ class PackageManager(object, metaclass=ABCMeta): | |||
321 | # TODO don't have sdk here but have a property on the superclass | 324 | # TODO don't have sdk here but have a property on the superclass |
322 | # (and respect in install_complementary) | 325 | # (and respect in install_complementary) |
323 | if sdk: | 326 | if sdk: |
324 | pkgdatadir = self.d.expand("${TMPDIR}/pkgdata/${SDK_SYS}") | 327 | pkgdatadir = self.d.getVar("PKGDATA_DIR_SDK") |
325 | else: | 328 | else: |
326 | pkgdatadir = self.d.getVar("PKGDATA_DIR") | 329 | pkgdatadir = self.d.getVar("PKGDATA_DIR") |
327 | 330 | ||
@@ -344,10 +347,8 @@ class PackageManager(object, metaclass=ABCMeta): | |||
344 | def install_complementary(self, globs=None): | 347 | def install_complementary(self, globs=None): |
345 | """ | 348 | """ |
346 | Install complementary packages based upon the list of currently installed | 349 | Install complementary packages based upon the list of currently installed |
347 | packages e.g. locales, *-dev, *-dbg, etc. This will only attempt to install | 350 | packages e.g. locales, *-dev, *-dbg, etc. Note: every backend needs to |
348 | these packages, if they don't exist then no error will occur. Note: every | 351 | call this function explicitly after the normal package installation. |
349 | backend needs to call this function explicitly after the normal package | ||
350 | installation | ||
351 | """ | 352 | """ |
352 | if globs is None: | 353 | if globs is None: |
353 | globs = self.d.getVar('IMAGE_INSTALL_COMPLEMENTARY') | 354 | globs = self.d.getVar('IMAGE_INSTALL_COMPLEMENTARY') |
@@ -364,45 +365,43 @@ class PackageManager(object, metaclass=ABCMeta): | |||
364 | for complementary_linguas in (self.d.getVar('IMAGE_LINGUAS_COMPLEMENTARY') or "").split(): | 365 | for complementary_linguas in (self.d.getVar('IMAGE_LINGUAS_COMPLEMENTARY') or "").split(): |
365 | globs += (" " + complementary_linguas) % lang | 366 | globs += (" " + complementary_linguas) % lang |
366 | 367 | ||
367 | if globs is None: | 368 | if globs: |
368 | return | 369 | # we need to write the list of installed packages to a file because the |
369 | 370 | # oe-pkgdata-util reads it from a file | |
370 | # we need to write the list of installed packages to a file because the | 371 | with tempfile.NamedTemporaryFile(mode="w+", prefix="installed-pkgs") as installed_pkgs: |
371 | # oe-pkgdata-util reads it from a file | 372 | pkgs = self.list_installed() |
372 | with tempfile.NamedTemporaryFile(mode="w+", prefix="installed-pkgs") as installed_pkgs: | 373 | |
373 | pkgs = self.list_installed() | 374 | provided_pkgs = set() |
374 | 375 | for pkg in pkgs.values(): | |
375 | provided_pkgs = set() | 376 | provided_pkgs |= set(pkg.get('provs', [])) |
376 | for pkg in pkgs.values(): | 377 | |
377 | provided_pkgs |= set(pkg.get('provs', [])) | 378 | output = oe.utils.format_pkg_list(pkgs, "arch") |
378 | 379 | installed_pkgs.write(output) | |
379 | output = oe.utils.format_pkg_list(pkgs, "arch") | 380 | installed_pkgs.flush() |
380 | installed_pkgs.write(output) | 381 | |
381 | installed_pkgs.flush() | 382 | cmd = ["oe-pkgdata-util", |
382 | 383 | "-p", self.d.getVar('PKGDATA_DIR'), "glob", installed_pkgs.name, | |
383 | cmd = ["oe-pkgdata-util", | 384 | globs] |
384 | "-p", self.d.getVar('PKGDATA_DIR'), "glob", installed_pkgs.name, | 385 | exclude = self.d.getVar('PACKAGE_EXCLUDE_COMPLEMENTARY') |
385 | globs] | 386 | if exclude: |
386 | exclude = self.d.getVar('PACKAGE_EXCLUDE_COMPLEMENTARY') | 387 | cmd.extend(['--exclude=' + '|'.join(exclude.split())]) |
387 | if exclude: | 388 | try: |
388 | cmd.extend(['--exclude=' + '|'.join(exclude.split())]) | 389 | bb.note('Running %s' % cmd) |
389 | try: | 390 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
390 | bb.note('Running %s' % cmd) | 391 | stdout, stderr = proc.communicate() |
391 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | 392 | if stderr: bb.note(stderr.decode("utf-8")) |
392 | stdout, stderr = proc.communicate() | 393 | complementary_pkgs = stdout.decode("utf-8") |
393 | if stderr: bb.note(stderr.decode("utf-8")) | 394 | complementary_pkgs = set(complementary_pkgs.split()) |
394 | complementary_pkgs = stdout.decode("utf-8") | 395 | skip_pkgs = sorted(complementary_pkgs & provided_pkgs) |
395 | complementary_pkgs = set(complementary_pkgs.split()) | 396 | install_pkgs = sorted(complementary_pkgs - provided_pkgs) |
396 | skip_pkgs = sorted(complementary_pkgs & provided_pkgs) | 397 | bb.note("Installing complementary packages ... %s (skipped already provided packages %s)" % ( |
397 | install_pkgs = sorted(complementary_pkgs - provided_pkgs) | 398 | ' '.join(install_pkgs), |
398 | bb.note("Installing complementary packages ... %s (skipped already provided packages %s)" % ( | 399 | ' '.join(skip_pkgs))) |
399 | ' '.join(install_pkgs), | 400 | self.install(install_pkgs, hard_depends_only=True) |
400 | ' '.join(skip_pkgs))) | 401 | except subprocess.CalledProcessError as e: |
401 | self.install(install_pkgs, attempt_only=True) | 402 | bb.fatal("Could not compute complementary packages list. Command " |
402 | except subprocess.CalledProcessError as e: | 403 | "'%s' returned %d:\n%s" % |
403 | bb.fatal("Could not compute complementary packages list. Command " | 404 | (' '.join(cmd), e.returncode, e.output.decode("utf-8"))) |
404 | "'%s' returned %d:\n%s" % | ||
405 | (' '.join(cmd), e.returncode, e.output.decode("utf-8"))) | ||
406 | 405 | ||
407 | if self.d.getVar('IMAGE_LOCALES_ARCHIVE') == '1': | 406 | if self.d.getVar('IMAGE_LOCALES_ARCHIVE') == '1': |
408 | target_arch = self.d.getVar('TARGET_ARCH') | 407 | target_arch = self.d.getVar('TARGET_ARCH') |
@@ -448,7 +447,7 @@ class PackageManager(object, metaclass=ABCMeta): | |||
448 | return res | 447 | return res |
449 | return _append(uris, base_paths) | 448 | return _append(uris, base_paths) |
450 | 449 | ||
451 | def create_packages_dir(d, subrepo_dir, deploydir, taskname, filterbydependencies): | 450 | def create_packages_dir(d, subrepo_dir, deploydir, taskname, filterbydependencies, include_self=False): |
452 | """ | 451 | """ |
453 | Go through our do_package_write_X dependencies and hardlink the packages we depend | 452 | Go through our do_package_write_X dependencies and hardlink the packages we depend |
454 | upon into the repo directory. This prevents us seeing other packages that may | 453 | upon into the repo directory. This prevents us seeing other packages that may |
@@ -469,7 +468,10 @@ def create_packages_dir(d, subrepo_dir, deploydir, taskname, filterbydependencie | |||
469 | # Detect bitbake -b usage | 468 | # Detect bitbake -b usage |
470 | nodeps = d.getVar("BB_LIMITEDDEPS") or False | 469 | nodeps = d.getVar("BB_LIMITEDDEPS") or False |
471 | if nodeps or not filterbydependencies: | 470 | if nodeps or not filterbydependencies: |
472 | oe.path.symlink(deploydir, subrepo_dir, True) | 471 | for arch in d.getVar("ALL_MULTILIB_PACKAGE_ARCHS").split() + d.getVar("ALL_MULTILIB_PACKAGE_ARCHS").replace("-", "_").split(): |
472 | target = os.path.join(deploydir + "/" + arch) | ||
473 | if os.path.exists(target): | ||
474 | oe.path.symlink(target, subrepo_dir + "/" + arch, True) | ||
473 | return | 475 | return |
474 | 476 | ||
475 | start = None | 477 | start = None |
@@ -482,14 +484,17 @@ def create_packages_dir(d, subrepo_dir, deploydir, taskname, filterbydependencie | |||
482 | bb.fatal("Couldn't find ourself in BB_TASKDEPDATA?") | 484 | bb.fatal("Couldn't find ourself in BB_TASKDEPDATA?") |
483 | pkgdeps = set() | 485 | pkgdeps = set() |
484 | start = [start] | 486 | start = [start] |
485 | seen = set(start) | 487 | if include_self: |
488 | seen = set() | ||
489 | else: | ||
490 | seen = set(start) | ||
486 | # Support direct dependencies (do_rootfs -> do_package_write_X) | 491 | # Support direct dependencies (do_rootfs -> do_package_write_X) |
487 | # or indirect dependencies within PN (do_populate_sdk_ext -> do_rootfs -> do_package_write_X) | 492 | # or indirect dependencies within PN (do_populate_sdk_ext -> do_rootfs -> do_package_write_X) |
488 | while start: | 493 | while start: |
489 | next = [] | 494 | next = [] |
490 | for dep2 in start: | 495 | for dep2 in start: |
491 | for dep in taskdepdata[dep2][3]: | 496 | for dep in taskdepdata[dep2][3]: |
492 | if taskdepdata[dep][0] != pn: | 497 | if include_self or taskdepdata[dep][0] != pn: |
493 | if "do_" + taskname in dep: | 498 | if "do_" + taskname in dep: |
494 | pkgdeps.add(dep) | 499 | pkgdeps.add(dep) |
495 | elif dep not in seen: | 500 | elif dep not in seen: |