aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2011-06-29 09:18:21 (GMT)
committerZac Medico <zmedico@gentoo.org>2011-06-29 09:18:21 (GMT)
commit31c9c68d7e96070166fe385141400fa3bcb5950e (patch)
treed36257a025b6afc9dc0a6d79febbf31d2d7a3822
parentread_corresponding_eapi_file(): Strip final \n from EAPI value. (diff)
downloadportage-31c9c68d7e96070166fe385141400fa3bcb5950e.zip
portage-31c9c68d7e96070166fe385141400fa3bcb5950e.tar.gz
portage-31c9c68d7e96070166fe385141400fa3bcb5950e.tar.bz2
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.py10
-rw-r--r--pym/portage/package/ebuild/doebuild.py81
2 files changed, 90 insertions, 1 deletions
diff --git a/pym/_emerge/EbuildPhase.py b/pym/_emerge/EbuildPhase.py
index 306932f..954c033 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 9df7dc7..35a0b0f 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 = []