diff options
author | Zac Medico <zmedico@gentoo.org> | 2011-06-29 02:18:21 -0700 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2011-06-29 02:18:21 -0700 |
commit | 31c9c68d7e96070166fe385141400fa3bcb5950e (patch) | |
tree | d36257a025b6afc9dc0a6d79febbf31d2d7a3822 | |
parent | f23816d7e520bf1f27eb2778d0129e9ad9d576e4 (diff) | |
download | portage-31c9c68d7e96070166fe385141400fa3bcb5950e.tar.gz portage-31c9c68d7e96070166fe385141400fa3bcb5950e.tar.bz2 portage-31c9c68d7e96070166fe385141400fa3bcb5950e.zip |
Detect/create missing soname symlinks for libs.
This will allow us to safely use the ldconfig -X option for all
ldconfig calls, an thereby avoid having ldconfig override our own
soname symlink policy which allows preserve-libs to work correctly
when libraries are downgraded as discussed in bug 373341.
-rw-r--r-- | pym/_emerge/EbuildPhase.py | 10 | ||||
-rw-r--r-- | pym/portage/package/ebuild/doebuild.py | 81 |
2 files changed, 90 insertions, 1 deletions
diff --git a/pym/_emerge/EbuildPhase.py b/pym/_emerge/EbuildPhase.py index 306932f42..954c0334c 100644 --- a/pym/_emerge/EbuildPhase.py +++ b/pym/_emerge/EbuildPhase.py @@ -18,6 +18,7 @@ portage.proxy.lazyimport.lazyimport(globals(), 'portage.package.ebuild.doebuild:_check_build_log,' + \ '_post_phase_cmds,_post_phase_userpriv_perms,' + \ '_post_src_install_chost_fix,' + \ + '_post_src_install_soname_symlinks,' + \ '_post_src_install_uid_fix,_postinst_bsdflags,' + \ '_preinst_bsdflags' ) @@ -254,6 +255,15 @@ class EbuildPhase(CompositeTask): noiselevel=-1) self._die_hooks() return + + if self.phase == "install": + out = portage.StringIO() + _post_src_install_soname_symlinks(self.settings, out) + msg = _unicode_decode(out.getvalue(), + encoding=_encodings['content'], errors='replace') + if msg: + self.scheduler.output(msg, log_path=log_path) + self._current_task = None self.wait() return diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py index 9df7dc76c..35a0b0ffa 100644 --- a/pym/portage/package/ebuild/doebuild.py +++ b/pym/portage/package/ebuild/doebuild.py @@ -5,6 +5,7 @@ __all__ = ['doebuild', 'doebuild_environment', 'spawn', 'spawnebuild'] import codecs import gzip +import errno from itertools import chain import logging import os as _os @@ -1612,12 +1613,90 @@ def _post_src_install_uid_fix(mysettings, out): mode='w', encoding=_encodings['repo.content'], errors='strict').write(v + '\n') + _reapply_bsdflags_to_image(mysettings) + +def _reapply_bsdflags_to_image(mysettings): + """ + Reapply flags saved and removed by _preinst_bsdflags. + """ if bsd_chflags: - # Restore all of the flags saved above. os.system("mtree -e -p %s -U -k flags < %s > /dev/null" % \ (_shell_quote(mysettings["D"]), _shell_quote(os.path.join(mysettings["T"], "bsdflags.mtree")))) +def _post_src_install_soname_symlinks(mysettings, out): + """ + Check that libraries in $D have corresponding soname symlinks. + If symlinks are missing then create them and trigger a QA Notice. + This requires $PORTAGE_BUILDDIR/build-info/NEEDED.ELF.2 for + operation. + """ + + image_dir = mysettings["D"] + needed_filename = os.path.join(mysettings["PORTAGE_BUILDDIR"], + "build-info", "NEEDED.ELF.2") + + try: + lines = codecs.open(_unicode_encode(needed_filename, + encoding=_encodings['fs'], errors='strict'), + 'r', encoding=_encodings['repo.content'], + errors='replace').readlines() + except IOError as e: + if e.errno not in (errno.ENOENT, errno.ESTALE): + raise + return + + missing_symlinks = [] + + # Parse NEEDED.ELF.2 like LinkageMapELF.rebuild() does. + for l in lines: + l = l.rstrip("\n") + if not l: + continue + fields = l.split(";") + if len(fields) < 5: + portage.util.writemsg_level(_("\nWrong number of fields " \ + "in %s: %s\n\n") % (needed_filename, l), + level=logging.ERROR, noiselevel=-1) + continue + + obj, soname = fields[1:3] + if not soname: + continue + + obj_file_path = os.path.join(image_dir, obj.lstrip(os.sep)) + sym_file_path = os.path.join(os.path.dirname(obj_file_path), soname) + try: + os.lstat(sym_file_path) + except OSError as e: + if e.errno not in (errno.ENOENT, errno.ESTALE): + raise + else: + continue + + missing_symlinks.append((obj, soname)) + + if not missing_symlinks: + return + + qa_msg = ["QA Notice: Missing soname symlink(s) " + \ + "will be automatically created:"] + qa_msg.append("") + qa_msg.extend("\t%s -> %s" % (os.path.join( + os.path.dirname(obj).lstrip(os.sep), soname), + os.path.basename(obj)) + for obj, soname in missing_symlinks) + qa_msg.append("") + for line in qa_msg: + eqawarn(line, key=mysettings.mycpv, out=out) + + _preinst_bsdflags(mysettings) + for obj, soname in missing_symlinks: + obj_file_path = os.path.join(image_dir, obj.lstrip(os.sep)) + sym_file_path = os.path.join(os.path.dirname(obj_file_path), soname) + os.symlink(os.path.basename(obj_file_path), sym_file_path) + _reapply_bsdflags_to_image(mysettings) + def _merge_unicode_error(errors): lines = [] |